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