blob: 55bcdf4bb893b3b5f4813d3f0d27ee1d26a82a81 [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"
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. */
paul8cc41982005-05-06 21:25:49 +000087 void (*add_hook) (struct access_list *);
paul718e3742002-12-13 20:15:29 +000088
89 /* Hook function which is executed when access_list is deleted. */
paul8cc41982005-05-06 21:25:49 +000090 void (*delete_hook) (struct access_list *);
paul718e3742002-12-13 20:15:29 +000091};
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
paul8cc41982005-05-06 21:25:49 +0000113static struct access_master *
paul718e3742002-12-13 20:15:29 +0000114access_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. */
paul8cc41982005-05-06 21:25:49 +0000126static struct filter *
127filter_new (void)
paul718e3742002-12-13 20:15:29 +0000128{
129 return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
130 sizeof (struct filter));
131}
132
paul8cc41982005-05-06 21:25:49 +0000133static void
paul718e3742002-12-13 20:15:29 +0000134filter_free (struct filter *filter)
135{
136 XFREE (MTYPE_ACCESS_FILTER, filter);
137}
138
139/* Return string of filter_type. */
hasso8c328f12004-10-05 21:01:23 +0000140const static char *
paul718e3742002-12-13 20:15:29 +0000141filter_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
211/* Allocate new access list structure. */
paul8cc41982005-05-06 21:25:49 +0000212static struct access_list *
213access_list_new (void)
paul718e3742002-12-13 20:15:29 +0000214{
215 return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
216 sizeof (struct access_list));
217}
218
219/* Free allocated access_list. */
paul8cc41982005-05-06 21:25:49 +0000220static void
paul718e3742002-12-13 20:15:29 +0000221access_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. */
paul8cc41982005-05-06 21:25:49 +0000227static void
paul718e3742002-12-13 20:15:29 +0000228access_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. */
paul8cc41982005-05-06 21:25:49 +0000269static struct access_list *
hasso8c328f12004-10-05 21:01:23 +0000270access_list_insert (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000271{
hasso8c328f12004-10-05 21:01:23 +0000272 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000273 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 *
hasso8c328f12004-10-05 21:01:23 +0000361access_list_lookup (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000362{
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. */
paul8cc41982005-05-06 21:25:49 +0000386static struct access_list *
hasso8c328f12004-10-05 21:01:23 +0000387access_list_get (afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000388{
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. */
paul8cc41982005-05-06 21:25:49 +0000447static void
paul718e3742002-12-13 20:15:29 +0000448access_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. */
paul8cc41982005-05-06 21:25:49 +0000476static void
paul718e3742002-12-13 20:15:29 +0000477access_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
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
paul8cc41982005-05-06 21:25:49 +0000516static struct filter *
paul718e3742002-12-13 20:15:29 +0000517filter_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
paul8cc41982005-05-06 21:25:49 +0000550static struct filter *
paul718e3742002-12-13 20:15:29 +0000551filter_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
paul8cc41982005-05-06 21:25:49 +0000571static int
paul9035efa2004-10-10 11:56:56 +0000572vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
paul718e3742002-12-13 20:15:29 +0000573{
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
paul8cc41982005-05-06 21:25:49 +0000596static int
paul9035efa2004-10-10 11:56:56 +0000597filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
hasso8c328f12004-10-05 21:01:23 +0000598 const char *addr_str, const char *addr_mask_str,
599 const char *mask_str, const char *mask_mask_str,
paul718e3742002-12-13 20:15:29 +0000600 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
paul8cc41982005-05-06 21:25:49 +00001155static int
hasso8c328f12004-10-05 21:01:23 +00001156filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
1157 afi_t afi, const char *prefix_str, int exact, int set)
paul718e3742002-12-13 20:15:29 +00001158{
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;
paul718e3742002-12-13 20:15:29 +00001362
1363 access = access_list_get (AFI_IP, argv[0]);
1364
1365 if (access->remark)
1366 {
1367 XFREE (MTYPE_TMP, access->remark);
1368 access->remark = NULL;
1369 }
ajs3b8b1852005-01-29 18:19:13 +00001370 access->remark = argv_concat(argv, argc, 1);
paul718e3742002-12-13 20:15:29 +00001371
1372 return CMD_SUCCESS;
1373}
1374
1375DEFUN (no_access_list_remark,
1376 no_access_list_remark_cmd,
1377 "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
1378 NO_STR
1379 "Add an access list entry\n"
1380 "IP standard access list\n"
1381 "IP extended access list\n"
1382 "IP standard access list (expanded range)\n"
1383 "IP extended access list (expanded range)\n"
1384 "IP zebra access-list\n"
1385 "Access list entry comment\n")
1386{
1387 return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
1388}
1389
1390ALIAS (no_access_list_remark,
1391 no_access_list_remark_arg_cmd,
1392 "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
1393 NO_STR
1394 "Add an access list entry\n"
1395 "IP standard access list\n"
1396 "IP extended access list\n"
1397 "IP standard access list (expanded range)\n"
1398 "IP extended access list (expanded range)\n"
1399 "IP zebra access-list\n"
1400 "Access list entry comment\n"
1401 "Comment up to 100 characters\n")
1402
1403#ifdef HAVE_IPV6
1404DEFUN (ipv6_access_list,
1405 ipv6_access_list_cmd,
1406 "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1407 IPV6_STR
1408 "Add an access list entry\n"
1409 "IPv6 zebra access-list\n"
1410 "Specify packets to reject\n"
1411 "Specify packets to forward\n"
1412 "Prefix to match. e.g. 3ffe:506::/32\n")
1413{
1414 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
1415}
1416
1417DEFUN (ipv6_access_list_exact,
1418 ipv6_access_list_exact_cmd,
1419 "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
1420 IPV6_STR
1421 "Add an access list entry\n"
1422 "IPv6 zebra access-list\n"
1423 "Specify packets to reject\n"
1424 "Specify packets to forward\n"
1425 "Prefix to match. e.g. 3ffe:506::/32\n"
1426 "Exact match of the prefixes\n")
1427{
1428 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
1429}
1430
1431DEFUN (ipv6_access_list_any,
1432 ipv6_access_list_any_cmd,
1433 "ipv6 access-list WORD (deny|permit) any",
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 "Any prefixi to match\n")
1440{
1441 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
1442}
1443
1444DEFUN (no_ipv6_access_list,
1445 no_ipv6_access_list_cmd,
1446 "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
1447 NO_STR
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 "Prefix to match. e.g. 3ffe:506::/32\n")
1454{
1455 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
1456}
1457
1458DEFUN (no_ipv6_access_list_exact,
1459 no_ipv6_access_list_exact_cmd,
1460 "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
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 "Exact match of the prefixes\n")
1469{
1470 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
1471}
1472
1473DEFUN (no_ipv6_access_list_any,
1474 no_ipv6_access_list_any_cmd,
1475 "no ipv6 access-list WORD (deny|permit) any",
1476 NO_STR
1477 IPV6_STR
1478 "Add an access list entry\n"
1479 "IPv6 zebra access-list\n"
1480 "Specify packets to reject\n"
1481 "Specify packets to forward\n"
1482 "Any prefixi to match\n")
1483{
1484 return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
1485}
1486
1487
1488DEFUN (no_ipv6_access_list_all,
1489 no_ipv6_access_list_all_cmd,
1490 "no ipv6 access-list WORD",
1491 NO_STR
1492 IPV6_STR
1493 "Add an access list entry\n"
1494 "IPv6 zebra access-list\n")
1495{
1496 struct access_list *access;
1497 struct access_master *master;
1498
1499 /* Looking up access_list. */
1500 access = access_list_lookup (AFI_IP6, argv[0]);
1501 if (access == NULL)
1502 {
1503 vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1504 VTY_NEWLINE);
1505 return CMD_WARNING;
1506 }
1507
1508 master = access->master;
1509
1510 /* Delete all filter from access-list. */
1511 access_list_delete (access);
1512
1513 /* Run hook function. */
1514 if (master->delete_hook)
1515 (*master->delete_hook) (access);
1516
1517 return CMD_SUCCESS;
1518}
1519
1520DEFUN (ipv6_access_list_remark,
1521 ipv6_access_list_remark_cmd,
1522 "ipv6 access-list WORD remark .LINE",
1523 IPV6_STR
1524 "Add an access list entry\n"
1525 "IPv6 zebra access-list\n"
1526 "Access list entry comment\n"
1527 "Comment up to 100 characters\n")
1528{
1529 struct access_list *access;
paul718e3742002-12-13 20:15:29 +00001530
1531 access = access_list_get (AFI_IP6, argv[0]);
1532
1533 if (access->remark)
1534 {
1535 XFREE (MTYPE_TMP, access->remark);
1536 access->remark = NULL;
1537 }
ajs3b8b1852005-01-29 18:19:13 +00001538 access->remark = argv_concat(argv, argc, 1);
paul718e3742002-12-13 20:15:29 +00001539
1540 return CMD_SUCCESS;
1541}
1542
1543DEFUN (no_ipv6_access_list_remark,
1544 no_ipv6_access_list_remark_cmd,
1545 "no ipv6 access-list WORD remark",
1546 NO_STR
1547 IPV6_STR
1548 "Add an access list entry\n"
1549 "IPv6 zebra access-list\n"
1550 "Access list entry comment\n")
1551{
1552 return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
1553}
1554
1555ALIAS (no_ipv6_access_list_remark,
1556 no_ipv6_access_list_remark_arg_cmd,
1557 "no ipv6 access-list WORD remark .LINE",
1558 NO_STR
1559 IPV6_STR
1560 "Add an access list entry\n"
1561 "IPv6 zebra access-list\n"
1562 "Access list entry comment\n"
1563 "Comment up to 100 characters\n")
1564#endif /* HAVE_IPV6 */
1565
1566void config_write_access_zebra (struct vty *, struct filter *);
1567void config_write_access_cisco (struct vty *, struct filter *);
1568
1569/* show access-list command. */
paul8cc41982005-05-06 21:25:49 +00001570static int
paul9035efa2004-10-10 11:56:56 +00001571filter_show (struct vty *vty, const char *name, afi_t afi)
paul718e3742002-12-13 20:15:29 +00001572{
1573 struct access_list *access;
1574 struct access_master *master;
1575 struct filter *mfilter;
1576 struct filter_cisco *filter;
1577 int write = 0;
1578
1579 master = access_master_get (afi);
1580 if (master == NULL)
1581 return 0;
1582
1583 for (access = master->num.head; access; access = access->next)
1584 {
1585 if (name && strcmp (access->name, name) != 0)
1586 continue;
1587
1588 write = 1;
1589
1590 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1591 {
1592 filter = &mfilter->u.cfilter;
1593
1594 if (write)
1595 {
1596 vty_out (vty, "%s IP%s access list %s%s",
1597 mfilter->cisco ?
1598 (filter->extended ? "Extended" : "Standard") : "Zebra",
1599 afi == AFI_IP6 ? "v6" : "",
1600 access->name, VTY_NEWLINE);
1601 write = 0;
1602 }
1603
1604 vty_out (vty, " %s%s", filter_type_str (mfilter),
1605 mfilter->type == FILTER_DENY ? " " : "");
1606
1607 if (! mfilter->cisco)
1608 config_write_access_zebra (vty, mfilter);
1609 else if (filter->extended)
1610 config_write_access_cisco (vty, mfilter);
1611 else
1612 {
1613 if (filter->addr_mask.s_addr == 0xffffffff)
1614 vty_out (vty, " any%s", VTY_NEWLINE);
1615 else
1616 {
1617 vty_out (vty, " %s", inet_ntoa (filter->addr));
1618 if (filter->addr_mask.s_addr != 0)
1619 vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1620 vty_out (vty, "%s", VTY_NEWLINE);
1621 }
1622 }
1623 }
1624 }
1625
1626 for (access = master->str.head; access; access = access->next)
1627 {
1628 if (name && strcmp (access->name, name) != 0)
1629 continue;
1630
1631 write = 1;
1632
1633 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1634 {
1635 filter = &mfilter->u.cfilter;
1636
1637 if (write)
1638 {
1639 vty_out (vty, "%s IP%s access list %s%s",
1640 mfilter->cisco ?
1641 (filter->extended ? "Extended" : "Standard") : "Zebra",
1642 afi == AFI_IP6 ? "v6" : "",
1643 access->name, VTY_NEWLINE);
1644 write = 0;
1645 }
1646
1647 vty_out (vty, " %s%s", filter_type_str (mfilter),
1648 mfilter->type == FILTER_DENY ? " " : "");
1649
1650 if (! mfilter->cisco)
1651 config_write_access_zebra (vty, mfilter);
1652 else if (filter->extended)
1653 config_write_access_cisco (vty, mfilter);
1654 else
1655 {
1656 if (filter->addr_mask.s_addr == 0xffffffff)
1657 vty_out (vty, " any%s", VTY_NEWLINE);
1658 else
1659 {
1660 vty_out (vty, " %s", inet_ntoa (filter->addr));
1661 if (filter->addr_mask.s_addr != 0)
1662 vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1663 vty_out (vty, "%s", VTY_NEWLINE);
1664 }
1665 }
1666 }
1667 }
1668 return CMD_SUCCESS;
1669}
1670
1671DEFUN (show_ip_access_list,
1672 show_ip_access_list_cmd,
1673 "show ip access-list",
1674 SHOW_STR
1675 IP_STR
1676 "List IP access lists\n")
1677{
1678 return filter_show (vty, NULL, AFI_IP);
1679}
1680
1681DEFUN (show_ip_access_list_name,
1682 show_ip_access_list_name_cmd,
1683 "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
1684 SHOW_STR
1685 IP_STR
1686 "List IP access lists\n"
1687 "IP standard access list\n"
1688 "IP extended access list\n"
1689 "IP standard access list (expanded range)\n"
1690 "IP extended access list (expanded range)\n"
1691 "IP zebra access-list\n")
1692{
1693 return filter_show (vty, argv[0], AFI_IP);
1694}
1695
1696#ifdef HAVE_IPV6
1697DEFUN (show_ipv6_access_list,
1698 show_ipv6_access_list_cmd,
1699 "show ipv6 access-list",
1700 SHOW_STR
1701 IPV6_STR
1702 "List IPv6 access lists\n")
1703{
1704 return filter_show (vty, NULL, AFI_IP6);
1705}
1706
1707DEFUN (show_ipv6_access_list_name,
1708 show_ipv6_access_list_name_cmd,
1709 "show ipv6 access-list WORD",
1710 SHOW_STR
1711 IPV6_STR
1712 "List IPv6 access lists\n"
1713 "IPv6 zebra access-list\n")
1714{
1715 return filter_show (vty, argv[0], AFI_IP6);
1716}
1717#endif /* HAVE_IPV6 */
1718
1719void
1720config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1721{
1722 struct filter_cisco *filter;
1723
1724 filter = &mfilter->u.cfilter;
1725
1726 if (filter->extended)
1727 {
1728 vty_out (vty, " ip");
1729 if (filter->addr_mask.s_addr == 0xffffffff)
1730 vty_out (vty, " any");
1731 else if (filter->addr_mask.s_addr == 0)
1732 vty_out (vty, " host %s", inet_ntoa (filter->addr));
1733 else
1734 {
1735 vty_out (vty, " %s", inet_ntoa (filter->addr));
1736 vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1737 }
1738
1739 if (filter->mask_mask.s_addr == 0xffffffff)
1740 vty_out (vty, " any");
1741 else if (filter->mask_mask.s_addr == 0)
1742 vty_out (vty, " host %s", inet_ntoa (filter->mask));
1743 else
1744 {
1745 vty_out (vty, " %s", inet_ntoa (filter->mask));
1746 vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1747 }
1748 vty_out (vty, "%s", VTY_NEWLINE);
1749 }
1750 else
1751 {
1752 if (filter->addr_mask.s_addr == 0xffffffff)
1753 vty_out (vty, " any%s", VTY_NEWLINE);
1754 else
1755 {
1756 vty_out (vty, " %s", inet_ntoa (filter->addr));
1757 if (filter->addr_mask.s_addr != 0)
1758 vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1759 vty_out (vty, "%s", VTY_NEWLINE);
1760 }
1761 }
1762}
1763
1764void
1765config_write_access_zebra (struct vty *vty, struct filter *mfilter)
1766{
1767 struct filter_zebra *filter;
1768 struct prefix *p;
1769 char buf[BUFSIZ];
1770
1771 filter = &mfilter->u.zfilter;
1772 p = &filter->prefix;
1773
1774 if (p->prefixlen == 0 && ! filter->exact)
1775 vty_out (vty, " any");
1776 else
1777 vty_out (vty, " %s/%d%s",
1778 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1779 p->prefixlen,
1780 filter->exact ? " exact-match" : "");
1781
1782 vty_out (vty, "%s", VTY_NEWLINE);
1783}
1784
paul8cc41982005-05-06 21:25:49 +00001785static int
paul718e3742002-12-13 20:15:29 +00001786config_write_access (struct vty *vty, afi_t afi)
1787{
1788 struct access_list *access;
1789 struct access_master *master;
1790 struct filter *mfilter;
1791 int write = 0;
1792
1793 master = access_master_get (afi);
1794 if (master == NULL)
1795 return 0;
1796
1797 for (access = master->num.head; access; access = access->next)
1798 {
1799 if (access->remark)
1800 {
1801 vty_out (vty, "%saccess-list %s remark %s%s",
1802 afi == AFI_IP ? "" : "ipv6 ",
1803 access->name, access->remark,
1804 VTY_NEWLINE);
1805 write++;
1806 }
1807
1808 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1809 {
1810 vty_out (vty, "%saccess-list %s %s",
1811 afi == AFI_IP ? "" : "ipv6 ",
1812 access->name,
1813 filter_type_str (mfilter));
1814
1815 if (mfilter->cisco)
1816 config_write_access_cisco (vty, mfilter);
1817 else
1818 config_write_access_zebra (vty, mfilter);
1819
1820 write++;
1821 }
1822 }
1823
1824 for (access = master->str.head; access; access = access->next)
1825 {
1826 if (access->remark)
1827 {
1828 vty_out (vty, "%saccess-list %s remark %s%s",
1829 afi == AFI_IP ? "" : "ipv6 ",
1830 access->name, access->remark,
1831 VTY_NEWLINE);
1832 write++;
1833 }
1834
1835 for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1836 {
1837 vty_out (vty, "%saccess-list %s %s",
1838 afi == AFI_IP ? "" : "ipv6 ",
1839 access->name,
1840 filter_type_str (mfilter));
1841
1842 if (mfilter->cisco)
1843 config_write_access_cisco (vty, mfilter);
1844 else
1845 config_write_access_zebra (vty, mfilter);
1846
1847 write++;
1848 }
1849 }
1850 return write;
1851}
1852
1853/* Access-list node. */
1854struct cmd_node access_node =
1855{
1856 ACCESS_NODE,
1857 "", /* Access list has no interface. */
1858 1
1859};
1860
paul8cc41982005-05-06 21:25:49 +00001861static int
paul718e3742002-12-13 20:15:29 +00001862config_write_access_ipv4 (struct vty *vty)
1863{
1864 return config_write_access (vty, AFI_IP);
1865}
1866
paul8cc41982005-05-06 21:25:49 +00001867static void
1868access_list_reset_ipv4 (void)
paul718e3742002-12-13 20:15:29 +00001869{
1870 struct access_list *access;
1871 struct access_list *next;
1872 struct access_master *master;
1873
1874 master = access_master_get (AFI_IP);
1875 if (master == NULL)
1876 return;
1877
1878 for (access = master->num.head; access; access = next)
1879 {
1880 next = access->next;
1881 access_list_delete (access);
1882 }
1883 for (access = master->str.head; access; access = next)
1884 {
1885 next = access->next;
1886 access_list_delete (access);
1887 }
1888
1889 assert (master->num.head == NULL);
1890 assert (master->num.tail == NULL);
1891
1892 assert (master->str.head == NULL);
1893 assert (master->str.tail == NULL);
1894}
1895
1896/* Install vty related command. */
paul8cc41982005-05-06 21:25:49 +00001897static void
1898access_list_init_ipv4 (void)
paul718e3742002-12-13 20:15:29 +00001899{
1900 install_node (&access_node, config_write_access_ipv4);
1901
1902 install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1903 install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
1904
1905 /* Zebra access-list */
1906 install_element (CONFIG_NODE, &access_list_cmd);
1907 install_element (CONFIG_NODE, &access_list_exact_cmd);
1908 install_element (CONFIG_NODE, &access_list_any_cmd);
1909 install_element (CONFIG_NODE, &no_access_list_cmd);
1910 install_element (CONFIG_NODE, &no_access_list_exact_cmd);
1911 install_element (CONFIG_NODE, &no_access_list_any_cmd);
1912
1913 /* Standard access-list */
1914 install_element (CONFIG_NODE, &access_list_standard_cmd);
1915 install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
1916 install_element (CONFIG_NODE, &access_list_standard_host_cmd);
1917 install_element (CONFIG_NODE, &access_list_standard_any_cmd);
1918 install_element (CONFIG_NODE, &no_access_list_standard_cmd);
1919 install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
1920 install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
1921 install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
1922
1923 /* Extended access-list */
1924 install_element (CONFIG_NODE, &access_list_extended_cmd);
1925 install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
1926 install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
1927 install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
1928 install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
1929 install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
1930 install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
1931 install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
1932 install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
1933 install_element (CONFIG_NODE, &no_access_list_extended_cmd);
1934 install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
1935 install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
1936 install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
1937 install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
1938 install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
1939 install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
1940 install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
1941 install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
1942
1943 install_element (CONFIG_NODE, &access_list_remark_cmd);
1944 install_element (CONFIG_NODE, &no_access_list_all_cmd);
1945 install_element (CONFIG_NODE, &no_access_list_remark_cmd);
1946 install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
1947}
1948
1949#ifdef HAVE_IPV6
1950struct cmd_node access_ipv6_node =
1951{
1952 ACCESS_IPV6_NODE,
1953 "",
1954 1
1955};
1956
paul8cc41982005-05-06 21:25:49 +00001957static int
paul718e3742002-12-13 20:15:29 +00001958config_write_access_ipv6 (struct vty *vty)
1959{
1960 return config_write_access (vty, AFI_IP6);
1961}
1962
paul8cc41982005-05-06 21:25:49 +00001963static void
1964access_list_reset_ipv6 (void)
paul718e3742002-12-13 20:15:29 +00001965{
1966 struct access_list *access;
1967 struct access_list *next;
1968 struct access_master *master;
1969
1970 master = access_master_get (AFI_IP6);
1971 if (master == NULL)
1972 return;
1973
1974 for (access = master->num.head; access; access = next)
1975 {
1976 next = access->next;
1977 access_list_delete (access);
1978 }
1979 for (access = master->str.head; access; access = next)
1980 {
1981 next = access->next;
1982 access_list_delete (access);
1983 }
1984
1985 assert (master->num.head == NULL);
1986 assert (master->num.tail == NULL);
1987
1988 assert (master->str.head == NULL);
1989 assert (master->str.tail == NULL);
1990}
1991
paul8cc41982005-05-06 21:25:49 +00001992static void
1993access_list_init_ipv6 (void)
paul718e3742002-12-13 20:15:29 +00001994{
1995 install_node (&access_ipv6_node, config_write_access_ipv6);
1996
1997 install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
1998 install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
1999
2000 install_element (CONFIG_NODE, &ipv6_access_list_cmd);
2001 install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
2002 install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
2003 install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2004 install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
2005 install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2006
2007 install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
2008 install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
2009 install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
2010 install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
2011}
2012#endif /* HAVE_IPV6 */
2013
2014void
2015access_list_init ()
2016{
2017 access_list_init_ipv4 ();
2018#ifdef HAVE_IPV6
2019 access_list_init_ipv6();
2020#endif /* HAVE_IPV6 */
2021}
2022
2023void
2024access_list_reset ()
2025{
2026 access_list_reset_ipv4 ();
2027#ifdef HAVE_IPV6
2028 access_list_reset_ipv6();
2029#endif /* HAVE_IPV6 */
2030}