]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - lib/filter.c
Import Upstream version 1.2.2
[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) (struct access_list *);
89
90   /* Hook function which is executed when access_list is deleted. */
91   void (*delete_hook) (struct access_list *);
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 (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 (strcmp (access->name, name) == 0)
376       return access;
377
378   for (access = master->str.head; access; access = access->next)
379     if (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) (struct access_list *access))
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) (struct access_list *access))
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);
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
482   master = access->master;
483
484   if (filter->next)
485     filter->next->prev = filter->prev;
486   else
487     access->tail = filter->prev;
488
489   if (filter->prev)
490     filter->prev->next = filter->next;
491   else
492     access->head = filter->next;
493
494   filter_free (filter);
495
496   /* Run hook function. */
497   if (master->delete_hook)
498     (*master->delete_hook) (access);
499
500   /* If access_list becomes empty delete it from access_master. */
501   if (access_list_empty (access))
502     access_list_delete (access);
503 }
504
505 /*
506   deny    Specify packets to reject
507   permit  Specify packets to forward
508   dynamic ?
509 */
510
511 /*
512   Hostname or A.B.C.D  Address to match
513   any                  Any source host
514   host                 A single host address
515 */
516
517 static struct filter *
518 filter_lookup_cisco (struct access_list *access, struct filter *mnew)
519 {
520   struct filter *mfilter;
521   struct filter_cisco *filter;
522   struct filter_cisco *new;
523
524   new = &mnew->u.cfilter;
525
526   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
527     {
528       filter = &mfilter->u.cfilter;
529
530       if (filter->extended)
531         {
532           if (mfilter->type == mnew->type
533               && filter->addr.s_addr == new->addr.s_addr
534               && filter->addr_mask.s_addr == new->addr_mask.s_addr
535               && filter->mask.s_addr == new->mask.s_addr
536               && filter->mask_mask.s_addr == new->mask_mask.s_addr)
537             return mfilter;
538         }
539       else
540         {
541           if (mfilter->type == mnew->type
542               && filter->addr.s_addr == new->addr.s_addr
543               && filter->addr_mask.s_addr == new->addr_mask.s_addr)
544             return mfilter;
545         }
546     }
547
548   return NULL;
549 }
550
551 static struct filter *
552 filter_lookup_zebra (struct access_list *access, struct filter *mnew)
553 {
554   struct filter *mfilter;
555   struct filter_zebra *filter;
556   struct filter_zebra *new;
557
558   new = &mnew->u.zfilter;
559
560   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
561     {
562       filter = &mfilter->u.zfilter;
563
564       if (filter->exact == new->exact
565           && mfilter->type == mnew->type
566           && prefix_same (&filter->prefix, &new->prefix))
567         return mfilter;
568     }
569   return NULL;
570 }
571
572 static int
573 vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
574 {
575   struct access_list *access;
576
577   access = access_list_lookup (afi, name);
578   if (! access)
579     {
580       vty_out (vty, "%% access-list %s doesn't exist%s", name,
581                VTY_NEWLINE);
582       return CMD_WARNING;
583     }
584
585   if (access->remark)
586     {
587       XFREE (MTYPE_TMP, access->remark);
588       access->remark = NULL;
589     }
590
591   if (access->head == NULL && access->tail == NULL && access->remark == NULL)
592     access_list_delete (access);
593
594   return CMD_SUCCESS;
595 }
596
597 static int
598 filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
599                   const char *addr_str, const char *addr_mask_str,
600                   const char *mask_str, const char *mask_mask_str,
601                   int extended, int set)
602 {
603   int ret;
604   enum filter_type type;
605   struct filter *mfilter;
606   struct filter_cisco *filter;
607   struct access_list *access;
608   struct in_addr addr;
609   struct in_addr addr_mask;
610   struct in_addr mask;
611   struct in_addr mask_mask;
612
613   /* Check of filter type. */
614   if (strncmp (type_str, "p", 1) == 0)
615     type = FILTER_PERMIT;
616   else if (strncmp (type_str, "d", 1) == 0)
617     type = FILTER_DENY;
618   else
619     {
620       vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
621       return CMD_WARNING;
622     }
623
624   ret = inet_aton (addr_str, &addr);
625   if (ret <= 0)
626     {
627       vty_out (vty, "%%Inconsistent address and mask%s",
628                VTY_NEWLINE);
629       return CMD_WARNING;
630     }
631
632   ret = inet_aton (addr_mask_str, &addr_mask);
633   if (ret <= 0)
634     {
635       vty_out (vty, "%%Inconsistent address and mask%s",
636                VTY_NEWLINE);
637       return CMD_WARNING;
638     }
639
640   if (extended)
641     {
642       ret = inet_aton (mask_str, &mask);
643       if (ret <= 0)
644         {
645           vty_out (vty, "%%Inconsistent address and mask%s",
646                    VTY_NEWLINE);
647           return CMD_WARNING;
648         }
649
650       ret = inet_aton (mask_mask_str, &mask_mask);
651       if (ret <= 0)
652         {
653           vty_out (vty, "%%Inconsistent address and mask%s",
654                    VTY_NEWLINE);
655           return CMD_WARNING;
656         }
657     }
658
659   mfilter = filter_new();
660   mfilter->type = type;
661   mfilter->cisco = 1;
662   filter = &mfilter->u.cfilter;
663   filter->extended = extended;
664   filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
665   filter->addr_mask.s_addr = addr_mask.s_addr;
666
667   if (extended)
668     {
669       filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
670       filter->mask_mask.s_addr = mask_mask.s_addr;
671     }
672
673   /* Install new filter to the access_list. */
674   access = access_list_get (AFI_IP, name_str);
675
676   if (set)
677     {
678       if (filter_lookup_cisco (access, mfilter))
679         filter_free (mfilter);
680       else
681         access_list_filter_add (access, mfilter);
682     }
683   else
684     {
685       struct filter *delete_filter;
686
687       delete_filter = filter_lookup_cisco (access, mfilter);
688       if (delete_filter)
689         access_list_filter_delete (access, delete_filter);
690
691       filter_free (mfilter);
692     }
693
694   return CMD_SUCCESS;
695 }
696
697 /* Standard access-list */
698 DEFUN (access_list_standard,
699        access_list_standard_cmd,
700        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
701        "Add an access list entry\n"
702        "IP standard access list\n"
703        "IP standard access list (expanded range)\n"
704        "Specify packets to reject\n"
705        "Specify packets to forward\n"
706        "Address to match\n"
707        "Wildcard bits\n")
708 {
709   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
710                            NULL, NULL, 0, 1);
711 }
712
713 DEFUN (access_list_standard_nomask,
714        access_list_standard_nomask_cmd,
715        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
716        "Add an access list entry\n"
717        "IP standard access list\n"
718        "IP standard access list (expanded range)\n"
719        "Specify packets to reject\n"
720        "Specify packets to forward\n"
721        "Address to match\n")
722 {
723   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
724                            NULL, NULL, 0, 1);
725 }
726
727 DEFUN (access_list_standard_host,
728        access_list_standard_host_cmd,
729        "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
730        "Add an access list entry\n"
731        "IP standard access list\n"
732        "IP standard access list (expanded range)\n"
733        "Specify packets to reject\n"
734        "Specify packets to forward\n"
735        "A single host address\n"
736        "Address to match\n")
737 {
738   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
739                            NULL, NULL, 0, 1);
740 }
741
742 DEFUN (access_list_standard_any,
743        access_list_standard_any_cmd,
744        "access-list (<1-99>|<1300-1999>) (deny|permit) any",
745        "Add an access list entry\n"
746        "IP standard access list\n"
747        "IP standard access list (expanded range)\n"
748        "Specify packets to reject\n"
749        "Specify packets to forward\n"
750        "Any source host\n")
751 {
752   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
753                            "255.255.255.255", NULL, NULL, 0, 1);
754 }
755
756 DEFUN (no_access_list_standard,
757        no_access_list_standard_cmd,
758        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
759        NO_STR
760        "Add an access list entry\n"
761        "IP standard access list\n"
762        "IP standard access list (expanded range)\n"
763        "Specify packets to reject\n"
764        "Specify packets to forward\n"
765        "Address to match\n"
766        "Wildcard bits\n")
767 {
768   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
769                            NULL, NULL, 0, 0);
770 }
771
772 DEFUN (no_access_list_standard_nomask,
773        no_access_list_standard_nomask_cmd,
774        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
775        NO_STR
776        "Add an access list entry\n"
777        "IP standard access list\n"
778        "IP standard access list (expanded range)\n"
779        "Specify packets to reject\n"
780        "Specify packets to forward\n"
781        "Address to match\n")
782 {
783   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
784                            NULL, NULL, 0, 0);
785 }
786
787 DEFUN (no_access_list_standard_host,
788        no_access_list_standard_host_cmd,
789        "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
790        NO_STR
791        "Add an access list entry\n"
792        "IP standard access list\n"
793        "IP standard access list (expanded range)\n"
794        "Specify packets to reject\n"
795        "Specify packets to forward\n"
796        "A single host address\n"
797        "Address to match\n")
798 {
799   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
800                            NULL, NULL, 0, 0);
801 }
802
803 DEFUN (no_access_list_standard_any,
804        no_access_list_standard_any_cmd,
805        "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
806        NO_STR
807        "Add an access list entry\n"
808        "IP standard access list\n"
809        "IP standard access list (expanded range)\n"
810        "Specify packets to reject\n"
811        "Specify packets to forward\n"
812        "Any source host\n")
813 {
814   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
815                            "255.255.255.255", NULL, NULL, 0, 0);
816 }
817
818 /* Extended access-list */
819 DEFUN (access_list_extended,
820        access_list_extended_cmd,
821        "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",
822        "Add an access list entry\n"
823        "IP extended access list\n"
824        "IP extended access list (expanded range)\n"
825        "Specify packets to reject\n"
826        "Specify packets to forward\n"
827        "Any Internet Protocol\n"
828        "Source address\n"
829        "Source wildcard bits\n"
830        "Destination address\n"
831        "Destination Wildcard bits\n")
832 {
833   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
834                            argv[3], argv[4], argv[5], 1 ,1);
835 }
836
837 DEFUN (access_list_extended_mask_any,
838        access_list_extended_mask_any_cmd,
839        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
840        "Add an access list entry\n"
841        "IP extended access list\n"
842        "IP extended access list (expanded range)\n"
843        "Specify packets to reject\n"
844        "Specify packets to forward\n"
845        "Any Internet Protocol\n"
846        "Source address\n"
847        "Source wildcard bits\n"
848        "Any destination host\n")
849 {
850   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
851                            argv[3], "0.0.0.0",
852                            "255.255.255.255", 1, 1);
853 }
854
855 DEFUN (access_list_extended_any_mask,
856        access_list_extended_any_mask_cmd,
857        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
858        "Add an access list entry\n"
859        "IP extended access list\n"
860        "IP extended access list (expanded range)\n"
861        "Specify packets to reject\n"
862        "Specify packets to forward\n"
863        "Any Internet Protocol\n"
864        "Any source host\n"
865        "Destination address\n"
866        "Destination Wildcard bits\n")
867 {
868   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
869                            "255.255.255.255", argv[2],
870                            argv[3], 1, 1);
871 }
872
873 DEFUN (access_list_extended_any_any,
874        access_list_extended_any_any_cmd,
875        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
876        "Add an access list entry\n"
877        "IP extended access list\n"
878        "IP extended access list (expanded range)\n"
879        "Specify packets to reject\n"
880        "Specify packets to forward\n"
881        "Any Internet Protocol\n"
882        "Any source host\n"
883        "Any destination host\n")
884 {
885   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
886                            "255.255.255.255", "0.0.0.0",
887                            "255.255.255.255", 1, 1);
888 }
889
890 DEFUN (access_list_extended_mask_host,
891        access_list_extended_mask_host_cmd,
892        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
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        "Source address\n"
900        "Source wildcard bits\n"
901        "A single destination host\n"
902        "Destination address\n")
903 {
904   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
905                            argv[3], argv[4],
906                            "0.0.0.0", 1, 1);
907 }
908
909 DEFUN (access_list_extended_host_mask,
910        access_list_extended_host_mask_cmd,
911        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
912        "Add an access list entry\n"
913        "IP extended access list\n"
914        "IP extended access list (expanded range)\n"
915        "Specify packets to reject\n"
916        "Specify packets to forward\n"
917        "Any Internet Protocol\n"
918        "A single source host\n"
919        "Source address\n"
920        "Destination address\n"
921        "Destination Wildcard bits\n")
922 {
923   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
924                            "0.0.0.0", argv[3],
925                            argv[4], 1, 1);
926 }
927
928 DEFUN (access_list_extended_host_host,
929        access_list_extended_host_host_cmd,
930        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
931        "Add an access list entry\n"
932        "IP extended access list\n"
933        "IP extended access list (expanded range)\n"
934        "Specify packets to reject\n"
935        "Specify packets to forward\n"
936        "Any Internet Protocol\n"
937        "A single source host\n"
938        "Source address\n"
939        "A single destination host\n"
940        "Destination address\n")
941 {
942   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
943                            "0.0.0.0", argv[3],
944                            "0.0.0.0", 1, 1);
945 }
946
947 DEFUN (access_list_extended_any_host,
948        access_list_extended_any_host_cmd,
949        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
950        "Add an access list entry\n"
951        "IP extended access list\n"
952        "IP extended access list (expanded range)\n"
953        "Specify packets to reject\n"
954        "Specify packets to forward\n"
955        "Any Internet Protocol\n"
956        "Any source host\n"
957        "A single destination host\n"
958        "Destination address\n")
959 {
960   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
961                            "255.255.255.255", argv[2],
962                            "0.0.0.0", 1, 1);
963 }
964
965 DEFUN (access_list_extended_host_any,
966        access_list_extended_host_any_cmd,
967        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
968        "Add an access list entry\n"
969        "IP extended access list\n"
970        "IP extended access list (expanded range)\n"
971        "Specify packets to reject\n"
972        "Specify packets to forward\n"
973        "Any Internet Protocol\n"
974        "A single source host\n"
975        "Source address\n"
976        "Any destination host\n")
977 {
978   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
979                            "0.0.0.0", "0.0.0.0",
980                            "255.255.255.255", 1, 1);
981 }
982
983 DEFUN (no_access_list_extended,
984        no_access_list_extended_cmd,
985        "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",
986        NO_STR
987        "Add an access list entry\n"
988        "IP extended access list\n"
989        "IP extended access list (expanded range)\n"
990        "Specify packets to reject\n"
991        "Specify packets to forward\n"
992        "Any Internet Protocol\n"
993        "Source address\n"
994        "Source wildcard bits\n"
995        "Destination address\n"
996        "Destination Wildcard bits\n")
997 {
998   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
999                            argv[3], argv[4], argv[5], 1, 0);
1000 }
1001
1002 DEFUN (no_access_list_extended_mask_any,
1003        no_access_list_extended_mask_any_cmd,
1004        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
1005        NO_STR
1006        "Add an access list entry\n"
1007        "IP extended access list\n"
1008        "IP extended access list (expanded range)\n"
1009        "Specify packets to reject\n"
1010        "Specify packets to forward\n"
1011        "Any Internet Protocol\n"
1012        "Source address\n"
1013        "Source wildcard bits\n"
1014        "Any destination host\n")
1015 {
1016   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1017                            argv[3], "0.0.0.0",
1018                            "255.255.255.255", 1, 0);
1019 }
1020
1021 DEFUN (no_access_list_extended_any_mask,
1022        no_access_list_extended_any_mask_cmd,
1023        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
1024        NO_STR
1025        "Add an access list entry\n"
1026        "IP extended access list\n"
1027        "IP extended access list (expanded range)\n"
1028        "Specify packets to reject\n"
1029        "Specify packets to forward\n"
1030        "Any Internet Protocol\n"
1031        "Any source host\n"
1032        "Destination address\n"
1033        "Destination Wildcard bits\n")
1034 {
1035   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1036                            "255.255.255.255", argv[2],
1037                            argv[3], 1, 0);
1038 }
1039
1040 DEFUN (no_access_list_extended_any_any,
1041        no_access_list_extended_any_any_cmd,
1042        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
1043        NO_STR
1044        "Add an access list entry\n"
1045        "IP extended access list\n"
1046        "IP extended access list (expanded range)\n"
1047        "Specify packets to reject\n"
1048        "Specify packets to forward\n"
1049        "Any Internet Protocol\n"
1050        "Any source host\n"
1051        "Any destination host\n")
1052 {
1053   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1054                            "255.255.255.255", "0.0.0.0",
1055                            "255.255.255.255", 1, 0);
1056 }
1057
1058 DEFUN (no_access_list_extended_mask_host,
1059        no_access_list_extended_mask_host_cmd,
1060        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
1061        NO_STR
1062        "Add an access list entry\n"
1063        "IP extended access list\n"
1064        "IP extended access list (expanded range)\n"
1065        "Specify packets to reject\n"
1066        "Specify packets to forward\n"
1067        "Any Internet Protocol\n"
1068        "Source address\n"
1069        "Source wildcard bits\n"
1070        "A single destination host\n"
1071        "Destination address\n")
1072 {
1073   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1074                            argv[3], argv[4],
1075                            "0.0.0.0", 1, 0);
1076 }
1077
1078 DEFUN (no_access_list_extended_host_mask,
1079        no_access_list_extended_host_mask_cmd,
1080        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
1081        NO_STR
1082        "Add an access list entry\n"
1083        "IP extended access list\n"
1084        "IP extended access list (expanded range)\n"
1085        "Specify packets to reject\n"
1086        "Specify packets to forward\n"
1087        "Any Internet Protocol\n"
1088        "A single source host\n"
1089        "Source address\n"
1090        "Destination address\n"
1091        "Destination Wildcard bits\n")
1092 {
1093   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1094                            "0.0.0.0", argv[3],
1095                            argv[4], 1, 0);
1096 }
1097
1098 DEFUN (no_access_list_extended_host_host,
1099        no_access_list_extended_host_host_cmd,
1100        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
1101        NO_STR
1102        "Add an access list entry\n"
1103        "IP extended access list\n"
1104        "IP extended access list (expanded range)\n"
1105        "Specify packets to reject\n"
1106        "Specify packets to forward\n"
1107        "Any Internet Protocol\n"
1108        "A single source host\n"
1109        "Source address\n"
1110        "A single destination host\n"
1111        "Destination address\n")
1112 {
1113   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1114                            "0.0.0.0", argv[3],
1115                            "0.0.0.0", 1, 0);
1116 }
1117
1118 DEFUN (no_access_list_extended_any_host,
1119        no_access_list_extended_any_host_cmd,
1120        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
1121        NO_STR
1122        "Add an access list entry\n"
1123        "IP extended access list\n"
1124        "IP extended access list (expanded range)\n"
1125        "Specify packets to reject\n"
1126        "Specify packets to forward\n"
1127        "Any Internet Protocol\n"
1128        "Any source host\n"
1129        "A single destination host\n"
1130        "Destination address\n")
1131 {
1132   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1133                            "255.255.255.255", argv[2],
1134                            "0.0.0.0", 1, 0);
1135 }
1136
1137 DEFUN (no_access_list_extended_host_any,
1138        no_access_list_extended_host_any_cmd,
1139        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
1140        NO_STR
1141        "Add an access list entry\n"
1142        "IP extended access list\n"
1143        "IP extended access list (expanded range)\n"
1144        "Specify packets to reject\n"
1145        "Specify packets to forward\n"
1146        "Any Internet Protocol\n"
1147        "A single source host\n"
1148        "Source address\n"
1149        "Any destination host\n")
1150 {
1151   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1152                            "0.0.0.0", "0.0.0.0",
1153                            "255.255.255.255", 1, 0);
1154 }
1155
1156 static int
1157 filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
1158                   afi_t afi, const char *prefix_str, int exact, int set)
1159 {
1160   int ret;
1161   enum filter_type type;
1162   struct filter *mfilter;
1163   struct filter_zebra *filter;
1164   struct access_list *access;
1165   struct prefix p;
1166
1167   /* Check of filter type. */
1168   if (strncmp (type_str, "p", 1) == 0)
1169     type = FILTER_PERMIT;
1170   else if (strncmp (type_str, "d", 1) == 0)
1171     type = FILTER_DENY;
1172   else
1173     {
1174       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
1175       return CMD_WARNING;
1176     }
1177
1178   /* Check string format of prefix and prefixlen. */
1179   if (afi == AFI_IP)
1180     {
1181       ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
1182       if (ret <= 0)
1183         {
1184           vty_out (vty, "IP address prefix/prefixlen is malformed%s",
1185                    VTY_NEWLINE);
1186           return CMD_WARNING;
1187         }
1188     }
1189 #ifdef HAVE_IPV6
1190   else if (afi == AFI_IP6)
1191     {
1192       ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
1193       if (ret <= 0)
1194         {
1195           vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
1196                    VTY_NEWLINE);
1197                    return CMD_WARNING;
1198         }
1199     }
1200 #endif /* HAVE_IPV6 */
1201   else
1202     return CMD_WARNING;
1203
1204   mfilter = filter_new ();
1205   mfilter->type = type;
1206   filter = &mfilter->u.zfilter;
1207   prefix_copy (&filter->prefix, &p);
1208
1209   /* "exact-match" */
1210   if (exact)
1211     filter->exact = 1;
1212
1213   /* Install new filter to the access_list. */
1214   access = access_list_get (afi, name_str);
1215
1216   if (set)
1217     {
1218       if (filter_lookup_zebra (access, mfilter))
1219         filter_free (mfilter);
1220       else
1221         access_list_filter_add (access, mfilter);
1222     }
1223   else
1224     {
1225       struct filter *delete_filter;
1226
1227       delete_filter = filter_lookup_zebra (access, mfilter);
1228       if (delete_filter)
1229         access_list_filter_delete (access, delete_filter);
1230
1231       filter_free (mfilter);
1232     }
1233
1234   return CMD_SUCCESS;
1235 }
1236
1237 /* Zebra access-list */
1238 DEFUN (access_list,
1239        access_list_cmd,
1240        "access-list WORD (deny|permit) A.B.C.D/M",
1241        "Add an access list entry\n"
1242        "IP zebra access-list name\n"
1243        "Specify packets to reject\n"
1244        "Specify packets to forward\n"
1245        "Prefix to match. e.g. 10.0.0.0/8\n")
1246 {
1247   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
1248 }
1249
1250 DEFUN (access_list_exact,
1251        access_list_exact_cmd,
1252        "access-list WORD (deny|permit) A.B.C.D/M exact-match",
1253        "Add an access list entry\n"
1254        "IP zebra access-list name\n"
1255        "Specify packets to reject\n"
1256        "Specify packets to forward\n"
1257        "Prefix to match. e.g. 10.0.0.0/8\n"
1258        "Exact match of the prefixes\n")
1259 {
1260   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
1261 }
1262
1263 DEFUN (access_list_any,
1264        access_list_any_cmd,
1265        "access-list WORD (deny|permit) any",
1266        "Add an access list entry\n"
1267        "IP zebra access-list name\n"
1268        "Specify packets to reject\n"
1269        "Specify packets to forward\n"
1270        "Prefix to match. e.g. 10.0.0.0/8\n")
1271 {
1272   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
1273 }
1274
1275 DEFUN (no_access_list,
1276        no_access_list_cmd,
1277        "no access-list WORD (deny|permit) A.B.C.D/M",
1278        NO_STR
1279        "Add an access list entry\n"
1280        "IP zebra access-list name\n"
1281        "Specify packets to reject\n"
1282        "Specify packets to forward\n"
1283        "Prefix to match. e.g. 10.0.0.0/8\n")
1284 {
1285   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
1286 }
1287
1288 DEFUN (no_access_list_exact,
1289        no_access_list_exact_cmd,
1290        "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
1291        NO_STR
1292        "Add an access list entry\n"
1293        "IP zebra access-list name\n"
1294        "Specify packets to reject\n"
1295        "Specify packets to forward\n"
1296        "Prefix to match. e.g. 10.0.0.0/8\n"
1297        "Exact match of the prefixes\n")
1298 {
1299   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
1300 }
1301
1302 DEFUN (no_access_list_any,
1303        no_access_list_any_cmd,
1304        "no access-list WORD (deny|permit) any",
1305        NO_STR
1306        "Add an access list entry\n"
1307        "IP zebra access-list name\n"
1308        "Specify packets to reject\n"
1309        "Specify packets to forward\n"
1310        "Prefix to match. e.g. 10.0.0.0/8\n")
1311 {
1312   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
1313 }
1314
1315 DEFUN (no_access_list_all,
1316        no_access_list_all_cmd,
1317        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1318        NO_STR
1319        "Add an access list entry\n"
1320        "IP standard access list\n"
1321        "IP extended access list\n"
1322        "IP standard access list (expanded range)\n"
1323        "IP extended access list (expanded range)\n"
1324        "IP zebra access-list name\n")
1325 {
1326   struct access_list *access;
1327   struct access_master *master;
1328
1329   /* Looking up access_list. */
1330   access = access_list_lookup (AFI_IP, argv[0]);
1331   if (access == NULL)
1332     {
1333       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1334                VTY_NEWLINE);
1335       return CMD_WARNING;
1336     }
1337
1338   master = access->master;
1339
1340   /* Run hook function. */
1341   if (master->delete_hook)
1342     (*master->delete_hook) (access);
1343  
1344   /* Delete all filter from access-list. */
1345   access_list_delete (access);
1346
1347   return CMD_SUCCESS;
1348 }
1349
1350 DEFUN (access_list_remark,
1351        access_list_remark_cmd,
1352        "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1353        "Add an access list entry\n"
1354        "IP standard access list\n"
1355        "IP extended access list\n"
1356        "IP standard access list (expanded range)\n"
1357        "IP extended access list (expanded range)\n"
1358        "IP zebra access-list\n"
1359        "Access list entry comment\n"
1360        "Comment up to 100 characters\n")
1361 {
1362   struct access_list *access;
1363
1364   access = access_list_get (AFI_IP, argv[0]);
1365
1366   if (access->remark)
1367     {
1368       XFREE (MTYPE_TMP, access->remark);
1369       access->remark = NULL;
1370     }
1371   access->remark = argv_concat(argv, argc, 1);
1372
1373   return CMD_SUCCESS;
1374 }
1375
1376 DEFUN (no_access_list_remark,
1377        no_access_list_remark_cmd,
1378        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
1379        NO_STR
1380        "Add an access list entry\n"
1381        "IP standard access list\n"
1382        "IP extended access list\n"
1383        "IP standard access list (expanded range)\n"
1384        "IP extended access list (expanded range)\n"
1385        "IP zebra access-list\n"
1386        "Access list entry comment\n")
1387 {
1388   return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
1389 }
1390         
1391 ALIAS (no_access_list_remark,
1392        no_access_list_remark_arg_cmd,
1393        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1394        NO_STR
1395        "Add an access list entry\n"
1396        "IP standard access list\n"
1397        "IP extended access list\n"
1398        "IP standard access list (expanded range)\n"
1399        "IP extended access list (expanded range)\n"
1400        "IP zebra access-list\n"
1401        "Access list entry comment\n"
1402        "Comment up to 100 characters\n")
1403
1404 #ifdef HAVE_IPV6
1405 DEFUN (ipv6_access_list,
1406        ipv6_access_list_cmd,
1407        "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1408        IPV6_STR
1409        "Add an access list entry\n"
1410        "IPv6 zebra access-list\n"
1411        "Specify packets to reject\n"
1412        "Specify packets to forward\n"
1413        "Prefix to match. e.g. 3ffe:506::/32\n")
1414 {
1415   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
1416 }
1417
1418 DEFUN (ipv6_access_list_exact,
1419        ipv6_access_list_exact_cmd,
1420        "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1421        IPV6_STR
1422        "Add an access list entry\n"
1423        "IPv6 zebra access-list\n"
1424        "Specify packets to reject\n"
1425        "Specify packets to forward\n"
1426        "Prefix to match. e.g. 3ffe:506::/32\n"
1427        "Exact match of the prefixes\n")
1428 {
1429   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
1430 }
1431
1432 DEFUN (ipv6_access_list_any,
1433        ipv6_access_list_any_cmd,
1434        "ipv6 access-list WORD (deny|permit) any",
1435        IPV6_STR
1436        "Add an access list entry\n"
1437        "IPv6 zebra access-list\n"
1438        "Specify packets to reject\n"
1439        "Specify packets to forward\n"
1440        "Any prefixi to match\n")
1441 {
1442   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
1443 }
1444
1445 DEFUN (no_ipv6_access_list,
1446        no_ipv6_access_list_cmd,
1447        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1448        NO_STR
1449        IPV6_STR
1450        "Add an access list entry\n"
1451        "IPv6 zebra access-list\n"
1452        "Specify packets to reject\n"
1453        "Specify packets to forward\n"
1454        "Prefix to match. e.g. 3ffe:506::/32\n")
1455 {
1456   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
1457 }
1458
1459 DEFUN (no_ipv6_access_list_exact,
1460        no_ipv6_access_list_exact_cmd,
1461        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1462        NO_STR
1463        IPV6_STR
1464        "Add an access list entry\n"
1465        "IPv6 zebra access-list\n"
1466        "Specify packets to reject\n"
1467        "Specify packets to forward\n"
1468        "Prefix to match. e.g. 3ffe:506::/32\n"
1469        "Exact match of the prefixes\n")
1470 {
1471   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
1472 }
1473
1474 DEFUN (no_ipv6_access_list_any,
1475        no_ipv6_access_list_any_cmd,
1476        "no ipv6 access-list WORD (deny|permit) any",
1477        NO_STR
1478        IPV6_STR
1479        "Add an access list entry\n"
1480        "IPv6 zebra access-list\n"
1481        "Specify packets to reject\n"
1482        "Specify packets to forward\n"
1483        "Any prefixi to match\n")
1484 {
1485   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
1486 }
1487
1488
1489 DEFUN (no_ipv6_access_list_all,
1490        no_ipv6_access_list_all_cmd,
1491        "no ipv6 access-list WORD",
1492        NO_STR
1493        IPV6_STR
1494        "Add an access list entry\n"
1495        "IPv6 zebra access-list\n")
1496 {
1497   struct access_list *access;
1498   struct access_master *master;
1499
1500   /* Looking up access_list. */
1501   access = access_list_lookup (AFI_IP6, argv[0]);
1502   if (access == NULL)
1503     {
1504       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1505                VTY_NEWLINE);
1506       return CMD_WARNING;
1507     }
1508
1509   master = access->master;
1510
1511   /* Run hook function. */
1512   if (master->delete_hook)
1513     (*master->delete_hook) (access);
1514
1515   /* Delete all filter from access-list. */
1516   access_list_delete (access);
1517
1518   return CMD_SUCCESS;
1519 }
1520
1521 DEFUN (ipv6_access_list_remark,
1522        ipv6_access_list_remark_cmd,
1523        "ipv6 access-list WORD remark .LINE",
1524        IPV6_STR
1525        "Add an access list entry\n"
1526        "IPv6 zebra access-list\n"
1527        "Access list entry comment\n"
1528        "Comment up to 100 characters\n")
1529 {
1530   struct access_list *access;
1531
1532   access = access_list_get (AFI_IP6, argv[0]);
1533
1534   if (access->remark)
1535     {
1536       XFREE (MTYPE_TMP, access->remark);
1537       access->remark = NULL;
1538     }
1539   access->remark = argv_concat(argv, argc, 1);
1540
1541   return CMD_SUCCESS;
1542 }
1543
1544 DEFUN (no_ipv6_access_list_remark,
1545        no_ipv6_access_list_remark_cmd,
1546        "no ipv6 access-list WORD remark",
1547        NO_STR
1548        IPV6_STR
1549        "Add an access list entry\n"
1550        "IPv6 zebra access-list\n"
1551        "Access list entry comment\n")
1552 {
1553   return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
1554 }
1555         
1556 ALIAS (no_ipv6_access_list_remark,
1557        no_ipv6_access_list_remark_arg_cmd,
1558        "no ipv6 access-list WORD remark .LINE",
1559        NO_STR
1560        IPV6_STR
1561        "Add an access list entry\n"
1562        "IPv6 zebra access-list\n"
1563        "Access list entry comment\n"
1564        "Comment up to 100 characters\n")
1565 #endif /* HAVE_IPV6 */
1566
1567 void config_write_access_zebra (struct vty *, struct filter *);
1568 void config_write_access_cisco (struct vty *, struct filter *);
1569
1570 /* show access-list command. */
1571 static int
1572 filter_show (struct vty *vty, const char *name, afi_t afi)
1573 {
1574   struct access_list *access;
1575   struct access_master *master;
1576   struct filter *mfilter;
1577   struct filter_cisco *filter;
1578   int write = 0;
1579
1580   master = access_master_get (afi);
1581   if (master == NULL)
1582     return 0;
1583
1584   /* Print the name of the protocol */
1585   if (zlog_default)
1586       vty_out (vty, "%s:%s",
1587       zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
1588
1589   for (access = master->num.head; access; access = access->next)
1590     {
1591       if (name && strcmp (access->name, name) != 0)
1592         continue;
1593
1594       write = 1;
1595
1596       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1597         {
1598           filter = &mfilter->u.cfilter;
1599
1600           if (write)
1601             {
1602               vty_out (vty, "%s IP%s access list %s%s",
1603                        mfilter->cisco ? 
1604                        (filter->extended ? "Extended" : "Standard") : "Zebra",
1605                        afi == AFI_IP6 ? "v6" : "",
1606                        access->name, VTY_NEWLINE);
1607               write = 0;
1608             }
1609
1610           vty_out (vty, "    %s%s", filter_type_str (mfilter),
1611                    mfilter->type == FILTER_DENY ? "  " : "");
1612
1613           if (! mfilter->cisco)
1614             config_write_access_zebra (vty, mfilter);
1615           else if (filter->extended)
1616             config_write_access_cisco (vty, mfilter);
1617           else
1618             {
1619               if (filter->addr_mask.s_addr == 0xffffffff)
1620                 vty_out (vty, " any%s", VTY_NEWLINE);
1621               else
1622                 {
1623                   vty_out (vty, " %s", inet_ntoa (filter->addr));
1624                   if (filter->addr_mask.s_addr != 0)
1625                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1626                   vty_out (vty, "%s", VTY_NEWLINE);
1627                 }
1628             }
1629         }
1630     }
1631
1632   for (access = master->str.head; access; access = access->next)
1633     {
1634       if (name && strcmp (access->name, name) != 0)
1635         continue;
1636
1637       write = 1;
1638
1639       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1640         {
1641           filter = &mfilter->u.cfilter;
1642
1643           if (write)
1644             {
1645               vty_out (vty, "%s IP%s access list %s%s",
1646                        mfilter->cisco ? 
1647                        (filter->extended ? "Extended" : "Standard") : "Zebra",
1648                        afi == AFI_IP6 ? "v6" : "",
1649                        access->name, VTY_NEWLINE);
1650               write = 0;
1651             }
1652
1653           vty_out (vty, "    %s%s", filter_type_str (mfilter),
1654                    mfilter->type == FILTER_DENY ? "  " : "");
1655
1656           if (! mfilter->cisco)
1657             config_write_access_zebra (vty, mfilter);
1658           else if (filter->extended)
1659             config_write_access_cisco (vty, mfilter);
1660           else
1661             {
1662               if (filter->addr_mask.s_addr == 0xffffffff)
1663                 vty_out (vty, " any%s", VTY_NEWLINE);
1664               else
1665                 {
1666                   vty_out (vty, " %s", inet_ntoa (filter->addr));
1667                   if (filter->addr_mask.s_addr != 0)
1668                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1669                   vty_out (vty, "%s", VTY_NEWLINE);
1670                 }
1671             }
1672         }
1673     }
1674   return CMD_SUCCESS;
1675 }
1676
1677 DEFUN (show_ip_access_list,
1678        show_ip_access_list_cmd,
1679        "show ip access-list",
1680        SHOW_STR
1681        IP_STR
1682        "List IP access lists\n")
1683 {
1684   return filter_show (vty, NULL, AFI_IP);
1685 }
1686
1687 DEFUN (show_ip_access_list_name,
1688        show_ip_access_list_name_cmd,
1689        "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1690        SHOW_STR
1691        IP_STR
1692        "List IP access lists\n"
1693        "IP standard access list\n"
1694        "IP extended access list\n"
1695        "IP standard access list (expanded range)\n"
1696        "IP extended access list (expanded range)\n"
1697        "IP zebra access-list\n")
1698 {
1699   return filter_show (vty, argv[0], AFI_IP);
1700 }
1701
1702 #ifdef HAVE_IPV6
1703 DEFUN (show_ipv6_access_list,
1704        show_ipv6_access_list_cmd,
1705        "show ipv6 access-list",
1706        SHOW_STR
1707        IPV6_STR
1708        "List IPv6 access lists\n")
1709 {
1710   return filter_show (vty, NULL, AFI_IP6);
1711 }
1712
1713 DEFUN (show_ipv6_access_list_name,
1714        show_ipv6_access_list_name_cmd,
1715        "show ipv6 access-list WORD",
1716        SHOW_STR
1717        IPV6_STR
1718        "List IPv6 access lists\n"
1719        "IPv6 zebra access-list\n")
1720 {
1721   return filter_show (vty, argv[0], AFI_IP6);
1722 }
1723 #endif /* HAVE_IPV6 */
1724
1725 void
1726 config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1727 {
1728   struct filter_cisco *filter;
1729
1730   filter = &mfilter->u.cfilter;
1731
1732   if (filter->extended)
1733     {
1734       vty_out (vty, " ip");
1735       if (filter->addr_mask.s_addr == 0xffffffff)
1736         vty_out (vty, " any");
1737       else if (filter->addr_mask.s_addr == 0)
1738         vty_out (vty, " host %s", inet_ntoa (filter->addr));
1739       else
1740         {
1741           vty_out (vty, " %s", inet_ntoa (filter->addr));
1742           vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1743         }
1744
1745       if (filter->mask_mask.s_addr == 0xffffffff)
1746         vty_out (vty, " any");
1747       else if (filter->mask_mask.s_addr == 0)
1748         vty_out (vty, " host %s", inet_ntoa (filter->mask));
1749       else
1750         {
1751           vty_out (vty, " %s", inet_ntoa (filter->mask));
1752           vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1753         }
1754       vty_out (vty, "%s", VTY_NEWLINE);
1755     }
1756   else
1757     {
1758       if (filter->addr_mask.s_addr == 0xffffffff)
1759         vty_out (vty, " any%s", VTY_NEWLINE);
1760       else
1761         {
1762           vty_out (vty, " %s", inet_ntoa (filter->addr));
1763           if (filter->addr_mask.s_addr != 0)
1764             vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1765           vty_out (vty, "%s", VTY_NEWLINE);
1766         }
1767     }
1768 }
1769
1770 void
1771 config_write_access_zebra (struct vty *vty, struct filter *mfilter)
1772 {
1773   struct filter_zebra *filter;
1774   struct prefix *p;
1775   char buf[BUFSIZ];
1776
1777   filter = &mfilter->u.zfilter;
1778   p = &filter->prefix;
1779
1780   if (p->prefixlen == 0 && ! filter->exact)
1781     vty_out (vty, " any");
1782   else
1783     vty_out (vty, " %s/%d%s",
1784              inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1785              p->prefixlen,
1786              filter->exact ? " exact-match" : "");
1787
1788   vty_out (vty, "%s", VTY_NEWLINE);
1789 }
1790
1791 static int
1792 config_write_access (struct vty *vty, afi_t afi)
1793 {
1794   struct access_list *access;
1795   struct access_master *master;
1796   struct filter *mfilter;
1797   int write = 0;
1798
1799   master = access_master_get (afi);
1800   if (master == NULL)
1801     return 0;
1802
1803   for (access = master->num.head; access; access = access->next)
1804     {
1805       if (access->remark)
1806         {
1807           vty_out (vty, "%saccess-list %s remark %s%s",
1808                    afi == AFI_IP ? "" : "ipv6 ",
1809                    access->name, access->remark,
1810                    VTY_NEWLINE);
1811           write++;
1812         }
1813
1814       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1815         {
1816           vty_out (vty, "%saccess-list %s %s",
1817              afi == AFI_IP ? "" : "ipv6 ",
1818              access->name,
1819              filter_type_str (mfilter));
1820
1821           if (mfilter->cisco)
1822             config_write_access_cisco (vty, mfilter);
1823           else
1824             config_write_access_zebra (vty, mfilter);
1825
1826           write++;
1827         }
1828     }
1829
1830   for (access = master->str.head; access; access = access->next)
1831     {
1832       if (access->remark)
1833         {
1834           vty_out (vty, "%saccess-list %s remark %s%s",
1835                    afi == AFI_IP ? "" : "ipv6 ",
1836                    access->name, access->remark,
1837                    VTY_NEWLINE);
1838           write++;
1839         }
1840
1841       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1842         {
1843           vty_out (vty, "%saccess-list %s %s",
1844              afi == AFI_IP ? "" : "ipv6 ",
1845              access->name,
1846              filter_type_str (mfilter));
1847
1848           if (mfilter->cisco)
1849             config_write_access_cisco (vty, mfilter);
1850           else
1851             config_write_access_zebra (vty, mfilter);
1852
1853           write++;
1854         }
1855     }
1856   return write;
1857 }
1858
1859 /* Access-list node. */
1860 static struct cmd_node access_node =
1861 {
1862   ACCESS_NODE,
1863   "",                           /* Access list has no interface. */
1864   1
1865 };
1866
1867 static int
1868 config_write_access_ipv4 (struct vty *vty)
1869 {
1870   return config_write_access (vty, AFI_IP);
1871 }
1872
1873 static void
1874 access_list_reset_ipv4 (void)
1875 {
1876   struct access_list *access;
1877   struct access_list *next;
1878   struct access_master *master;
1879
1880   master = access_master_get (AFI_IP);
1881   if (master == NULL)
1882     return;
1883
1884   for (access = master->num.head; access; access = next)
1885     {
1886       next = access->next;
1887       access_list_delete (access);
1888     }
1889   for (access = master->str.head; access; access = next)
1890     {
1891       next = access->next;
1892       access_list_delete (access);
1893     }
1894
1895   assert (master->num.head == NULL);
1896   assert (master->num.tail == NULL);
1897
1898   assert (master->str.head == NULL);
1899   assert (master->str.tail == NULL);
1900 }
1901
1902 /* Install vty related command. */
1903 static void
1904 access_list_init_ipv4 (void)
1905 {
1906   install_node (&access_node, config_write_access_ipv4);
1907
1908   install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1909   install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
1910
1911   /* Zebra access-list */
1912   install_element (CONFIG_NODE, &access_list_cmd);
1913   install_element (CONFIG_NODE, &access_list_exact_cmd);
1914   install_element (CONFIG_NODE, &access_list_any_cmd);
1915   install_element (CONFIG_NODE, &no_access_list_cmd);
1916   install_element (CONFIG_NODE, &no_access_list_exact_cmd);
1917   install_element (CONFIG_NODE, &no_access_list_any_cmd);
1918
1919   /* Standard access-list */
1920   install_element (CONFIG_NODE, &access_list_standard_cmd);
1921   install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
1922   install_element (CONFIG_NODE, &access_list_standard_host_cmd);
1923   install_element (CONFIG_NODE, &access_list_standard_any_cmd);
1924   install_element (CONFIG_NODE, &no_access_list_standard_cmd);
1925   install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
1926   install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
1927   install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
1928
1929   /* Extended access-list */
1930   install_element (CONFIG_NODE, &access_list_extended_cmd);
1931   install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
1932   install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
1933   install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
1934   install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
1935   install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
1936   install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
1937   install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
1938   install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
1939   install_element (CONFIG_NODE, &no_access_list_extended_cmd);
1940   install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
1941   install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
1942   install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
1943   install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
1944   install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
1945   install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
1946   install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
1947   install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
1948
1949   install_element (CONFIG_NODE, &access_list_remark_cmd);
1950   install_element (CONFIG_NODE, &no_access_list_all_cmd);
1951   install_element (CONFIG_NODE, &no_access_list_remark_cmd);
1952   install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
1953 }
1954
1955 #ifdef HAVE_IPV6
1956 static struct cmd_node access_ipv6_node =
1957 {
1958   ACCESS_IPV6_NODE,
1959   "",
1960   1
1961 };
1962
1963 static int
1964 config_write_access_ipv6 (struct vty *vty)
1965 {
1966   return config_write_access (vty, AFI_IP6);
1967 }
1968
1969 static void
1970 access_list_reset_ipv6 (void)
1971 {
1972   struct access_list *access;
1973   struct access_list *next;
1974   struct access_master *master;
1975
1976   master = access_master_get (AFI_IP6);
1977   if (master == NULL)
1978     return;
1979
1980   for (access = master->num.head; access; access = next)
1981     {
1982       next = access->next;
1983       access_list_delete (access);
1984     }
1985   for (access = master->str.head; access; access = next)
1986     {
1987       next = access->next;
1988       access_list_delete (access);
1989     }
1990
1991   assert (master->num.head == NULL);
1992   assert (master->num.tail == NULL);
1993
1994   assert (master->str.head == NULL);
1995   assert (master->str.tail == NULL);
1996 }
1997
1998 static void
1999 access_list_init_ipv6 (void)
2000 {
2001   install_node (&access_ipv6_node, config_write_access_ipv6);
2002
2003   install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
2004   install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
2005
2006   install_element (CONFIG_NODE, &ipv6_access_list_cmd);
2007   install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
2008   install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
2009   install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2010   install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
2011   install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2012
2013   install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
2014   install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
2015   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
2016   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
2017 }
2018 #endif /* HAVE_IPV6 */
2019
2020 void
2021 access_list_init ()
2022 {
2023   access_list_init_ipv4 ();
2024 #ifdef HAVE_IPV6
2025   access_list_init_ipv6();
2026 #endif /* HAVE_IPV6 */
2027 }
2028
2029 void
2030 access_list_reset ()
2031 {
2032   access_list_reset_ipv4 ();
2033 #ifdef HAVE_IPV6
2034   access_list_reset_ipv6();
2035 #endif /* HAVE_IPV6 */
2036 }