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