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