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