]> git.proxmox.com Git - mirror_frr.git/blob - lib/filter.c
Merge pull request #5778 from ton31337/fix/add_doc_for_ebgp_connected_route_check
[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 /* Sequence number */
64 int64_t seq;
65
66 /* Cisco access-list */
67 int cisco;
68
69 union {
70 struct filter_cisco cfilter;
71 struct filter_zebra zfilter;
72 } u;
73 };
74
75 /* List of access_list. */
76 struct access_list_list {
77 struct access_list *head;
78 struct access_list *tail;
79 };
80
81 /* Master structure of access_list. */
82 struct access_master {
83 /* List of access_list which name is number. */
84 struct access_list_list num;
85
86 /* List of access_list which name is string. */
87 struct access_list_list str;
88
89 /* Hook function which is executed when new access_list is added. */
90 void (*add_hook)(struct access_list *);
91
92 /* Hook function which is executed when access_list is deleted. */
93 void (*delete_hook)(struct access_list *);
94 };
95
96 /* Static structure for mac access_list's master. */
97 static struct access_master access_master_mac = {
98 {NULL, NULL},
99 {NULL, NULL},
100 NULL,
101 NULL,
102 };
103
104 /* Static structure for IPv4 access_list's master. */
105 static struct access_master access_master_ipv4 = {
106 {NULL, NULL},
107 {NULL, NULL},
108 NULL,
109 NULL,
110 };
111
112 /* Static structure for IPv6 access_list's master. */
113 static struct access_master access_master_ipv6 = {
114 {NULL, NULL},
115 {NULL, NULL},
116 NULL,
117 NULL,
118 };
119
120 static struct access_master *access_master_get(afi_t afi)
121 {
122 if (afi == AFI_IP)
123 return &access_master_ipv4;
124 else if (afi == AFI_IP6)
125 return &access_master_ipv6;
126 else if (afi == AFI_L2VPN)
127 return &access_master_mac;
128 return NULL;
129 }
130
131 /* Allocate new filter structure. */
132 static struct filter *filter_new(void)
133 {
134 return XCALLOC(MTYPE_ACCESS_FILTER, sizeof(struct filter));
135 }
136
137 static void filter_free(struct filter *filter)
138 {
139 XFREE(MTYPE_ACCESS_FILTER, filter);
140 }
141
142 /* Return string of filter_type. */
143 static const char *filter_type_str(struct filter *filter)
144 {
145 switch (filter->type) {
146 case FILTER_PERMIT:
147 return "permit";
148 break;
149 case FILTER_DENY:
150 return "deny";
151 break;
152 case FILTER_DYNAMIC:
153 return "dynamic";
154 break;
155 default:
156 return "";
157 break;
158 }
159 }
160
161 /* If filter match to the prefix then return 1. */
162 static int filter_match_cisco(struct filter *mfilter, const struct prefix *p)
163 {
164 struct filter_cisco *filter;
165 struct in_addr mask;
166 uint32_t check_addr;
167 uint32_t check_mask;
168
169 filter = &mfilter->u.cfilter;
170 check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
171
172 if (filter->extended) {
173 masklen2ip(p->prefixlen, &mask);
174 check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
175
176 if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0
177 && memcmp(&check_mask, &filter->mask.s_addr, 4) == 0)
178 return 1;
179 } else if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0)
180 return 1;
181
182 return 0;
183 }
184
185 /* If filter match to the prefix then return 1. */
186 static int filter_match_zebra(struct filter *mfilter, const struct prefix *p)
187 {
188 struct filter_zebra *filter = NULL;
189
190 filter = &mfilter->u.zfilter;
191
192 if (filter->prefix.family == p->family) {
193 if (filter->exact) {
194 if (filter->prefix.prefixlen == p->prefixlen)
195 return prefix_match(&filter->prefix, p);
196 else
197 return 0;
198 } else
199 return prefix_match(&filter->prefix, p);
200 } else
201 return 0;
202 }
203
204 /* Allocate new access list structure. */
205 static struct access_list *access_list_new(void)
206 {
207 return XCALLOC(MTYPE_ACCESS_LIST, sizeof(struct access_list));
208 }
209
210 /* Free allocated access_list. */
211 static void access_list_free(struct access_list *access)
212 {
213 XFREE(MTYPE_ACCESS_LIST, access);
214 }
215
216 /* Delete access_list from access_master and free it. */
217 static void access_list_delete(struct access_list *access)
218 {
219 struct filter *filter;
220 struct filter *next;
221 struct access_list_list *list;
222 struct access_master *master;
223
224 for (filter = access->head; filter; filter = next) {
225 next = filter->next;
226 filter_free(filter);
227 }
228
229 master = access->master;
230
231 if (access->type == ACCESS_TYPE_NUMBER)
232 list = &master->num;
233 else
234 list = &master->str;
235
236 if (access->next)
237 access->next->prev = access->prev;
238 else
239 list->tail = access->prev;
240
241 if (access->prev)
242 access->prev->next = access->next;
243 else
244 list->head = access->next;
245
246 XFREE(MTYPE_ACCESS_LIST_STR, access->name);
247
248 XFREE(MTYPE_TMP, access->remark);
249
250 access_list_free(access);
251 }
252
253 /* Insert new access list to list of access_list. Each acceess_list
254 is sorted by the name. */
255 static struct access_list *access_list_insert(afi_t afi, const char *name)
256 {
257 unsigned int i;
258 long number;
259 struct access_list *access;
260 struct access_list *point;
261 struct access_list_list *alist;
262 struct access_master *master;
263
264 master = access_master_get(afi);
265 if (master == NULL)
266 return NULL;
267
268 /* Allocate new access_list and copy given name. */
269 access = access_list_new();
270 access->name = XSTRDUP(MTYPE_ACCESS_LIST_STR, name);
271 access->master = master;
272
273 /* If name is made by all digit character. We treat it as
274 number. */
275 for (number = 0, i = 0; i < strlen(name); i++) {
276 if (isdigit((unsigned char)name[i]))
277 number = (number * 10) + (name[i] - '0');
278 else
279 break;
280 }
281
282 /* In case of name is all digit character */
283 if (i == strlen(name)) {
284 access->type = ACCESS_TYPE_NUMBER;
285
286 /* Set access_list to number list. */
287 alist = &master->num;
288
289 for (point = alist->head; point; point = point->next)
290 if (atol(point->name) >= number)
291 break;
292 } else {
293 access->type = ACCESS_TYPE_STRING;
294
295 /* Set access_list to string list. */
296 alist = &master->str;
297
298 /* Set point to insertion point. */
299 for (point = alist->head; point; point = point->next)
300 if (strcmp(point->name, name) >= 0)
301 break;
302 }
303
304 /* In case of this is the first element of master. */
305 if (alist->head == NULL) {
306 alist->head = alist->tail = access;
307 return access;
308 }
309
310 /* In case of insertion is made at the tail of access_list. */
311 if (point == NULL) {
312 access->prev = alist->tail;
313 alist->tail->next = access;
314 alist->tail = access;
315 return access;
316 }
317
318 /* In case of insertion is made at the head of access_list. */
319 if (point == alist->head) {
320 access->next = alist->head;
321 alist->head->prev = access;
322 alist->head = access;
323 return access;
324 }
325
326 /* Insertion is made at middle of the access_list. */
327 access->next = point;
328 access->prev = point->prev;
329
330 if (point->prev)
331 point->prev->next = access;
332 point->prev = access;
333
334 return access;
335 }
336
337 /* Lookup access_list from list of access_list by name. */
338 struct access_list *access_list_lookup(afi_t afi, const char *name)
339 {
340 struct access_list *access;
341 struct access_master *master;
342
343 if (name == NULL)
344 return NULL;
345
346 master = access_master_get(afi);
347 if (master == NULL)
348 return NULL;
349
350 for (access = master->num.head; access; access = access->next)
351 if (strcmp(access->name, name) == 0)
352 return access;
353
354 for (access = master->str.head; access; access = access->next)
355 if (strcmp(access->name, name) == 0)
356 return access;
357
358 return NULL;
359 }
360
361 /* Get access list from list of access_list. If there isn't matched
362 access_list create new one and return it. */
363 static struct access_list *access_list_get(afi_t afi, const char *name)
364 {
365 struct access_list *access;
366
367 access = access_list_lookup(afi, name);
368 if (access == NULL)
369 access = access_list_insert(afi, name);
370 return access;
371 }
372
373 /* Apply access list to object (which should be struct prefix *). */
374 enum filter_type access_list_apply(struct access_list *access,
375 const void *object)
376 {
377 struct filter *filter;
378 const struct prefix *p = (const 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 /* Calculate new sequential number. */
413 static int64_t filter_new_seq_get(struct access_list *access)
414 {
415 int64_t maxseq;
416 int64_t newseq;
417 struct filter *filter;
418
419 maxseq = newseq = 0;
420
421 for (filter = access->head; filter; filter = filter->next) {
422 if (maxseq < filter->seq)
423 maxseq = filter->seq;
424 }
425
426 newseq = ((maxseq / 5) * 5) + 5;
427
428 return (newseq > UINT_MAX) ? UINT_MAX : newseq;
429 }
430
431 /* Return access list entry which has same seq number. */
432 static struct filter *filter_seq_check(struct access_list *access,
433 int64_t seq)
434 {
435 struct filter *filter;
436
437 for (filter = access->head; filter; filter = filter->next)
438 if (filter->seq == seq)
439 return filter;
440 return NULL;
441 }
442
443 /* If access_list has no filter then return 1. */
444 static int access_list_empty(struct access_list *access)
445 {
446 if (access->head == NULL && access->tail == NULL)
447 return 1;
448 else
449 return 0;
450 }
451
452 /* Delete filter from specified access_list. If there is hook
453 function execute it. */
454 static void access_list_filter_delete(struct access_list *access,
455 struct filter *filter)
456 {
457 struct access_master *master;
458
459 master = access->master;
460
461 if (filter->next)
462 filter->next->prev = filter->prev;
463 else
464 access->tail = filter->prev;
465
466 if (filter->prev)
467 filter->prev->next = filter->next;
468 else
469 access->head = filter->next;
470
471 filter_free(filter);
472
473 route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
474 /* Run hook function. */
475 if (master->delete_hook)
476 (*master->delete_hook)(access);
477
478 /* If access_list becomes empty delete it from access_master. */
479 if (access_list_empty(access))
480 access_list_delete(access);
481 }
482
483 /* Add new filter to the end of specified access_list. */
484 static void access_list_filter_add(struct access_list *access,
485 struct filter *filter)
486 {
487 struct filter *replace;
488 struct filter *point;
489
490 /* Automatic asignment of seq no. */
491 if (filter->seq == -1)
492 filter->seq = filter_new_seq_get(access);
493
494 if (access->tail && filter->seq > access->tail->seq)
495 point = NULL;
496 else {
497 /* Is there any same seq access list filter? */
498 replace = filter_seq_check(access, filter->seq);
499 if (replace)
500 access_list_filter_delete(access, replace);
501
502 /* Check insert point. */
503 for (point = access->head; point; point = point->next)
504 if (point->seq >= filter->seq)
505 break;
506 }
507
508 /* In case of this is the first element of the list. */
509 filter->next = point;
510
511 if (point) {
512 if (point->prev)
513 point->prev->next = filter;
514 else
515 access->head = filter;
516
517 filter->prev = point->prev;
518 point->prev = filter;
519 } else {
520 if (access->tail)
521 access->tail->next = filter;
522 else
523 access->head = filter;
524
525 filter->prev = access->tail;
526 access->tail = filter;
527 }
528
529 /* Run hook function. */
530 if (access->master->add_hook)
531 (*access->master->add_hook)(access);
532 route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_ADDED);
533 }
534
535 /*
536 deny Specify packets to reject
537 permit Specify packets to forward
538 dynamic ?
539 */
540
541 /*
542 Hostname or A.B.C.D Address to match
543 any Any source host
544 host A single host address
545 */
546
547 static struct filter *filter_lookup_cisco(struct access_list *access,
548 struct filter *mnew)
549 {
550 struct filter *mfilter;
551 struct filter_cisco *filter;
552 struct filter_cisco *new;
553
554 new = &mnew->u.cfilter;
555
556 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
557 filter = &mfilter->u.cfilter;
558
559 if (filter->extended) {
560 if (mfilter->type == mnew->type
561 && filter->addr.s_addr == new->addr.s_addr
562 && filter->addr_mask.s_addr == new->addr_mask.s_addr
563 && filter->mask.s_addr == new->mask.s_addr
564 && filter->mask_mask.s_addr
565 == new->mask_mask.s_addr)
566 return mfilter;
567 } else {
568 if (mfilter->type == mnew->type
569 && filter->addr.s_addr == new->addr.s_addr
570 && filter->addr_mask.s_addr
571 == new->addr_mask.s_addr)
572 return mfilter;
573 }
574 }
575
576 return NULL;
577 }
578
579 static struct filter *filter_lookup_zebra(struct access_list *access,
580 struct filter *mnew)
581 {
582 struct filter *mfilter;
583 struct filter_zebra *filter;
584 struct filter_zebra *new;
585
586 new = &mnew->u.zfilter;
587
588 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
589 filter = &mfilter->u.zfilter;
590
591 if (filter->exact == new->exact
592 && mfilter->type == mnew->type) {
593 if (prefix_same(&filter->prefix, &new->prefix))
594 return mfilter;
595 }
596 }
597 return NULL;
598 }
599
600 static int vty_access_list_remark_unset(struct vty *vty, afi_t afi,
601 const char *name)
602 {
603 struct access_list *access;
604
605 access = access_list_lookup(afi, name);
606 if (!access) {
607 vty_out(vty, "%% access-list %s doesn't exist\n", name);
608 return CMD_WARNING_CONFIG_FAILED;
609 }
610
611 XFREE(MTYPE_TMP, access->remark);
612
613 if (access->head == NULL && access->tail == NULL)
614 access_list_delete(access);
615
616 return CMD_SUCCESS;
617 }
618
619 static int filter_set_cisco(struct vty *vty, const char *name_str,
620 const char *seq, const char *type_str,
621 const char *addr_str, const char *addr_mask_str,
622 const char *mask_str, const char *mask_mask_str,
623 int extended, int set)
624 {
625 int ret;
626 enum filter_type type = FILTER_DENY;
627 struct filter *mfilter;
628 struct filter_cisco *filter;
629 struct access_list *access;
630 struct in_addr addr;
631 struct in_addr addr_mask;
632 struct in_addr mask;
633 struct in_addr mask_mask;
634 int64_t seqnum = -1;
635
636 if (seq)
637 seqnum = (int64_t)atol(seq);
638
639 /* Check of filter type. */
640 if (type_str) {
641 if (strncmp(type_str, "p", 1) == 0)
642 type = FILTER_PERMIT;
643 else if (strncmp(type_str, "d", 1) == 0)
644 type = FILTER_DENY;
645 else {
646 vty_out(vty, "%% filter type must be permit or deny\n");
647 return CMD_WARNING_CONFIG_FAILED;
648 }
649 }
650
651 ret = inet_aton(addr_str, &addr);
652 if (ret <= 0) {
653 vty_out(vty, "%%Inconsistent address and mask\n");
654 return CMD_WARNING_CONFIG_FAILED;
655 }
656
657 ret = inet_aton(addr_mask_str, &addr_mask);
658 if (ret <= 0) {
659 vty_out(vty, "%%Inconsistent address and mask\n");
660 return CMD_WARNING_CONFIG_FAILED;
661 }
662
663 if (extended) {
664 ret = inet_aton(mask_str, &mask);
665 if (ret <= 0) {
666 vty_out(vty, "%%Inconsistent address and mask\n");
667 return CMD_WARNING_CONFIG_FAILED;
668 }
669
670 ret = inet_aton(mask_mask_str, &mask_mask);
671 if (ret <= 0) {
672 vty_out(vty, "%%Inconsistent address and mask\n");
673 return CMD_WARNING_CONFIG_FAILED;
674 }
675 }
676
677 mfilter = filter_new();
678 mfilter->type = type;
679 mfilter->cisco = 1;
680 mfilter->seq = seqnum;
681 filter = &mfilter->u.cfilter;
682 filter->extended = extended;
683 filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
684 filter->addr_mask.s_addr = addr_mask.s_addr;
685
686 if (extended) {
687 filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
688 filter->mask_mask.s_addr = mask_mask.s_addr;
689 }
690
691 /* Install new filter to the access_list. */
692 access = access_list_get(AFI_IP, name_str);
693
694 if (set) {
695 if (filter_lookup_cisco(access, mfilter))
696 filter_free(mfilter);
697 else
698 access_list_filter_add(access, mfilter);
699 } else {
700 struct filter *delete_filter;
701
702 delete_filter = filter_lookup_cisco(access, mfilter);
703 if (delete_filter)
704 access_list_filter_delete(access, delete_filter);
705
706 filter_free(mfilter);
707 }
708
709 return CMD_SUCCESS;
710 }
711
712 /* Standard access-list */
713 DEFUN (access_list_standard,
714 access_list_standard_cmd,
715 "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D A.B.C.D",
716 "Add an access list entry\n"
717 "IP standard access list\n"
718 "IP standard access list (expanded range)\n"
719 "Sequence number of an entry\n"
720 "Sequence number\n"
721 "Specify packets to reject\n"
722 "Specify packets to forward\n"
723 "Address to match\n"
724 "Wildcard bits\n")
725 {
726 int idx_acl = 1;
727 int idx = 0;
728 char *seq = NULL;
729 char *permit_deny = NULL;
730 char *address = NULL;
731 char *wildcard = NULL;
732
733 argv_find(argv, argc, "(1-4294967295)", &idx);
734 if (idx)
735 seq = argv[idx]->arg;
736
737 idx = 0;
738 argv_find(argv, argc, "permit", &idx);
739 argv_find(argv, argc, "deny", &idx);
740 if (idx)
741 permit_deny = argv[idx]->arg;
742
743 idx = 0;
744 argv_find(argv, argc, "A.B.C.D", &idx);
745 if (idx) {
746 address = argv[idx]->arg;
747 wildcard = argv[idx + 1]->arg;
748 }
749
750 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
751 address, wildcard, NULL, NULL, 0, 1);
752 }
753
754 DEFUN (access_list_standard_nomask,
755 access_list_standard_nomask_cmd,
756 "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D",
757 "Add an access list entry\n"
758 "IP standard access list\n"
759 "IP standard access list (expanded range)\n"
760 "Sequence number of an entry\n"
761 "Sequence number\n"
762 "Specify packets to reject\n"
763 "Specify packets to forward\n"
764 "Address to match\n")
765 {
766 int idx_acl = 1;
767 int idx = 0;
768 char *seq = NULL;
769 char *permit_deny = NULL;
770 char *address = NULL;
771
772 argv_find(argv, argc, "(1-4294967295)", &idx);
773 if (idx)
774 seq = argv[idx]->arg;
775
776 idx = 0;
777 argv_find(argv, argc, "permit", &idx);
778 argv_find(argv, argc, "deny", &idx);
779 if (idx)
780 permit_deny = argv[idx]->arg;
781
782 idx = 0;
783 argv_find(argv, argc, "A.B.C.D", &idx);
784 if (idx)
785 address = argv[idx]->arg;
786
787 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
788 address, "0.0.0.0", NULL, NULL, 0, 1);
789 }
790
791 DEFUN (access_list_standard_host,
792 access_list_standard_host_cmd,
793 "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> host A.B.C.D",
794 "Add an access list entry\n"
795 "IP standard access list\n"
796 "IP standard access list (expanded range)\n"
797 "Sequence number of an entry\n"
798 "Sequence number\n"
799 "Specify packets to reject\n"
800 "Specify packets to forward\n"
801 "A single host address\n"
802 "Address to match\n")
803 {
804 int idx_acl = 1;
805 int idx = 0;
806 char *seq = NULL;
807 char *permit_deny = NULL;
808 char *address = NULL;
809
810 argv_find(argv, argc, "(1-4294967295)", &idx);
811 if (idx)
812 seq = argv[idx]->arg;
813
814 idx = 0;
815 argv_find(argv, argc, "permit", &idx);
816 argv_find(argv, argc, "deny", &idx);
817 if (idx)
818 permit_deny = argv[idx]->arg;
819
820 idx = 0;
821 argv_find(argv, argc, "A.B.C.D", &idx);
822 if (idx)
823 address = argv[idx]->arg;
824
825 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
826 address, "0.0.0.0", NULL, NULL, 0, 1);
827 }
828
829 DEFUN (access_list_standard_any,
830 access_list_standard_any_cmd,
831 "access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> any",
832 "Add an access list entry\n"
833 "IP standard access list\n"
834 "IP standard access list (expanded range)\n"
835 "Sequence number of an entry\n"
836 "Sequence number\n"
837 "Specify packets to reject\n"
838 "Specify packets to forward\n"
839 "Any source host\n")
840 {
841 int idx_acl = 1;
842 int idx = 0;
843 char *seq = NULL;
844 char *permit_deny = NULL;
845
846 argv_find(argv, argc, "(1-4294967295)", &idx);
847 if (idx)
848 seq = argv[idx]->arg;
849
850 idx = 0;
851 argv_find(argv, argc, "permit", &idx);
852 argv_find(argv, argc, "deny", &idx);
853 if (idx)
854 permit_deny = argv[idx]->arg;
855
856 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
857 "0.0.0.0", "255.255.255.255", NULL, NULL, 0, 1);
858 }
859
860 DEFUN (no_access_list_standard,
861 no_access_list_standard_cmd,
862 "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D A.B.C.D",
863 NO_STR
864 "Add an access list entry\n"
865 "IP standard access list\n"
866 "IP standard access list (expanded range)\n"
867 "Sequence number of an entry\n"
868 "Sequence number\n"
869 "Specify packets to reject\n"
870 "Specify packets to forward\n"
871 "Address to match\n"
872 "Wildcard bits\n")
873 {
874 int idx_acl = 1;
875 int idx = 0;
876 char *seq = NULL;
877 char *permit_deny = NULL;
878 char *address = NULL;
879 char *wildcard = NULL;
880
881 argv_find(argv, argc, "(1-4294967295)", &idx);
882 if (idx)
883 seq = argv[idx]->arg;
884
885 idx = 0;
886 argv_find(argv, argc, "permit", &idx);
887 argv_find(argv, argc, "deny", &idx);
888 if (idx)
889 permit_deny = argv[idx]->arg;
890
891 idx = 0;
892 argv_find(argv, argc, "A.B.C.D", &idx);
893 if (idx) {
894 address = argv[idx]->arg;
895 wildcard = argv[idx + 1]->arg;
896 }
897
898 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
899 address, wildcard, NULL, NULL, 0, 0);
900 }
901
902 DEFUN (no_access_list_standard_nomask,
903 no_access_list_standard_nomask_cmd,
904 "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> A.B.C.D",
905 NO_STR
906 "Add an access list entry\n"
907 "IP standard access list\n"
908 "IP standard access list (expanded range)\n"
909 "Sequence number of an entry\n"
910 "Sequence number\n"
911 "Specify packets to reject\n"
912 "Specify packets to forward\n"
913 "Address to match\n")
914 {
915 int idx_acl = 2;
916 int idx = 0;
917 char *seq = NULL;
918 char *permit_deny = NULL;
919 char *address = NULL;
920
921 argv_find(argv, argc, "(1-4294967295)", &idx);
922 if (idx)
923 seq = argv[idx]->arg;
924
925 idx = 0;
926 argv_find(argv, argc, "permit", &idx);
927 argv_find(argv, argc, "deny", &idx);
928 if (idx)
929 permit_deny = argv[idx]->arg;
930
931 idx = 0;
932 argv_find(argv, argc, "A.B.C.D", &idx);
933 if (idx)
934 address = argv[idx]->arg;
935
936 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
937 address, "0.0.0.0", NULL, NULL, 0, 0);
938 }
939
940 DEFUN (no_access_list_standard_host,
941 no_access_list_standard_host_cmd,
942 "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> host A.B.C.D",
943 NO_STR
944 "Add an access list entry\n"
945 "IP standard access list\n"
946 "IP standard access list (expanded range)\n"
947 "Sequence number of an entry\n"
948 "Sequence number\n"
949 "Specify packets to reject\n"
950 "Specify packets to forward\n"
951 "A single host address\n"
952 "Address to match\n")
953 {
954 int idx_acl = 2;
955 int idx = 0;
956 char *seq = NULL;
957 char *permit_deny = NULL;
958 char *address = NULL;
959
960 argv_find(argv, argc, "(1-4294967295)", &idx);
961 if (idx)
962 seq = argv[idx]->arg;
963
964 idx = 0;
965 argv_find(argv, argc, "permit", &idx);
966 argv_find(argv, argc, "deny", &idx);
967 if (idx)
968 permit_deny = argv[idx]->arg;
969
970 idx = 0;
971 argv_find(argv, argc, "A.B.C.D", &idx);
972 if (idx)
973 address = argv[idx]->arg;
974
975 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
976 address, "0.0.0.0", NULL, NULL, 0, 0);
977 }
978
979 DEFUN (no_access_list_standard_any,
980 no_access_list_standard_any_cmd,
981 "no access-list <(1-99)|(1300-1999)> [seq (1-4294967295)] <deny|permit> any",
982 NO_STR
983 "Add an access list entry\n"
984 "IP standard access list\n"
985 "IP standard access list (expanded range)\n"
986 "Sequence number of an entry\n"
987 "Sequence number\n"
988 "Specify packets to reject\n"
989 "Specify packets to forward\n"
990 "Any source host\n")
991 {
992 int idx_acl = 2;
993 int idx = 0;
994 char *seq = NULL;
995 char *permit_deny = NULL;
996
997 argv_find(argv, argc, "(1-4294967295)", &idx);
998 if (idx)
999 seq = argv[idx]->arg;
1000
1001 idx = 0;
1002 argv_find(argv, argc, "permit", &idx);
1003 argv_find(argv, argc, "deny", &idx);
1004 if (idx)
1005 permit_deny = argv[idx]->arg;
1006
1007 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1008 "0.0.0.0", "255.255.255.255", NULL, NULL, 0, 0);
1009 }
1010
1011 /* Extended access-list */
1012 DEFUN (access_list_extended,
1013 access_list_extended_cmd,
1014 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
1015 "Add an access list entry\n"
1016 "IP extended access list\n"
1017 "IP extended access list (expanded range)\n"
1018 "Sequence number of an entry\n"
1019 "Sequence number\n"
1020 "Specify packets to reject\n"
1021 "Specify packets to forward\n"
1022 "Any Internet Protocol\n"
1023 "Source address\n"
1024 "Source wildcard bits\n"
1025 "Destination address\n"
1026 "Destination Wildcard bits\n")
1027 {
1028 int idx_acl = 1;
1029 int idx = 0;
1030 char *seq = NULL;
1031 char *permit_deny = NULL;
1032 char *src = NULL;
1033 char *dst = NULL;
1034 char *src_wildcard = NULL;
1035 char *dst_wildcard = NULL;
1036
1037 argv_find(argv, argc, "(1-4294967295)", &idx);
1038 if (idx)
1039 seq = argv[idx]->arg;
1040
1041 idx = 0;
1042 argv_find(argv, argc, "permit", &idx);
1043 argv_find(argv, argc, "deny", &idx);
1044 if (idx)
1045 permit_deny = argv[idx]->arg;
1046
1047 idx = 0;
1048 argv_find(argv, argc, "A.B.C.D", &idx);
1049 if (idx) {
1050 src = argv[idx]->arg;
1051 src_wildcard = argv[idx + 1]->arg;
1052 dst = argv[idx + 2]->arg;
1053 dst_wildcard = argv[idx + 3]->arg;
1054 }
1055
1056 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1057 src_wildcard, dst, dst_wildcard, 1, 1);
1058 }
1059
1060 DEFUN (access_list_extended_mask_any,
1061 access_list_extended_mask_any_cmd,
1062 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D any",
1063 "Add an access list entry\n"
1064 "IP extended access list\n"
1065 "IP extended access list (expanded range)\n"
1066 "Sequence number of an entry\n"
1067 "Sequence number\n"
1068 "Specify packets to reject\n"
1069 "Specify packets to forward\n"
1070 "Any Internet Protocol\n"
1071 "Source address\n"
1072 "Source wildcard bits\n"
1073 "Any destination host\n")
1074 {
1075 int idx_acl = 1;
1076 int idx = 0;
1077 char *seq = NULL;
1078 char *permit_deny = NULL;
1079 char *src = NULL;
1080 char *src_wildcard = NULL;
1081
1082 argv_find(argv, argc, "(1-4294967295)", &idx);
1083 if (idx)
1084 seq = argv[idx]->arg;
1085
1086 idx = 0;
1087 argv_find(argv, argc, "permit", &idx);
1088 argv_find(argv, argc, "deny", &idx);
1089 if (idx)
1090 permit_deny = argv[idx]->arg;
1091
1092 idx = 0;
1093 argv_find(argv, argc, "A.B.C.D", &idx);
1094 if (idx) {
1095 src = argv[idx]->arg;
1096 src_wildcard = argv[idx + 1]->arg;
1097 }
1098
1099 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1100 src_wildcard, "0.0.0.0", "255.255.255.255", 1,
1101 1);
1102 }
1103
1104 DEFUN (access_list_extended_any_mask,
1105 access_list_extended_any_mask_cmd,
1106 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any A.B.C.D A.B.C.D",
1107 "Add an access list entry\n"
1108 "IP extended access list\n"
1109 "IP extended access list (expanded range)\n"
1110 "Sequence number of an entry\n"
1111 "Sequence number\n"
1112 "Specify packets to reject\n"
1113 "Specify packets to forward\n"
1114 "Any Internet Protocol\n"
1115 "Any source host\n"
1116 "Destination address\n"
1117 "Destination Wildcard bits\n")
1118 {
1119 int idx_acl = 1;
1120 int idx = 0;
1121 char *seq = NULL;
1122 char *permit_deny = NULL;
1123 char *dst = NULL;
1124 char *dst_wildcard = NULL;
1125
1126 argv_find(argv, argc, "(1-4294967295)", &idx);
1127 if (idx)
1128 seq = argv[idx]->arg;
1129
1130 idx = 0;
1131 argv_find(argv, argc, "permit", &idx);
1132 argv_find(argv, argc, "deny", &idx);
1133 if (idx)
1134 permit_deny = argv[idx]->arg;
1135
1136 idx = 0;
1137 argv_find(argv, argc, "A.B.C.D", &idx);
1138 if (idx) {
1139 dst = argv[idx]->arg;
1140 dst_wildcard = argv[idx + 1]->arg;
1141 }
1142
1143 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1144 "0.0.0.0", "255.255.255.255", dst, dst_wildcard,
1145 1, 1);
1146 }
1147
1148 DEFUN (access_list_extended_any_any,
1149 access_list_extended_any_any_cmd,
1150 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any any",
1151 "Add an access list entry\n"
1152 "IP extended access list\n"
1153 "IP extended access list (expanded range)\n"
1154 "Sequence number of an entry\n"
1155 "Sequence number\n"
1156 "Specify packets to reject\n"
1157 "Specify packets to forward\n"
1158 "Any Internet Protocol\n"
1159 "Any source host\n"
1160 "Any destination host\n")
1161 {
1162 int idx_acl = 1;
1163 int idx = 0;
1164 char *seq = NULL;
1165 char *permit_deny = NULL;
1166
1167 argv_find(argv, argc, "(1-4294967295)", &idx);
1168 if (idx)
1169 seq = argv[idx]->arg;
1170
1171 idx = 0;
1172 argv_find(argv, argc, "permit", &idx);
1173 argv_find(argv, argc, "deny", &idx);
1174 if (idx)
1175 permit_deny = argv[idx]->arg;
1176
1177 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1178 "0.0.0.0", "255.255.255.255", "0.0.0.0",
1179 "255.255.255.255", 1, 1);
1180 }
1181
1182 DEFUN (access_list_extended_mask_host,
1183 access_list_extended_mask_host_cmd,
1184 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
1185 "Add an access list entry\n"
1186 "IP extended access list\n"
1187 "IP extended access list (expanded range)\n"
1188 "Sequence number of an entry\n"
1189 "Sequence number\n"
1190 "Specify packets to reject\n"
1191 "Specify packets to forward\n"
1192 "Any Internet Protocol\n"
1193 "Source address\n"
1194 "Source wildcard bits\n"
1195 "A single destination host\n"
1196 "Destination address\n")
1197 {
1198 int idx_acl = 1;
1199 int idx = 0;
1200 char *seq = NULL;
1201 char *permit_deny = NULL;
1202 char *src = NULL;
1203 char *dst = NULL;
1204 char *src_wildcard = NULL;
1205
1206 argv_find(argv, argc, "(1-4294967295)", &idx);
1207 if (idx)
1208 seq = argv[idx]->arg;
1209
1210 idx = 0;
1211 argv_find(argv, argc, "permit", &idx);
1212 argv_find(argv, argc, "deny", &idx);
1213 if (idx)
1214 permit_deny = argv[idx]->arg;
1215
1216 idx = 0;
1217 argv_find(argv, argc, "A.B.C.D", &idx);
1218 if (idx) {
1219 src = argv[idx]->arg;
1220 src_wildcard = argv[idx + 1]->arg;
1221 dst = argv[idx + 3]->arg;
1222 }
1223
1224 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1225 src_wildcard, dst, "0.0.0.0", 1, 1);
1226 }
1227
1228 DEFUN (access_list_extended_host_mask,
1229 access_list_extended_host_mask_cmd,
1230 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
1231 "Add an access list entry\n"
1232 "IP extended access list\n"
1233 "IP extended access list (expanded range)\n"
1234 "Sequence number of an entry\n"
1235 "Sequence number\n"
1236 "Specify packets to reject\n"
1237 "Specify packets to forward\n"
1238 "Any Internet Protocol\n"
1239 "A single source host\n"
1240 "Source address\n"
1241 "Destination address\n"
1242 "Destination Wildcard bits\n")
1243 {
1244 int idx_acl = 1;
1245 int idx = 0;
1246 char *seq = NULL;
1247 char *permit_deny = NULL;
1248 char *src = NULL;
1249 char *dst = NULL;
1250 char *dst_wildcard = NULL;
1251
1252 argv_find(argv, argc, "(1-4294967295)", &idx);
1253 if (idx)
1254 seq = argv[idx]->arg;
1255
1256 idx = 0;
1257 argv_find(argv, argc, "permit", &idx);
1258 argv_find(argv, argc, "deny", &idx);
1259 if (idx)
1260 permit_deny = argv[idx]->arg;
1261
1262 idx = 0;
1263 argv_find(argv, argc, "A.B.C.D", &idx);
1264 if (idx) {
1265 src = argv[idx]->arg;
1266 dst = argv[idx + 1]->arg;
1267 dst_wildcard = argv[idx + 2]->arg;
1268 }
1269
1270 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1271 "0.0.0.0", dst, dst_wildcard, 1, 1);
1272 }
1273
1274 DEFUN (access_list_extended_host_host,
1275 access_list_extended_host_host_cmd,
1276 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D host A.B.C.D",
1277 "Add an access list entry\n"
1278 "IP extended access list\n"
1279 "IP extended access list (expanded range)\n"
1280 "Sequence number of an entry\n"
1281 "Sequence number\n"
1282 "Specify packets to reject\n"
1283 "Specify packets to forward\n"
1284 "Any Internet Protocol\n"
1285 "A single source host\n"
1286 "Source address\n"
1287 "A single destination host\n"
1288 "Destination address\n")
1289 {
1290 int idx_acl = 1;
1291 int idx = 0;
1292 char *seq = NULL;
1293 char *permit_deny = NULL;
1294 char *src = NULL;
1295 char *dst = NULL;
1296
1297 argv_find(argv, argc, "(1-4294967295)", &idx);
1298 if (idx)
1299 seq = argv[idx]->arg;
1300
1301 idx = 0;
1302 argv_find(argv, argc, "permit", &idx);
1303 argv_find(argv, argc, "deny", &idx);
1304 if (idx)
1305 permit_deny = argv[idx]->arg;
1306
1307 idx = 0;
1308 argv_find(argv, argc, "A.B.C.D", &idx);
1309 if (idx) {
1310 src = argv[idx]->arg;
1311 dst = argv[idx + 2]->arg;
1312 }
1313
1314 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1315 "0.0.0.0", dst, "0.0.0.0", 1, 1);
1316 }
1317
1318 DEFUN (access_list_extended_any_host,
1319 access_list_extended_any_host_cmd,
1320 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any host A.B.C.D",
1321 "Add an access list entry\n"
1322 "IP extended access list\n"
1323 "IP extended access list (expanded range)\n"
1324 "Sequence number of an entry\n"
1325 "Sequence number\n"
1326 "Specify packets to reject\n"
1327 "Specify packets to forward\n"
1328 "Any Internet Protocol\n"
1329 "Any source host\n"
1330 "A single destination host\n"
1331 "Destination address\n")
1332 {
1333 int idx_acl = 1;
1334 int idx = 0;
1335 char *seq = NULL;
1336 char *permit_deny = NULL;
1337 char *dst = NULL;
1338
1339 argv_find(argv, argc, "(1-4294967295)", &idx);
1340 if (idx)
1341 seq = argv[idx]->arg;
1342
1343 idx = 0;
1344 argv_find(argv, argc, "permit", &idx);
1345 argv_find(argv, argc, "deny", &idx);
1346 if (idx)
1347 permit_deny = argv[idx]->arg;
1348
1349 idx = 0;
1350 argv_find(argv, argc, "A.B.C.D", &idx);
1351 if (idx)
1352 dst = argv[idx]->arg;
1353
1354 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1355 "0.0.0.0", "255.255.255.255", dst, "0.0.0.0", 1,
1356 1);
1357 }
1358
1359 DEFUN (access_list_extended_host_any,
1360 access_list_extended_host_any_cmd,
1361 "access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D any",
1362 "Add an access list entry\n"
1363 "IP extended access list\n"
1364 "IP extended access list (expanded range)\n"
1365 "Sequence number of an entry\n"
1366 "Sequence number\n"
1367 "Specify packets to reject\n"
1368 "Specify packets to forward\n"
1369 "Any Internet Protocol\n"
1370 "A single source host\n"
1371 "Source address\n"
1372 "Any destination host\n")
1373 {
1374 int idx_acl = 1;
1375 int idx = 0;
1376 char *seq = NULL;
1377 char *permit_deny = NULL;
1378 char *src = NULL;
1379
1380 argv_find(argv, argc, "(1-4294967295)", &idx);
1381 if (idx)
1382 seq = argv[idx]->arg;
1383
1384 idx = 0;
1385 argv_find(argv, argc, "permit", &idx);
1386 argv_find(argv, argc, "deny", &idx);
1387 if (idx)
1388 permit_deny = argv[idx]->arg;
1389
1390 idx = 0;
1391 argv_find(argv, argc, "A.B.C.D", &idx);
1392 if (idx)
1393 src = argv[idx]->arg;
1394
1395 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1396 "0.0.0.0", "0.0.0.0", "255.255.255.255", 1, 1);
1397 }
1398
1399 DEFUN (no_access_list_extended,
1400 no_access_list_extended_cmd,
1401 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
1402 NO_STR
1403 "Add an access list entry\n"
1404 "IP extended access list\n"
1405 "IP extended access list (expanded range)\n"
1406 "Sequence number of an entry\n"
1407 "Sequence number\n"
1408 "Specify packets to reject\n"
1409 "Specify packets to forward\n"
1410 "Any Internet Protocol\n"
1411 "Source address\n"
1412 "Source wildcard bits\n"
1413 "Destination address\n"
1414 "Destination Wildcard bits\n")
1415 {
1416 int idx_acl = 2;
1417 int idx = 0;
1418 char *seq = NULL;
1419 char *permit_deny = NULL;
1420 char *src = NULL;
1421 char *dst = NULL;
1422 char *src_wildcard = NULL;
1423 char *dst_wildcard = NULL;
1424
1425 argv_find(argv, argc, "(1-4294967295)", &idx);
1426 if (idx)
1427 seq = argv[idx]->arg;
1428
1429 idx = 0;
1430 argv_find(argv, argc, "permit", &idx);
1431 argv_find(argv, argc, "deny", &idx);
1432 if (idx)
1433 permit_deny = argv[idx]->arg;
1434
1435 idx = 0;
1436 argv_find(argv, argc, "A.B.C.D", &idx);
1437 if (idx) {
1438 src = argv[idx]->arg;
1439 src_wildcard = argv[idx + 1]->arg;
1440 dst = argv[idx + 2]->arg;
1441 dst_wildcard = argv[idx + 3]->arg;
1442 }
1443
1444 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1445 src_wildcard, dst, dst_wildcard, 1, 0);
1446 }
1447
1448 DEFUN (no_access_list_extended_mask_any,
1449 no_access_list_extended_mask_any_cmd,
1450 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D any",
1451 NO_STR
1452 "Add an access list entry\n"
1453 "IP extended access list\n"
1454 "IP extended access list (expanded range)\n"
1455 "Sequence number of an entry\n"
1456 "Sequence number\n"
1457 "Specify packets to reject\n"
1458 "Specify packets to forward\n"
1459 "Any Internet Protocol\n"
1460 "Source address\n"
1461 "Source wildcard bits\n"
1462 "Any destination host\n")
1463 {
1464 int idx_acl = 2;
1465 int idx = 0;
1466 char *seq = NULL;
1467 char *permit_deny = NULL;
1468 char *src = NULL;
1469 char *src_wildcard = NULL;
1470
1471 argv_find(argv, argc, "(1-4294967295)", &idx);
1472 if (idx)
1473 seq = argv[idx]->arg;
1474
1475 idx = 0;
1476 argv_find(argv, argc, "permit", &idx);
1477 argv_find(argv, argc, "deny", &idx);
1478 if (idx)
1479 permit_deny = argv[idx]->arg;
1480
1481 idx = 0;
1482 argv_find(argv, argc, "A.B.C.D", &idx);
1483 if (idx) {
1484 src = argv[idx]->arg;
1485 src_wildcard = argv[idx + 1]->arg;
1486 }
1487
1488 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1489 src_wildcard, "0.0.0.0", "255.255.255.255", 1,
1490 0);
1491 }
1492
1493 DEFUN (no_access_list_extended_any_mask,
1494 no_access_list_extended_any_mask_cmd,
1495 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any A.B.C.D A.B.C.D",
1496 NO_STR
1497 "Add an access list entry\n"
1498 "IP extended access list\n"
1499 "IP extended access list (expanded range)\n"
1500 "Sequence number of an entry\n"
1501 "Sequence number\n"
1502 "Specify packets to reject\n"
1503 "Specify packets to forward\n"
1504 "Any Internet Protocol\n"
1505 "Any source host\n"
1506 "Destination address\n"
1507 "Destination Wildcard bits\n")
1508 {
1509 int idx_acl = 2;
1510 int idx = 0;
1511 char *seq = NULL;
1512 char *permit_deny = NULL;
1513 char *dst = NULL;
1514 char *dst_wildcard = NULL;
1515
1516 argv_find(argv, argc, "(1-4294967295)", &idx);
1517 if (idx)
1518 seq = argv[idx]->arg;
1519
1520 idx = 0;
1521 argv_find(argv, argc, "permit", &idx);
1522 argv_find(argv, argc, "deny", &idx);
1523 if (idx)
1524 permit_deny = argv[idx]->arg;
1525
1526 idx = 0;
1527 argv_find(argv, argc, "A.B.C.D", &idx);
1528 if (idx) {
1529 dst = argv[idx]->arg;
1530 dst_wildcard = argv[idx + 1]->arg;
1531 }
1532
1533 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1534 "0.0.0.0", "255.255.255.255", dst, dst_wildcard,
1535 1, 0);
1536 }
1537
1538 DEFUN (no_access_list_extended_any_any,
1539 no_access_list_extended_any_any_cmd,
1540 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any any",
1541 NO_STR
1542 "Add an access list entry\n"
1543 "IP extended access list\n"
1544 "IP extended access list (expanded range)\n"
1545 "Sequence number of an entry\n"
1546 "Sequence number\n"
1547 "Specify packets to reject\n"
1548 "Specify packets to forward\n"
1549 "Any Internet Protocol\n"
1550 "Any source host\n"
1551 "Any destination host\n")
1552 {
1553 int idx_acl = 2;
1554 int idx = 0;
1555 char *seq = NULL;
1556 char *permit_deny = NULL;
1557
1558 argv_find(argv, argc, "(1-4294967295)", &idx);
1559 if (idx)
1560 seq = argv[idx]->arg;
1561
1562 idx = 0;
1563 argv_find(argv, argc, "permit", &idx);
1564 argv_find(argv, argc, "deny", &idx);
1565 if (idx)
1566 permit_deny = argv[idx]->arg;
1567
1568 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1569 "0.0.0.0", "255.255.255.255", "0.0.0.0",
1570 "255.255.255.255", 1, 0);
1571 }
1572
1573 DEFUN (no_access_list_extended_mask_host,
1574 no_access_list_extended_mask_host_cmd,
1575 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip A.B.C.D A.B.C.D host A.B.C.D",
1576 NO_STR
1577 "Add an access list entry\n"
1578 "IP extended access list\n"
1579 "IP extended access list (expanded range)\n"
1580 "Sequence number of an entry\n"
1581 "Sequence number\n"
1582 "Specify packets to reject\n"
1583 "Specify packets to forward\n"
1584 "Any Internet Protocol\n"
1585 "Source address\n"
1586 "Source wildcard bits\n"
1587 "A single destination host\n"
1588 "Destination address\n")
1589 {
1590 int idx_acl = 2;
1591 int idx = 0;
1592 char *seq = NULL;
1593 char *permit_deny = NULL;
1594 char *src = NULL;
1595 char *dst = NULL;
1596 char *src_wildcard = NULL;
1597
1598 argv_find(argv, argc, "(1-4294967295)", &idx);
1599 if (idx)
1600 seq = argv[idx]->arg;
1601
1602 idx = 0;
1603 argv_find(argv, argc, "permit", &idx);
1604 argv_find(argv, argc, "deny", &idx);
1605 if (idx)
1606 permit_deny = argv[idx]->arg;
1607
1608 idx = 0;
1609 argv_find(argv, argc, "A.B.C.D", &idx);
1610 if (idx) {
1611 src = argv[idx]->arg;
1612 src_wildcard = argv[idx + 1]->arg;
1613 dst = argv[idx + 3]->arg;
1614 }
1615
1616 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1617 src_wildcard, dst, "0.0.0.0", 1, 0);
1618 }
1619
1620 DEFUN (no_access_list_extended_host_mask,
1621 no_access_list_extended_host_mask_cmd,
1622 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D A.B.C.D A.B.C.D",
1623 NO_STR
1624 "Add an access list entry\n"
1625 "IP extended access list\n"
1626 "IP extended access list (expanded range)\n"
1627 "Sequence number of an entry\n"
1628 "Sequence number\n"
1629 "Specify packets to reject\n"
1630 "Specify packets to forward\n"
1631 "Any Internet Protocol\n"
1632 "A single source host\n"
1633 "Source address\n"
1634 "Destination address\n"
1635 "Destination Wildcard bits\n")
1636 {
1637 int idx_acl = 2;
1638 int idx = 0;
1639 char *seq = NULL;
1640 char *permit_deny = NULL;
1641 char *src = NULL;
1642 char *dst = NULL;
1643 char *dst_wildcard = NULL;
1644
1645 argv_find(argv, argc, "(1-4294967295)", &idx);
1646 if (idx)
1647 seq = argv[idx]->arg;
1648
1649 idx = 0;
1650 argv_find(argv, argc, "permit", &idx);
1651 argv_find(argv, argc, "deny", &idx);
1652 if (idx)
1653 permit_deny = argv[idx]->arg;
1654
1655 idx = 0;
1656 argv_find(argv, argc, "A.B.C.D", &idx);
1657 if (idx) {
1658 src = argv[idx]->arg;
1659 dst = argv[idx + 1]->arg;
1660 dst_wildcard = argv[idx + 2]->arg;
1661 }
1662
1663 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1664 "0.0.0.0", dst, dst_wildcard, 1, 0);
1665 }
1666
1667 DEFUN (no_access_list_extended_host_host,
1668 no_access_list_extended_host_host_cmd,
1669 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D host A.B.C.D",
1670 NO_STR
1671 "Add an access list entry\n"
1672 "IP extended access list\n"
1673 "IP extended access list (expanded range)\n"
1674 "Sequence number of an entry\n"
1675 "Sequence number\n"
1676 "Specify packets to reject\n"
1677 "Specify packets to forward\n"
1678 "Any Internet Protocol\n"
1679 "A single source host\n"
1680 "Source address\n"
1681 "A single destination host\n"
1682 "Destination address\n")
1683 {
1684 int idx_acl = 2;
1685 int idx = 0;
1686 char *seq = NULL;
1687 char *permit_deny = NULL;
1688 char *src = NULL;
1689 char *dst = NULL;
1690
1691 argv_find(argv, argc, "(1-4294967295)", &idx);
1692 if (idx)
1693 seq = argv[idx]->arg;
1694
1695 idx = 0;
1696 argv_find(argv, argc, "permit", &idx);
1697 argv_find(argv, argc, "deny", &idx);
1698 if (idx)
1699 permit_deny = argv[idx]->arg;
1700
1701 idx = 0;
1702 argv_find(argv, argc, "A.B.C.D", &idx);
1703 if (idx) {
1704 src = argv[idx]->arg;
1705 dst = argv[idx + 2]->arg;
1706 }
1707
1708 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1709 "0.0.0.0", dst, "0.0.0.0", 1, 0);
1710 }
1711
1712 DEFUN (no_access_list_extended_any_host,
1713 no_access_list_extended_any_host_cmd,
1714 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip any host A.B.C.D",
1715 NO_STR
1716 "Add an access list entry\n"
1717 "IP extended access list\n"
1718 "IP extended access list (expanded range)\n"
1719 "Sequence number of an entry\n"
1720 "Sequence number\n"
1721 "Specify packets to reject\n"
1722 "Specify packets to forward\n"
1723 "Any Internet Protocol\n"
1724 "Any source host\n"
1725 "A single destination host\n"
1726 "Destination address\n")
1727 {
1728 int idx_acl = 2;
1729 int idx = 0;
1730 char *seq = NULL;
1731 char *permit_deny = NULL;
1732 char *dst = NULL;
1733
1734 argv_find(argv, argc, "(1-4294967295)", &idx);
1735 if (idx)
1736 seq = argv[idx]->arg;
1737
1738 idx = 0;
1739 argv_find(argv, argc, "permit", &idx);
1740 argv_find(argv, argc, "deny", &idx);
1741 if (idx)
1742 permit_deny = argv[idx]->arg;
1743
1744 idx = 0;
1745 argv_find(argv, argc, "A.B.C.D", &idx);
1746 if (idx)
1747 dst = argv[idx]->arg;
1748
1749 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny,
1750 "0.0.0.0", "255.255.255.255", dst, "0.0.0.0", 1,
1751 0);
1752 }
1753
1754 DEFUN (no_access_list_extended_host_any,
1755 no_access_list_extended_host_any_cmd,
1756 "no access-list <(100-199)|(2000-2699)> [seq (1-4294967295)] <deny|permit> ip host A.B.C.D any",
1757 NO_STR
1758 "Add an access list entry\n"
1759 "IP extended access list\n"
1760 "IP extended access list (expanded range)\n"
1761 "Sequence number of an entry\n"
1762 "Sequence number\n"
1763 "Specify packets to reject\n"
1764 "Specify packets to forward\n"
1765 "Any Internet Protocol\n"
1766 "A single source host\n"
1767 "Source address\n"
1768 "Any destination host\n")
1769 {
1770 int idx_acl = 2;
1771 int idx = 0;
1772 char *seq = NULL;
1773 char *permit_deny = NULL;
1774 char *src = NULL;
1775
1776 argv_find(argv, argc, "(1-4294967295)", &idx);
1777 if (idx)
1778 seq = argv[idx]->arg;
1779
1780 idx = 0;
1781 argv_find(argv, argc, "permit", &idx);
1782 argv_find(argv, argc, "deny", &idx);
1783 if (idx)
1784 permit_deny = argv[idx]->arg;
1785
1786 idx = 0;
1787 argv_find(argv, argc, "A.B.C.D", &idx);
1788 if (idx)
1789 src = argv[idx]->arg;
1790
1791 return filter_set_cisco(vty, argv[idx_acl]->arg, seq, permit_deny, src,
1792 "0.0.0.0", "0.0.0.0", "255.255.255.255", 1, 0);
1793 }
1794
1795 static int filter_set_zebra(struct vty *vty, const char *name_str,
1796 const char *seq, const char *type_str, afi_t afi,
1797 const char *prefix_str, int exact, int set)
1798 {
1799 int ret;
1800 enum filter_type type = FILTER_DENY;
1801 struct filter *mfilter;
1802 struct filter_zebra *filter;
1803 struct access_list *access;
1804 struct prefix p;
1805 int64_t seqnum = -1;
1806
1807 if (strlen(name_str) > ACL_NAMSIZ) {
1808 vty_out(vty,
1809 "%% ACL name %s is invalid: length exceeds "
1810 "%d characters\n",
1811 name_str, ACL_NAMSIZ);
1812 return CMD_WARNING_CONFIG_FAILED;
1813 }
1814
1815 if (seq)
1816 seqnum = (int64_t)atol(seq);
1817
1818 /* Check of filter type. */
1819 if (type_str) {
1820 if (strncmp(type_str, "p", 1) == 0)
1821 type = FILTER_PERMIT;
1822 else if (strncmp(type_str, "d", 1) == 0)
1823 type = FILTER_DENY;
1824 else {
1825 vty_out(vty, "filter type must be [permit|deny]\n");
1826 return CMD_WARNING_CONFIG_FAILED;
1827 }
1828 }
1829
1830 /* Check string format of prefix and prefixlen. */
1831 if (afi == AFI_IP) {
1832 ret = str2prefix_ipv4(prefix_str, (struct prefix_ipv4 *)&p);
1833 if (ret <= 0) {
1834 vty_out(vty,
1835 "IP address prefix/prefixlen is malformed\n");
1836 return CMD_WARNING_CONFIG_FAILED;
1837 }
1838 } else if (afi == AFI_IP6) {
1839 ret = str2prefix_ipv6(prefix_str, (struct prefix_ipv6 *)&p);
1840 if (ret <= 0) {
1841 vty_out(vty,
1842 "IPv6 address prefix/prefixlen is malformed\n");
1843 return CMD_WARNING_CONFIG_FAILED;
1844 }
1845 } else if (afi == AFI_L2VPN) {
1846 ret = str2prefix_eth(prefix_str, (struct prefix_eth *)&p);
1847 if (ret <= 0) {
1848 vty_out(vty, "MAC address is malformed\n");
1849 return CMD_WARNING;
1850 }
1851 } else
1852 return CMD_WARNING_CONFIG_FAILED;
1853
1854 mfilter = filter_new();
1855 mfilter->type = type;
1856 mfilter->seq = seqnum;
1857 filter = &mfilter->u.zfilter;
1858 prefix_copy(&filter->prefix, &p);
1859
1860 /* "exact-match" */
1861 if (exact)
1862 filter->exact = 1;
1863
1864 /* Install new filter to the access_list. */
1865 access = access_list_get(afi, name_str);
1866
1867 if (set) {
1868 if (filter_lookup_zebra(access, mfilter))
1869 filter_free(mfilter);
1870 else
1871 access_list_filter_add(access, mfilter);
1872 } else {
1873 struct filter *delete_filter;
1874 delete_filter = filter_lookup_zebra(access, mfilter);
1875 if (delete_filter)
1876 access_list_filter_delete(access, delete_filter);
1877
1878 filter_free(mfilter);
1879 }
1880
1881 return CMD_SUCCESS;
1882 }
1883
1884 DEFUN (mac_access_list,
1885 mac_access_list_cmd,
1886 "mac access-list WORD [seq (1-4294967295)] <deny|permit> X:X:X:X:X:X",
1887 "Add a mac access-list\n"
1888 "Add an access list entry\n"
1889 "MAC zebra access-list name\n"
1890 "Sequence number of an entry\n"
1891 "Sequence number\n"
1892 "Specify packets to reject\n"
1893 "Specify packets to forward\n"
1894 "MAC address to match. e.g. 00:01:00:01:00:01\n")
1895 {
1896 int idx = 0;
1897 char *seq = NULL;
1898 char *permit_deny = NULL;
1899 char *mac = NULL;
1900
1901 argv_find(argv, argc, "(1-4294967295)", &idx);
1902 if (idx)
1903 seq = argv[idx]->arg;
1904
1905 idx = 0;
1906 argv_find(argv, argc, "permit", &idx);
1907 argv_find(argv, argc, "deny", &idx);
1908 if (idx)
1909 permit_deny = argv[idx]->arg;
1910
1911 idx = 0;
1912 argv_find(argv, argc, "X:X:X:X:X:X", &idx);
1913 if (idx)
1914 mac = argv[idx]->arg;
1915 assert(mac);
1916
1917 return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
1918 mac, 0, 1);
1919 }
1920
1921 DEFUN (no_mac_access_list,
1922 no_mac_access_list_cmd,
1923 "no mac access-list WORD [seq (1-4294967295)] <deny|permit> X:X:X:X:X:X",
1924 NO_STR
1925 "Remove a mac access-list\n"
1926 "Remove an access list entry\n"
1927 "MAC zebra access-list name\n"
1928 "Sequence number of an entry\n"
1929 "Sequence number\n"
1930 "Specify packets to reject\n"
1931 "Specify packets to forward\n"
1932 "MAC address to match. e.g. 00:01:00:01:00:01\n")
1933 {
1934 int idx = 0;
1935 char *seq = NULL;
1936 char *permit_deny = NULL;
1937 char *mac = NULL;
1938
1939 argv_find(argv, argc, "(1-4294967295)", &idx);
1940 if (idx)
1941 seq = argv[idx]->arg;
1942
1943 idx = 0;
1944 argv_find(argv, argc, "permit", &idx);
1945 argv_find(argv, argc, "deny", &idx);
1946 if (idx)
1947 permit_deny = argv[idx]->arg;
1948
1949 idx = 0;
1950 argv_find(argv, argc, "X:X:X:X:X:X", &idx);
1951 if (idx)
1952 mac = argv[idx]->arg;
1953 assert(mac);
1954
1955 return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
1956 mac, 0, 0);
1957 }
1958
1959 DEFUN (mac_access_list_any,
1960 mac_access_list_any_cmd,
1961 "mac access-list WORD [seq (1-4294967295)] <deny|permit> any",
1962 "Add a mac access-list\n"
1963 "Add an access list entry\n"
1964 "MAC zebra access-list name\n"
1965 "Sequence number of an entry\n"
1966 "Sequence number\n"
1967 "Specify packets to reject\n"
1968 "Specify packets to forward\n"
1969 "MAC address to match. e.g. 00:01:00:01:00:01\n")
1970 {
1971 int idx = 0;
1972 char *seq = NULL;
1973 char *permit_deny = NULL;
1974
1975 argv_find(argv, argc, "(1-4294967295)", &idx);
1976 if (idx)
1977 seq = argv[idx]->arg;
1978
1979 idx = 0;
1980 argv_find(argv, argc, "permit", &idx);
1981 argv_find(argv, argc, "deny", &idx);
1982 if (idx)
1983 permit_deny = argv[idx]->arg;
1984
1985 return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
1986 "00:00:00:00:00:00", 0, 1);
1987 }
1988
1989 DEFUN (no_mac_access_list_any,
1990 no_mac_access_list_any_cmd,
1991 "no mac access-list WORD [seq (1-4294967295)] <deny|permit> any",
1992 NO_STR
1993 "Remove a mac access-list\n"
1994 "Remove an access list entry\n"
1995 "MAC zebra access-list name\n"
1996 "Sequence number of an entry\n"
1997 "Sequence number\n"
1998 "Specify packets to reject\n"
1999 "Specify packets to forward\n"
2000 "MAC address to match. e.g. 00:01:00:01:00:01\n")
2001 {
2002 int idx = 0;
2003 char *seq = NULL;
2004 char *permit_deny = NULL;
2005
2006 argv_find(argv, argc, "(1-4294967295)", &idx);
2007 if (idx)
2008 seq = argv[idx]->arg;
2009
2010 idx = 0;
2011 argv_find(argv, argc, "permit", &idx);
2012 argv_find(argv, argc, "deny", &idx);
2013 if (idx)
2014 permit_deny = argv[idx]->arg;
2015
2016 return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny, AFI_L2VPN,
2017 "00:00:00:00:00:00", 0, 0);
2018 }
2019
2020 DEFUN (access_list_exact,
2021 access_list_exact_cmd,
2022 "access-list WORD [seq (1-4294967295)] <deny|permit> A.B.C.D/M [exact-match]",
2023 "Add an access list entry\n"
2024 "IP zebra access-list name\n"
2025 "Sequence number of an entry\n"
2026 "Sequence number\n"
2027 "Specify packets to reject\n"
2028 "Specify packets to forward\n"
2029 "Prefix to match. e.g. 10.0.0.0/8\n"
2030 "Exact match of the prefixes\n")
2031 {
2032 int idx = 0;
2033 int exact = 0;
2034 char *seq = NULL;
2035 char *permit_deny = NULL;
2036 char *prefix = NULL;
2037
2038 argv_find(argv, argc, "(1-4294967295)", &idx);
2039 if (idx)
2040 seq = argv[idx]->arg;
2041
2042 idx = 0;
2043 argv_find(argv, argc, "permit", &idx);
2044 argv_find(argv, argc, "deny", &idx);
2045 if (idx)
2046 permit_deny = argv[idx]->arg;
2047
2048 idx = 0;
2049 argv_find(argv, argc, "A.B.C.D/M", &idx);
2050 if (idx)
2051 prefix = argv[idx]->arg;
2052 assert(prefix);
2053
2054 idx = 0;
2055 if (argv_find(argv, argc, "exact-match", &idx))
2056 exact = 1;
2057
2058 return filter_set_zebra(vty, argv[1]->arg, seq, permit_deny,
2059 AFI_IP, prefix, exact, 1);
2060 }
2061
2062 DEFUN (access_list_any,
2063 access_list_any_cmd,
2064 "access-list WORD [seq (1-4294967295)] <deny|permit> any",
2065 "Add an access list entry\n"
2066 "IP zebra access-list name\n"
2067 "Sequence number of an entry\n"
2068 "Sequence number\n"
2069 "Specify packets to reject\n"
2070 "Specify packets to forward\n"
2071 "Prefix to match. e.g. 10.0.0.0/8\n")
2072 {
2073 int idx_word = 1;
2074 int idx = 0;
2075 char *seq = NULL;
2076 char *permit_deny = NULL;
2077
2078 argv_find(argv, argc, "(1-4294967295)", &idx);
2079 if (idx)
2080 seq = argv[idx]->arg;
2081
2082 idx = 0;
2083 argv_find(argv, argc, "permit", &idx);
2084 argv_find(argv, argc, "deny", &idx);
2085 if (idx)
2086 permit_deny = argv[idx]->arg;
2087
2088 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2089 AFI_IP, "0.0.0.0/0", 0, 1);
2090 }
2091
2092 DEFUN (no_access_list_exact,
2093 no_access_list_exact_cmd,
2094 "no access-list WORD [seq (1-4294967295)] <deny|permit> A.B.C.D/M [exact-match]",
2095 NO_STR
2096 "Add an access list entry\n"
2097 "IP zebra access-list name\n"
2098 "Sequence number of an entry\n"
2099 "Sequence number\n"
2100 "Specify packets to reject\n"
2101 "Specify packets to forward\n"
2102 "Prefix to match. e.g. 10.0.0.0/8\n"
2103 "Exact match of the prefixes\n")
2104 {
2105 int idx = 0;
2106 int exact = 0;
2107 char *seq = NULL;
2108 char *permit_deny = NULL;
2109 char *prefix = NULL;
2110
2111 argv_find(argv, argc, "(1-4294967295)", &idx);
2112 if (idx)
2113 seq = argv[idx]->arg;
2114
2115 idx = 0;
2116 argv_find(argv, argc, "permit", &idx);
2117 argv_find(argv, argc, "deny", &idx);
2118 if (idx)
2119 permit_deny = argv[idx]->arg;
2120
2121 idx = 0;
2122 argv_find(argv, argc, "A.B.C.D/M", &idx);
2123 if (idx)
2124 prefix = argv[idx]->arg;
2125 assert(prefix);
2126
2127 idx = 0;
2128 if (argv_find(argv, argc, "exact-match", &idx))
2129 exact = 1;
2130
2131 return filter_set_zebra(vty, argv[2]->arg, seq, permit_deny,
2132 AFI_IP, prefix, exact, 0);
2133 }
2134
2135 DEFUN (no_access_list_any,
2136 no_access_list_any_cmd,
2137 "no access-list WORD [seq (1-4294967295)] <deny|permit> any",
2138 NO_STR
2139 "Add an access list entry\n"
2140 "IP zebra access-list name\n"
2141 "Sequence number of an entry\n"
2142 "Sequence number\n"
2143 "Specify packets to reject\n"
2144 "Specify packets to forward\n"
2145 "Prefix to match. e.g. 10.0.0.0/8\n")
2146 {
2147 int idx_word = 2;
2148 int idx = 0;
2149 char *seq = NULL;
2150 char *permit_deny = NULL;
2151
2152 argv_find(argv, argc, "(1-4294967295)", &idx);
2153 if (idx)
2154 seq = argv[idx]->arg;
2155
2156 idx = 0;
2157 argv_find(argv, argc, "permit", &idx);
2158 argv_find(argv, argc, "deny", &idx);
2159 if (idx)
2160 permit_deny = argv[idx]->arg;
2161
2162 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2163 AFI_IP, "0.0.0.0/0", 0, 0);
2164 }
2165
2166 DEFUN (no_access_list_all,
2167 no_access_list_all_cmd,
2168 "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
2169 NO_STR
2170 "Add an access list entry\n"
2171 "IP standard access list\n"
2172 "IP extended access list\n"
2173 "IP standard access list (expanded range)\n"
2174 "IP extended access list (expanded range)\n"
2175 "IP zebra access-list name\n")
2176 {
2177 int idx_acl = 2;
2178 struct access_list *access;
2179 struct access_master *master;
2180
2181 /* Looking up access_list. */
2182 access = access_list_lookup(AFI_IP, argv[idx_acl]->arg);
2183 if (access == NULL) {
2184 vty_out(vty, "%% access-list %s doesn't exist\n",
2185 argv[idx_acl]->arg);
2186 return CMD_WARNING_CONFIG_FAILED;
2187 }
2188
2189 master = access->master;
2190
2191 route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
2192 /* Run hook function. */
2193 if (master->delete_hook)
2194 (*master->delete_hook)(access);
2195
2196 /* Delete all filter from access-list. */
2197 access_list_delete(access);
2198
2199 return CMD_SUCCESS;
2200 }
2201
2202 DEFUN (access_list_remark,
2203 access_list_remark_cmd,
2204 "access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
2205 "Add an access list entry\n"
2206 "IP standard access list\n"
2207 "IP extended access list\n"
2208 "IP standard access list (expanded range)\n"
2209 "IP extended access list (expanded range)\n"
2210 "IP zebra access-list\n"
2211 "Access list entry comment\n"
2212 "Comment up to 100 characters\n")
2213 {
2214 int idx_acl = 1;
2215 int idx_remark = 3;
2216 struct access_list *access;
2217
2218 access = access_list_get(AFI_IP, argv[idx_acl]->arg);
2219
2220 if (access->remark) {
2221 XFREE(MTYPE_TMP, access->remark);
2222 access->remark = NULL;
2223 }
2224 access->remark = argv_concat(argv, argc, idx_remark);
2225
2226 return CMD_SUCCESS;
2227 }
2228
2229 DEFUN (no_access_list_remark,
2230 no_access_list_remark_cmd,
2231 "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark",
2232 NO_STR
2233 "Add an access list entry\n"
2234 "IP standard access list\n"
2235 "IP extended access list\n"
2236 "IP standard access list (expanded range)\n"
2237 "IP extended access list (expanded range)\n"
2238 "IP zebra access-list\n"
2239 "Access list entry comment\n")
2240 {
2241 int idx_acl = 2;
2242 return vty_access_list_remark_unset(vty, AFI_IP, argv[idx_acl]->arg);
2243 }
2244
2245 /* ALIAS_FIXME */
2246 DEFUN (no_access_list_remark_comment,
2247 no_access_list_remark_comment_cmd,
2248 "no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD> remark LINE...",
2249 NO_STR
2250 "Add an access list entry\n"
2251 "IP standard access list\n"
2252 "IP extended access list\n"
2253 "IP standard access list (expanded range)\n"
2254 "IP extended access list (expanded range)\n"
2255 "IP zebra access-list\n"
2256 "Access list entry comment\n"
2257 "Comment up to 100 characters\n")
2258 {
2259 return no_access_list_remark(self, vty, argc, argv);
2260 }
2261
2262 DEFUN (ipv6_access_list_exact,
2263 ipv6_access_list_exact_cmd,
2264 "ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> X:X::X:X/M [exact-match]",
2265 IPV6_STR
2266 "Add an access list entry\n"
2267 "IPv6 zebra access-list\n"
2268 "Sequence number of an entry\n"
2269 "Sequence number\n"
2270 "Specify packets to reject\n"
2271 "Specify packets to forward\n"
2272 "IPv6 prefix\n"
2273 "Exact match of the prefixes\n")
2274 {
2275 int idx = 0;
2276 int exact = 0;
2277 int idx_word = 2;
2278 char *seq = NULL;
2279 char *permit_deny = NULL;
2280 char *prefix = NULL;
2281
2282 argv_find(argv, argc, "(1-4294967295)", &idx);
2283 if (idx)
2284 seq = argv[idx]->arg;
2285
2286 idx = 0;
2287 argv_find(argv, argc, "permit", &idx);
2288 argv_find(argv, argc, "deny", &idx);
2289 if (idx)
2290 permit_deny = argv[idx]->arg;
2291
2292 idx = 0;
2293 argv_find(argv, argc, "X:X::X:X/M", &idx);
2294 if (idx)
2295 prefix = argv[idx]->arg;
2296
2297 idx = 0;
2298 if (argv_find(argv, argc, "exact-match", &idx))
2299 exact = 1;
2300
2301 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2302 AFI_IP6, prefix, exact, 1);
2303 }
2304
2305 DEFUN (ipv6_access_list_any,
2306 ipv6_access_list_any_cmd,
2307 "ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> any",
2308 IPV6_STR
2309 "Add an access list entry\n"
2310 "IPv6 zebra access-list\n"
2311 "Sequence number of an entry\n"
2312 "Sequence number\n"
2313 "Specify packets to reject\n"
2314 "Specify packets to forward\n"
2315 "Any prefixi to match\n")
2316 {
2317 int idx_word = 2;
2318 int idx = 0;
2319 char *seq = NULL;
2320 char *permit_deny = NULL;
2321
2322 argv_find(argv, argc, "(1-4294967295)", &idx);
2323 if (idx)
2324 seq = argv[idx]->arg;
2325
2326 idx = 0;
2327 argv_find(argv, argc, "permit", &idx);
2328 argv_find(argv, argc, "deny", &idx);
2329 if (idx)
2330 permit_deny = argv[idx]->arg;
2331
2332 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2333 AFI_IP6, "::/0", 0, 1);
2334 }
2335
2336 DEFUN (no_ipv6_access_list_exact,
2337 no_ipv6_access_list_exact_cmd,
2338 "no ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> X:X::X:X/M [exact-match]",
2339 NO_STR
2340 IPV6_STR
2341 "Add an access list entry\n"
2342 "IPv6 zebra access-list\n"
2343 "Sequence number of an entry\n"
2344 "Sequence number\n"
2345 "Specify packets to reject\n"
2346 "Specify packets to forward\n"
2347 "Prefix to match. e.g. 3ffe:506::/32\n"
2348 "Exact match of the prefixes\n")
2349 {
2350 int idx = 0;
2351 int exact = 0;
2352 int idx_word = 3;
2353 char *seq = NULL;
2354 char *permit_deny = NULL;
2355 char *prefix = NULL;
2356
2357 argv_find(argv, argc, "(1-4294967295)", &idx);
2358 if (idx)
2359 seq = argv[idx]->arg;
2360
2361 idx = 0;
2362 argv_find(argv, argc, "permit", &idx);
2363 argv_find(argv, argc, "deny", &idx);
2364 if (idx)
2365 permit_deny = argv[idx]->arg;
2366
2367 idx = 0;
2368 argv_find(argv, argc, "X:X::X:X/M", &idx);
2369 if (idx)
2370 prefix = argv[idx]->arg;
2371 assert(prefix);
2372
2373 idx = 0;
2374 if (argv_find(argv, argc, "exact-match", &idx))
2375 exact = 1;
2376
2377 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2378 AFI_IP6, prefix, exact, 0);
2379 }
2380
2381 DEFUN (no_ipv6_access_list_any,
2382 no_ipv6_access_list_any_cmd,
2383 "no ipv6 access-list WORD [seq (1-4294967295)] <deny|permit> any",
2384 NO_STR
2385 IPV6_STR
2386 "Add an access list entry\n"
2387 "IPv6 zebra access-list\n"
2388 "Sequence number of an entry\n"
2389 "Sequence number\n"
2390 "Specify packets to reject\n"
2391 "Specify packets to forward\n"
2392 "Any prefixi to match\n")
2393 {
2394 int idx_word = 3;
2395 int idx = 0;
2396 char *seq = NULL;
2397 char *permit_deny = NULL;
2398
2399 argv_find(argv, argc, "(1-4294967295)", &idx);
2400 if (idx)
2401 seq = argv[idx]->arg;
2402
2403 idx = 0;
2404 argv_find(argv, argc, "permit", &idx);
2405 argv_find(argv, argc, "deny", &idx);
2406 if (idx)
2407 permit_deny = argv[idx]->arg;
2408
2409 return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny,
2410 AFI_IP6, "::/0", 0, 0);
2411 }
2412
2413
2414 DEFUN (no_ipv6_access_list_all,
2415 no_ipv6_access_list_all_cmd,
2416 "no ipv6 access-list WORD",
2417 NO_STR
2418 IPV6_STR
2419 "Add an access list entry\n"
2420 "IPv6 zebra access-list\n")
2421 {
2422 int idx_word = 3;
2423 struct access_list *access;
2424 struct access_master *master;
2425
2426 /* Looking up access_list. */
2427 access = access_list_lookup(AFI_IP6, argv[idx_word]->arg);
2428 if (access == NULL) {
2429 vty_out(vty, "%% access-list %s doesn't exist\n",
2430 argv[idx_word]->arg);
2431 return CMD_WARNING_CONFIG_FAILED;
2432 }
2433
2434 master = access->master;
2435
2436 route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
2437 /* Run hook function. */
2438 if (master->delete_hook)
2439 (*master->delete_hook)(access);
2440
2441 /* Delete all filter from access-list. */
2442 access_list_delete(access);
2443
2444 return CMD_SUCCESS;
2445 }
2446
2447 DEFUN (ipv6_access_list_remark,
2448 ipv6_access_list_remark_cmd,
2449 "ipv6 access-list WORD remark LINE...",
2450 IPV6_STR
2451 "Add an access list entry\n"
2452 "IPv6 zebra access-list\n"
2453 "Access list entry comment\n"
2454 "Comment up to 100 characters\n")
2455 {
2456 int idx_word = 2;
2457 int idx_line = 4;
2458 struct access_list *access;
2459
2460 access = access_list_get(AFI_IP6, argv[idx_word]->arg);
2461
2462 if (access->remark) {
2463 XFREE(MTYPE_TMP, access->remark);
2464 access->remark = NULL;
2465 }
2466 access->remark = argv_concat(argv, argc, idx_line);
2467
2468 return CMD_SUCCESS;
2469 }
2470
2471 DEFUN (no_ipv6_access_list_remark,
2472 no_ipv6_access_list_remark_cmd,
2473 "no ipv6 access-list WORD remark",
2474 NO_STR
2475 IPV6_STR
2476 "Add an access list entry\n"
2477 "IPv6 zebra access-list\n"
2478 "Access list entry comment\n")
2479 {
2480 int idx_word = 3;
2481 return vty_access_list_remark_unset(vty, AFI_IP6, argv[idx_word]->arg);
2482 }
2483
2484 /* ALIAS_FIXME */
2485 DEFUN (no_ipv6_access_list_remark_comment,
2486 no_ipv6_access_list_remark_comment_cmd,
2487 "no ipv6 access-list WORD remark LINE...",
2488 NO_STR
2489 IPV6_STR
2490 "Add an access list entry\n"
2491 "IPv6 zebra access-list\n"
2492 "Access list entry comment\n"
2493 "Comment up to 100 characters\n")
2494 {
2495 return no_ipv6_access_list_remark(self, vty, argc, argv);
2496 }
2497
2498 static void config_write_access_zebra(struct vty *, struct filter *);
2499 static void config_write_access_cisco(struct vty *, struct filter *);
2500
2501 /* show access-list command. */
2502 static int filter_show(struct vty *vty, const char *name, afi_t afi)
2503 {
2504 struct access_list *access;
2505 struct access_master *master;
2506 struct filter *mfilter;
2507 struct filter_cisco *filter;
2508 int write = 0;
2509
2510 master = access_master_get(afi);
2511 if (master == NULL)
2512 return 0;
2513
2514 /* Print the name of the protocol */
2515 vty_out(vty, "%s:\n", frr_protoname);
2516
2517 for (access = master->num.head; access; access = access->next) {
2518 if (name && strcmp(access->name, name) != 0)
2519 continue;
2520
2521 write = 1;
2522
2523 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
2524 filter = &mfilter->u.cfilter;
2525
2526 if (write) {
2527 vty_out(vty, "%s %s access list %s\n",
2528 mfilter->cisco ? (filter->extended
2529 ? "Extended"
2530 : "Standard")
2531 : "Zebra",
2532 (afi == AFI_IP)
2533 ? ("IP")
2534 : ((afi == AFI_IP6) ? ("IPv6 ")
2535 : ("MAC ")),
2536 access->name);
2537 write = 0;
2538 }
2539
2540 vty_out(vty, " seq %" PRId64, mfilter->seq);
2541 vty_out(vty, " %s%s", filter_type_str(mfilter),
2542 mfilter->type == FILTER_DENY ? " " : "");
2543
2544 if (!mfilter->cisco)
2545 config_write_access_zebra(vty, mfilter);
2546 else if (filter->extended)
2547 config_write_access_cisco(vty, mfilter);
2548 else {
2549 if (filter->addr_mask.s_addr == 0xffffffff)
2550 vty_out(vty, " any\n");
2551 else {
2552 vty_out(vty, " %s",
2553 inet_ntoa(filter->addr));
2554 if (filter->addr_mask.s_addr
2555 != INADDR_ANY)
2556 vty_out(vty,
2557 ", wildcard bits %s",
2558 inet_ntoa(
2559 filter->addr_mask));
2560 vty_out(vty, "\n");
2561 }
2562 }
2563 }
2564 }
2565
2566 for (access = master->str.head; access; access = access->next) {
2567 if (name && strcmp(access->name, name) != 0)
2568 continue;
2569
2570 write = 1;
2571
2572 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
2573 filter = &mfilter->u.cfilter;
2574
2575 if (write) {
2576 vty_out(vty, "%s %s access list %s\n",
2577 mfilter->cisco ? (filter->extended
2578 ? "Extended"
2579 : "Standard")
2580 : "Zebra",
2581 (afi == AFI_IP)
2582 ? ("IP")
2583 : ((afi == AFI_IP6) ? ("IPv6 ")
2584 : ("MAC ")),
2585 access->name);
2586 write = 0;
2587 }
2588
2589 vty_out(vty, " seq %" PRId64, mfilter->seq);
2590 vty_out(vty, " %s%s", filter_type_str(mfilter),
2591 mfilter->type == FILTER_DENY ? " " : "");
2592
2593 if (!mfilter->cisco)
2594 config_write_access_zebra(vty, mfilter);
2595 else if (filter->extended)
2596 config_write_access_cisco(vty, mfilter);
2597 else {
2598 if (filter->addr_mask.s_addr == 0xffffffff)
2599 vty_out(vty, " any\n");
2600 else {
2601 vty_out(vty, " %s",
2602 inet_ntoa(filter->addr));
2603 if (filter->addr_mask.s_addr
2604 != INADDR_ANY)
2605 vty_out(vty,
2606 ", wildcard bits %s",
2607 inet_ntoa(
2608 filter->addr_mask));
2609 vty_out(vty, "\n");
2610 }
2611 }
2612 }
2613 }
2614 return CMD_SUCCESS;
2615 }
2616
2617 /* show MAC access list - this only has MAC filters for now*/
2618 DEFUN (show_mac_access_list,
2619 show_mac_access_list_cmd,
2620 "show mac access-list",
2621 SHOW_STR
2622 "mac access lists\n"
2623 "List mac access lists\n")
2624 {
2625 return filter_show(vty, NULL, AFI_L2VPN);
2626 }
2627
2628 DEFUN (show_mac_access_list_name,
2629 show_mac_access_list_name_cmd,
2630 "show mac access-list WORD",
2631 SHOW_STR
2632 "mac access lists\n"
2633 "List mac access lists\n"
2634 "mac address\n")
2635 {
2636 return filter_show(vty, argv[3]->arg, AFI_L2VPN);
2637 }
2638
2639 DEFUN (show_ip_access_list,
2640 show_ip_access_list_cmd,
2641 "show ip access-list",
2642 SHOW_STR
2643 IP_STR
2644 "List IP access lists\n")
2645 {
2646 return filter_show(vty, NULL, AFI_IP);
2647 }
2648
2649 DEFUN (show_ip_access_list_name,
2650 show_ip_access_list_name_cmd,
2651 "show ip access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
2652 SHOW_STR
2653 IP_STR
2654 "List IP access lists\n"
2655 "IP standard access list\n"
2656 "IP extended access list\n"
2657 "IP standard access list (expanded range)\n"
2658 "IP extended access list (expanded range)\n"
2659 "IP zebra access-list\n")
2660 {
2661 int idx_acl = 3;
2662 return filter_show(vty, argv[idx_acl]->arg, AFI_IP);
2663 }
2664
2665 DEFUN (show_ipv6_access_list,
2666 show_ipv6_access_list_cmd,
2667 "show ipv6 access-list",
2668 SHOW_STR
2669 IPV6_STR
2670 "List IPv6 access lists\n")
2671 {
2672 return filter_show(vty, NULL, AFI_IP6);
2673 }
2674
2675 DEFUN (show_ipv6_access_list_name,
2676 show_ipv6_access_list_name_cmd,
2677 "show ipv6 access-list WORD",
2678 SHOW_STR
2679 IPV6_STR
2680 "List IPv6 access lists\n"
2681 "IPv6 zebra access-list\n")
2682 {
2683 int idx_word = 3;
2684 return filter_show(vty, argv[idx_word]->arg, AFI_IP6);
2685 }
2686
2687 static void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
2688 {
2689 struct filter_cisco *filter;
2690
2691 filter = &mfilter->u.cfilter;
2692
2693 if (filter->extended) {
2694 vty_out(vty, " ip");
2695 if (filter->addr_mask.s_addr == 0xffffffff)
2696 vty_out(vty, " any");
2697 else if (filter->addr_mask.s_addr == INADDR_ANY)
2698 vty_out(vty, " host %s", inet_ntoa(filter->addr));
2699 else {
2700 vty_out(vty, " %s", inet_ntoa(filter->addr));
2701 vty_out(vty, " %s", inet_ntoa(filter->addr_mask));
2702 }
2703
2704 if (filter->mask_mask.s_addr == 0xffffffff)
2705 vty_out(vty, " any");
2706 else if (filter->mask_mask.s_addr == INADDR_ANY)
2707 vty_out(vty, " host %s", inet_ntoa(filter->mask));
2708 else {
2709 vty_out(vty, " %s", inet_ntoa(filter->mask));
2710 vty_out(vty, " %s", inet_ntoa(filter->mask_mask));
2711 }
2712 vty_out(vty, "\n");
2713 } else {
2714 if (filter->addr_mask.s_addr == 0xffffffff)
2715 vty_out(vty, " any\n");
2716 else {
2717 vty_out(vty, " %s", inet_ntoa(filter->addr));
2718 if (filter->addr_mask.s_addr != INADDR_ANY)
2719 vty_out(vty, " %s",
2720 inet_ntoa(filter->addr_mask));
2721 vty_out(vty, "\n");
2722 }
2723 }
2724 }
2725
2726 static void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
2727 {
2728 struct filter_zebra *filter;
2729 struct prefix *p;
2730 char buf[BUFSIZ];
2731
2732 filter = &mfilter->u.zfilter;
2733 p = &filter->prefix;
2734
2735 if (p->prefixlen == 0 && !filter->exact)
2736 vty_out(vty, " any");
2737 else if (p->family == AF_INET6 || p->family == AF_INET)
2738 vty_out(vty, " %s/%d%s",
2739 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
2740 p->prefixlen, filter->exact ? " exact-match" : "");
2741 else if (p->family == AF_ETHERNET) {
2742 if (p->prefixlen == 0)
2743 vty_out(vty, " any");
2744 else
2745 vty_out(vty, " %s", prefix_mac2str(&(p->u.prefix_eth),
2746 buf, sizeof(buf)));
2747 }
2748
2749 vty_out(vty, "\n");
2750 }
2751
2752 static int config_write_access(struct vty *vty, afi_t afi)
2753 {
2754 struct access_list *access;
2755 struct access_master *master;
2756 struct filter *mfilter;
2757 int write = 0;
2758
2759 master = access_master_get(afi);
2760 if (master == NULL)
2761 return 0;
2762
2763 for (access = master->num.head; access; access = access->next) {
2764 if (access->remark) {
2765 vty_out(vty, "%saccess-list %s remark %s\n",
2766 (afi == AFI_IP) ? ("")
2767 : ((afi == AFI_IP6) ? ("ipv6 ")
2768 : ("mac ")),
2769 access->name, access->remark);
2770 write++;
2771 }
2772
2773 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
2774 vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
2775 (afi == AFI_IP) ? ("")
2776 : ((afi == AFI_IP6) ? ("ipv6 ")
2777 : ("mac ")),
2778 access->name, mfilter->seq,
2779 filter_type_str(mfilter));
2780
2781 if (mfilter->cisco)
2782 config_write_access_cisco(vty, mfilter);
2783 else
2784 config_write_access_zebra(vty, mfilter);
2785
2786 write++;
2787 }
2788 }
2789
2790 for (access = master->str.head; access; access = access->next) {
2791 if (access->remark) {
2792 vty_out(vty, "%saccess-list %s remark %s\n",
2793 (afi == AFI_IP) ? ("")
2794 : ((afi == AFI_IP6) ? ("ipv6 ")
2795 : ("mac ")),
2796 access->name, access->remark);
2797 write++;
2798 }
2799
2800 for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
2801 vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
2802 (afi == AFI_IP) ? ("")
2803 : ((afi == AFI_IP6) ? ("ipv6 ")
2804 : ("mac ")),
2805 access->name, mfilter->seq,
2806 filter_type_str(mfilter));
2807
2808 if (mfilter->cisco)
2809 config_write_access_cisco(vty, mfilter);
2810 else
2811 config_write_access_zebra(vty, mfilter);
2812
2813 write++;
2814 }
2815 }
2816 return write;
2817 }
2818
2819 static struct cmd_node access_mac_node = {
2820 ACCESS_MAC_NODE, "", /* Access list has no interface. */
2821 1};
2822
2823 static int config_write_access_mac(struct vty *vty)
2824 {
2825 return config_write_access(vty, AFI_L2VPN);
2826 }
2827
2828 static void access_list_reset_mac(void)
2829 {
2830 struct access_list *access;
2831 struct access_list *next;
2832 struct access_master *master;
2833
2834 master = access_master_get(AFI_L2VPN);
2835 if (master == NULL)
2836 return;
2837
2838 for (access = master->num.head; access; access = next) {
2839 next = access->next;
2840 access_list_delete(access);
2841 }
2842 for (access = master->str.head; access; access = next) {
2843 next = access->next;
2844 access_list_delete(access);
2845 }
2846
2847 assert(master->num.head == NULL);
2848 assert(master->num.tail == NULL);
2849
2850 assert(master->str.head == NULL);
2851 assert(master->str.tail == NULL);
2852 }
2853
2854 /* Install vty related command. */
2855 static void access_list_init_mac(void)
2856 {
2857 install_node(&access_mac_node, config_write_access_mac);
2858
2859 install_element(ENABLE_NODE, &show_mac_access_list_cmd);
2860 install_element(ENABLE_NODE, &show_mac_access_list_name_cmd);
2861
2862 /* Zebra access-list */
2863 install_element(CONFIG_NODE, &mac_access_list_cmd);
2864 install_element(CONFIG_NODE, &no_mac_access_list_cmd);
2865 install_element(CONFIG_NODE, &mac_access_list_any_cmd);
2866 install_element(CONFIG_NODE, &no_mac_access_list_any_cmd);
2867 }
2868
2869 /* Access-list node. */
2870 static struct cmd_node access_node = {ACCESS_NODE,
2871 "", /* Access list has no interface. */
2872 1};
2873
2874 static int config_write_access_ipv4(struct vty *vty)
2875 {
2876 return config_write_access(vty, AFI_IP);
2877 }
2878
2879 static void access_list_reset_ipv4(void)
2880 {
2881 struct access_list *access;
2882 struct access_list *next;
2883 struct access_master *master;
2884
2885 master = access_master_get(AFI_IP);
2886 if (master == NULL)
2887 return;
2888
2889 for (access = master->num.head; access; access = next) {
2890 next = access->next;
2891 access_list_delete(access);
2892 }
2893 for (access = master->str.head; access; access = next) {
2894 next = access->next;
2895 access_list_delete(access);
2896 }
2897
2898 assert(master->num.head == NULL);
2899 assert(master->num.tail == NULL);
2900
2901 assert(master->str.head == NULL);
2902 assert(master->str.tail == NULL);
2903 }
2904
2905 /* Install vty related command. */
2906 static void access_list_init_ipv4(void)
2907 {
2908 install_node(&access_node, config_write_access_ipv4);
2909
2910 install_element(ENABLE_NODE, &show_ip_access_list_cmd);
2911 install_element(ENABLE_NODE, &show_ip_access_list_name_cmd);
2912
2913 /* Zebra access-list */
2914 install_element(CONFIG_NODE, &access_list_exact_cmd);
2915 install_element(CONFIG_NODE, &access_list_any_cmd);
2916 install_element(CONFIG_NODE, &no_access_list_exact_cmd);
2917 install_element(CONFIG_NODE, &no_access_list_any_cmd);
2918
2919 /* Standard access-list */
2920 install_element(CONFIG_NODE, &access_list_standard_cmd);
2921 install_element(CONFIG_NODE, &access_list_standard_nomask_cmd);
2922 install_element(CONFIG_NODE, &access_list_standard_host_cmd);
2923 install_element(CONFIG_NODE, &access_list_standard_any_cmd);
2924 install_element(CONFIG_NODE, &no_access_list_standard_cmd);
2925 install_element(CONFIG_NODE, &no_access_list_standard_nomask_cmd);
2926 install_element(CONFIG_NODE, &no_access_list_standard_host_cmd);
2927 install_element(CONFIG_NODE, &no_access_list_standard_any_cmd);
2928
2929 /* Extended access-list */
2930 install_element(CONFIG_NODE, &access_list_extended_cmd);
2931 install_element(CONFIG_NODE, &access_list_extended_any_mask_cmd);
2932 install_element(CONFIG_NODE, &access_list_extended_mask_any_cmd);
2933 install_element(CONFIG_NODE, &access_list_extended_any_any_cmd);
2934 install_element(CONFIG_NODE, &access_list_extended_host_mask_cmd);
2935 install_element(CONFIG_NODE, &access_list_extended_mask_host_cmd);
2936 install_element(CONFIG_NODE, &access_list_extended_host_host_cmd);
2937 install_element(CONFIG_NODE, &access_list_extended_any_host_cmd);
2938 install_element(CONFIG_NODE, &access_list_extended_host_any_cmd);
2939 install_element(CONFIG_NODE, &no_access_list_extended_cmd);
2940 install_element(CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
2941 install_element(CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
2942 install_element(CONFIG_NODE, &no_access_list_extended_any_any_cmd);
2943 install_element(CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
2944 install_element(CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
2945 install_element(CONFIG_NODE, &no_access_list_extended_host_host_cmd);
2946 install_element(CONFIG_NODE, &no_access_list_extended_any_host_cmd);
2947 install_element(CONFIG_NODE, &no_access_list_extended_host_any_cmd);
2948
2949 install_element(CONFIG_NODE, &access_list_remark_cmd);
2950 install_element(CONFIG_NODE, &no_access_list_all_cmd);
2951 install_element(CONFIG_NODE, &no_access_list_remark_cmd);
2952 install_element(CONFIG_NODE, &no_access_list_remark_comment_cmd);
2953 }
2954
2955 static struct cmd_node access_ipv6_node = {ACCESS_IPV6_NODE, "", 1};
2956
2957 static int config_write_access_ipv6(struct vty *vty)
2958 {
2959 return config_write_access(vty, AFI_IP6);
2960 }
2961
2962 static void access_list_reset_ipv6(void)
2963 {
2964 struct access_list *access;
2965 struct access_list *next;
2966 struct access_master *master;
2967
2968 master = access_master_get(AFI_IP6);
2969 if (master == NULL)
2970 return;
2971
2972 for (access = master->num.head; access; access = next) {
2973 next = access->next;
2974 access_list_delete(access);
2975 }
2976 for (access = master->str.head; access; access = next) {
2977 next = access->next;
2978 access_list_delete(access);
2979 }
2980
2981 assert(master->num.head == NULL);
2982 assert(master->num.tail == NULL);
2983
2984 assert(master->str.head == NULL);
2985 assert(master->str.tail == NULL);
2986 }
2987
2988 static void access_list_init_ipv6(void)
2989 {
2990 install_node(&access_ipv6_node, config_write_access_ipv6);
2991
2992 install_element(ENABLE_NODE, &show_ipv6_access_list_cmd);
2993 install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd);
2994
2995 install_element(CONFIG_NODE, &ipv6_access_list_exact_cmd);
2996 install_element(CONFIG_NODE, &ipv6_access_list_any_cmd);
2997 install_element(CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2998 install_element(CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2999
3000 install_element(CONFIG_NODE, &no_ipv6_access_list_all_cmd);
3001 install_element(CONFIG_NODE, &ipv6_access_list_remark_cmd);
3002 install_element(CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
3003 install_element(CONFIG_NODE, &no_ipv6_access_list_remark_comment_cmd);
3004 }
3005
3006 void access_list_init(void)
3007 {
3008 access_list_init_ipv4();
3009 access_list_init_ipv6();
3010 access_list_init_mac();
3011 }
3012
3013 void access_list_reset(void)
3014 {
3015 access_list_reset_ipv4();
3016 access_list_reset_ipv6();
3017 access_list_reset_mac();
3018 }