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