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