Line data Source code
1 : /* Route filtering function.
2 : * Copyright (C) 1998, 1999 Kunihiro Ishiguro
3 : *
4 : * This file is part of GNU Zebra.
5 : *
6 : * GNU Zebra is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published
8 : * by the Free Software Foundation; either version 2, or (at your
9 : * option) any later version.
10 : *
11 : * GNU Zebra is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with GNU Zebra; see the file COPYING. If not, write to the
18 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 : * Boston, MA 02111-1307, USA.
20 : */
21 :
22 : #include <zebra.h>
23 :
24 : #include "prefix.h"
25 : #include "filter.h"
26 : #include "memory.h"
27 : #include "command.h"
28 : #include "sockunion.h"
29 : #include "buffer.h"
30 : #include "log.h"
31 :
32 : struct filter_cisco
33 : {
34 : /* Cisco access-list */
35 : int extended;
36 : struct in_addr addr;
37 : struct in_addr addr_mask;
38 : struct in_addr mask;
39 : struct in_addr mask_mask;
40 : };
41 :
42 : struct filter_zebra
43 : {
44 : /* If this filter is "exact" match then this flag is set. */
45 : int exact;
46 :
47 : /* Prefix information. */
48 : struct prefix prefix;
49 : };
50 :
51 : /* Filter element of access list */
52 : struct filter
53 : {
54 : /* For doubly linked list. */
55 : struct filter *next;
56 : struct filter *prev;
57 :
58 : /* Filter type information. */
59 : enum filter_type type;
60 :
61 : /* Cisco access-list */
62 : int cisco;
63 :
64 : union
65 : {
66 : struct filter_cisco cfilter;
67 : struct filter_zebra zfilter;
68 : } u;
69 : };
70 :
71 : /* List of access_list. */
72 : struct access_list_list
73 : {
74 : struct access_list *head;
75 : struct access_list *tail;
76 : };
77 :
78 : /* Master structure of access_list. */
79 : struct access_master
80 : {
81 : /* List of access_list which name is number. */
82 : struct access_list_list num;
83 :
84 : /* List of access_list which name is string. */
85 : struct access_list_list str;
86 :
87 : /* Hook function which is executed when new access_list is added. */
88 : void (*add_hook) (struct access_list *);
89 :
90 : /* Hook function which is executed when access_list is deleted. */
91 : void (*delete_hook) (struct access_list *);
92 : };
93 :
94 : /* Static structure for IPv4 access_list's master. */
95 : static struct access_master access_master_ipv4 =
96 : {
97 : {NULL, NULL},
98 : {NULL, NULL},
99 : NULL,
100 : NULL,
101 : };
102 :
103 : #ifdef HAVE_IPV6
104 : /* Static structure for IPv6 access_list's master. */
105 : static struct access_master access_master_ipv6 =
106 : {
107 : {NULL, NULL},
108 : {NULL, NULL},
109 : NULL,
110 : NULL,
111 : };
112 : #endif /* HAVE_IPV6 */
113 :
114 : static struct access_master *
115 16 : access_master_get (afi_t afi)
116 : {
117 16 : if (afi == AFI_IP)
118 16 : return &access_master_ipv4;
119 : #ifdef HAVE_IPV6
120 0 : else if (afi == AFI_IP6)
121 0 : return &access_master_ipv6;
122 : #endif /* HAVE_IPV6 */
123 0 : return NULL;
124 : }
125 :
126 : /* Allocate new filter structure. */
127 : static struct filter *
128 4 : filter_new (void)
129 : {
130 4 : return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
131 : sizeof (struct filter));
132 : }
133 :
134 : static void
135 0 : filter_free (struct filter *filter)
136 : {
137 0 : XFREE (MTYPE_ACCESS_FILTER, filter);
138 0 : }
139 :
140 : /* Return string of filter_type. */
141 : static const char *
142 0 : filter_type_str (struct filter *filter)
143 : {
144 0 : switch (filter->type)
145 : {
146 : case FILTER_PERMIT:
147 0 : return "permit";
148 : break;
149 : case FILTER_DENY:
150 0 : return "deny";
151 : break;
152 : case FILTER_DYNAMIC:
153 0 : return "dynamic";
154 : break;
155 : default:
156 0 : return "";
157 : break;
158 : }
159 : }
160 :
161 : /* If filter match to the prefix then return 1. */
162 : static int
163 14 : filter_match_cisco (struct filter *mfilter, struct prefix *p)
164 : {
165 : struct filter_cisco *filter;
166 : struct in_addr mask;
167 : u_int32_t check_addr;
168 : u_int32_t check_mask;
169 :
170 14 : filter = &mfilter->u.cfilter;
171 14 : check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
172 :
173 14 : if (filter->extended)
174 : {
175 0 : masklen2ip (p->prefixlen, &mask);
176 0 : check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
177 :
178 0 : if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
179 0 : && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
180 0 : return 1;
181 : }
182 14 : else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
183 10 : return 1;
184 :
185 4 : return 0;
186 : }
187 :
188 : /* If filter match to the prefix then return 1. */
189 : static int
190 0 : filter_match_zebra (struct filter *mfilter, struct prefix *p)
191 : {
192 : struct filter_zebra *filter;
193 :
194 0 : filter = &mfilter->u.zfilter;
195 :
196 0 : if (filter->prefix.family == p->family)
197 : {
198 0 : if (filter->exact)
199 : {
200 0 : if (filter->prefix.prefixlen == p->prefixlen)
201 0 : return prefix_match (&filter->prefix, p);
202 : else
203 0 : return 0;
204 : }
205 : else
206 0 : return prefix_match (&filter->prefix, p);
207 : }
208 : else
209 0 : return 0;
210 : }
211 :
212 : /* Allocate new access list structure. */
213 : static struct access_list *
214 2 : access_list_new (void)
215 : {
216 2 : return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
217 : sizeof (struct access_list));
218 : }
219 :
220 : /* Free allocated access_list. */
221 : static void
222 0 : access_list_free (struct access_list *access)
223 : {
224 0 : XFREE (MTYPE_ACCESS_LIST, access);
225 0 : }
226 :
227 : /* Delete access_list from access_master and free it. */
228 : static void
229 0 : access_list_delete (struct access_list *access)
230 : {
231 : struct filter *filter;
232 : struct filter *next;
233 : struct access_list_list *list;
234 : struct access_master *master;
235 :
236 0 : for (filter = access->head; filter; filter = next)
237 : {
238 0 : next = filter->next;
239 0 : filter_free (filter);
240 : }
241 :
242 0 : master = access->master;
243 :
244 0 : if (access->type == ACCESS_TYPE_NUMBER)
245 0 : list = &master->num;
246 : else
247 0 : list = &master->str;
248 :
249 0 : if (access->next)
250 0 : access->next->prev = access->prev;
251 : else
252 0 : list->tail = access->prev;
253 :
254 0 : if (access->prev)
255 0 : access->prev->next = access->next;
256 : else
257 0 : list->head = access->next;
258 :
259 0 : if (access->name)
260 0 : XFREE (MTYPE_ACCESS_LIST_STR, access->name);
261 :
262 0 : if (access->remark)
263 0 : XFREE (MTYPE_TMP, access->remark);
264 :
265 0 : access_list_free (access);
266 0 : }
267 :
268 : /* Insert new access list to list of access_list. Each acceess_list
269 : is sorted by the name. */
270 : static struct access_list *
271 2 : access_list_insert (afi_t afi, const char *name)
272 : {
273 : unsigned int i;
274 : long number;
275 : struct access_list *access;
276 : struct access_list *point;
277 : struct access_list_list *alist;
278 : struct access_master *master;
279 :
280 2 : master = access_master_get (afi);
281 2 : if (master == NULL)
282 0 : return NULL;
283 :
284 : /* Allocate new access_list and copy given name. */
285 2 : access = access_list_new ();
286 2 : access->name = XSTRDUP (MTYPE_ACCESS_LIST_STR, name);
287 2 : access->master = master;
288 :
289 : /* If name is made by all digit character. We treat it as
290 : number. */
291 6 : for (number = 0, i = 0; i < strlen (name); i++)
292 : {
293 4 : if (isdigit ((int) name[i]))
294 4 : number = (number * 10) + (name[i] - '0');
295 : else
296 0 : break;
297 : }
298 :
299 : /* In case of name is all digit character */
300 2 : if (i == strlen (name))
301 : {
302 2 : access->type = ACCESS_TYPE_NUMBER;
303 :
304 : /* Set access_list to number list. */
305 2 : alist = &master->num;
306 :
307 2 : for (point = alist->head; point; point = point->next)
308 0 : if (atol (point->name) >= number)
309 0 : break;
310 : }
311 : else
312 : {
313 0 : access->type = ACCESS_TYPE_STRING;
314 :
315 : /* Set access_list to string list. */
316 0 : alist = &master->str;
317 :
318 : /* Set point to insertion point. */
319 0 : for (point = alist->head; point; point = point->next)
320 0 : if (strcmp (point->name, name) >= 0)
321 0 : break;
322 : }
323 :
324 : /* In case of this is the first element of master. */
325 2 : if (alist->head == NULL)
326 : {
327 2 : alist->head = alist->tail = access;
328 2 : return access;
329 : }
330 :
331 : /* In case of insertion is made at the tail of access_list. */
332 0 : if (point == NULL)
333 : {
334 0 : access->prev = alist->tail;
335 0 : alist->tail->next = access;
336 0 : alist->tail = access;
337 0 : return access;
338 : }
339 :
340 : /* In case of insertion is made at the head of access_list. */
341 0 : if (point == alist->head)
342 : {
343 0 : access->next = alist->head;
344 0 : alist->head->prev = access;
345 0 : alist->head = access;
346 0 : return access;
347 : }
348 :
349 : /* Insertion is made at middle of the access_list. */
350 0 : access->next = point;
351 0 : access->prev = point->prev;
352 :
353 0 : if (point->prev)
354 0 : point->prev->next = access;
355 0 : point->prev = access;
356 :
357 0 : return access;
358 : }
359 :
360 : /* Lookup access_list from list of access_list by name. */
361 : struct access_list *
362 14 : access_list_lookup (afi_t afi, const char *name)
363 : {
364 : struct access_list *access;
365 : struct access_master *master;
366 :
367 14 : if (name == NULL)
368 0 : return NULL;
369 :
370 14 : master = access_master_get (afi);
371 14 : if (master == NULL)
372 0 : return NULL;
373 :
374 14 : for (access = master->num.head; access; access = access->next)
375 12 : if (strcmp (access->name, name) == 0)
376 12 : return access;
377 :
378 2 : for (access = master->str.head; access; access = access->next)
379 0 : if (strcmp (access->name, name) == 0)
380 0 : return access;
381 :
382 2 : return NULL;
383 : }
384 :
385 : /* Get access list from list of access_list. If there isn't matched
386 : access_list create new one and return it. */
387 : static struct access_list *
388 4 : access_list_get (afi_t afi, const char *name)
389 : {
390 : struct access_list *access;
391 :
392 4 : access = access_list_lookup (afi, name);
393 4 : if (access == NULL)
394 2 : access = access_list_insert (afi, name);
395 4 : return access;
396 : }
397 :
398 : /* Apply access list to object (which should be struct prefix *). */
399 : enum filter_type
400 10 : access_list_apply (struct access_list *access, void *object)
401 : {
402 : struct filter *filter;
403 : struct prefix *p;
404 :
405 10 : p = (struct prefix *) object;
406 :
407 10 : if (access == NULL)
408 0 : return FILTER_DENY;
409 :
410 14 : for (filter = access->head; filter; filter = filter->next)
411 : {
412 14 : if (filter->cisco)
413 : {
414 14 : if (filter_match_cisco (filter, p))
415 10 : return filter->type;
416 : }
417 : else
418 : {
419 0 : if (filter_match_zebra (filter, p))
420 0 : return filter->type;
421 : }
422 : }
423 :
424 0 : return FILTER_DENY;
425 : }
426 :
427 : /* Add hook function. */
428 : void
429 0 : access_list_add_hook (void (*func) (struct access_list *access))
430 : {
431 0 : access_master_ipv4.add_hook = func;
432 : #ifdef HAVE_IPV6
433 0 : access_master_ipv6.add_hook = func;
434 : #endif /* HAVE_IPV6 */
435 0 : }
436 :
437 : /* Delete hook function. */
438 : void
439 0 : access_list_delete_hook (void (*func) (struct access_list *access))
440 : {
441 0 : access_master_ipv4.delete_hook = func;
442 : #ifdef HAVE_IPV6
443 0 : access_master_ipv6.delete_hook = func;
444 : #endif /* HAVE_IPV6 */
445 0 : }
446 :
447 : /* Add new filter to the end of specified access_list. */
448 : static void
449 4 : access_list_filter_add (struct access_list *access, struct filter *filter)
450 : {
451 4 : filter->next = NULL;
452 4 : filter->prev = access->tail;
453 :
454 4 : if (access->tail)
455 2 : access->tail->next = filter;
456 : else
457 2 : access->head = filter;
458 4 : access->tail = filter;
459 :
460 : /* Run hook function. */
461 4 : if (access->master->add_hook)
462 0 : (*access->master->add_hook) (access);
463 4 : }
464 :
465 : /* If access_list has no filter then return 1. */
466 : static int
467 0 : access_list_empty (struct access_list *access)
468 : {
469 0 : if (access->head == NULL && access->tail == NULL)
470 0 : return 1;
471 : else
472 0 : return 0;
473 : }
474 :
475 : /* Delete filter from specified access_list. If there is hook
476 : function execute it. */
477 : static void
478 0 : access_list_filter_delete (struct access_list *access, struct filter *filter)
479 : {
480 : struct access_master *master;
481 :
482 0 : master = access->master;
483 :
484 0 : if (filter->next)
485 0 : filter->next->prev = filter->prev;
486 : else
487 0 : access->tail = filter->prev;
488 :
489 0 : if (filter->prev)
490 0 : filter->prev->next = filter->next;
491 : else
492 0 : access->head = filter->next;
493 :
494 0 : filter_free (filter);
495 :
496 : /* If access_list becomes empty delete it from access_master. */
497 0 : if (access_list_empty (access))
498 0 : access_list_delete (access);
499 :
500 : /* Run hook function. */
501 0 : if (master->delete_hook)
502 0 : (*master->delete_hook) (access);
503 0 : }
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 :
517 : static struct filter *
518 4 : filter_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 4 : new = &mnew->u.cfilter;
525 :
526 6 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
527 : {
528 2 : filter = &mfilter->u.cfilter;
529 :
530 2 : if (filter->extended)
531 : {
532 0 : if (mfilter->type == mnew->type
533 0 : && filter->addr.s_addr == new->addr.s_addr
534 0 : && filter->addr_mask.s_addr == new->addr_mask.s_addr
535 0 : && filter->mask.s_addr == new->mask.s_addr
536 0 : && filter->mask_mask.s_addr == new->mask_mask.s_addr)
537 0 : return mfilter;
538 : }
539 : else
540 : {
541 2 : if (mfilter->type == mnew->type
542 0 : && filter->addr.s_addr == new->addr.s_addr
543 0 : && filter->addr_mask.s_addr == new->addr_mask.s_addr)
544 0 : return mfilter;
545 : }
546 : }
547 :
548 4 : return NULL;
549 : }
550 :
551 : static struct filter *
552 0 : filter_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 0 : new = &mnew->u.zfilter;
559 :
560 0 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
561 : {
562 0 : filter = &mfilter->u.zfilter;
563 :
564 0 : if (filter->exact == new->exact
565 0 : && mfilter->type == mnew->type
566 0 : && prefix_same (&filter->prefix, &new->prefix))
567 0 : return mfilter;
568 : }
569 0 : return NULL;
570 : }
571 :
572 : static int
573 0 : vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
574 : {
575 : struct access_list *access;
576 :
577 0 : access = access_list_lookup (afi, name);
578 0 : if (! access)
579 : {
580 0 : vty_out (vty, "%% access-list %s doesn't exist%s", name,
581 0 : VTY_NEWLINE);
582 0 : return CMD_WARNING;
583 : }
584 :
585 0 : if (access->remark)
586 : {
587 0 : XFREE (MTYPE_TMP, access->remark);
588 0 : access->remark = NULL;
589 : }
590 :
591 0 : if (access->head == NULL && access->tail == NULL && access->remark == NULL)
592 0 : access_list_delete (access);
593 :
594 0 : return CMD_SUCCESS;
595 : }
596 :
597 : static int
598 4 : filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
599 : const char *addr_str, const char *addr_mask_str,
600 : const char *mask_str, const char *mask_mask_str,
601 : 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 4 : if (strncmp (type_str, "p", 1) == 0)
615 2 : type = FILTER_PERMIT;
616 2 : else if (strncmp (type_str, "d", 1) == 0)
617 2 : type = FILTER_DENY;
618 : else
619 : {
620 0 : vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
621 0 : return CMD_WARNING;
622 : }
623 :
624 4 : ret = inet_aton (addr_str, &addr);
625 4 : if (ret <= 0)
626 : {
627 0 : vty_out (vty, "%%Inconsistent address and mask%s",
628 0 : VTY_NEWLINE);
629 0 : return CMD_WARNING;
630 : }
631 :
632 4 : ret = inet_aton (addr_mask_str, &addr_mask);
633 4 : if (ret <= 0)
634 : {
635 0 : vty_out (vty, "%%Inconsistent address and mask%s",
636 0 : VTY_NEWLINE);
637 0 : return CMD_WARNING;
638 : }
639 :
640 4 : if (extended)
641 : {
642 0 : ret = inet_aton (mask_str, &mask);
643 0 : if (ret <= 0)
644 : {
645 0 : vty_out (vty, "%%Inconsistent address and mask%s",
646 0 : VTY_NEWLINE);
647 0 : return CMD_WARNING;
648 : }
649 :
650 0 : ret = inet_aton (mask_mask_str, &mask_mask);
651 0 : if (ret <= 0)
652 : {
653 0 : vty_out (vty, "%%Inconsistent address and mask%s",
654 0 : VTY_NEWLINE);
655 0 : return CMD_WARNING;
656 : }
657 : }
658 :
659 4 : mfilter = filter_new();
660 4 : mfilter->type = type;
661 4 : mfilter->cisco = 1;
662 4 : filter = &mfilter->u.cfilter;
663 4 : filter->extended = extended;
664 4 : filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
665 4 : filter->addr_mask.s_addr = addr_mask.s_addr;
666 :
667 4 : if (extended)
668 : {
669 0 : filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
670 0 : filter->mask_mask.s_addr = mask_mask.s_addr;
671 : }
672 :
673 : /* Install new filter to the access_list. */
674 4 : access = access_list_get (AFI_IP, name_str);
675 :
676 4 : if (set)
677 : {
678 4 : if (filter_lookup_cisco (access, mfilter))
679 0 : filter_free (mfilter);
680 : else
681 4 : access_list_filter_add (access, mfilter);
682 : }
683 : else
684 : {
685 : struct filter *delete_filter;
686 :
687 0 : delete_filter = filter_lookup_cisco (access, mfilter);
688 0 : if (delete_filter)
689 0 : access_list_filter_delete (access, delete_filter);
690 :
691 0 : filter_free (mfilter);
692 : }
693 :
694 4 : return CMD_SUCCESS;
695 : }
696 :
697 : /* Standard access-list */
698 2 : DEFUN (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 2 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
710 : NULL, NULL, 0, 1);
711 : }
712 :
713 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
724 : NULL, NULL, 0, 1);
725 : }
726 :
727 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
739 : NULL, NULL, 0, 1);
740 : }
741 :
742 2 : DEFUN (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 2 : return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
753 : "255.255.255.255", NULL, NULL, 0, 1);
754 : }
755 :
756 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
769 : NULL, NULL, 0, 0);
770 : }
771 :
772 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
784 : NULL, NULL, 0, 0);
785 : }
786 :
787 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
800 : NULL, NULL, 0, 0);
801 : }
802 :
803 0 : DEFUN (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 0 : 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 */
819 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
834 0 : argv[3], argv[4], argv[5], 1 ,1);
835 : }
836 :
837 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
851 0 : argv[3], "0.0.0.0",
852 : "255.255.255.255", 1, 1);
853 : }
854 :
855 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
869 0 : "255.255.255.255", argv[2],
870 0 : argv[3], 1, 1);
871 : }
872 :
873 0 : DEFUN (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 0 : 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 :
890 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
905 0 : argv[3], argv[4],
906 : "0.0.0.0", 1, 1);
907 : }
908 :
909 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
924 0 : "0.0.0.0", argv[3],
925 0 : argv[4], 1, 1);
926 : }
927 :
928 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
943 0 : "0.0.0.0", argv[3],
944 : "0.0.0.0", 1, 1);
945 : }
946 :
947 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
961 0 : "255.255.255.255", argv[2],
962 : "0.0.0.0", 1, 1);
963 : }
964 :
965 0 : DEFUN (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 0 : 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 :
983 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
999 0 : argv[3], argv[4], argv[5], 1, 0);
1000 : }
1001 :
1002 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1017 0 : argv[3], "0.0.0.0",
1018 : "255.255.255.255", 1, 0);
1019 : }
1020 :
1021 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1036 0 : "255.255.255.255", argv[2],
1037 0 : argv[3], 1, 0);
1038 : }
1039 :
1040 0 : DEFUN (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 0 : 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 :
1058 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1074 0 : argv[3], argv[4],
1075 : "0.0.0.0", 1, 0);
1076 : }
1077 :
1078 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1094 0 : "0.0.0.0", argv[3],
1095 0 : argv[4], 1, 0);
1096 : }
1097 :
1098 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], argv[2],
1114 0 : "0.0.0.0", argv[3],
1115 : "0.0.0.0", 1, 0);
1116 : }
1117 :
1118 0 : DEFUN (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 0 : return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
1133 0 : "255.255.255.255", argv[2],
1134 : "0.0.0.0", 1, 0);
1135 : }
1136 :
1137 0 : DEFUN (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 0 : 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 :
1156 : static int
1157 0 : filter_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)
1159 : {
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 0 : if (strncmp (type_str, "p", 1) == 0)
1169 0 : type = FILTER_PERMIT;
1170 0 : else if (strncmp (type_str, "d", 1) == 0)
1171 0 : type = FILTER_DENY;
1172 : else
1173 : {
1174 0 : vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
1175 0 : return CMD_WARNING;
1176 : }
1177 :
1178 : /* Check string format of prefix and prefixlen. */
1179 0 : if (afi == AFI_IP)
1180 : {
1181 0 : ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
1182 0 : if (ret <= 0)
1183 : {
1184 0 : vty_out (vty, "IP address prefix/prefixlen is malformed%s",
1185 0 : VTY_NEWLINE);
1186 0 : return CMD_WARNING;
1187 : }
1188 : }
1189 : #ifdef HAVE_IPV6
1190 0 : else if (afi == AFI_IP6)
1191 : {
1192 0 : ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
1193 0 : if (ret <= 0)
1194 : {
1195 0 : vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
1196 0 : VTY_NEWLINE);
1197 0 : return CMD_WARNING;
1198 : }
1199 : }
1200 : #endif /* HAVE_IPV6 */
1201 : else
1202 0 : return CMD_WARNING;
1203 :
1204 0 : mfilter = filter_new ();
1205 0 : mfilter->type = type;
1206 0 : filter = &mfilter->u.zfilter;
1207 0 : prefix_copy (&filter->prefix, &p);
1208 :
1209 : /* "exact-match" */
1210 0 : if (exact)
1211 0 : filter->exact = 1;
1212 :
1213 : /* Install new filter to the access_list. */
1214 0 : access = access_list_get (afi, name_str);
1215 :
1216 0 : if (set)
1217 : {
1218 0 : if (filter_lookup_zebra (access, mfilter))
1219 0 : filter_free (mfilter);
1220 : else
1221 0 : access_list_filter_add (access, mfilter);
1222 : }
1223 : else
1224 : {
1225 : struct filter *delete_filter;
1226 :
1227 0 : delete_filter = filter_lookup_zebra (access, mfilter);
1228 0 : if (delete_filter)
1229 0 : access_list_filter_delete (access, delete_filter);
1230 :
1231 0 : filter_free (mfilter);
1232 : }
1233 :
1234 0 : return CMD_SUCCESS;
1235 : }
1236 :
1237 : /* Zebra access-list */
1238 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
1248 : }
1249 :
1250 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
1261 : }
1262 :
1263 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
1273 : }
1274 :
1275 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
1286 : }
1287 :
1288 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
1300 : }
1301 :
1302 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
1313 : }
1314 :
1315 0 : DEFUN (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 0 : access = access_list_lookup (AFI_IP, argv[0]);
1331 0 : if (access == NULL)
1332 : {
1333 0 : vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1334 0 : VTY_NEWLINE);
1335 0 : return CMD_WARNING;
1336 : }
1337 :
1338 0 : master = access->master;
1339 :
1340 : /* Run hook function. */
1341 0 : if (master->delete_hook)
1342 0 : (*master->delete_hook) (access);
1343 :
1344 : /* Delete all filter from access-list. */
1345 0 : access_list_delete (access);
1346 :
1347 0 : return CMD_SUCCESS;
1348 : }
1349 :
1350 0 : DEFUN (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;
1363 :
1364 0 : access = access_list_get (AFI_IP, argv[0]);
1365 :
1366 0 : if (access->remark)
1367 : {
1368 0 : XFREE (MTYPE_TMP, access->remark);
1369 0 : access->remark = NULL;
1370 : }
1371 0 : access->remark = argv_concat(argv, argc, 1);
1372 :
1373 0 : return CMD_SUCCESS;
1374 : }
1375 :
1376 0 : DEFUN (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 0 : return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
1389 : }
1390 :
1391 : ALIAS (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
1405 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
1416 : }
1417 :
1418 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
1430 : }
1431 :
1432 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
1443 : }
1444 :
1445 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
1457 : }
1458 :
1459 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
1472 : }
1473 :
1474 0 : DEFUN (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 0 : return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
1486 : }
1487 :
1488 :
1489 0 : DEFUN (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 0 : access = access_list_lookup (AFI_IP6, argv[0]);
1502 0 : if (access == NULL)
1503 : {
1504 0 : vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
1505 0 : VTY_NEWLINE);
1506 0 : return CMD_WARNING;
1507 : }
1508 :
1509 0 : master = access->master;
1510 :
1511 : /* Run hook function. */
1512 0 : if (master->delete_hook)
1513 0 : (*master->delete_hook) (access);
1514 :
1515 : /* Delete all filter from access-list. */
1516 0 : access_list_delete (access);
1517 :
1518 0 : return CMD_SUCCESS;
1519 : }
1520 :
1521 0 : DEFUN (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;
1531 :
1532 0 : access = access_list_get (AFI_IP6, argv[0]);
1533 :
1534 0 : if (access->remark)
1535 : {
1536 0 : XFREE (MTYPE_TMP, access->remark);
1537 0 : access->remark = NULL;
1538 : }
1539 0 : access->remark = argv_concat(argv, argc, 1);
1540 :
1541 0 : return CMD_SUCCESS;
1542 : }
1543 :
1544 0 : DEFUN (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 0 : return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
1554 : }
1555 :
1556 : ALIAS (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 :
1567 : void config_write_access_zebra (struct vty *, struct filter *);
1568 : void config_write_access_cisco (struct vty *, struct filter *);
1569 :
1570 : /* show access-list command. */
1571 : static int
1572 0 : filter_show (struct vty *vty, const char *name, afi_t afi)
1573 : {
1574 : struct access_list *access;
1575 : struct access_master *master;
1576 : struct filter *mfilter;
1577 : struct filter_cisco *filter;
1578 0 : int write = 0;
1579 :
1580 0 : master = access_master_get (afi);
1581 0 : if (master == NULL)
1582 0 : return 0;
1583 :
1584 : /* Print the name of the protocol */
1585 0 : if (zlog_default)
1586 0 : vty_out (vty, "%s:%s",
1587 0 : zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
1588 :
1589 0 : for (access = master->num.head; access; access = access->next)
1590 : {
1591 0 : if (name && strcmp (access->name, name) != 0)
1592 0 : continue;
1593 :
1594 0 : write = 1;
1595 :
1596 0 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1597 : {
1598 0 : filter = &mfilter->u.cfilter;
1599 :
1600 0 : if (write)
1601 : {
1602 0 : vty_out (vty, "%s IP%s access list %s%s",
1603 0 : mfilter->cisco ?
1604 0 : (filter->extended ? "Extended" : "Standard") : "Zebra",
1605 : afi == AFI_IP6 ? "v6" : "",
1606 0 : access->name, VTY_NEWLINE);
1607 0 : write = 0;
1608 : }
1609 :
1610 0 : vty_out (vty, " %s%s", filter_type_str (mfilter),
1611 0 : mfilter->type == FILTER_DENY ? " " : "");
1612 :
1613 0 : if (! mfilter->cisco)
1614 0 : config_write_access_zebra (vty, mfilter);
1615 0 : else if (filter->extended)
1616 0 : config_write_access_cisco (vty, mfilter);
1617 : else
1618 : {
1619 0 : if (filter->addr_mask.s_addr == 0xffffffff)
1620 0 : vty_out (vty, " any%s", VTY_NEWLINE);
1621 : else
1622 : {
1623 0 : vty_out (vty, " %s", inet_ntoa (filter->addr));
1624 0 : if (filter->addr_mask.s_addr != 0)
1625 0 : vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1626 0 : vty_out (vty, "%s", VTY_NEWLINE);
1627 : }
1628 : }
1629 : }
1630 : }
1631 :
1632 0 : for (access = master->str.head; access; access = access->next)
1633 : {
1634 0 : if (name && strcmp (access->name, name) != 0)
1635 0 : continue;
1636 :
1637 0 : write = 1;
1638 :
1639 0 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1640 : {
1641 0 : filter = &mfilter->u.cfilter;
1642 :
1643 0 : if (write)
1644 : {
1645 0 : vty_out (vty, "%s IP%s access list %s%s",
1646 0 : mfilter->cisco ?
1647 0 : (filter->extended ? "Extended" : "Standard") : "Zebra",
1648 : afi == AFI_IP6 ? "v6" : "",
1649 0 : access->name, VTY_NEWLINE);
1650 0 : write = 0;
1651 : }
1652 :
1653 0 : vty_out (vty, " %s%s", filter_type_str (mfilter),
1654 0 : mfilter->type == FILTER_DENY ? " " : "");
1655 :
1656 0 : if (! mfilter->cisco)
1657 0 : config_write_access_zebra (vty, mfilter);
1658 0 : else if (filter->extended)
1659 0 : config_write_access_cisco (vty, mfilter);
1660 : else
1661 : {
1662 0 : if (filter->addr_mask.s_addr == 0xffffffff)
1663 0 : vty_out (vty, " any%s", VTY_NEWLINE);
1664 : else
1665 : {
1666 0 : vty_out (vty, " %s", inet_ntoa (filter->addr));
1667 0 : if (filter->addr_mask.s_addr != 0)
1668 0 : vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
1669 0 : vty_out (vty, "%s", VTY_NEWLINE);
1670 : }
1671 : }
1672 : }
1673 : }
1674 0 : return CMD_SUCCESS;
1675 : }
1676 :
1677 0 : DEFUN (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 0 : return filter_show (vty, NULL, AFI_IP);
1685 : }
1686 :
1687 0 : DEFUN (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 0 : return filter_show (vty, argv[0], AFI_IP);
1700 : }
1701 :
1702 : #ifdef HAVE_IPV6
1703 0 : DEFUN (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 0 : return filter_show (vty, NULL, AFI_IP6);
1711 : }
1712 :
1713 0 : DEFUN (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 0 : return filter_show (vty, argv[0], AFI_IP6);
1722 : }
1723 : #endif /* HAVE_IPV6 */
1724 :
1725 : void
1726 0 : config_write_access_cisco (struct vty *vty, struct filter *mfilter)
1727 : {
1728 : struct filter_cisco *filter;
1729 :
1730 0 : filter = &mfilter->u.cfilter;
1731 :
1732 0 : if (filter->extended)
1733 : {
1734 0 : vty_out (vty, " ip");
1735 0 : if (filter->addr_mask.s_addr == 0xffffffff)
1736 0 : vty_out (vty, " any");
1737 0 : else if (filter->addr_mask.s_addr == 0)
1738 0 : vty_out (vty, " host %s", inet_ntoa (filter->addr));
1739 : else
1740 : {
1741 0 : vty_out (vty, " %s", inet_ntoa (filter->addr));
1742 0 : vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1743 : }
1744 :
1745 0 : if (filter->mask_mask.s_addr == 0xffffffff)
1746 0 : vty_out (vty, " any");
1747 0 : else if (filter->mask_mask.s_addr == 0)
1748 0 : vty_out (vty, " host %s", inet_ntoa (filter->mask));
1749 : else
1750 : {
1751 0 : vty_out (vty, " %s", inet_ntoa (filter->mask));
1752 0 : vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
1753 : }
1754 0 : vty_out (vty, "%s", VTY_NEWLINE);
1755 : }
1756 : else
1757 : {
1758 0 : if (filter->addr_mask.s_addr == 0xffffffff)
1759 0 : vty_out (vty, " any%s", VTY_NEWLINE);
1760 : else
1761 : {
1762 0 : vty_out (vty, " %s", inet_ntoa (filter->addr));
1763 0 : if (filter->addr_mask.s_addr != 0)
1764 0 : vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
1765 0 : vty_out (vty, "%s", VTY_NEWLINE);
1766 : }
1767 : }
1768 0 : }
1769 :
1770 : void
1771 0 : config_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 0 : filter = &mfilter->u.zfilter;
1778 0 : p = &filter->prefix;
1779 :
1780 0 : if (p->prefixlen == 0 && ! filter->exact)
1781 0 : vty_out (vty, " any");
1782 : else
1783 0 : vty_out (vty, " %s/%d%s",
1784 0 : inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
1785 0 : p->prefixlen,
1786 0 : filter->exact ? " exact-match" : "");
1787 :
1788 0 : vty_out (vty, "%s", VTY_NEWLINE);
1789 0 : }
1790 :
1791 : static int
1792 0 : config_write_access (struct vty *vty, afi_t afi)
1793 : {
1794 : struct access_list *access;
1795 : struct access_master *master;
1796 : struct filter *mfilter;
1797 0 : int write = 0;
1798 :
1799 0 : master = access_master_get (afi);
1800 0 : if (master == NULL)
1801 0 : return 0;
1802 :
1803 0 : for (access = master->num.head; access; access = access->next)
1804 : {
1805 0 : if (access->remark)
1806 : {
1807 0 : vty_out (vty, "%saccess-list %s remark %s%s",
1808 : afi == AFI_IP ? "" : "ipv6 ",
1809 : access->name, access->remark,
1810 0 : VTY_NEWLINE);
1811 0 : write++;
1812 : }
1813 :
1814 0 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1815 : {
1816 0 : vty_out (vty, "%saccess-list %s %s",
1817 : afi == AFI_IP ? "" : "ipv6 ",
1818 : access->name,
1819 : filter_type_str (mfilter));
1820 :
1821 0 : if (mfilter->cisco)
1822 0 : config_write_access_cisco (vty, mfilter);
1823 : else
1824 0 : config_write_access_zebra (vty, mfilter);
1825 :
1826 0 : write++;
1827 : }
1828 : }
1829 :
1830 0 : for (access = master->str.head; access; access = access->next)
1831 : {
1832 0 : if (access->remark)
1833 : {
1834 0 : vty_out (vty, "%saccess-list %s remark %s%s",
1835 : afi == AFI_IP ? "" : "ipv6 ",
1836 : access->name, access->remark,
1837 0 : VTY_NEWLINE);
1838 0 : write++;
1839 : }
1840 :
1841 0 : for (mfilter = access->head; mfilter; mfilter = mfilter->next)
1842 : {
1843 0 : vty_out (vty, "%saccess-list %s %s",
1844 : afi == AFI_IP ? "" : "ipv6 ",
1845 : access->name,
1846 : filter_type_str (mfilter));
1847 :
1848 0 : if (mfilter->cisco)
1849 0 : config_write_access_cisco (vty, mfilter);
1850 : else
1851 0 : config_write_access_zebra (vty, mfilter);
1852 :
1853 0 : write++;
1854 : }
1855 : }
1856 0 : return write;
1857 : }
1858 :
1859 : /* Access-list node. */
1860 : static struct cmd_node access_node =
1861 : {
1862 : ACCESS_NODE,
1863 : "", /* Access list has no interface. */
1864 : 1
1865 : };
1866 :
1867 : static int
1868 0 : config_write_access_ipv4 (struct vty *vty)
1869 : {
1870 0 : return config_write_access (vty, AFI_IP);
1871 : }
1872 :
1873 : static void
1874 0 : access_list_reset_ipv4 (void)
1875 : {
1876 : struct access_list *access;
1877 : struct access_list *next;
1878 : struct access_master *master;
1879 :
1880 0 : master = access_master_get (AFI_IP);
1881 0 : if (master == NULL)
1882 0 : return;
1883 :
1884 0 : for (access = master->num.head; access; access = next)
1885 : {
1886 0 : next = access->next;
1887 0 : access_list_delete (access);
1888 : }
1889 0 : for (access = master->str.head; access; access = next)
1890 : {
1891 0 : next = access->next;
1892 0 : access_list_delete (access);
1893 : }
1894 :
1895 0 : assert (master->num.head == NULL);
1896 0 : assert (master->num.tail == NULL);
1897 :
1898 0 : assert (master->str.head == NULL);
1899 0 : assert (master->str.tail == NULL);
1900 : }
1901 :
1902 : /* Install vty related command. */
1903 : static void
1904 45 : access_list_init_ipv4 (void)
1905 : {
1906 45 : install_node (&access_node, config_write_access_ipv4);
1907 :
1908 45 : install_element (ENABLE_NODE, &show_ip_access_list_cmd);
1909 45 : install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
1910 :
1911 : /* Zebra access-list */
1912 45 : install_element (CONFIG_NODE, &access_list_cmd);
1913 45 : install_element (CONFIG_NODE, &access_list_exact_cmd);
1914 45 : install_element (CONFIG_NODE, &access_list_any_cmd);
1915 45 : install_element (CONFIG_NODE, &no_access_list_cmd);
1916 45 : install_element (CONFIG_NODE, &no_access_list_exact_cmd);
1917 45 : install_element (CONFIG_NODE, &no_access_list_any_cmd);
1918 :
1919 : /* Standard access-list */
1920 45 : install_element (CONFIG_NODE, &access_list_standard_cmd);
1921 45 : install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
1922 45 : install_element (CONFIG_NODE, &access_list_standard_host_cmd);
1923 45 : install_element (CONFIG_NODE, &access_list_standard_any_cmd);
1924 45 : install_element (CONFIG_NODE, &no_access_list_standard_cmd);
1925 45 : install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
1926 45 : install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
1927 45 : install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
1928 :
1929 : /* Extended access-list */
1930 45 : install_element (CONFIG_NODE, &access_list_extended_cmd);
1931 45 : install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
1932 45 : install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
1933 45 : install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
1934 45 : install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
1935 45 : install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
1936 45 : install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
1937 45 : install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
1938 45 : install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
1939 45 : install_element (CONFIG_NODE, &no_access_list_extended_cmd);
1940 45 : install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
1941 45 : install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
1942 45 : install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
1943 45 : install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
1944 45 : install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
1945 45 : install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
1946 45 : install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
1947 45 : install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
1948 :
1949 45 : install_element (CONFIG_NODE, &access_list_remark_cmd);
1950 45 : install_element (CONFIG_NODE, &no_access_list_all_cmd);
1951 45 : install_element (CONFIG_NODE, &no_access_list_remark_cmd);
1952 45 : install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
1953 45 : }
1954 :
1955 : #ifdef HAVE_IPV6
1956 : static struct cmd_node access_ipv6_node =
1957 : {
1958 : ACCESS_IPV6_NODE,
1959 : "",
1960 : 1
1961 : };
1962 :
1963 : static int
1964 0 : config_write_access_ipv6 (struct vty *vty)
1965 : {
1966 0 : return config_write_access (vty, AFI_IP6);
1967 : }
1968 :
1969 : static void
1970 0 : access_list_reset_ipv6 (void)
1971 : {
1972 : struct access_list *access;
1973 : struct access_list *next;
1974 : struct access_master *master;
1975 :
1976 0 : master = access_master_get (AFI_IP6);
1977 0 : if (master == NULL)
1978 0 : return;
1979 :
1980 0 : for (access = master->num.head; access; access = next)
1981 : {
1982 0 : next = access->next;
1983 0 : access_list_delete (access);
1984 : }
1985 0 : for (access = master->str.head; access; access = next)
1986 : {
1987 0 : next = access->next;
1988 0 : access_list_delete (access);
1989 : }
1990 :
1991 0 : assert (master->num.head == NULL);
1992 0 : assert (master->num.tail == NULL);
1993 :
1994 0 : assert (master->str.head == NULL);
1995 0 : assert (master->str.tail == NULL);
1996 : }
1997 :
1998 : static void
1999 45 : access_list_init_ipv6 (void)
2000 : {
2001 45 : install_node (&access_ipv6_node, config_write_access_ipv6);
2002 :
2003 45 : install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
2004 45 : install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
2005 :
2006 45 : install_element (CONFIG_NODE, &ipv6_access_list_cmd);
2007 45 : install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
2008 45 : install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
2009 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
2010 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
2011 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
2012 :
2013 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
2014 45 : install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
2015 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
2016 45 : install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
2017 45 : }
2018 : #endif /* HAVE_IPV6 */
2019 :
2020 : void
2021 45 : access_list_init ()
2022 : {
2023 45 : access_list_init_ipv4 ();
2024 : #ifdef HAVE_IPV6
2025 45 : access_list_init_ipv6();
2026 : #endif /* HAVE_IPV6 */
2027 45 : }
2028 :
2029 : void
2030 0 : access_list_reset ()
2031 : {
2032 0 : access_list_reset_ipv4 ();
2033 : #ifdef HAVE_IPV6
2034 0 : access_list_reset_ipv6();
2035 : #endif /* HAVE_IPV6 */
2036 0 : }
|