]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - lib/filter.c
New upstream version 1.2.4
[quagga-debian.git] / lib / filter.c
1 /* Route filtering function.
2  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
3  *
4  * This file is part of GNU Zebra.
5  *
6  * GNU Zebra is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your
9  * option) any later version.
10  *
11  * GNU Zebra is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GNU Zebra; see the file COPYING.  If not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "filter.h"
26 #include "memory.h"
27 #include "command.h"
28 #include "sockunion.h"
29 #include "buffer.h"
30 #include "log.h"
31
32 struct filter_cisco
33 {
34   /* Cisco access-list */
35   int extended;
36   struct in_addr addr;
37   struct in_addr addr_mask;
38   struct in_addr mask;
39   struct in_addr mask_mask;
40 };
41
42 struct filter_zebra
43 {
44   /* If this filter is "exact" match then this flag is set. */
45   int exact;
46
47   /* Prefix information. */
48   struct prefix prefix;
49 };
50
51 /* Filter element of access list */
52 struct filter
53 {
54   /* For doubly linked list. */
55   struct filter *next;
56   struct filter *prev;
57
58   /* Filter type information. */
59   enum filter_type type;
60
61   /* Cisco access-list */
62   int cisco;
63
64   union
65     {
66       struct filter_cisco cfilter;
67       struct filter_zebra zfilter;
68     } u;
69 };
70
71 /* List of access_list. */
72 struct access_list_list
73 {
74   struct access_list *head;
75   struct access_list *tail;
76 };
77
78 /* Master structure of access_list. */
79 struct access_master
80 {
81   /* List of access_list which name is number. */
82   struct access_list_list num;
83
84   /* List of access_list which name is string. */
85   struct access_list_list str;
86
87   /* Hook function which is executed when new access_list is added. */
88   void (*add_hook) (const char *);
89
90   /* Hook function which is executed when access_list is deleted. */
91   void (*delete_hook) (const char *);
92 };
93
94 /* Static structure for IPv4 access_list's master. */
95 static struct access_master access_master_ipv4 = 
96
97   {NULL, NULL},
98   {NULL, NULL},
99   NULL,
100   NULL,
101 };
102
103 #ifdef HAVE_IPV6
104 /* Static structure for IPv6 access_list's master. */
105 static struct access_master access_master_ipv6 = 
106
107   {NULL, NULL},
108   {NULL, NULL},
109   NULL,
110   NULL,
111 };
112 #endif /* HAVE_IPV6 */
113
114 static struct access_master *
115 access_master_get (afi_t afi)
116 {
117   if (afi == AFI_IP)
118     return &access_master_ipv4;
119 #ifdef HAVE_IPV6
120   else if (afi == AFI_IP6)
121     return &access_master_ipv6;
122 #endif /* HAVE_IPV6 */
123   return NULL;
124 }
125
126 /* Allocate new filter structure. */
127 static struct filter *
128 filter_new (void)
129 {
130   return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
131                                     sizeof (struct filter));
132 }
133
134 static void
135 filter_free (struct filter *filter)
136 {
137   XFREE (MTYPE_ACCESS_FILTER, filter);
138 }
139
140 /* Return string of filter_type. */
141 static const char *
142 filter_type_str (struct filter *filter)
143 {
144   switch (filter->type)
145     {
146     case FILTER_PERMIT:
147       return "permit";
148       break;
149     case FILTER_DENY:
150       return "deny";
151       break;
152     case FILTER_DYNAMIC:
153       return "dynamic";
154       break;
155     default:
156       return "";
157       break;
158     }
159 }
160
161 /* If filter match to the prefix then return 1. */
162 static int
163 filter_match_cisco (struct filter *mfilter, struct prefix *p)
164 {
165   struct filter_cisco *filter;
166   struct in_addr mask;
167   u_int32_t check_addr;
168   u_int32_t check_mask;
169
170   filter = &mfilter->u.cfilter;
171   check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
172
173   if (filter->extended)
174     {
175       masklen2ip (p->prefixlen, &mask);
176       check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
177
178       if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
179           && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
180         return 1;
181     }
182   else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
183     return 1;
184
185   return 0;
186 }
187
188 /* If filter match to the prefix then return 1. */
189 static int
190 filter_match_zebra (struct filter *mfilter, struct prefix *p)
191 {
192   struct filter_zebra *filter;
193
194   filter = &mfilter->u.zfilter;
195
196   if (filter->prefix.family == p->family)
197     {
198       if (filter->exact)
199         {
200           if (filter->prefix.prefixlen == p->prefixlen)
201             return prefix_match (&filter->prefix, p);
202           else
203             return 0;
204         }
205       else
206         return prefix_match (&filter->prefix, p);
207     }
208   else
209     return 0;
210 }
211
212 /* Allocate new access list structure. */
213 static struct access_list *
214 access_list_new (void)
215 {
216   return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
217                                          sizeof (struct access_list));
218 }
219
220 /* Free allocated access_list. */
221 static void
222 access_list_free (struct access_list *access)
223 {
224   XFREE (MTYPE_ACCESS_LIST, access);
225 }
226
227 /* Delete access_list from access_master and free it. */
228 static void
229 access_list_delete (struct access_list *access)
230 {
231   struct filter *filter;
232   struct filter *next;
233   struct access_list_list *list;
234   struct access_master *master;
235
236   for (filter = access->head; filter; filter = next)
237     {
238       next = filter->next;
239       filter_free (filter);
240     }
241
242   master = access->master;
243
244   if (access->type == ACCESS_TYPE_NUMBER)
245     list = &master->num;
246   else
247     list = &master->str;
248
249   if (access->next)
250     access->next->prev = access->prev;
251   else
252     list->tail = access->prev;
253
254   if (access->prev)
255     access->prev->next = access->next;
256   else
257     list->head = access->next;
258
259   if (access->name)
260     XFREE (MTYPE_ACCESS_LIST_STR, access->name);
261
262   if (access->remark)
263     XFREE (MTYPE_TMP, access->remark);
264
265   access_list_free (access);
266 }
267
268 /* Insert new access list to list of access_list.  Each acceess_list
269    is sorted by the name. */
270 static struct access_list *
271 access_list_insert (afi_t afi, const char *name)
272 {
273   unsigned int i;
274   long number;
275   struct access_list *access;
276   struct access_list *point;
277   struct access_list_list *alist;
278   struct access_master *master;
279
280   master = access_master_get (afi);
281   if (master == NULL)
282     return NULL;
283
284   /* Allocate new access_list and copy given name. */
285   access = access_list_new ();
286   access->name = XSTRDUP (MTYPE_ACCESS_LIST_STR, name);
287   access->master = master;
288
289   /* If name is made by all digit character.  We treat it as
290      number. */
291   for (number = 0, i = 0; i < strlen (name); i++)
292     {
293       if (isdigit ((int) name[i]))
294         number = (number * 10) + (name[i] - '0');
295       else
296         break;
297     }
298
299   /* In case of name is all digit character */
300   if (i == strlen (name))
301     {
302       access->type = ACCESS_TYPE_NUMBER;
303
304       /* Set access_list to number list. */
305       alist = &master->num;
306
307       for (point = alist->head; point; point = point->next)
308         if (atol (point->name) >= number)
309           break;
310     }
311   else
312     {
313       access->type = ACCESS_TYPE_STRING;
314
315       /* Set access_list to string list. */
316       alist = &master->str;
317   
318       /* Set point to insertion point. */
319       for (point = alist->head; point; point = point->next)
320         if (point->name && strcmp (point->name, name) >= 0)
321           break;
322     }
323
324   /* In case of this is the first element of master. */
325   if (alist->head == NULL)
326     {
327       alist->head = alist->tail = access;
328       return access;
329     }
330
331   /* In case of insertion is made at the tail of access_list. */
332   if (point == NULL)
333     {
334       access->prev = alist->tail;
335       alist->tail->next = access;
336       alist->tail = access;
337       return access;
338     }
339
340   /* In case of insertion is made at the head of access_list. */
341   if (point == alist->head)
342     {
343       access->next = alist->head;
344       alist->head->prev = access;
345       alist->head = access;
346       return access;
347     }
348
349   /* Insertion is made at middle of the access_list. */
350   access->next = point;
351   access->prev = point->prev;
352
353   if (point->prev)
354     point->prev->next = access;
355   point->prev = access;
356
357   return access;
358 }
359
360 /* Lookup access_list from list of access_list by name. */
361 struct access_list *
362 access_list_lookup (afi_t afi, const char *name)
363 {
364   struct access_list *access;
365   struct access_master *master;
366
367   if (name == NULL)
368     return NULL;
369
370   master = access_master_get (afi);
371   if (master == NULL)
372     return NULL;
373
374   for (access = master->num.head; access; access = access->next)
375     if (access->name && strcmp (access->name, name) == 0)
376       return access;
377
378   for (access = master->str.head; access; access = access->next)
379     if (access->name && strcmp (access->name, name) == 0)
380       return access;
381
382   return NULL;
383 }
384
385 /* Get access list from list of access_list.  If there isn't matched
386    access_list create new one and return it. */
387 static struct access_list *
388 access_list_get (afi_t afi, const char *name)
389 {
390   struct access_list *access;
391
392   access = access_list_lookup (afi, name);
393   if (access == NULL)
394     access = access_list_insert (afi, name);
395   return access;
396 }
397
398 /* Apply access list to object (which should be struct prefix *). */
399 enum filter_type
400 access_list_apply (struct access_list *access, void *object)
401 {
402   struct filter *filter;
403   struct prefix *p;
404
405   p = (struct prefix *) object;
406
407   if (access == NULL)
408     return FILTER_DENY;
409
410   for (filter = access->head; filter; filter = filter->next)
411     {
412       if (filter->cisco)
413         {
414           if (filter_match_cisco (filter, p))
415             return filter->type;
416         }
417       else
418         {
419           if (filter_match_zebra (filter, p))
420             return filter->type;
421         }
422     }
423
424   return FILTER_DENY;
425 }
426
427 /* Add hook function. */
428 void
429 access_list_add_hook (void (*func) (const char *))
430 {
431   access_master_ipv4.add_hook = func;
432 #ifdef HAVE_IPV6
433   access_master_ipv6.add_hook = func;
434 #endif /* HAVE_IPV6 */
435 }
436
437 /* Delete hook function. */
438 void
439 access_list_delete_hook (void (*func) (const char *))
440 {
441   access_master_ipv4.delete_hook = func;
442 #ifdef HAVE_IPV6
443   access_master_ipv6.delete_hook = func;
444 #endif /* HAVE_IPV6 */
445 }
446
447 /* Add new filter to the end of specified access_list. */
448 static void
449 access_list_filter_add (struct access_list *access, struct filter *filter)
450 {
451   filter->next = NULL;
452   filter->prev = access->tail;
453
454   if (access->tail)
455     access->tail->next = filter;
456   else
457     access->head = filter;
458   access->tail = filter;
459
460   /* Run hook function. */
461   if (access->master->add_hook)
462     (*access->master->add_hook) (access->name);
463 }
464
465 /* If access_list has no filter then return 1. */
466 static int
467 access_list_empty (struct access_list *access)
468 {
469   if (access->head == NULL && access->tail == NULL)
470     return 1;
471   else
472     return 0;
473 }
474
475 /* Delete filter from specified access_list.  If there is hook
476    function execute it. */
477 static void
478 access_list_filter_delete (struct access_list *access, struct filter *filter)
479 {
480   struct access_master *master;
481   /* transfer ownership of access->name to a local, to retain the name
482    * to pass to a delete hook, while the access-list is deleted
483    *
484    * It is important that access-lists that are deleted, or are in process
485    * of being deleted, are not visible via access_list_lookup. This is
486    * because some (all?) users process the delete_hook callback the same
487    * as an add - they simply refresh all their access_list name references
488    * by looking up the name.
489    *
490    * If an access list can be looked up while being deleted, such users will
491    * not remove an access-list, and will keep dangling references to
492    * freed access lists.
493    */
494   char *name = access->name;
495   access->name = NULL;
496   
497   master = access->master;
498
499   if (filter->next)
500     filter->next->prev = filter->prev;
501   else
502     access->tail = filter->prev;
503
504   if (filter->prev)
505     filter->prev->next = filter->next;
506   else
507     access->head = filter->next;
508
509   filter_free (filter);
510   
511   /* If access_list becomes empty delete it from access_master. */
512   if (access_list_empty (access))
513     access_list_delete (access);
514   
515   /* Run hook function. */
516   if (master->delete_hook)
517     (*master->delete_hook) (name);
518   
519   XFREE (MTYPE_ACCESS_LIST_STR, name);
520 }
521
522 /*
523   deny    Specify packets to reject
524   permit  Specify packets to forward
525   dynamic ?
526 */
527
528 /*
529   Hostname or A.B.C.D  Address to match
530   any                  Any source host
531   host                 A single host address
532 */
533
534 static struct filter *
535 filter_lookup_cisco (struct access_list *access, struct filter *mnew)
536 {
537   struct filter *mfilter;
538   struct filter_cisco *filter;
539   struct filter_cisco *new;
540
541   new = &mnew->u.cfilter;
542
543   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
544     {
545       filter = &mfilter->u.cfilter;
546
547       if (filter->extended)
548         {
549           if (mfilter->type == mnew->type
550               && filter->addr.s_addr == new->addr.s_addr
551               && filter->addr_mask.s_addr == new->addr_mask.s_addr
552               && filter->mask.s_addr == new->mask.s_addr
553               && filter->mask_mask.s_addr == new->mask_mask.s_addr)
554             return mfilter;
555         }
556       else
557         {
558           if (mfilter->type == mnew->type
559               && filter->addr.s_addr == new->addr.s_addr
560               && filter->addr_mask.s_addr == new->addr_mask.s_addr)
561             return mfilter;
562         }
563     }
564
565   return NULL;
566 }
567
568 static struct filter *
569 filter_lookup_zebra (struct access_list *access, struct filter *mnew)
570 {
571   struct filter *mfilter;
572   struct filter_zebra *filter;
573   struct filter_zebra *new;
574
575   new = &mnew->u.zfilter;
576
577   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
578     {
579       filter = &mfilter->u.zfilter;
580
581       if (filter->exact == new->exact
582           && mfilter->type == mnew->type
583           && prefix_same (&filter->prefix, &new->prefix))
584         return mfilter;
585     }
586   return NULL;
587 }
588
589 static int
590 vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
591 {
592   struct access_list *access;
593
594   access = access_list_lookup (afi, name);
595   if (! access)
596     {
597       vty_out (vty, "%% access-list %s doesn't exist%s", name,
598                VTY_NEWLINE);
599       return CMD_WARNING;
600     }
601
602   if (access->remark)
603     {
604       XFREE (MTYPE_TMP, access->remark);
605       access->remark = NULL;
606     }
607
608   if (access->head == NULL && access->tail == NULL && access->remark == NULL)
609     access_list_delete (access);
610
611   return CMD_SUCCESS;
612 }
613
614 static int
615 filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
616                   const char *addr_str, const char *addr_mask_str,
617                   const char *mask_str, const char *mask_mask_str,
618                   int extended, int set)
619 {
620   int ret;
621   enum filter_type type;
622   struct filter *mfilter;
623   struct filter_cisco *filter;
624   struct access_list *access;
625   struct in_addr addr;
626   struct in_addr addr_mask;
627   struct in_addr mask;
628   struct in_addr mask_mask;
629
630   /* Check of filter type. */
631   if (strncmp (type_str, "p", 1) == 0)
632     type = FILTER_PERMIT;
633   else if (strncmp (type_str, "d", 1) == 0)
634     type = FILTER_DENY;
635   else
636     {
637       vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
638       return CMD_WARNING;
639     }
640
641   ret = inet_aton (addr_str, &addr);
642   if (ret <= 0)
643     {
644       vty_out (vty, "%%Inconsistent address and mask%s",
645                VTY_NEWLINE);
646       return CMD_WARNING;
647     }
648
649   ret = inet_aton (addr_mask_str, &addr_mask);
650   if (ret <= 0)
651     {
652       vty_out (vty, "%%Inconsistent address and mask%s",
653                VTY_NEWLINE);
654       return CMD_WARNING;
655     }
656
657   if (extended)
658     {
659       ret = inet_aton (mask_str, &mask);
660       if (ret <= 0)
661         {
662           vty_out (vty, "%%Inconsistent address and mask%s",
663                    VTY_NEWLINE);
664           return CMD_WARNING;
665         }
666
667       ret = inet_aton (mask_mask_str, &mask_mask);
668       if (ret <= 0)
669         {
670           vty_out (vty, "%%Inconsistent address and mask%s",
671                    VTY_NEWLINE);
672           return CMD_WARNING;
673         }
674     }
675
676   mfilter = filter_new();
677   mfilter->type = type;
678   mfilter->cisco = 1;
679   filter = &mfilter->u.cfilter;
680   filter->extended = extended;
681   filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
682   filter->addr_mask.s_addr = addr_mask.s_addr;
683
684   if (extended)
685     {
686       filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
687       filter->mask_mask.s_addr = mask_mask.s_addr;
688     }
689
690   /* Install new filter to the access_list. */
691   access = access_list_get (AFI_IP, name_str);
692
693   if (set)
694     {
695       if (filter_lookup_cisco (access, mfilter))
696         filter_free (mfilter);
697       else
698         access_list_filter_add (access, mfilter);
699     }
700   else
701     {
702       struct filter *delete_filter;
703
704       delete_filter = filter_lookup_cisco (access, mfilter);
705       if (delete_filter)
706         access_list_filter_delete (access, delete_filter);
707
708       filter_free (mfilter);
709     }
710
711   return CMD_SUCCESS;
712 }
713
714 /* Standard access-list */
715 DEFUN (access_list_standard,
716        access_list_standard_cmd,
717        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
718        "Add an access list entry\n"
719        "IP standard access list\n"
720        "IP standard access list (expanded range)\n"
721        "Specify packets to reject\n"
722        "Specify packets to forward\n"
723        "Address to match\n"
724        "Wildcard bits\n")
725 {
726   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
727                            NULL, NULL, 0, 1);
728 }
729
730 DEFUN (access_list_standard_nomask,
731        access_list_standard_nomask_cmd,
732        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
733        "Add an access list entry\n"
734        "IP standard access list\n"
735        "IP standard access list (expanded range)\n"
736        "Specify packets to reject\n"
737        "Specify packets to forward\n"
738        "Address to match\n")
739 {
740   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
741                            NULL, NULL, 0, 1);
742 }
743
744 DEFUN (access_list_standard_host,
745        access_list_standard_host_cmd,
746        "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
747        "Add an access list entry\n"
748        "IP standard access list\n"
749        "IP standard access list (expanded range)\n"
750        "Specify packets to reject\n"
751        "Specify packets to forward\n"
752        "A single host address\n"
753        "Address to match\n")
754 {
755   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
756                            NULL, NULL, 0, 1);
757 }
758
759 DEFUN (access_list_standard_any,
760        access_list_standard_any_cmd,
761        "access-list (<1-99>|<1300-1999>) (deny|permit) any",
762        "Add an access list entry\n"
763        "IP standard access list\n"
764        "IP standard access list (expanded range)\n"
765        "Specify packets to reject\n"
766        "Specify packets to forward\n"
767        "Any source host\n")
768 {
769   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
770                            "255.255.255.255", NULL, NULL, 0, 1);
771 }
772
773 DEFUN (no_access_list_standard,
774        no_access_list_standard_cmd,
775        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
776        NO_STR
777        "Add an access list entry\n"
778        "IP standard access list\n"
779        "IP standard access list (expanded range)\n"
780        "Specify packets to reject\n"
781        "Specify packets to forward\n"
782        "Address to match\n"
783        "Wildcard bits\n")
784 {
785   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
786                            NULL, NULL, 0, 0);
787 }
788
789 DEFUN (no_access_list_standard_nomask,
790        no_access_list_standard_nomask_cmd,
791        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
792        NO_STR
793        "Add an access list entry\n"
794        "IP standard access list\n"
795        "IP standard access list (expanded range)\n"
796        "Specify packets to reject\n"
797        "Specify packets to forward\n"
798        "Address to match\n")
799 {
800   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
801                            NULL, NULL, 0, 0);
802 }
803
804 DEFUN (no_access_list_standard_host,
805        no_access_list_standard_host_cmd,
806        "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
807        NO_STR
808        "Add an access list entry\n"
809        "IP standard access list\n"
810        "IP standard access list (expanded range)\n"
811        "Specify packets to reject\n"
812        "Specify packets to forward\n"
813        "A single host address\n"
814        "Address to match\n")
815 {
816   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
817                            NULL, NULL, 0, 0);
818 }
819
820 DEFUN (no_access_list_standard_any,
821        no_access_list_standard_any_cmd,
822        "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
823        NO_STR
824        "Add an access list entry\n"
825        "IP standard access list\n"
826        "IP standard access list (expanded range)\n"
827        "Specify packets to reject\n"
828        "Specify packets to forward\n"
829        "Any source host\n")
830 {
831   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
832                            "255.255.255.255", NULL, NULL, 0, 0);
833 }
834
835 /* Extended access-list */
836 DEFUN (access_list_extended,
837        access_list_extended_cmd,
838        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
839        "Add an access list entry\n"
840        "IP extended access list\n"
841        "IP extended access list (expanded range)\n"
842        "Specify packets to reject\n"
843        "Specify packets to forward\n"
844        "Any Internet Protocol\n"
845        "Source address\n"
846        "Source wildcard bits\n"
847        "Destination address\n"
848        "Destination Wildcard bits\n")
849 {
850   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
851                            argv[3], argv[4], argv[5], 1 ,1);
852 }
853
854 DEFUN (access_list_extended_mask_any,
855        access_list_extended_mask_any_cmd,
856        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
857        "Add an access list entry\n"
858        "IP extended access list\n"
859        "IP extended access list (expanded range)\n"
860        "Specify packets to reject\n"
861        "Specify packets to forward\n"
862        "Any Internet Protocol\n"
863        "Source address\n"
864        "Source wildcard bits\n"
865        "Any destination host\n")
866 {
867   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
868                            argv[3], "0.0.0.0",
869                            "255.255.255.255", 1, 1);
870 }
871
872 DEFUN (access_list_extended_any_mask,
873        access_list_extended_any_mask_cmd,
874        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
875        "Add an access list entry\n"
876        "IP extended access list\n"
877        "IP extended access list (expanded range)\n"
878        "Specify packets to reject\n"
879        "Specify packets to forward\n"
880        "Any Internet Protocol\n"
881        "Any source host\n"
882        "Destination address\n"
883        "Destination Wildcard bits\n")
884 {
885   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
886                            "255.255.255.255", argv[2],
887                            argv[3], 1, 1);
888 }
889
890 DEFUN (access_list_extended_any_any,
891        access_list_extended_any_any_cmd,
892        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
893        "Add an access list entry\n"
894        "IP extended access list\n"
895        "IP extended access list (expanded range)\n"
896        "Specify packets to reject\n"
897        "Specify packets to forward\n"
898        "Any Internet Protocol\n"
899        "Any source host\n"
900        "Any destination host\n")
901 {
902   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
903                            "255.255.255.255", "0.0.0.0",
904                            "255.255.255.255", 1, 1);
905 }
906
907 DEFUN (access_list_extended_mask_host,
908        access_list_extended_mask_host_cmd,
909        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
910        "Add an access list entry\n"
911        "IP extended access list\n"
912        "IP extended access list (expanded range)\n"
913        "Specify packets to reject\n"
914        "Specify packets to forward\n"
915        "Any Internet Protocol\n"
916        "Source address\n"
917        "Source wildcard bits\n"
918        "A single destination host\n"
919        "Destination address\n")
920 {
921   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
922                            argv[3], argv[4],
923                            "0.0.0.0", 1, 1);
924 }
925
926 DEFUN (access_list_extended_host_mask,
927        access_list_extended_host_mask_cmd,
928        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
929        "Add an access list entry\n"
930        "IP extended access list\n"
931        "IP extended access list (expanded range)\n"
932        "Specify packets to reject\n"
933        "Specify packets to forward\n"
934        "Any Internet Protocol\n"
935        "A single source host\n"
936        "Source address\n"
937        "Destination address\n"
938        "Destination Wildcard bits\n")
939 {
940   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
941                            "0.0.0.0", argv[3],
942                            argv[4], 1, 1);
943 }
944
945 DEFUN (access_list_extended_host_host,
946        access_list_extended_host_host_cmd,
947        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
948        "Add an access list entry\n"
949        "IP extended access list\n"
950        "IP extended access list (expanded range)\n"
951        "Specify packets to reject\n"
952        "Specify packets to forward\n"
953        "Any Internet Protocol\n"
954        "A single source host\n"
955        "Source address\n"
956        "A single destination host\n"
957        "Destination address\n")
958 {
959   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
960                            "0.0.0.0", argv[3],
961                            "0.0.0.0", 1, 1);
962 }
963
964 DEFUN (access_list_extended_any_host,
965        access_list_extended_any_host_cmd,
966        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
967        "Add an access list entry\n"
968        "IP extended access list\n"
969        "IP extended access list (expanded range)\n"
970        "Specify packets to reject\n"
971        "Specify packets to forward\n"
972        "Any Internet Protocol\n"
973        "Any source host\n"
974        "A single destination host\n"
975        "Destination address\n")
976 {
977   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
978                            "255.255.255.255", argv[2],
979                            "0.0.0.0", 1, 1);
980 }
981
982 DEFUN (access_list_extended_host_any,
983        access_list_extended_host_any_cmd,
984        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
985        "Add an access list entry\n"
986        "IP extended access list\n"
987        "IP extended access list (expanded range)\n"
988        "Specify packets to reject\n"
989        "Specify packets to forward\n"
990        "Any Internet Protocol\n"
991        "A single source host\n"
992        "Source address\n"
993        "Any destination host\n")
994 {
995   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
996                            "0.0.0.0", "0.0.0.0",
997                            "255.255.255.255", 1, 1);
998 }
999
1000 DEFUN (no_access_list_extended,
1001        no_access_list_extended_cmd,
1002        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
1003        NO_STR
1004        "Add an access list entry\n"
1005        "IP extended access list\n"
1006        "IP extended access list (expanded range)\n"
1007        "Specify packets to reject\n"
1008        "Specify packets to forward\n"
1009        "Any Internet Protocol\n"
1010        "Source address\n"
1011        "Source wildcard bits\n"
1012        "Destination address\n"
1013        "Destination Wildcard bits\n")
1014 {
1015   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1016                            argv[3], argv[4], argv[5], 1, 0);
1017 }
1018
1019 DEFUN (no_access_list_extended_mask_any,
1020        no_access_list_extended_mask_any_cmd,
1021        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
1022        NO_STR
1023        "Add an access list entry\n"
1024        "IP extended access list\n"
1025        "IP extended access list (expanded range)\n"
1026        "Specify packets to reject\n"
1027        "Specify packets to forward\n"
1028        "Any Internet Protocol\n"
1029        "Source address\n"
1030        "Source wildcard bits\n"
1031        "Any destination host\n")
1032 {
1033   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1034                            argv[3], "0.0.0.0",
1035                            "255.255.255.255", 1, 0);
1036 }
1037
1038 DEFUN (no_access_list_extended_any_mask,
1039        no_access_list_extended_any_mask_cmd,
1040        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
1041        NO_STR
1042        "Add an access list entry\n"
1043        "IP extended access list\n"
1044        "IP extended access list (expanded range)\n"
1045        "Specify packets to reject\n"
1046        "Specify packets to forward\n"
1047        "Any Internet Protocol\n"
1048        "Any source host\n"
1049        "Destination address\n"
1050        "Destination Wildcard bits\n")
1051 {
1052   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1053                            "255.255.255.255", argv[2],
1054                            argv[3], 1, 0);
1055 }
1056
1057 DEFUN (no_access_list_extended_any_any,
1058        no_access_list_extended_any_any_cmd,
1059        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
1060        NO_STR
1061        "Add an access list entry\n"
1062        "IP extended access list\n"
1063        "IP extended access list (expanded range)\n"
1064        "Specify packets to reject\n"
1065        "Specify packets to forward\n"
1066        "Any Internet Protocol\n"
1067        "Any source host\n"
1068        "Any destination host\n")
1069 {
1070   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1071                            "255.255.255.255", "0.0.0.0",
1072                            "255.255.255.255", 1, 0);
1073 }
1074
1075 DEFUN (no_access_list_extended_mask_host,
1076        no_access_list_extended_mask_host_cmd,
1077        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
1078        NO_STR
1079        "Add an access list entry\n"
1080        "IP extended access list\n"
1081        "IP extended access list (expanded range)\n"
1082        "Specify packets to reject\n"
1083        "Specify packets to forward\n"
1084        "Any Internet Protocol\n"
1085        "Source address\n"
1086        "Source wildcard bits\n"
1087        "A single destination host\n"
1088        "Destination address\n")
1089 {
1090   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1091                            argv[3], argv[4],
1092                            "0.0.0.0", 1, 0);
1093 }
1094
1095 DEFUN (no_access_list_extended_host_mask,
1096        no_access_list_extended_host_mask_cmd,
1097        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
1098        NO_STR
1099        "Add an access list entry\n"
1100        "IP extended access list\n"
1101        "IP extended access list (expanded range)\n"
1102        "Specify packets to reject\n"
1103        "Specify packets to forward\n"
1104        "Any Internet Protocol\n"
1105        "A single source host\n"
1106        "Source address\n"
1107        "Destination address\n"
1108        "Destination Wildcard bits\n")
1109 {
1110   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1111                            "0.0.0.0", argv[3],
1112                            argv[4], 1, 0);
1113 }
1114
1115 DEFUN (no_access_list_extended_host_host,
1116        no_access_list_extended_host_host_cmd,
1117        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
1118        NO_STR
1119        "Add an access list entry\n"
1120        "IP extended access list\n"
1121        "IP extended access list (expanded range)\n"
1122        "Specify packets to reject\n"
1123        "Specify packets to forward\n"
1124        "Any Internet Protocol\n"
1125        "A single source host\n"
1126        "Source address\n"
1127        "A single destination host\n"
1128        "Destination address\n")
1129 {
1130   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1131                            "0.0.0.0", argv[3],
1132                            "0.0.0.0", 1, 0);
1133 }
1134
1135 DEFUN (no_access_list_extended_any_host,
1136        no_access_list_extended_any_host_cmd,
1137        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
1138        NO_STR
1139        "Add an access list entry\n"
1140        "IP extended access list\n"
1141        "IP extended access list (expanded range)\n"
1142        "Specify packets to reject\n"
1143        "Specify packets to forward\n"
1144        "Any Internet Protocol\n"
1145        "Any source host\n"
1146        "A single destination host\n"
1147        "Destination address\n")
1148 {
1149   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1150                            "255.255.255.255", argv[2],
1151                            "0.0.0.0", 1, 0);
1152 }
1153
1154 DEFUN (no_access_list_extended_host_any,
1155        no_access_list_extended_host_any_cmd,
1156        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
1157        NO_STR
1158        "Add an access list entry\n"
1159        "IP extended access list\n"
1160        "IP extended access list (expanded range)\n"
1161        "Specify packets to reject\n"
1162        "Specify packets to forward\n"
1163        "Any Internet Protocol\n"
1164        "A single source host\n"
1165        "Source address\n"
1166        "Any destination host\n")
1167 {
1168   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1169                            "0.0.0.0", "0.0.0.0",
1170                            "255.255.255.255", 1, 0);
1171 }
1172
1173 static int
1174 filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
1175                   afi_t afi, const char *prefix_str, int exact, int set)
1176 {
1177   int ret;
1178   enum filter_type type;
1179   struct filter *mfilter;
1180   struct filter_zebra *filter;
1181   struct access_list *access;
1182   struct prefix p;
1183
1184   /* Check of filter type. */
1185   if (strncmp (type_str, "p", 1) == 0)
1186     type = FILTER_PERMIT;
1187   else if (strncmp (type_str, "d", 1) == 0)
1188     type = FILTER_DENY;
1189   else
1190     {
1191       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
1192       return CMD_WARNING;
1193     }
1194
1195   /* Check string format of prefix and prefixlen. */
1196   if (afi == AFI_IP)
1197     {
1198       ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
1199       if (ret <= 0)
1200         {
1201           vty_out (vty, "IP address prefix/prefixlen is malformed%s",
1202                    VTY_NEWLINE);
1203           return CMD_WARNING;
1204         }
1205     }
1206 #ifdef HAVE_IPV6
1207   else if (afi == AFI_IP6)
1208     {
1209       ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
1210       if (ret <= 0)
1211         {
1212           vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
1213                    VTY_NEWLINE);
1214                    return CMD_WARNING;
1215         }
1216     }
1217 #endif /* HAVE_IPV6 */
1218   else
1219     return CMD_WARNING;
1220
1221   mfilter = filter_new ();
1222   mfilter->type = type;
1223   filter = &mfilter->u.zfilter;
1224   prefix_copy (&filter->prefix, &p);
1225
1226   /* "exact-match" */
1227   if (exact)
1228     filter->exact = 1;
1229
1230   /* Install new filter to the access_list. */
1231   access = access_list_get (afi, name_str);
1232
1233   if (set)
1234     {
1235       if (filter_lookup_zebra (access, mfilter))
1236         filter_free (mfilter);
1237       else
1238         access_list_filter_add (access, mfilter);
1239     }
1240   else
1241     {
1242       struct filter *delete_filter;
1243
1244       delete_filter = filter_lookup_zebra (access, mfilter);
1245       if (delete_filter)
1246         access_list_filter_delete (access, delete_filter);
1247
1248       filter_free (mfilter);
1249     }
1250
1251   return CMD_SUCCESS;
1252 }
1253
1254 /* Zebra access-list */
1255 DEFUN (access_list,
1256        access_list_cmd,
1257        "access-list WORD (deny|permit) A.B.C.D/M",
1258        "Add an access list entry\n"
1259        "IP zebra access-list name\n"
1260        "Specify packets to reject\n"
1261        "Specify packets to forward\n"
1262        "Prefix to match. e.g. 10.0.0.0/8\n")
1263 {
1264   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
1265 }
1266
1267 DEFUN (access_list_exact,
1268        access_list_exact_cmd,
1269        "access-list WORD (deny|permit) A.B.C.D/M exact-match",
1270        "Add an access list entry\n"
1271        "IP zebra access-list name\n"
1272        "Specify packets to reject\n"
1273        "Specify packets to forward\n"
1274        "Prefix to match. e.g. 10.0.0.0/8\n"
1275        "Exact match of the prefixes\n")
1276 {
1277   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
1278 }
1279
1280 DEFUN (access_list_any,
1281        access_list_any_cmd,
1282        "access-list WORD (deny|permit) any",
1283        "Add an access list entry\n"
1284        "IP zebra access-list name\n"
1285        "Specify packets to reject\n"
1286        "Specify packets to forward\n"
1287        "Prefix to match. e.g. 10.0.0.0/8\n")
1288 {
1289   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
1290 }
1291
1292 DEFUN (no_access_list,
1293        no_access_list_cmd,
1294        "no access-list WORD (deny|permit) A.B.C.D/M",
1295        NO_STR
1296        "Add an access list entry\n"
1297        "IP zebra access-list name\n"
1298        "Specify packets to reject\n"
1299        "Specify packets to forward\n"
1300        "Prefix to match. e.g. 10.0.0.0/8\n")
1301 {
1302   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
1303 }
1304
1305 DEFUN (no_access_list_exact,
1306        no_access_list_exact_cmd,
1307        "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
1308        NO_STR
1309        "Add an access list entry\n"
1310        "IP zebra access-list name\n"
1311        "Specify packets to reject\n"
1312        "Specify packets to forward\n"
1313        "Prefix to match. e.g. 10.0.0.0/8\n"
1314        "Exact match of the prefixes\n")
1315 {
1316   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
1317 }
1318
1319 DEFUN (no_access_list_any,
1320        no_access_list_any_cmd,
1321        "no access-list WORD (deny|permit) any",
1322        NO_STR
1323        "Add an access list entry\n"
1324        "IP zebra access-list name\n"
1325        "Specify packets to reject\n"
1326        "Specify packets to forward\n"
1327        "Prefix to match. e.g. 10.0.0.0/8\n")
1328 {
1329   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
1330 }
1331
1332 DEFUN (no_access_list_all,
1333        no_access_list_all_cmd,
1334        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1335        NO_STR
1336        "Add an access list entry\n"
1337        "IP standard access list\n"
1338        "IP extended access list\n"
1339        "IP standard access list (expanded range)\n"
1340        "IP extended access list (expanded range)\n"
1341        "IP zebra access-list name\n")
1342 {
1343   struct access_list *access;
1344   struct access_master *master;
1345   char *name;
1346     
1347   /* Looking up access_list. */
1348   access = access_list_lookup (AFI_IP, argv[0]);
1349   if (access == NULL)
1350     {
1351       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1352                VTY_NEWLINE);
1353       return CMD_WARNING;
1354     }
1355
1356   master = access->master;
1357   /* transfer ownership of access->name to a local, to retain 
1358    * a while longer, past access_list being freed */
1359   name = access->name;
1360   access->name = NULL;
1361   
1362   /* Delete all filter from access-list. */
1363   access_list_delete (access);
1364
1365   /* Run hook function. */
1366   if (master->delete_hook)
1367     (*master->delete_hook) (name);
1368  
1369   XFREE (MTYPE_ACCESS_LIST_STR, name);
1370   
1371   return CMD_SUCCESS;
1372 }
1373
1374 DEFUN (access_list_remark,
1375        access_list_remark_cmd,
1376        "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1377        "Add an access list entry\n"
1378        "IP standard access list\n"
1379        "IP extended access list\n"
1380        "IP standard access list (expanded range)\n"
1381        "IP extended access list (expanded range)\n"
1382        "IP zebra access-list\n"
1383        "Access list entry comment\n"
1384        "Comment up to 100 characters\n")
1385 {
1386   struct access_list *access;
1387
1388   access = access_list_get (AFI_IP, argv[0]);
1389
1390   if (access->remark)
1391     {
1392       XFREE (MTYPE_TMP, access->remark);
1393       access->remark = NULL;
1394     }
1395   access->remark = argv_concat(argv, argc, 1);
1396
1397   return CMD_SUCCESS;
1398 }
1399
1400 DEFUN (no_access_list_remark,
1401        no_access_list_remark_cmd,
1402        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
1403        NO_STR
1404        "Add an access list entry\n"
1405        "IP standard access list\n"
1406        "IP extended access list\n"
1407        "IP standard access list (expanded range)\n"
1408        "IP extended access list (expanded range)\n"
1409        "IP zebra access-list\n"
1410        "Access list entry comment\n")
1411 {
1412   return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
1413 }
1414         
1415 ALIAS (no_access_list_remark,
1416        no_access_list_remark_arg_cmd,
1417        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1418        NO_STR
1419        "Add an access list entry\n"
1420        "IP standard access list\n"
1421        "IP extended access list\n"
1422        "IP standard access list (expanded range)\n"
1423        "IP extended access list (expanded range)\n"
1424        "IP zebra access-list\n"
1425        "Access list entry comment\n"
1426        "Comment up to 100 characters\n")
1427
1428 #ifdef HAVE_IPV6
1429 DEFUN (ipv6_access_list,
1430        ipv6_access_list_cmd,
1431        "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1432        IPV6_STR
1433        "Add an access list entry\n"
1434        "IPv6 zebra access-list\n"
1435        "Specify packets to reject\n"
1436        "Specify packets to forward\n"
1437        "Prefix to match. e.g. 3ffe:506::/32\n")
1438 {
1439   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
1440 }
1441
1442 DEFUN (ipv6_access_list_exact,
1443        ipv6_access_list_exact_cmd,
1444        "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1445        IPV6_STR
1446        "Add an access list entry\n"
1447        "IPv6 zebra access-list\n"
1448        "Specify packets to reject\n"
1449        "Specify packets to forward\n"
1450        "Prefix to match. e.g. 3ffe:506::/32\n"
1451        "Exact match of the prefixes\n")
1452 {
1453   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
1454 }
1455
1456 DEFUN (ipv6_access_list_any,
1457        ipv6_access_list_any_cmd,
1458        "ipv6 access-list WORD (deny|permit) any",
1459        IPV6_STR
1460        "Add an access list entry\n"
1461        "IPv6 zebra access-list\n"
1462        "Specify packets to reject\n"
1463        "Specify packets to forward\n"
1464        "Any prefixi to match\n")
1465 {
1466   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
1467 }
1468
1469 DEFUN (no_ipv6_access_list,
1470        no_ipv6_access_list_cmd,
1471        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1472        NO_STR
1473        IPV6_STR
1474        "Add an access list entry\n"
1475        "IPv6 zebra access-list\n"
1476        "Specify packets to reject\n"
1477        "Specify packets to forward\n"
1478        "Prefix to match. e.g. 3ffe:506::/32\n")
1479 {
1480   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
1481 }
1482
1483 DEFUN (no_ipv6_access_list_exact,
1484        no_ipv6_access_list_exact_cmd,
1485        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1486        NO_STR
1487        IPV6_STR
1488        "Add an access list entry\n"
1489        "IPv6 zebra access-list\n"
1490        "Specify packets to reject\n"
1491        "Specify packets to forward\n"
1492        "Prefix to match. e.g. 3ffe:506::/32\n"
1493        "Exact match of the prefixes\n")
1494 {
1495   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
1496 }
1497
1498 DEFUN (no_ipv6_access_list_any,
1499        no_ipv6_access_list_any_cmd,
1500        "no ipv6 access-list WORD (deny|permit) any",
1501        NO_STR
1502        IPV6_STR
1503        "Add an access list entry\n"
1504        "IPv6 zebra access-list\n"
1505        "Specify packets to reject\n"
1506        "Specify packets to forward\n"
1507        "Any prefixi to match\n")
1508 {
1509   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
1510 }
1511
1512
1513 DEFUN (no_ipv6_access_list_all,
1514        no_ipv6_access_list_all_cmd,
1515        "no ipv6 access-list WORD",
1516        NO_STR
1517        IPV6_STR
1518        "Add an access list entry\n"
1519        "IPv6 zebra access-list\n")
1520 {
1521   struct access_list *access;
1522   struct access_master *master;
1523   char *name;
1524   
1525   /* Looking up access_list. */
1526   access = access_list_lookup (AFI_IP6, argv[0]);
1527   if (access == NULL)
1528     {
1529       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1530                VTY_NEWLINE);
1531       return CMD_WARNING;
1532     }
1533
1534   master = access->master;
1535   name = access->name;
1536   access->name = NULL;
1537   
1538   /* Delete all filter from access-list. */
1539   access_list_delete (access);
1540
1541   /* Run hook function. */
1542   if (master->delete_hook)
1543     (*master->delete_hook) (name);
1544
1545   XFREE (MTYPE_ACCESS_LIST_STR, name);
1546   return CMD_SUCCESS;
1547 }
1548
1549 DEFUN (ipv6_access_list_remark,
1550        ipv6_access_list_remark_cmd,
1551        "ipv6 access-list WORD remark .LINE",
1552        IPV6_STR
1553        "Add an access list entry\n"
1554        "IPv6 zebra access-list\n"
1555        "Access list entry comment\n"
1556        "Comment up to 100 characters\n")
1557 {
1558   struct access_list *access;
1559
1560   access = access_list_get (AFI_IP6, argv[0]);
1561
1562   if (access->remark)
1563     {
1564       XFREE (MTYPE_TMP, access->remark);
1565       access->remark = NULL;
1566     }
1567   access->remark = argv_concat(argv, argc, 1);
1568
1569   return CMD_SUCCESS;
1570 }
1571
1572 DEFUN (no_ipv6_access_list_remark,
1573        no_ipv6_access_list_remark_cmd,
1574        "no ipv6 access-list WORD remark",
1575        NO_STR
1576        IPV6_STR
1577        "Add an access list entry\n"
1578        "IPv6 zebra access-list\n"
1579        "Access list entry comment\n")
1580 {
1581   return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
1582 }
1583         
1584 ALIAS (no_ipv6_access_list_remark,
1585        no_ipv6_access_list_remark_arg_cmd,
1586        "no ipv6 access-list WORD remark .LINE",
1587        NO_STR
1588        IPV6_STR
1589        "Add an access list entry\n"
1590        "IPv6 zebra access-list\n"
1591        "Access list entry comment\n"
1592        "Comment up to 100 characters\n")
1593 #endif /* HAVE_IPV6 */
1594
1595 void config_write_access_zebra (struct vty *, struct filter *);
1596 void config_write_access_cisco (struct vty *, struct filter *);
1597
1598 /* show access-list command. */
1599 static int
1600 filter_show (struct vty *vty, const char *name, afi_t afi)
1601 {
1602   struct access_list *access;
1603   struct access_master *master;
1604   struct filter *mfilter;
1605   struct filter_cisco *filter;
1606   int write = 0;
1607
1608   master = access_master_get (afi);
1609   if (master == NULL)
1610     return 0;
1611
1612   /* Print the name of the protocol */
1613   if (zlog_default)
1614       vty_out (vty, "%s:%s",
1615       zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
1616
1617   for (access = master->num.head; access; access = access->next)
1618     {
1619       if (!access->name || (name && strcmp (access->name, name) != 0))
1620         continue;
1621
1622       write = 1;
1623
1624       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1625         {
1626           filter = &mfilter->u.cfilter;
1627
1628           if (write)
1629             {
1630               vty_out (vty, "%s IP%s access list %s%s",
1631                        mfilter->cisco ? 
1632                        (filter->extended ? "Extended" : "Standard") : "Zebra",
1633                        afi == AFI_IP6 ? "v6" : "",
1634                        access->name, VTY_NEWLINE);
1635               write = 0;
1636             }
1637
1638           vty_out (vty, "    %s%s", filter_type_str (mfilter),
1639                    mfilter->type == FILTER_DENY ? "  " : "");
1640
1641           if (! mfilter->cisco)
1642             config_write_access_zebra (vty, mfilter);
1643           else if (filter->extended)
1644             config_write_access_cisco (vty, mfilter);
1645           else
1646             {
1647               if (filter->addr_mask.s_addr == 0xffffffff)
1648                 vty_out (vty, " any%s", VTY_NEWLINE);
1649               else
1650                 {
1651                   vty_out (vty, " %s", inet_ntoa (filter->addr));
1652                   if (filter->addr_mask.s_addr != 0)
1653                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1654                   vty_out (vty, "%s", VTY_NEWLINE);
1655                 }
1656             }
1657         }
1658     }
1659
1660   for (access = master->str.head; access; access = access->next)
1661     {
1662       if (!access->name || (name && strcmp (access->name, name) != 0))
1663         continue;
1664
1665       write = 1;
1666
1667       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1668         {
1669           filter = &mfilter->u.cfilter;
1670
1671           if (write)
1672             {
1673               vty_out (vty, "%s IP%s access list %s%s",
1674                        mfilter->cisco ? 
1675                        (filter->extended ? "Extended" : "Standard") : "Zebra",
1676                        afi == AFI_IP6 ? "v6" : "",
1677                        access->name, VTY_NEWLINE);
1678               write = 0;
1679             }
1680
1681           vty_out (vty, "    %s%s", filter_type_str (mfilter),
1682                    mfilter->type == FILTER_DENY ? "  " : "");
1683
1684           if (! mfilter->cisco)
1685             config_write_access_zebra (vty, mfilter);
1686           else if (filter->extended)
1687             config_write_access_cisco (vty, mfilter);
1688           else
1689             {
1690               if (filter->addr_mask.s_addr == 0xffffffff)
1691                 vty_out (vty, " any%s", VTY_NEWLINE);
1692               else
1693                 {
1694                   vty_out (vty, " %s", inet_ntoa (filter->addr));
1695                   if (filter->addr_mask.s_addr != 0)
1696                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1697                   vty_out (vty, "%s", VTY_NEWLINE);
1698                 }
1699             }
1700         }
1701     }
1702   return CMD_SUCCESS;
1703 }
1704
1705 DEFUN (show_ip_access_list,
1706        show_ip_access_list_cmd,
1707        "show ip access-list",
1708        SHOW_STR
1709        IP_STR
1710        "List IP access lists\n")
1711 {
1712   return filter_show (vty, NULL, AFI_IP);
1713 }
1714
1715 DEFUN (show_ip_access_list_name,
1716        show_ip_access_list_name_cmd,
1717        "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1718        SHOW_STR
1719        IP_STR
1720        "List IP access lists\n"
1721        "IP standard access list\n"
1722        "IP extended access list\n"
1723        "IP standard access list (expanded range)\n"
1724        "IP extended access list (expanded range)\n"
1725        "IP zebra access-list\n")
1726 {
1727   return filter_show (vty, argv[0], AFI_IP);
1728 }
1729
1730 #ifdef HAVE_IPV6
1731 DEFUN (show_ipv6_access_list,
1732        show_ipv6_access_list_cmd,
1733        "show ipv6 access-list",
1734        SHOW_STR
1735        IPV6_STR
1736        "List IPv6 access lists\n")
1737 {
1738   return filter_show (vty, NULL, AFI_IP6);
1739 }
1740
1741 DEFUN (show_ipv6_access_list_name,
1742        show_ipv6_access_list_name_cmd,
1743        "show ipv6 access-list WORD",
1744        SHOW_STR
1745        IPV6_STR
1746        "List IPv6 access lists\n"
1747        "IPv6 zebra access-list\n")
1748 {
1749   return filter_show (vty, argv[0], AFI_IP6);
1750 }
1751 #endif /* HAVE_IPV6 */
1752
1753 void
1754 config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1755 {
1756   struct filter_cisco *filter;
1757
1758   filter = &mfilter->u.cfilter;
1759
1760   if (filter->extended)
1761     {
1762       vty_out (vty, " ip");
1763       if (filter->addr_mask.s_addr == 0xffffffff)
1764         vty_out (vty, " any");
1765       else if (filter->addr_mask.s_addr == 0)
1766         vty_out (vty, " host %s", inet_ntoa (filter->addr));
1767       else
1768         {
1769           vty_out (vty, " %s", inet_ntoa (filter->addr));
1770           vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1771         }
1772
1773       if (filter->mask_mask.s_addr == 0xffffffff)
1774         vty_out (vty, " any");
1775       else if (filter->mask_mask.s_addr == 0)
1776         vty_out (vty, " host %s", inet_ntoa (filter->mask));
1777       else
1778         {
1779           vty_out (vty, " %s", inet_ntoa (filter->mask));
1780           vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1781         }
1782       vty_out (vty, "%s", VTY_NEWLINE);
1783     }
1784   else
1785     {
1786       if (filter->addr_mask.s_addr == 0xffffffff)
1787         vty_out (vty, " any%s", VTY_NEWLINE);
1788       else
1789         {
1790           vty_out (vty, " %s", inet_ntoa (filter->addr));
1791           if (filter->addr_mask.s_addr != 0)
1792             vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1793           vty_out (vty, "%s", VTY_NEWLINE);
1794         }
1795     }
1796 }
1797
1798 void
1799 config_write_access_zebra (struct vty *vty, struct filter *mfilter)
1800 {
1801   struct filter_zebra *filter;
1802   struct prefix *p;
1803   char buf[BUFSIZ];
1804
1805   filter = &mfilter->u.zfilter;
1806   p = &filter->prefix;
1807
1808   if (p->prefixlen == 0 && ! filter->exact)
1809     vty_out (vty, " any");
1810   else
1811     vty_out (vty, " %s/%d%s",
1812              inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1813              p->prefixlen,
1814              filter->exact ? " exact-match" : "");
1815
1816   vty_out (vty, "%s", VTY_NEWLINE);
1817 }
1818
1819 static int
1820 config_write_access (struct vty *vty, afi_t afi)
1821 {
1822   struct access_list *access;
1823   struct access_master *master;
1824   struct filter *mfilter;
1825   int write = 0;
1826
1827   master = access_master_get (afi);
1828   if (master == NULL)
1829     return 0;
1830
1831   for (access = master->num.head; access; access = access->next)
1832     {
1833       if (access->remark)
1834         {
1835           vty_out (vty, "%saccess-list %s remark %s%s",
1836                    afi == AFI_IP ? "" : "ipv6 ",
1837                    access->name, access->remark,
1838                    VTY_NEWLINE);
1839           write++;
1840         }
1841
1842       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1843         {
1844           vty_out (vty, "%saccess-list %s %s",
1845              afi == AFI_IP ? "" : "ipv6 ",
1846              access->name,
1847              filter_type_str (mfilter));
1848
1849           if (mfilter->cisco)
1850             config_write_access_cisco (vty, mfilter);
1851           else
1852             config_write_access_zebra (vty, mfilter);
1853
1854           write++;
1855         }
1856     }
1857
1858   for (access = master->str.head; access; access = access->next)
1859     {
1860       if (access->remark)
1861         {
1862           vty_out (vty, "%saccess-list %s remark %s%s",
1863                    afi == AFI_IP ? "" : "ipv6 ",
1864                    access->name, access->remark,
1865                    VTY_NEWLINE);
1866           write++;
1867         }
1868
1869       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1870         {
1871           vty_out (vty, "%saccess-list %s %s",
1872              afi == AFI_IP ? "" : "ipv6 ",
1873              access->name,
1874              filter_type_str (mfilter));
1875
1876           if (mfilter->cisco)
1877             config_write_access_cisco (vty, mfilter);
1878           else
1879             config_write_access_zebra (vty, mfilter);
1880
1881           write++;
1882         }
1883     }
1884   return write;
1885 }
1886
1887 /* Access-list node. */
1888 static struct cmd_node access_node =
1889 {
1890   ACCESS_NODE,
1891   "",                           /* Access list has no interface. */
1892   1
1893 };
1894
1895 static int
1896 config_write_access_ipv4 (struct vty *vty)
1897 {
1898   return config_write_access (vty, AFI_IP);
1899 }
1900
1901 static void
1902 access_list_reset_ipv4 (void)
1903 {
1904   struct access_list *access;
1905   struct access_list *next;
1906   struct access_master *master;
1907
1908   master = access_master_get (AFI_IP);
1909   if (master == NULL)
1910     return;
1911
1912   for (access = master->num.head; access; access = next)
1913     {
1914       next = access->next;
1915       access_list_delete (access);
1916     }
1917   for (access = master->str.head; access; access = next)
1918     {
1919       next = access->next;
1920       access_list_delete (access);
1921     }
1922
1923   assert (master->num.head == NULL);
1924   assert (master->num.tail == NULL);
1925
1926   assert (master->str.head == NULL);
1927   assert (master->str.tail == NULL);
1928 }
1929
1930 /* Install vty related command. */
1931 static void
1932 access_list_init_ipv4 (void)
1933 {
1934   install_node (&access_node, config_write_access_ipv4);
1935
1936   install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1937   install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
1938
1939   /* Zebra access-list */
1940   install_element (CONFIG_NODE, &access_list_cmd);
1941   install_element (CONFIG_NODE, &access_list_exact_cmd);
1942   install_element (CONFIG_NODE, &access_list_any_cmd);
1943   install_element (CONFIG_NODE, &no_access_list_cmd);
1944   install_element (CONFIG_NODE, &no_access_list_exact_cmd);
1945   install_element (CONFIG_NODE, &no_access_list_any_cmd);
1946
1947   /* Standard access-list */
1948   install_element (CONFIG_NODE, &access_list_standard_cmd);
1949   install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
1950   install_element (CONFIG_NODE, &access_list_standard_host_cmd);
1951   install_element (CONFIG_NODE, &access_list_standard_any_cmd);
1952   install_element (CONFIG_NODE, &no_access_list_standard_cmd);
1953   install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
1954   install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
1955   install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
1956
1957   /* Extended access-list */
1958   install_element (CONFIG_NODE, &access_list_extended_cmd);
1959   install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
1960   install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
1961   install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
1962   install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
1963   install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
1964   install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
1965   install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
1966   install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
1967   install_element (CONFIG_NODE, &no_access_list_extended_cmd);
1968   install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
1969   install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
1970   install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
1971   install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
1972   install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
1973   install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
1974   install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
1975   install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
1976
1977   install_element (CONFIG_NODE, &access_list_remark_cmd);
1978   install_element (CONFIG_NODE, &no_access_list_all_cmd);
1979   install_element (CONFIG_NODE, &no_access_list_remark_cmd);
1980   install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
1981 }
1982
1983 #ifdef HAVE_IPV6
1984 static struct cmd_node access_ipv6_node =
1985 {
1986   ACCESS_IPV6_NODE,
1987   "",
1988   1
1989 };
1990
1991 static int
1992 config_write_access_ipv6 (struct vty *vty)
1993 {
1994   return config_write_access (vty, AFI_IP6);
1995 }
1996
1997 static void
1998 access_list_reset_ipv6 (void)
1999 {
2000   struct access_list *access;
2001   struct access_list *next;
2002   struct access_master *master;
2003
2004   master = access_master_get (AFI_IP6);
2005   if (master == NULL)
2006     return;
2007
2008   for (access = master->num.head; access; access = next)
2009     {
2010       next = access->next;
2011       access_list_delete (access);
2012     }
2013   for (access = master->str.head; access; access = next)
2014     {
2015       next = access->next;
2016       access_list_delete (access);
2017     }
2018
2019   assert (master->num.head == NULL);
2020   assert (master->num.tail == NULL);
2021
2022   assert (master->str.head == NULL);
2023   assert (master->str.tail == NULL);
2024 }
2025
2026 static void
2027 access_list_init_ipv6 (void)
2028 {
2029   install_node (&access_ipv6_node, config_write_access_ipv6);
2030
2031   install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
2032   install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
2033
2034   install_element (CONFIG_NODE, &ipv6_access_list_cmd);
2035   install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
2036   install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
2037   install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2038   install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
2039   install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2040
2041   install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
2042   install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
2043   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
2044   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
2045 }
2046 #endif /* HAVE_IPV6 */
2047
2048 void
2049 access_list_init ()
2050 {
2051   access_list_init_ipv4 ();
2052 #ifdef HAVE_IPV6
2053   access_list_init_ipv6();
2054 #endif /* HAVE_IPV6 */
2055 }
2056
2057 void
2058 access_list_reset ()
2059 {
2060   access_list_reset_ipv4 ();
2061 #ifdef HAVE_IPV6
2062   access_list_reset_ipv6();
2063 #endif /* HAVE_IPV6 */
2064 }