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