[bgpd] Allow accepted peers to progress even if realpeer is in Connect
[jleu-quagga.git] / lib / filter.c
blob7aeb8deb7e266c8ee4546206bd6bb57fc908c25c
1 /* Route filtering function.
2 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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.
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.
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.
22 #include <zebra.h>
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"
32 struct filter_cisco
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;
42 struct filter_zebra
44 /* If this filter is "exact" match then this flag is set. */
45 int exact;
47 /* Prefix information. */
48 struct prefix prefix;
51 /* Filter element of access list */
52 struct filter
54 /* For doubly linked list. */
55 struct filter *next;
56 struct filter *prev;
58 /* Filter type information. */
59 enum filter_type type;
61 /* Cisco access-list */
62 int cisco;
64 union
66 struct filter_cisco cfilter;
67 struct filter_zebra zfilter;
68 } u;
71 /* List of access_list. */
72 struct access_list_list
74 struct access_list *head;
75 struct access_list *tail;
78 /* Master structure of access_list. */
79 struct access_master
81 /* List of access_list which name is number. */
82 struct access_list_list num;
84 /* List of access_list which name is string. */
85 struct access_list_list str;
87 /* Hook function which is executed when new access_list is added. */
88 void (*add_hook) (struct access_list *);
90 /* Hook function which is executed when access_list is deleted. */
91 void (*delete_hook) (struct access_list *);
94 /* Static structure for IPv4 access_list's master. */
95 static struct access_master access_master_ipv4 =
97 {NULL, NULL},
98 {NULL, NULL},
99 NULL,
100 NULL,
103 #ifdef HAVE_IPV6
104 /* Static structure for IPv6 access_list's master. */
105 static struct access_master access_master_ipv6 =
107 {NULL, NULL},
108 {NULL, NULL},
109 NULL,
110 NULL,
112 #endif /* HAVE_IPV6 */
114 static struct access_master *
115 access_master_get (afi_t afi)
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;
126 /* Allocate new filter structure. */
127 static struct filter *
128 filter_new (void)
130 return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
131 sizeof (struct filter));
134 static void
135 filter_free (struct filter *filter)
137 XFREE (MTYPE_ACCESS_FILTER, filter);
140 /* Return string of filter_type. */
141 static const char *
142 filter_type_str (struct filter *filter)
144 switch (filter->type)
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;
161 /* If filter match to the prefix then return 1. */
162 static int
163 filter_match_cisco (struct filter *mfilter, struct prefix *p)
165 struct filter_cisco *filter;
166 struct in_addr mask;
167 u_int32_t check_addr;
168 u_int32_t check_mask;
170 filter = &mfilter->u.cfilter;
171 check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
173 if (filter->extended)
175 masklen2ip (p->prefixlen, &mask);
176 check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
178 if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
179 && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
180 return 1;
182 else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
183 return 1;
185 return 0;
188 /* If filter match to the prefix then return 1. */
189 static int
190 filter_match_zebra (struct filter *mfilter, struct prefix *p)
192 struct filter_zebra *filter;
194 filter = &mfilter->u.zfilter;
196 if (filter->prefix.family == p->family)
198 if (filter->exact)
200 if (filter->prefix.prefixlen == p->prefixlen)
201 return prefix_match (&filter->prefix, p);
202 else
203 return 0;
205 else
206 return prefix_match (&filter->prefix, p);
208 else
209 return 0;
212 /* Allocate new access list structure. */
213 static struct access_list *
214 access_list_new (void)
216 return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
217 sizeof (struct access_list));
220 /* Free allocated access_list. */
221 static void
222 access_list_free (struct access_list *access)
224 XFREE (MTYPE_ACCESS_LIST, access);
227 /* Delete access_list from access_master and free it. */
228 static void
229 access_list_delete (struct access_list *access)
231 struct filter *filter;
232 struct filter *next;
233 struct access_list_list *list;
234 struct access_master *master;
236 for (filter = access->head; filter; filter = next)
238 next = filter->next;
239 filter_free (filter);
242 master = access->master;
244 if (access->type == ACCESS_TYPE_NUMBER)
245 list = &master->num;
246 else
247 list = &master->str;
249 if (access->next)
250 access->next->prev = access->prev;
251 else
252 list->tail = access->prev;
254 if (access->prev)
255 access->prev->next = access->next;
256 else
257 list->head = access->next;
259 if (access->name)
260 XFREE (MTYPE_ACCESS_LIST_STR, access->name);
262 if (access->remark)
263 XFREE (MTYPE_TMP, access->remark);
265 access_list_free (access);
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)
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;
280 master = access_master_get (afi);
281 if (master == NULL)
282 return NULL;
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;
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++)
293 if (isdigit ((int) name[i]))
294 number = (number * 10) + (name[i] - '0');
295 else
296 break;
299 /* In case of name is all digit character */
300 if (i == strlen (name))
302 access->type = ACCESS_TYPE_NUMBER;
304 /* Set access_list to number list. */
305 alist = &master->num;
307 for (point = alist->head; point; point = point->next)
308 if (atol (point->name) >= number)
309 break;
311 else
313 access->type = ACCESS_TYPE_STRING;
315 /* Set access_list to string list. */
316 alist = &master->str;
318 /* Set point to insertion point. */
319 for (point = alist->head; point; point = point->next)
320 if (strcmp (point->name, name) >= 0)
321 break;
324 /* In case of this is the first element of master. */
325 if (alist->head == NULL)
327 alist->head = alist->tail = access;
328 return access;
331 /* In case of insertion is made at the tail of access_list. */
332 if (point == NULL)
334 access->prev = alist->tail;
335 alist->tail->next = access;
336 alist->tail = access;
337 return access;
340 /* In case of insertion is made at the head of access_list. */
341 if (point == alist->head)
343 access->next = alist->head;
344 alist->head->prev = access;
345 alist->head = access;
346 return access;
349 /* Insertion is made at middle of the access_list. */
350 access->next = point;
351 access->prev = point->prev;
353 if (point->prev)
354 point->prev->next = access;
355 point->prev = access;
357 return access;
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)
364 struct access_list *access;
365 struct access_master *master;
367 if (name == NULL)
368 return NULL;
370 master = access_master_get (afi);
371 if (master == NULL)
372 return NULL;
374 for (access = master->num.head; access; access = access->next)
375 if (strcmp (access->name, name) == 0)
376 return access;
378 for (access = master->str.head; access; access = access->next)
379 if (strcmp (access->name, name) == 0)
380 return access;
382 return NULL;
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)
390 struct access_list *access;
392 access = access_list_lookup (afi, name);
393 if (access == NULL)
394 access = access_list_insert (afi, name);
395 return access;
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)
402 struct filter *filter;
403 struct prefix *p;
405 p = (struct prefix *) object;
407 if (access == NULL)
408 return FILTER_DENY;
410 for (filter = access->head; filter; filter = filter->next)
412 if (filter->cisco)
414 if (filter_match_cisco (filter, p))
415 return filter->type;
417 else
419 if (filter_match_zebra (filter, p))
420 return filter->type;
424 return FILTER_DENY;
427 /* Add hook function. */
428 void
429 access_list_add_hook (void (*func) (struct access_list *access))
431 access_master_ipv4.add_hook = func;
432 #ifdef HAVE_IPV6
433 access_master_ipv6.add_hook = func;
434 #endif /* HAVE_IPV6 */
437 /* Delete hook function. */
438 void
439 access_list_delete_hook (void (*func) (struct access_list *access))
441 access_master_ipv4.delete_hook = func;
442 #ifdef HAVE_IPV6
443 access_master_ipv6.delete_hook = func;
444 #endif /* HAVE_IPV6 */
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)
451 filter->next = NULL;
452 filter->prev = access->tail;
454 if (access->tail)
455 access->tail->next = filter;
456 else
457 access->head = filter;
458 access->tail = filter;
460 /* Run hook function. */
461 if (access->master->add_hook)
462 (*access->master->add_hook) (access);
465 /* If access_list has no filter then return 1. */
466 static int
467 access_list_empty (struct access_list *access)
469 if (access->head == NULL && access->tail == NULL)
470 return 1;
471 else
472 return 0;
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)
480 struct access_master *master;
482 master = access->master;
484 if (filter->next)
485 filter->next->prev = filter->prev;
486 else
487 access->tail = filter->prev;
489 if (filter->prev)
490 filter->prev->next = filter->next;
491 else
492 access->head = filter->next;
494 filter_free (filter);
496 /* If access_list becomes empty delete it from access_master. */
497 if (access_list_empty (access))
498 access_list_delete (access);
500 /* Run hook function. */
501 if (master->delete_hook)
502 (*master->delete_hook) (access);
506 deny Specify packets to reject
507 permit Specify packets to forward
508 dynamic ?
512 Hostname or A.B.C.D Address to match
513 any Any source host
514 host A single host address
517 static struct filter *
518 filter_lookup_cisco (struct access_list *access, struct filter *mnew)
520 struct filter *mfilter;
521 struct filter_cisco *filter;
522 struct filter_cisco *new;
524 new = &mnew->u.cfilter;
526 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
528 filter = &mfilter->u.cfilter;
530 if (filter->extended)
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;
539 else
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;
548 return NULL;
551 static struct filter *
552 filter_lookup_zebra (struct access_list *access, struct filter *mnew)
554 struct filter *mfilter;
555 struct filter_zebra *filter;
556 struct filter_zebra *new;
558 new = &mnew->u.zfilter;
560 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
562 filter = &mfilter->u.zfilter;
564 if (filter->exact == new->exact
565 && mfilter->type == mnew->type
566 && prefix_same (&filter->prefix, &new->prefix))
567 return mfilter;
569 return NULL;
572 static int
573 vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
575 struct access_list *access;
577 access = access_list_lookup (afi, name);
578 if (! access)
580 vty_out (vty, "%% access-list %s doesn't exist%s", name,
581 VTY_NEWLINE);
582 return CMD_WARNING;
585 if (access->remark)
587 XFREE (MTYPE_TMP, access->remark);
588 access->remark = NULL;
591 if (access->head == NULL && access->tail == NULL && access->remark == NULL)
592 access_list_delete (access);
594 return CMD_SUCCESS;
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)
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;
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
620 vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
621 return CMD_WARNING;
624 ret = inet_aton (addr_str, &addr);
625 if (ret <= 0)
627 vty_out (vty, "%%Inconsistent address and mask%s",
628 VTY_NEWLINE);
629 return CMD_WARNING;
632 ret = inet_aton (addr_mask_str, &addr_mask);
633 if (ret <= 0)
635 vty_out (vty, "%%Inconsistent address and mask%s",
636 VTY_NEWLINE);
637 return CMD_WARNING;
640 if (extended)
642 ret = inet_aton (mask_str, &mask);
643 if (ret <= 0)
645 vty_out (vty, "%%Inconsistent address and mask%s",
646 VTY_NEWLINE);
647 return CMD_WARNING;
650 ret = inet_aton (mask_mask_str, &mask_mask);
651 if (ret <= 0)
653 vty_out (vty, "%%Inconsistent address and mask%s",
654 VTY_NEWLINE);
655 return CMD_WARNING;
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;
667 if (extended)
669 filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
670 filter->mask_mask.s_addr = mask_mask.s_addr;
673 /* Install new filter to the access_list. */
674 access = access_list_get (AFI_IP, name_str);
676 if (set)
678 if (filter_lookup_cisco (access, mfilter))
679 filter_free (mfilter);
680 else
681 access_list_filter_add (access, mfilter);
683 else
685 struct filter *delete_filter;
687 delete_filter = filter_lookup_cisco (access, mfilter);
688 if (delete_filter)
689 access_list_filter_delete (access, delete_filter);
691 filter_free (mfilter);
694 return CMD_SUCCESS;
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")
709 return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
710 NULL, NULL, 0, 1);
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")
723 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
724 NULL, NULL, 0, 1);
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")
738 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
739 NULL, NULL, 0, 1);
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")
752 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
753 "255.255.255.255", NULL, NULL, 0, 1);
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")
768 return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
769 NULL, NULL, 0, 0);
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")
783 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
784 NULL, NULL, 0, 0);
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")
799 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
800 NULL, NULL, 0, 0);
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")
814 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
815 "255.255.255.255", NULL, NULL, 0, 0);
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")
833 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
834 argv[3], argv[4], argv[5], 1 ,1);
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")
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);
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")
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);
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")
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);
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")
904 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
905 argv[3], argv[4],
906 "0.0.0.0", 1, 1);
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")
923 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
924 "0.0.0.0", argv[3],
925 argv[4], 1, 1);
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")
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);
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")
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);
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")
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);
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")
998 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
999 argv[3], argv[4], argv[5], 1, 0);
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")
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);
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")
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);
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")
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);
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")
1073 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1074 argv[3], argv[4],
1075 "0.0.0.0", 1, 0);
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")
1093 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1094 "0.0.0.0", argv[3],
1095 argv[4], 1, 0);
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")
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);
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")
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);
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")
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);
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)
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;
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
1174 vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
1175 return CMD_WARNING;
1178 /* Check string format of prefix and prefixlen. */
1179 if (afi == AFI_IP)
1181 ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
1182 if (ret <= 0)
1184 vty_out (vty, "IP address prefix/prefixlen is malformed%s",
1185 VTY_NEWLINE);
1186 return CMD_WARNING;
1189 #ifdef HAVE_IPV6
1190 else if (afi == AFI_IP6)
1192 ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
1193 if (ret <= 0)
1195 vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
1196 VTY_NEWLINE);
1197 return CMD_WARNING;
1200 #endif /* HAVE_IPV6 */
1201 else
1202 return CMD_WARNING;
1204 mfilter = filter_new ();
1205 mfilter->type = type;
1206 filter = &mfilter->u.zfilter;
1207 prefix_copy (&filter->prefix, &p);
1209 /* "exact-match" */
1210 if (exact)
1211 filter->exact = 1;
1213 /* Install new filter to the access_list. */
1214 access = access_list_get (afi, name_str);
1216 if (set)
1218 if (filter_lookup_zebra (access, mfilter))
1219 filter_free (mfilter);
1220 else
1221 access_list_filter_add (access, mfilter);
1223 else
1225 struct filter *delete_filter;
1227 delete_filter = filter_lookup_zebra (access, mfilter);
1228 if (delete_filter)
1229 access_list_filter_delete (access, delete_filter);
1231 filter_free (mfilter);
1234 return CMD_SUCCESS;
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")
1247 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
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")
1260 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
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")
1272 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
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")
1285 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
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")
1299 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
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")
1312 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
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")
1326 struct access_list *access;
1327 struct access_master *master;
1329 /* Looking up access_list. */
1330 access = access_list_lookup (AFI_IP, argv[0]);
1331 if (access == NULL)
1333 vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1334 VTY_NEWLINE);
1335 return CMD_WARNING;
1338 master = access->master;
1340 /* Delete all filter from access-list. */
1341 access_list_delete (access);
1343 /* Run hook function. */
1344 if (master->delete_hook)
1345 (*master->delete_hook) (access);
1347 return CMD_SUCCESS;
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")
1362 struct access_list *access;
1364 access = access_list_get (AFI_IP, argv[0]);
1366 if (access->remark)
1368 XFREE (MTYPE_TMP, access->remark);
1369 access->remark = NULL;
1371 access->remark = argv_concat(argv, argc, 1);
1373 return CMD_SUCCESS;
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")
1388 return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
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")
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")
1415 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
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")
1429 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
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")
1442 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
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")
1456 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
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")
1471 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
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")
1485 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
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")
1497 struct access_list *access;
1498 struct access_master *master;
1500 /* Looking up access_list. */
1501 access = access_list_lookup (AFI_IP6, argv[0]);
1502 if (access == NULL)
1504 vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1505 VTY_NEWLINE);
1506 return CMD_WARNING;
1509 master = access->master;
1511 /* Delete all filter from access-list. */
1512 access_list_delete (access);
1514 /* Run hook function. */
1515 if (master->delete_hook)
1516 (*master->delete_hook) (access);
1518 return CMD_SUCCESS;
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")
1530 struct access_list *access;
1532 access = access_list_get (AFI_IP6, argv[0]);
1534 if (access->remark)
1536 XFREE (MTYPE_TMP, access->remark);
1537 access->remark = NULL;
1539 access->remark = argv_concat(argv, argc, 1);
1541 return CMD_SUCCESS;
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")
1553 return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
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 */
1567 void config_write_access_zebra (struct vty *, struct filter *);
1568 void config_write_access_cisco (struct vty *, struct filter *);
1570 /* show access-list command. */
1571 static int
1572 filter_show (struct vty *vty, const char *name, afi_t afi)
1574 struct access_list *access;
1575 struct access_master *master;
1576 struct filter *mfilter;
1577 struct filter_cisco *filter;
1578 int write = 0;
1580 master = access_master_get (afi);
1581 if (master == NULL)
1582 return 0;
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);
1589 for (access = master->num.head; access; access = access->next)
1591 if (name && strcmp (access->name, name) != 0)
1592 continue;
1594 write = 1;
1596 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1598 filter = &mfilter->u.cfilter;
1600 if (write)
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;
1610 vty_out (vty, " %s%s", filter_type_str (mfilter),
1611 mfilter->type == FILTER_DENY ? " " : "");
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
1619 if (filter->addr_mask.s_addr == 0xffffffff)
1620 vty_out (vty, " any%s", VTY_NEWLINE);
1621 else
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);
1632 for (access = master->str.head; access; access = access->next)
1634 if (name && strcmp (access->name, name) != 0)
1635 continue;
1637 write = 1;
1639 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1641 filter = &mfilter->u.cfilter;
1643 if (write)
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;
1653 vty_out (vty, " %s%s", filter_type_str (mfilter),
1654 mfilter->type == FILTER_DENY ? " " : "");
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
1662 if (filter->addr_mask.s_addr == 0xffffffff)
1663 vty_out (vty, " any%s", VTY_NEWLINE);
1664 else
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);
1674 return CMD_SUCCESS;
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")
1684 return filter_show (vty, NULL, AFI_IP);
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")
1699 return filter_show (vty, argv[0], AFI_IP);
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")
1710 return filter_show (vty, NULL, AFI_IP6);
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")
1721 return filter_show (vty, argv[0], AFI_IP6);
1723 #endif /* HAVE_IPV6 */
1725 void
1726 config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1728 struct filter_cisco *filter;
1730 filter = &mfilter->u.cfilter;
1732 if (filter->extended)
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
1741 vty_out (vty, " %s", inet_ntoa (filter->addr));
1742 vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
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
1751 vty_out (vty, " %s", inet_ntoa (filter->mask));
1752 vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1754 vty_out (vty, "%s", VTY_NEWLINE);
1756 else
1758 if (filter->addr_mask.s_addr == 0xffffffff)
1759 vty_out (vty, " any%s", VTY_NEWLINE);
1760 else
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);
1770 void
1771 config_write_access_zebra (struct vty *vty, struct filter *mfilter)
1773 struct filter_zebra *filter;
1774 struct prefix *p;
1775 char buf[BUFSIZ];
1777 filter = &mfilter->u.zfilter;
1778 p = &filter->prefix;
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" : "");
1788 vty_out (vty, "%s", VTY_NEWLINE);
1791 static int
1792 config_write_access (struct vty *vty, afi_t afi)
1794 struct access_list *access;
1795 struct access_master *master;
1796 struct filter *mfilter;
1797 int write = 0;
1799 master = access_master_get (afi);
1800 if (master == NULL)
1801 return 0;
1803 for (access = master->num.head; access; access = access->next)
1805 if (access->remark)
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++;
1814 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1816 vty_out (vty, "%saccess-list %s %s",
1817 afi == AFI_IP ? "" : "ipv6 ",
1818 access->name,
1819 filter_type_str (mfilter));
1821 if (mfilter->cisco)
1822 config_write_access_cisco (vty, mfilter);
1823 else
1824 config_write_access_zebra (vty, mfilter);
1826 write++;
1830 for (access = master->str.head; access; access = access->next)
1832 if (access->remark)
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++;
1841 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1843 vty_out (vty, "%saccess-list %s %s",
1844 afi == AFI_IP ? "" : "ipv6 ",
1845 access->name,
1846 filter_type_str (mfilter));
1848 if (mfilter->cisco)
1849 config_write_access_cisco (vty, mfilter);
1850 else
1851 config_write_access_zebra (vty, mfilter);
1853 write++;
1856 return write;
1859 /* Access-list node. */
1860 struct cmd_node access_node =
1862 ACCESS_NODE,
1863 "", /* Access list has no interface. */
1867 static int
1868 config_write_access_ipv4 (struct vty *vty)
1870 return config_write_access (vty, AFI_IP);
1873 static void
1874 access_list_reset_ipv4 (void)
1876 struct access_list *access;
1877 struct access_list *next;
1878 struct access_master *master;
1880 master = access_master_get (AFI_IP);
1881 if (master == NULL)
1882 return;
1884 for (access = master->num.head; access; access = next)
1886 next = access->next;
1887 access_list_delete (access);
1889 for (access = master->str.head; access; access = next)
1891 next = access->next;
1892 access_list_delete (access);
1895 assert (master->num.head == NULL);
1896 assert (master->num.tail == NULL);
1898 assert (master->str.head == NULL);
1899 assert (master->str.tail == NULL);
1902 /* Install vty related command. */
1903 static void
1904 access_list_init_ipv4 (void)
1906 install_node (&access_node, config_write_access_ipv4);
1908 install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1909 install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
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);
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);
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);
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);
1955 #ifdef HAVE_IPV6
1956 struct cmd_node access_ipv6_node =
1958 ACCESS_IPV6_NODE,
1963 static int
1964 config_write_access_ipv6 (struct vty *vty)
1966 return config_write_access (vty, AFI_IP6);
1969 static void
1970 access_list_reset_ipv6 (void)
1972 struct access_list *access;
1973 struct access_list *next;
1974 struct access_master *master;
1976 master = access_master_get (AFI_IP6);
1977 if (master == NULL)
1978 return;
1980 for (access = master->num.head; access; access = next)
1982 next = access->next;
1983 access_list_delete (access);
1985 for (access = master->str.head; access; access = next)
1987 next = access->next;
1988 access_list_delete (access);
1991 assert (master->num.head == NULL);
1992 assert (master->num.tail == NULL);
1994 assert (master->str.head == NULL);
1995 assert (master->str.tail == NULL);
1998 static void
1999 access_list_init_ipv6 (void)
2001 install_node (&access_ipv6_node, config_write_access_ipv6);
2003 install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
2004 install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
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);
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);
2018 #endif /* HAVE_IPV6 */
2020 void
2021 access_list_init ()
2023 access_list_init_ipv4 ();
2024 #ifdef HAVE_IPV6
2025 access_list_init_ipv6();
2026 #endif /* HAVE_IPV6 */
2029 void
2030 access_list_reset ()
2032 access_list_reset_ipv4 ();
2033 #ifdef HAVE_IPV6
2034 access_list_reset_ipv6();
2035 #endif /* HAVE_IPV6 */