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