blob: 7aeb8deb7e266c8ee4546206bd6bb57fc908c25c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
vincentfbf5d032005-09-29 11:25:50 +000030#include "log.h"
paul718e3742002-12-13 20:15:29 +000031
32struct 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
42struct 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 */
52struct 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. */
72struct access_list_list
73{
74 struct access_list *head;
75 struct access_list *tail;
76};
77
78/* Master structure of access_list. */
79struct 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. */
paul8cc41982005-05-06 21:25:49 +000088 void (*add_hook) (struct access_list *);
paul718e3742002-12-13 20:15:29 +000089
90 /* Hook function which is executed when access_list is deleted. */
paul8cc41982005-05-06 21:25:49 +000091 void (*delete_hook) (struct access_list *);
paul718e3742002-12-13 20:15:29 +000092};
93
94/* Static structure for IPv4 access_list's master. */
95static 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. */
105static struct access_master access_master_ipv6 =
106{
107 {NULL, NULL},
108 {NULL, NULL},
109 NULL,
110 NULL,
111};
112#endif /* HAVE_IPV6 */
113
paul8cc41982005-05-06 21:25:49 +0000114static struct access_master *
paul718e3742002-12-13 20:15:29 +0000115access_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. */
paul8cc41982005-05-06 21:25:49 +0000127static struct filter *
128filter_new (void)
paul718e3742002-12-13 20:15:29 +0000129{
130 return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
131 sizeof (struct filter));
132}
133
paul8cc41982005-05-06 21:25:49 +0000134static void
paul718e3742002-12-13 20:15:29 +0000135filter_free (struct filter *filter)
136{
137 XFREE (MTYPE_ACCESS_FILTER, filter);
138}
139
140/* Return string of filter_type. */
Paul Jakma30a22312008-08-15 14:05:22 +0100141static const char *
paul718e3742002-12-13 20:15:29 +0000142filter_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. */
162static int
163filter_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. */
189static int
190filter_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. */
paul8cc41982005-05-06 21:25:49 +0000213static struct access_list *
214access_list_new (void)
paul718e3742002-12-13 20:15:29 +0000215{
216 return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
217 sizeof (struct access_list));
218}
219
220/* Free allocated access_list. */
paul8cc41982005-05-06 21:25:49 +0000221static void
paul718e3742002-12-13 20:15:29 +0000222access_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. */
paul8cc41982005-05-06 21:25:49 +0000228static void
paul718e3742002-12-13 20:15:29 +0000229access_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. */
paul8cc41982005-05-06 21:25:49 +0000270static struct access_list *
hasso8c328f12004-10-05 21:01:23 +0000271access_list_insert (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000272{
hasso8c328f12004-10-05 21:01:23 +0000273 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000274 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 (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. */
361struct access_list *
hasso8c328f12004-10-05 21:01:23 +0000362access_list_lookup (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000363{
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 (strcmp (access->name, name) == 0)
376 return access;
377
378 for (access = master->str.head; access; access = access->next)
379 if (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. */
paul8cc41982005-05-06 21:25:49 +0000387static struct access_list *
hasso8c328f12004-10-05 21:01:23 +0000388access_list_get (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000389{
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 *). */
399enum filter_type
400access_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. */
428void
429access_list_add_hook (void (*func) (struct access_list *access))
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. */
438void
439access_list_delete_hook (void (*func) (struct access_list *access))
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. */
paul8cc41982005-05-06 21:25:49 +0000448static void
paul718e3742002-12-13 20:15:29 +0000449access_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);
463}
464
465/* If access_list has no filter then return 1. */
466static int
467access_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. */
paul8cc41982005-05-06 21:25:49 +0000477static void
paul718e3742002-12-13 20:15:29 +0000478access_list_filter_delete (struct access_list *access, struct filter *filter)
479{
480 struct access_master *master;
481
482 master = access->master;
483
484 if (filter->next)
485 filter->next->prev = filter->prev;
486 else
487 access->tail = filter->prev;
488
489 if (filter->prev)
490 filter->prev->next = filter->next;
491 else
492 access->head = filter->next;
493
494 filter_free (filter);
495
496 /* If access_list becomes empty delete it from access_master. */
497 if (access_list_empty (access))
498 access_list_delete (access);
499
500 /* Run hook function. */
501 if (master->delete_hook)
502 (*master->delete_hook) (access);
503}
504
505/*
506 deny Specify packets to reject
507 permit Specify packets to forward
508 dynamic ?
509*/
510
511/*
512 Hostname or A.B.C.D Address to match
513 any Any source host
514 host A single host address
515*/
516
paul8cc41982005-05-06 21:25:49 +0000517static struct filter *
paul718e3742002-12-13 20:15:29 +0000518filter_lookup_cisco (struct access_list *access, struct filter *mnew)
519{
520 struct filter *mfilter;
521 struct filter_cisco *filter;
522 struct filter_cisco *new;
523
524 new = &mnew->u.cfilter;
525
526 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
527 {
528 filter = &mfilter->u.cfilter;
529
530 if (filter->extended)
531 {
532 if (mfilter->type == mnew->type
533 && filter->addr.s_addr == new->addr.s_addr
534 && filter->addr_mask.s_addr == new->addr_mask.s_addr
535 && filter->mask.s_addr == new->mask.s_addr
536 && filter->mask_mask.s_addr == new->mask_mask.s_addr)
537 return mfilter;
538 }
539 else
540 {
541 if (mfilter->type == mnew->type
542 && filter->addr.s_addr == new->addr.s_addr
543 && filter->addr_mask.s_addr == new->addr_mask.s_addr)
544 return mfilter;
545 }
546 }
547
548 return NULL;
549}
550
paul8cc41982005-05-06 21:25:49 +0000551static struct filter *
paul718e3742002-12-13 20:15:29 +0000552filter_lookup_zebra (struct access_list *access, struct filter *mnew)
553{
554 struct filter *mfilter;
555 struct filter_zebra *filter;
556 struct filter_zebra *new;
557
558 new = &mnew->u.zfilter;
559
560 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
561 {
562 filter = &mfilter->u.zfilter;
563
564 if (filter->exact == new->exact
565 && mfilter->type == mnew->type
566 && prefix_same (&filter->prefix, &new->prefix))
567 return mfilter;
568 }
569 return NULL;
570}
571
paul8cc41982005-05-06 21:25:49 +0000572static int
paul9035efa2004-10-10 11:56:56 +0000573vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000574{
575 struct access_list *access;
576
577 access = access_list_lookup (afi, name);
578 if (! access)
579 {
580 vty_out (vty, "%% access-list %s doesn't exist%s", name,
581 VTY_NEWLINE);
582 return CMD_WARNING;
583 }
584
585 if (access->remark)
586 {
587 XFREE (MTYPE_TMP, access->remark);
588 access->remark = NULL;
589 }
590
591 if (access->head == NULL && access->tail == NULL && access->remark == NULL)
592 access_list_delete (access);
593
594 return CMD_SUCCESS;
595}
596
paul8cc41982005-05-06 21:25:49 +0000597static int
paul9035efa2004-10-10 11:56:56 +0000598filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
hasso8c328f12004-10-05 21:01:23 +0000599 const char *addr_str, const char *addr_mask_str,
600 const char *mask_str, const char *mask_mask_str,
paul718e3742002-12-13 20:15:29 +0000601 int extended, int set)
602{
603 int ret;
604 enum filter_type type;
605 struct filter *mfilter;
606 struct filter_cisco *filter;
607 struct access_list *access;
608 struct in_addr addr;
609 struct in_addr addr_mask;
610 struct in_addr mask;
611 struct in_addr mask_mask;
612
613 /* Check of filter type. */
614 if (strncmp (type_str, "p", 1) == 0)
615 type = FILTER_PERMIT;
616 else if (strncmp (type_str, "d", 1) == 0)
617 type = FILTER_DENY;
618 else
619 {
620 vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
621 return CMD_WARNING;
622 }
623
624 ret = inet_aton (addr_str, &addr);
625 if (ret <= 0)
626 {
627 vty_out (vty, "%%Inconsistent address and mask%s",
628 VTY_NEWLINE);
629 return CMD_WARNING;
630 }
631
632 ret = inet_aton (addr_mask_str, &addr_mask);
633 if (ret <= 0)
634 {
635 vty_out (vty, "%%Inconsistent address and mask%s",
636 VTY_NEWLINE);
637 return CMD_WARNING;
638 }
639
640 if (extended)
641 {
642 ret = inet_aton (mask_str, &mask);
643 if (ret <= 0)
644 {
645 vty_out (vty, "%%Inconsistent address and mask%s",
646 VTY_NEWLINE);
647 return CMD_WARNING;
648 }
649
650 ret = inet_aton (mask_mask_str, &mask_mask);
651 if (ret <= 0)
652 {
653 vty_out (vty, "%%Inconsistent address and mask%s",
654 VTY_NEWLINE);
655 return CMD_WARNING;
656 }
657 }
658
659 mfilter = filter_new();
660 mfilter->type = type;
661 mfilter->cisco = 1;
662 filter = &mfilter->u.cfilter;
663 filter->extended = extended;
664 filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
665 filter->addr_mask.s_addr = addr_mask.s_addr;
666
667 if (extended)
668 {
669 filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
670 filter->mask_mask.s_addr = mask_mask.s_addr;
671 }
672
673 /* Install new filter to the access_list. */
674 access = access_list_get (AFI_IP, name_str);
675
676 if (set)
677 {
678 if (filter_lookup_cisco (access, mfilter))
679 filter_free (mfilter);
680 else
681 access_list_filter_add (access, mfilter);
682 }
683 else
684 {
685 struct filter *delete_filter;
686
687 delete_filter = filter_lookup_cisco (access, mfilter);
688 if (delete_filter)
689 access_list_filter_delete (access, delete_filter);
690
691 filter_free (mfilter);
692 }
693
694 return CMD_SUCCESS;
695}
696
697/* Standard access-list */
698DEFUN (access_list_standard,
699 access_list_standard_cmd,
700 "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
701 "Add an access list entry\n"
702 "IP standard access list\n"
703 "IP standard access list (expanded range)\n"
704 "Specify packets to reject\n"
705 "Specify packets to forward\n"
706 "Address to match\n"
707 "Wildcard bits\n")
708{
709 return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
710 NULL, NULL, 0, 1);
711}
712
713DEFUN (access_list_standard_nomask,
714 access_list_standard_nomask_cmd,
715 "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
716 "Add an access list entry\n"
717 "IP standard access list\n"
718 "IP standard access list (expanded range)\n"
719 "Specify packets to reject\n"
720 "Specify packets to forward\n"
721 "Address to match\n")
722{
723 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
724 NULL, NULL, 0, 1);
725}
726
727DEFUN (access_list_standard_host,
728 access_list_standard_host_cmd,
729 "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
730 "Add an access list entry\n"
731 "IP standard access list\n"
732 "IP standard access list (expanded range)\n"
733 "Specify packets to reject\n"
734 "Specify packets to forward\n"
735 "A single host address\n"
736 "Address to match\n")
737{
738 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
739 NULL, NULL, 0, 1);
740}
741
742DEFUN (access_list_standard_any,
743 access_list_standard_any_cmd,
744 "access-list (<1-99>|<1300-1999>) (deny|permit) any",
745 "Add an access list entry\n"
746 "IP standard access list\n"
747 "IP standard access list (expanded range)\n"
748 "Specify packets to reject\n"
749 "Specify packets to forward\n"
750 "Any source host\n")
751{
752 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
753 "255.255.255.255", NULL, NULL, 0, 1);
754}
755
756DEFUN (no_access_list_standard,
757 no_access_list_standard_cmd,
758 "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
759 NO_STR
760 "Add an access list entry\n"
761 "IP standard access list\n"
762 "IP standard access list (expanded range)\n"
763 "Specify packets to reject\n"
764 "Specify packets to forward\n"
765 "Address to match\n"
766 "Wildcard bits\n")
767{
768 return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
769 NULL, NULL, 0, 0);
770}
771
772DEFUN (no_access_list_standard_nomask,
773 no_access_list_standard_nomask_cmd,
774 "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
775 NO_STR
776 "Add an access list entry\n"
777 "IP standard access list\n"
778 "IP standard access list (expanded range)\n"
779 "Specify packets to reject\n"
780 "Specify packets to forward\n"
781 "Address to match\n")
782{
783 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
784 NULL, NULL, 0, 0);
785}
786
787DEFUN (no_access_list_standard_host,
788 no_access_list_standard_host_cmd,
789 "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
790 NO_STR
791 "Add an access list entry\n"
792 "IP standard access list\n"
793 "IP standard access list (expanded range)\n"
794 "Specify packets to reject\n"
795 "Specify packets to forward\n"
796 "A single host address\n"
797 "Address to match\n")
798{
799 return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
800 NULL, NULL, 0, 0);
801}
802
803DEFUN (no_access_list_standard_any,
804 no_access_list_standard_any_cmd,
805 "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
806 NO_STR
807 "Add an access list entry\n"
808 "IP standard access list\n"
809 "IP standard access list (expanded range)\n"
810 "Specify packets to reject\n"
811 "Specify packets to forward\n"
812 "Any source host\n")
813{
814 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
815 "255.255.255.255", NULL, NULL, 0, 0);
816}
817
818/* Extended access-list */
819DEFUN (access_list_extended,
820 access_list_extended_cmd,
821 "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",
822 "Add an access list entry\n"
823 "IP extended access list\n"
824 "IP extended access list (expanded range)\n"
825 "Specify packets to reject\n"
826 "Specify packets to forward\n"
827 "Any Internet Protocol\n"
828 "Source address\n"
829 "Source wildcard bits\n"
830 "Destination address\n"
831 "Destination Wildcard bits\n")
832{
833 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
834 argv[3], argv[4], argv[5], 1 ,1);
835}
836
837DEFUN (access_list_extended_mask_any,
838 access_list_extended_mask_any_cmd,
839 "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
840 "Add an access list entry\n"
841 "IP extended access list\n"
842 "IP extended access list (expanded range)\n"
843 "Specify packets to reject\n"
844 "Specify packets to forward\n"
845 "Any Internet Protocol\n"
846 "Source address\n"
847 "Source wildcard bits\n"
848 "Any destination host\n")
849{
850 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
851 argv[3], "0.0.0.0",
852 "255.255.255.255", 1, 1);
853}
854
855DEFUN (access_list_extended_any_mask,
856 access_list_extended_any_mask_cmd,
857 "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
858 "Add an access list entry\n"
859 "IP extended access list\n"
860 "IP extended access list (expanded range)\n"
861 "Specify packets to reject\n"
862 "Specify packets to forward\n"
863 "Any Internet Protocol\n"
864 "Any source host\n"
865 "Destination address\n"
866 "Destination Wildcard bits\n")
867{
868 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
869 "255.255.255.255", argv[2],
870 argv[3], 1, 1);
871}
872
873DEFUN (access_list_extended_any_any,
874 access_list_extended_any_any_cmd,
875 "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
876 "Add an access list entry\n"
877 "IP extended access list\n"
878 "IP extended access list (expanded range)\n"
879 "Specify packets to reject\n"
880 "Specify packets to forward\n"
881 "Any Internet Protocol\n"
882 "Any source host\n"
883 "Any destination host\n")
884{
885 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
886 "255.255.255.255", "0.0.0.0",
887 "255.255.255.255", 1, 1);
888}
889
890DEFUN (access_list_extended_mask_host,
891 access_list_extended_mask_host_cmd,
892 "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
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 "Source address\n"
900 "Source wildcard bits\n"
901 "A single destination host\n"
902 "Destination address\n")
903{
904 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
905 argv[3], argv[4],
906 "0.0.0.0", 1, 1);
907}
908
909DEFUN (access_list_extended_host_mask,
910 access_list_extended_host_mask_cmd,
911 "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
912 "Add an access list entry\n"
913 "IP extended access list\n"
914 "IP extended access list (expanded range)\n"
915 "Specify packets to reject\n"
916 "Specify packets to forward\n"
917 "Any Internet Protocol\n"
918 "A single source host\n"
919 "Source address\n"
920 "Destination address\n"
921 "Destination Wildcard bits\n")
922{
923 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
924 "0.0.0.0", argv[3],
925 argv[4], 1, 1);
926}
927
928DEFUN (access_list_extended_host_host,
929 access_list_extended_host_host_cmd,
930 "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
931 "Add an access list entry\n"
932 "IP extended access list\n"
933 "IP extended access list (expanded range)\n"
934 "Specify packets to reject\n"
935 "Specify packets to forward\n"
936 "Any Internet Protocol\n"
937 "A single source host\n"
938 "Source address\n"
939 "A single destination host\n"
940 "Destination address\n")
941{
942 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
943 "0.0.0.0", argv[3],
944 "0.0.0.0", 1, 1);
945}
946
947DEFUN (access_list_extended_any_host,
948 access_list_extended_any_host_cmd,
949 "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
950 "Add an access list entry\n"
951 "IP extended access list\n"
952 "IP extended access list (expanded range)\n"
953 "Specify packets to reject\n"
954 "Specify packets to forward\n"
955 "Any Internet Protocol\n"
956 "Any source host\n"
957 "A single destination host\n"
958 "Destination address\n")
959{
960 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
961 "255.255.255.255", argv[2],
962 "0.0.0.0", 1, 1);
963}
964
965DEFUN (access_list_extended_host_any,
966 access_list_extended_host_any_cmd,
967 "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
968 "Add an access list entry\n"
969 "IP extended access list\n"
970 "IP extended access list (expanded range)\n"
971 "Specify packets to reject\n"
972 "Specify packets to forward\n"
973 "Any Internet Protocol\n"
974 "A single source host\n"
975 "Source address\n"
976 "Any destination host\n")
977{
978 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
979 "0.0.0.0", "0.0.0.0",
980 "255.255.255.255", 1, 1);
981}
982
983DEFUN (no_access_list_extended,
984 no_access_list_extended_cmd,
985 "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",
986 NO_STR
987 "Add an access list entry\n"
988 "IP extended access list\n"
989 "IP extended access list (expanded range)\n"
990 "Specify packets to reject\n"
991 "Specify packets to forward\n"
992 "Any Internet Protocol\n"
993 "Source address\n"
994 "Source wildcard bits\n"
995 "Destination address\n"
996 "Destination Wildcard bits\n")
997{
998 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
999 argv[3], argv[4], argv[5], 1, 0);
1000}
1001
1002DEFUN (no_access_list_extended_mask_any,
1003 no_access_list_extended_mask_any_cmd,
1004 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
1005 NO_STR
1006 "Add an access list entry\n"
1007 "IP extended access list\n"
1008 "IP extended access list (expanded range)\n"
1009 "Specify packets to reject\n"
1010 "Specify packets to forward\n"
1011 "Any Internet Protocol\n"
1012 "Source address\n"
1013 "Source wildcard bits\n"
1014 "Any destination host\n")
1015{
1016 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1017 argv[3], "0.0.0.0",
1018 "255.255.255.255", 1, 0);
1019}
1020
1021DEFUN (no_access_list_extended_any_mask,
1022 no_access_list_extended_any_mask_cmd,
1023 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
1024 NO_STR
1025 "Add an access list entry\n"
1026 "IP extended access list\n"
1027 "IP extended access list (expanded range)\n"
1028 "Specify packets to reject\n"
1029 "Specify packets to forward\n"
1030 "Any Internet Protocol\n"
1031 "Any source host\n"
1032 "Destination address\n"
1033 "Destination Wildcard bits\n")
1034{
1035 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1036 "255.255.255.255", argv[2],
1037 argv[3], 1, 0);
1038}
1039
1040DEFUN (no_access_list_extended_any_any,
1041 no_access_list_extended_any_any_cmd,
1042 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
1043 NO_STR
1044 "Add an access list entry\n"
1045 "IP extended access list\n"
1046 "IP extended access list (expanded range)\n"
1047 "Specify packets to reject\n"
1048 "Specify packets to forward\n"
1049 "Any Internet Protocol\n"
1050 "Any source host\n"
1051 "Any destination host\n")
1052{
1053 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1054 "255.255.255.255", "0.0.0.0",
1055 "255.255.255.255", 1, 0);
1056}
1057
1058DEFUN (no_access_list_extended_mask_host,
1059 no_access_list_extended_mask_host_cmd,
1060 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
1061 NO_STR
1062 "Add an access list entry\n"
1063 "IP extended access list\n"
1064 "IP extended access list (expanded range)\n"
1065 "Specify packets to reject\n"
1066 "Specify packets to forward\n"
1067 "Any Internet Protocol\n"
1068 "Source address\n"
1069 "Source wildcard bits\n"
1070 "A single destination host\n"
1071 "Destination address\n")
1072{
1073 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1074 argv[3], argv[4],
1075 "0.0.0.0", 1, 0);
1076}
1077
1078DEFUN (no_access_list_extended_host_mask,
1079 no_access_list_extended_host_mask_cmd,
1080 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
1081 NO_STR
1082 "Add an access list entry\n"
1083 "IP extended access list\n"
1084 "IP extended access list (expanded range)\n"
1085 "Specify packets to reject\n"
1086 "Specify packets to forward\n"
1087 "Any Internet Protocol\n"
1088 "A single source host\n"
1089 "Source address\n"
1090 "Destination address\n"
1091 "Destination Wildcard bits\n")
1092{
1093 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1094 "0.0.0.0", argv[3],
1095 argv[4], 1, 0);
1096}
1097
1098DEFUN (no_access_list_extended_host_host,
1099 no_access_list_extended_host_host_cmd,
1100 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
1101 NO_STR
1102 "Add an access list entry\n"
1103 "IP extended access list\n"
1104 "IP extended access list (expanded range)\n"
1105 "Specify packets to reject\n"
1106 "Specify packets to forward\n"
1107 "Any Internet Protocol\n"
1108 "A single source host\n"
1109 "Source address\n"
1110 "A single destination host\n"
1111 "Destination address\n")
1112{
1113 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1114 "0.0.0.0", argv[3],
1115 "0.0.0.0", 1, 0);
1116}
1117
1118DEFUN (no_access_list_extended_any_host,
1119 no_access_list_extended_any_host_cmd,
1120 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
1121 NO_STR
1122 "Add an access list entry\n"
1123 "IP extended access list\n"
1124 "IP extended access list (expanded range)\n"
1125 "Specify packets to reject\n"
1126 "Specify packets to forward\n"
1127 "Any Internet Protocol\n"
1128 "Any source host\n"
1129 "A single destination host\n"
1130 "Destination address\n")
1131{
1132 return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1133 "255.255.255.255", argv[2],
1134 "0.0.0.0", 1, 0);
1135}
1136
1137DEFUN (no_access_list_extended_host_any,
1138 no_access_list_extended_host_any_cmd,
1139 "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
1140 NO_STR
1141 "Add an access list entry\n"
1142 "IP extended access list\n"
1143 "IP extended access list (expanded range)\n"
1144 "Specify packets to reject\n"
1145 "Specify packets to forward\n"
1146 "Any Internet Protocol\n"
1147 "A single source host\n"
1148 "Source address\n"
1149 "Any destination host\n")
1150{
1151 return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1152 "0.0.0.0", "0.0.0.0",
1153 "255.255.255.255", 1, 0);
1154}
1155
paul8cc41982005-05-06 21:25:49 +00001156static int
hasso8c328f12004-10-05 21:01:23 +00001157filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
1158 afi_t afi, const char *prefix_str, int exact, int set)
paul718e3742002-12-13 20:15:29 +00001159{
1160 int ret;
1161 enum filter_type type;
1162 struct filter *mfilter;
1163 struct filter_zebra *filter;
1164 struct access_list *access;
1165 struct prefix p;
1166
1167 /* Check of filter type. */
1168 if (strncmp (type_str, "p", 1) == 0)
1169 type = FILTER_PERMIT;
1170 else if (strncmp (type_str, "d", 1) == 0)
1171 type = FILTER_DENY;
1172 else
1173 {
1174 vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
1175 return CMD_WARNING;
1176 }
1177
1178 /* Check string format of prefix and prefixlen. */
1179 if (afi == AFI_IP)
1180 {
1181 ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
1182 if (ret <= 0)
1183 {
1184 vty_out (vty, "IP address prefix/prefixlen is malformed%s",
1185 VTY_NEWLINE);
1186 return CMD_WARNING;
1187 }
1188 }
1189#ifdef HAVE_IPV6
1190 else if (afi == AFI_IP6)
1191 {
1192 ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
1193 if (ret <= 0)
1194 {
1195 vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
1196 VTY_NEWLINE);
1197 return CMD_WARNING;
1198 }
1199 }
1200#endif /* HAVE_IPV6 */
1201 else
1202 return CMD_WARNING;
1203
1204 mfilter = filter_new ();
1205 mfilter->type = type;
1206 filter = &mfilter->u.zfilter;
1207 prefix_copy (&filter->prefix, &p);
1208
1209 /* "exact-match" */
1210 if (exact)
1211 filter->exact = 1;
1212
1213 /* Install new filter to the access_list. */
1214 access = access_list_get (afi, name_str);
1215
1216 if (set)
1217 {
1218 if (filter_lookup_zebra (access, mfilter))
1219 filter_free (mfilter);
1220 else
1221 access_list_filter_add (access, mfilter);
1222 }
1223 else
1224 {
1225 struct filter *delete_filter;
1226
1227 delete_filter = filter_lookup_zebra (access, mfilter);
1228 if (delete_filter)
1229 access_list_filter_delete (access, delete_filter);
1230
1231 filter_free (mfilter);
1232 }
1233
1234 return CMD_SUCCESS;
1235}
1236
1237/* Zebra access-list */
1238DEFUN (access_list,
1239 access_list_cmd,
1240 "access-list WORD (deny|permit) A.B.C.D/M",
1241 "Add an access list entry\n"
1242 "IP zebra access-list name\n"
1243 "Specify packets to reject\n"
1244 "Specify packets to forward\n"
1245 "Prefix to match. e.g. 10.0.0.0/8\n")
1246{
1247 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
1248}
1249
1250DEFUN (access_list_exact,
1251 access_list_exact_cmd,
1252 "access-list WORD (deny|permit) A.B.C.D/M exact-match",
1253 "Add an access list entry\n"
1254 "IP zebra access-list name\n"
1255 "Specify packets to reject\n"
1256 "Specify packets to forward\n"
1257 "Prefix to match. e.g. 10.0.0.0/8\n"
1258 "Exact match of the prefixes\n")
1259{
1260 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
1261}
1262
1263DEFUN (access_list_any,
1264 access_list_any_cmd,
1265 "access-list WORD (deny|permit) any",
1266 "Add an access list entry\n"
1267 "IP zebra access-list name\n"
1268 "Specify packets to reject\n"
1269 "Specify packets to forward\n"
1270 "Prefix to match. e.g. 10.0.0.0/8\n")
1271{
1272 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
1273}
1274
1275DEFUN (no_access_list,
1276 no_access_list_cmd,
1277 "no access-list WORD (deny|permit) A.B.C.D/M",
1278 NO_STR
1279 "Add an access list entry\n"
1280 "IP zebra access-list name\n"
1281 "Specify packets to reject\n"
1282 "Specify packets to forward\n"
1283 "Prefix to match. e.g. 10.0.0.0/8\n")
1284{
1285 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
1286}
1287
1288DEFUN (no_access_list_exact,
1289 no_access_list_exact_cmd,
1290 "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
1291 NO_STR
1292 "Add an access list entry\n"
1293 "IP zebra access-list name\n"
1294 "Specify packets to reject\n"
1295 "Specify packets to forward\n"
1296 "Prefix to match. e.g. 10.0.0.0/8\n"
1297 "Exact match of the prefixes\n")
1298{
1299 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
1300}
1301
1302DEFUN (no_access_list_any,
1303 no_access_list_any_cmd,
1304 "no access-list WORD (deny|permit) any",
1305 NO_STR
1306 "Add an access list entry\n"
1307 "IP zebra access-list name\n"
1308 "Specify packets to reject\n"
1309 "Specify packets to forward\n"
1310 "Prefix to match. e.g. 10.0.0.0/8\n")
1311{
1312 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
1313}
1314
1315DEFUN (no_access_list_all,
1316 no_access_list_all_cmd,
1317 "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1318 NO_STR
1319 "Add an access list entry\n"
1320 "IP standard access list\n"
1321 "IP extended access list\n"
1322 "IP standard access list (expanded range)\n"
1323 "IP extended access list (expanded range)\n"
1324 "IP zebra access-list name\n")
1325{
1326 struct access_list *access;
1327 struct access_master *master;
1328
1329 /* Looking up access_list. */
1330 access = access_list_lookup (AFI_IP, argv[0]);
1331 if (access == NULL)
1332 {
1333 vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1334 VTY_NEWLINE);
1335 return CMD_WARNING;
1336 }
1337
1338 master = access->master;
1339
1340 /* Delete all filter from access-list. */
1341 access_list_delete (access);
1342
1343 /* Run hook function. */
1344 if (master->delete_hook)
1345 (*master->delete_hook) (access);
1346
1347 return CMD_SUCCESS;
1348}
1349
1350DEFUN (access_list_remark,
1351 access_list_remark_cmd,
1352 "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1353 "Add an access list entry\n"
1354 "IP standard access list\n"
1355 "IP extended access list\n"
1356 "IP standard access list (expanded range)\n"
1357 "IP extended access list (expanded range)\n"
1358 "IP zebra access-list\n"
1359 "Access list entry comment\n"
1360 "Comment up to 100 characters\n")
1361{
1362 struct access_list *access;
paul718e3742002-12-13 20:15:29 +00001363
1364 access = access_list_get (AFI_IP, argv[0]);
1365
1366 if (access->remark)
1367 {
1368 XFREE (MTYPE_TMP, access->remark);
1369 access->remark = NULL;
1370 }
ajs3b8b1852005-01-29 18:19:13 +00001371 access->remark = argv_concat(argv, argc, 1);
paul718e3742002-12-13 20:15:29 +00001372
1373 return CMD_SUCCESS;
1374}
1375
1376DEFUN (no_access_list_remark,
1377 no_access_list_remark_cmd,
1378 "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
1379 NO_STR
1380 "Add an access list entry\n"
1381 "IP standard access list\n"
1382 "IP extended access list\n"
1383 "IP standard access list (expanded range)\n"
1384 "IP extended access list (expanded range)\n"
1385 "IP zebra access-list\n"
1386 "Access list entry comment\n")
1387{
1388 return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
1389}
1390
1391ALIAS (no_access_list_remark,
1392 no_access_list_remark_arg_cmd,
1393 "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1394 NO_STR
1395 "Add an access list entry\n"
1396 "IP standard access list\n"
1397 "IP extended access list\n"
1398 "IP standard access list (expanded range)\n"
1399 "IP extended access list (expanded range)\n"
1400 "IP zebra access-list\n"
1401 "Access list entry comment\n"
1402 "Comment up to 100 characters\n")
1403
1404#ifdef HAVE_IPV6
1405DEFUN (ipv6_access_list,
1406 ipv6_access_list_cmd,
1407 "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1408 IPV6_STR
1409 "Add an access list entry\n"
1410 "IPv6 zebra access-list\n"
1411 "Specify packets to reject\n"
1412 "Specify packets to forward\n"
1413 "Prefix to match. e.g. 3ffe:506::/32\n")
1414{
1415 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
1416}
1417
1418DEFUN (ipv6_access_list_exact,
1419 ipv6_access_list_exact_cmd,
1420 "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
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 "Exact match of the prefixes\n")
1428{
1429 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
1430}
1431
1432DEFUN (ipv6_access_list_any,
1433 ipv6_access_list_any_cmd,
1434 "ipv6 access-list WORD (deny|permit) any",
1435 IPV6_STR
1436 "Add an access list entry\n"
1437 "IPv6 zebra access-list\n"
1438 "Specify packets to reject\n"
1439 "Specify packets to forward\n"
1440 "Any prefixi to match\n")
1441{
1442 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
1443}
1444
1445DEFUN (no_ipv6_access_list,
1446 no_ipv6_access_list_cmd,
1447 "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1448 NO_STR
1449 IPV6_STR
1450 "Add an access list entry\n"
1451 "IPv6 zebra access-list\n"
1452 "Specify packets to reject\n"
1453 "Specify packets to forward\n"
1454 "Prefix to match. e.g. 3ffe:506::/32\n")
1455{
1456 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
1457}
1458
1459DEFUN (no_ipv6_access_list_exact,
1460 no_ipv6_access_list_exact_cmd,
1461 "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1462 NO_STR
1463 IPV6_STR
1464 "Add an access list entry\n"
1465 "IPv6 zebra access-list\n"
1466 "Specify packets to reject\n"
1467 "Specify packets to forward\n"
1468 "Prefix to match. e.g. 3ffe:506::/32\n"
1469 "Exact match of the prefixes\n")
1470{
1471 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
1472}
1473
1474DEFUN (no_ipv6_access_list_any,
1475 no_ipv6_access_list_any_cmd,
1476 "no ipv6 access-list WORD (deny|permit) any",
1477 NO_STR
1478 IPV6_STR
1479 "Add an access list entry\n"
1480 "IPv6 zebra access-list\n"
1481 "Specify packets to reject\n"
1482 "Specify packets to forward\n"
1483 "Any prefixi to match\n")
1484{
1485 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
1486}
1487
1488
1489DEFUN (no_ipv6_access_list_all,
1490 no_ipv6_access_list_all_cmd,
1491 "no ipv6 access-list WORD",
1492 NO_STR
1493 IPV6_STR
1494 "Add an access list entry\n"
1495 "IPv6 zebra access-list\n")
1496{
1497 struct access_list *access;
1498 struct access_master *master;
1499
1500 /* Looking up access_list. */
1501 access = access_list_lookup (AFI_IP6, argv[0]);
1502 if (access == NULL)
1503 {
1504 vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1505 VTY_NEWLINE);
1506 return CMD_WARNING;
1507 }
1508
1509 master = access->master;
1510
1511 /* Delete all filter from access-list. */
1512 access_list_delete (access);
1513
1514 /* Run hook function. */
1515 if (master->delete_hook)
1516 (*master->delete_hook) (access);
1517
1518 return CMD_SUCCESS;
1519}
1520
1521DEFUN (ipv6_access_list_remark,
1522 ipv6_access_list_remark_cmd,
1523 "ipv6 access-list WORD remark .LINE",
1524 IPV6_STR
1525 "Add an access list entry\n"
1526 "IPv6 zebra access-list\n"
1527 "Access list entry comment\n"
1528 "Comment up to 100 characters\n")
1529{
1530 struct access_list *access;
paul718e3742002-12-13 20:15:29 +00001531
1532 access = access_list_get (AFI_IP6, argv[0]);
1533
1534 if (access->remark)
1535 {
1536 XFREE (MTYPE_TMP, access->remark);
1537 access->remark = NULL;
1538 }
ajs3b8b1852005-01-29 18:19:13 +00001539 access->remark = argv_concat(argv, argc, 1);
paul718e3742002-12-13 20:15:29 +00001540
1541 return CMD_SUCCESS;
1542}
1543
1544DEFUN (no_ipv6_access_list_remark,
1545 no_ipv6_access_list_remark_cmd,
1546 "no ipv6 access-list WORD remark",
1547 NO_STR
1548 IPV6_STR
1549 "Add an access list entry\n"
1550 "IPv6 zebra access-list\n"
1551 "Access list entry comment\n")
1552{
1553 return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
1554}
1555
1556ALIAS (no_ipv6_access_list_remark,
1557 no_ipv6_access_list_remark_arg_cmd,
1558 "no ipv6 access-list WORD remark .LINE",
1559 NO_STR
1560 IPV6_STR
1561 "Add an access list entry\n"
1562 "IPv6 zebra access-list\n"
1563 "Access list entry comment\n"
1564 "Comment up to 100 characters\n")
1565#endif /* HAVE_IPV6 */
1566
1567void config_write_access_zebra (struct vty *, struct filter *);
1568void config_write_access_cisco (struct vty *, struct filter *);
1569
1570/* show access-list command. */
paul8cc41982005-05-06 21:25:49 +00001571static int
paul9035efa2004-10-10 11:56:56 +00001572filter_show (struct vty *vty, const char *name, afi_t afi)
paul718e3742002-12-13 20:15:29 +00001573{
1574 struct access_list *access;
1575 struct access_master *master;
1576 struct filter *mfilter;
1577 struct filter_cisco *filter;
1578 int write = 0;
1579
1580 master = access_master_get (afi);
1581 if (master == NULL)
1582 return 0;
1583
vincentfbf5d032005-09-29 11:25:50 +00001584 /* Print the name of the protocol */
1585 if (zlog_default)
1586 vty_out (vty, "%s:%s",
1587 zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
1588
paul718e3742002-12-13 20:15:29 +00001589 for (access = master->num.head; access; access = access->next)
1590 {
1591 if (name && strcmp (access->name, name) != 0)
1592 continue;
1593
1594 write = 1;
1595
1596 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1597 {
1598 filter = &mfilter->u.cfilter;
1599
1600 if (write)
1601 {
1602 vty_out (vty, "%s IP%s access list %s%s",
1603 mfilter->cisco ?
1604 (filter->extended ? "Extended" : "Standard") : "Zebra",
1605 afi == AFI_IP6 ? "v6" : "",
1606 access->name, VTY_NEWLINE);
1607 write = 0;
1608 }
1609
1610 vty_out (vty, " %s%s", filter_type_str (mfilter),
1611 mfilter->type == FILTER_DENY ? " " : "");
1612
1613 if (! mfilter->cisco)
1614 config_write_access_zebra (vty, mfilter);
1615 else if (filter->extended)
1616 config_write_access_cisco (vty, mfilter);
1617 else
1618 {
1619 if (filter->addr_mask.s_addr == 0xffffffff)
1620 vty_out (vty, " any%s", VTY_NEWLINE);
1621 else
1622 {
1623 vty_out (vty, " %s", inet_ntoa (filter->addr));
1624 if (filter->addr_mask.s_addr != 0)
1625 vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1626 vty_out (vty, "%s", VTY_NEWLINE);
1627 }
1628 }
1629 }
1630 }
1631
1632 for (access = master->str.head; access; access = access->next)
1633 {
1634 if (name && strcmp (access->name, name) != 0)
1635 continue;
1636
1637 write = 1;
1638
1639 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1640 {
1641 filter = &mfilter->u.cfilter;
1642
1643 if (write)
1644 {
1645 vty_out (vty, "%s IP%s access list %s%s",
1646 mfilter->cisco ?
1647 (filter->extended ? "Extended" : "Standard") : "Zebra",
1648 afi == AFI_IP6 ? "v6" : "",
1649 access->name, VTY_NEWLINE);
1650 write = 0;
1651 }
1652
1653 vty_out (vty, " %s%s", filter_type_str (mfilter),
1654 mfilter->type == FILTER_DENY ? " " : "");
1655
1656 if (! mfilter->cisco)
1657 config_write_access_zebra (vty, mfilter);
1658 else if (filter->extended)
1659 config_write_access_cisco (vty, mfilter);
1660 else
1661 {
1662 if (filter->addr_mask.s_addr == 0xffffffff)
1663 vty_out (vty, " any%s", VTY_NEWLINE);
1664 else
1665 {
1666 vty_out (vty, " %s", inet_ntoa (filter->addr));
1667 if (filter->addr_mask.s_addr != 0)
1668 vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1669 vty_out (vty, "%s", VTY_NEWLINE);
1670 }
1671 }
1672 }
1673 }
1674 return CMD_SUCCESS;
1675}
1676
1677DEFUN (show_ip_access_list,
1678 show_ip_access_list_cmd,
1679 "show ip access-list",
1680 SHOW_STR
1681 IP_STR
1682 "List IP access lists\n")
1683{
1684 return filter_show (vty, NULL, AFI_IP);
1685}
1686
1687DEFUN (show_ip_access_list_name,
1688 show_ip_access_list_name_cmd,
1689 "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1690 SHOW_STR
1691 IP_STR
1692 "List IP access lists\n"
1693 "IP standard access list\n"
1694 "IP extended access list\n"
1695 "IP standard access list (expanded range)\n"
1696 "IP extended access list (expanded range)\n"
1697 "IP zebra access-list\n")
1698{
1699 return filter_show (vty, argv[0], AFI_IP);
1700}
1701
1702#ifdef HAVE_IPV6
1703DEFUN (show_ipv6_access_list,
1704 show_ipv6_access_list_cmd,
1705 "show ipv6 access-list",
1706 SHOW_STR
1707 IPV6_STR
1708 "List IPv6 access lists\n")
1709{
1710 return filter_show (vty, NULL, AFI_IP6);
1711}
1712
1713DEFUN (show_ipv6_access_list_name,
1714 show_ipv6_access_list_name_cmd,
1715 "show ipv6 access-list WORD",
1716 SHOW_STR
1717 IPV6_STR
1718 "List IPv6 access lists\n"
1719 "IPv6 zebra access-list\n")
1720{
1721 return filter_show (vty, argv[0], AFI_IP6);
1722}
1723#endif /* HAVE_IPV6 */
1724
1725void
1726config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1727{
1728 struct filter_cisco *filter;
1729
1730 filter = &mfilter->u.cfilter;
1731
1732 if (filter->extended)
1733 {
1734 vty_out (vty, " ip");
1735 if (filter->addr_mask.s_addr == 0xffffffff)
1736 vty_out (vty, " any");
1737 else if (filter->addr_mask.s_addr == 0)
1738 vty_out (vty, " host %s", inet_ntoa (filter->addr));
1739 else
1740 {
1741 vty_out (vty, " %s", inet_ntoa (filter->addr));
1742 vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1743 }
1744
1745 if (filter->mask_mask.s_addr == 0xffffffff)
1746 vty_out (vty, " any");
1747 else if (filter->mask_mask.s_addr == 0)
1748 vty_out (vty, " host %s", inet_ntoa (filter->mask));
1749 else
1750 {
1751 vty_out (vty, " %s", inet_ntoa (filter->mask));
1752 vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1753 }
1754 vty_out (vty, "%s", VTY_NEWLINE);
1755 }
1756 else
1757 {
1758 if (filter->addr_mask.s_addr == 0xffffffff)
1759 vty_out (vty, " any%s", VTY_NEWLINE);
1760 else
1761 {
1762 vty_out (vty, " %s", inet_ntoa (filter->addr));
1763 if (filter->addr_mask.s_addr != 0)
1764 vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1765 vty_out (vty, "%s", VTY_NEWLINE);
1766 }
1767 }
1768}
1769
1770void
1771config_write_access_zebra (struct vty *vty, struct filter *mfilter)
1772{
1773 struct filter_zebra *filter;
1774 struct prefix *p;
1775 char buf[BUFSIZ];
1776
1777 filter = &mfilter->u.zfilter;
1778 p = &filter->prefix;
1779
1780 if (p->prefixlen == 0 && ! filter->exact)
1781 vty_out (vty, " any");
1782 else
1783 vty_out (vty, " %s/%d%s",
1784 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1785 p->prefixlen,
1786 filter->exact ? " exact-match" : "");
1787
1788 vty_out (vty, "%s", VTY_NEWLINE);
1789}
1790
paul8cc41982005-05-06 21:25:49 +00001791static int
paul718e3742002-12-13 20:15:29 +00001792config_write_access (struct vty *vty, afi_t afi)
1793{
1794 struct access_list *access;
1795 struct access_master *master;
1796 struct filter *mfilter;
1797 int write = 0;
1798
1799 master = access_master_get (afi);
1800 if (master == NULL)
1801 return 0;
1802
1803 for (access = master->num.head; access; access = access->next)
1804 {
1805 if (access->remark)
1806 {
1807 vty_out (vty, "%saccess-list %s remark %s%s",
1808 afi == AFI_IP ? "" : "ipv6 ",
1809 access->name, access->remark,
1810 VTY_NEWLINE);
1811 write++;
1812 }
1813
1814 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1815 {
1816 vty_out (vty, "%saccess-list %s %s",
1817 afi == AFI_IP ? "" : "ipv6 ",
1818 access->name,
1819 filter_type_str (mfilter));
1820
1821 if (mfilter->cisco)
1822 config_write_access_cisco (vty, mfilter);
1823 else
1824 config_write_access_zebra (vty, mfilter);
1825
1826 write++;
1827 }
1828 }
1829
1830 for (access = master->str.head; access; access = access->next)
1831 {
1832 if (access->remark)
1833 {
1834 vty_out (vty, "%saccess-list %s remark %s%s",
1835 afi == AFI_IP ? "" : "ipv6 ",
1836 access->name, access->remark,
1837 VTY_NEWLINE);
1838 write++;
1839 }
1840
1841 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1842 {
1843 vty_out (vty, "%saccess-list %s %s",
1844 afi == AFI_IP ? "" : "ipv6 ",
1845 access->name,
1846 filter_type_str (mfilter));
1847
1848 if (mfilter->cisco)
1849 config_write_access_cisco (vty, mfilter);
1850 else
1851 config_write_access_zebra (vty, mfilter);
1852
1853 write++;
1854 }
1855 }
1856 return write;
1857}
1858
1859/* Access-list node. */
1860struct cmd_node access_node =
1861{
1862 ACCESS_NODE,
1863 "", /* Access list has no interface. */
1864 1
1865};
1866
paul8cc41982005-05-06 21:25:49 +00001867static int
paul718e3742002-12-13 20:15:29 +00001868config_write_access_ipv4 (struct vty *vty)
1869{
1870 return config_write_access (vty, AFI_IP);
1871}
1872
paul8cc41982005-05-06 21:25:49 +00001873static void
1874access_list_reset_ipv4 (void)
paul718e3742002-12-13 20:15:29 +00001875{
1876 struct access_list *access;
1877 struct access_list *next;
1878 struct access_master *master;
1879
1880 master = access_master_get (AFI_IP);
1881 if (master == NULL)
1882 return;
1883
1884 for (access = master->num.head; access; access = next)
1885 {
1886 next = access->next;
1887 access_list_delete (access);
1888 }
1889 for (access = master->str.head; access; access = next)
1890 {
1891 next = access->next;
1892 access_list_delete (access);
1893 }
1894
1895 assert (master->num.head == NULL);
1896 assert (master->num.tail == NULL);
1897
1898 assert (master->str.head == NULL);
1899 assert (master->str.tail == NULL);
1900}
1901
1902/* Install vty related command. */
paul8cc41982005-05-06 21:25:49 +00001903static void
1904access_list_init_ipv4 (void)
paul718e3742002-12-13 20:15:29 +00001905{
1906 install_node (&access_node, config_write_access_ipv4);
1907
1908 install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1909 install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
1910
1911 /* Zebra access-list */
1912 install_element (CONFIG_NODE, &access_list_cmd);
1913 install_element (CONFIG_NODE, &access_list_exact_cmd);
1914 install_element (CONFIG_NODE, &access_list_any_cmd);
1915 install_element (CONFIG_NODE, &no_access_list_cmd);
1916 install_element (CONFIG_NODE, &no_access_list_exact_cmd);
1917 install_element (CONFIG_NODE, &no_access_list_any_cmd);
1918
1919 /* Standard access-list */
1920 install_element (CONFIG_NODE, &access_list_standard_cmd);
1921 install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
1922 install_element (CONFIG_NODE, &access_list_standard_host_cmd);
1923 install_element (CONFIG_NODE, &access_list_standard_any_cmd);
1924 install_element (CONFIG_NODE, &no_access_list_standard_cmd);
1925 install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
1926 install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
1927 install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
1928
1929 /* Extended access-list */
1930 install_element (CONFIG_NODE, &access_list_extended_cmd);
1931 install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
1932 install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
1933 install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
1934 install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
1935 install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
1936 install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
1937 install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
1938 install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
1939 install_element (CONFIG_NODE, &no_access_list_extended_cmd);
1940 install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
1941 install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
1942 install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
1943 install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
1944 install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
1945 install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
1946 install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
1947 install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
1948
1949 install_element (CONFIG_NODE, &access_list_remark_cmd);
1950 install_element (CONFIG_NODE, &no_access_list_all_cmd);
1951 install_element (CONFIG_NODE, &no_access_list_remark_cmd);
1952 install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
1953}
1954
1955#ifdef HAVE_IPV6
1956struct cmd_node access_ipv6_node =
1957{
1958 ACCESS_IPV6_NODE,
1959 "",
1960 1
1961};
1962
paul8cc41982005-05-06 21:25:49 +00001963static int
paul718e3742002-12-13 20:15:29 +00001964config_write_access_ipv6 (struct vty *vty)
1965{
1966 return config_write_access (vty, AFI_IP6);
1967}
1968
paul8cc41982005-05-06 21:25:49 +00001969static void
1970access_list_reset_ipv6 (void)
paul718e3742002-12-13 20:15:29 +00001971{
1972 struct access_list *access;
1973 struct access_list *next;
1974 struct access_master *master;
1975
1976 master = access_master_get (AFI_IP6);
1977 if (master == NULL)
1978 return;
1979
1980 for (access = master->num.head; access; access = next)
1981 {
1982 next = access->next;
1983 access_list_delete (access);
1984 }
1985 for (access = master->str.head; access; access = next)
1986 {
1987 next = access->next;
1988 access_list_delete (access);
1989 }
1990
1991 assert (master->num.head == NULL);
1992 assert (master->num.tail == NULL);
1993
1994 assert (master->str.head == NULL);
1995 assert (master->str.tail == NULL);
1996}
1997
paul8cc41982005-05-06 21:25:49 +00001998static void
1999access_list_init_ipv6 (void)
paul718e3742002-12-13 20:15:29 +00002000{
2001 install_node (&access_ipv6_node, config_write_access_ipv6);
2002
2003 install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
2004 install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
2005
2006 install_element (CONFIG_NODE, &ipv6_access_list_cmd);
2007 install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
2008 install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
2009 install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2010 install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
2011 install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2012
2013 install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
2014 install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
2015 install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
2016 install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
2017}
2018#endif /* HAVE_IPV6 */
2019
2020void
2021access_list_init ()
2022{
2023 access_list_init_ipv4 ();
2024#ifdef HAVE_IPV6
2025 access_list_init_ipv6();
2026#endif /* HAVE_IPV6 */
2027}
2028
2029void
2030access_list_reset ()
2031{
2032 access_list_reset_ipv4 ();
2033#ifdef HAVE_IPV6
2034 access_list_reset_ipv6();
2035#endif /* HAVE_IPV6 */
2036}