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 *
access_master_get(afi_t afi)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 *
filter_new(void)128 filter_new (void)
129 {
130   return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
131 				    sizeof (struct filter));
132 }
133 
134 static void
filter_free(struct filter * filter)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 *
filter_type_str(struct filter * filter)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
filter_match_cisco(struct filter * mfilter,struct prefix * p)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
filter_match_zebra(struct filter * mfilter,struct prefix * p)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 *
access_list_new(void)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
access_list_free(struct access_list * access)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
access_list_delete(struct access_list * access)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 *
access_list_insert(afi_t afi,const char * name)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 *
access_list_lookup(afi_t afi,const char * name)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 *
access_list_get(afi_t afi,const char * name)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
access_list_apply(struct access_list * access,void * object)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
access_list_add_hook(void (* func)(const char *))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
access_list_delete_hook(void (* func)(const char *))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
access_list_filter_add(struct access_list * access,struct filter * filter)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
access_list_empty(struct access_list * access)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
access_list_filter_delete(struct access_list * access,struct filter * filter)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 *
filter_lookup_cisco(struct access_list * access,struct filter * mnew)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 *
filter_lookup_zebra(struct access_list * access,struct filter * mnew)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
vty_access_list_remark_unset(struct vty * vty,afi_t afi,const char * name)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
filter_set_cisco(struct vty * vty,const char * name_str,const char * type_str,const char * addr_str,const char * addr_mask_str,const char * mask_str,const char * mask_mask_str,int extended,int set)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
filter_set_zebra(struct vty * vty,const char * name_str,const char * type_str,afi_t afi,const char * prefix_str,int exact,int set)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
filter_show(struct vty * vty,const char * name,afi_t afi)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
config_write_access_cisco(struct vty * vty,struct filter * mfilter)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
config_write_access_zebra(struct vty * vty,struct filter * mfilter)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
config_write_access(struct vty * vty,afi_t afi)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
config_write_access_ipv4(struct vty * vty)1896 config_write_access_ipv4 (struct vty *vty)
1897 {
1898   return config_write_access (vty, AFI_IP);
1899 }
1900 
1901 static void
access_list_reset_ipv4(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
access_list_init_ipv4(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
config_write_access_ipv6(struct vty * vty)1992 config_write_access_ipv6 (struct vty *vty)
1993 {
1994   return config_write_access (vty, AFI_IP6);
1995 }
1996 
1997 static void
access_list_reset_ipv6(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
access_list_init_ipv6(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
access_list_init()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
access_list_reset()2058 access_list_reset ()
2059 {
2060   access_list_reset_ipv4 ();
2061 #ifdef HAVE_IPV6
2062   access_list_reset_ipv6();
2063 #endif /* HAVE_IPV6 */
2064 }
2065