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