Annotation of embedaddon/quagga/lib/distribute.c, revision 1.1.1.1
1.1 misho 1: /* Distribute list functions
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 "hash.h"
25: #include "if.h"
26: #include "filter.h"
27: #include "command.h"
28: #include "distribute.h"
29: #include "memory.h"
30:
31: /* Hash of distribute list. */
32: struct hash *disthash;
33:
34: /* Hook functions. */
35: void (*distribute_add_hook) (struct distribute *);
36: void (*distribute_delete_hook) (struct distribute *);
37:
38: static struct distribute *
39: distribute_new (void)
40: {
41: return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
42: }
43:
44: /* Free distribute object. */
45: static void
46: distribute_free (struct distribute *dist)
47: {
48: if (dist->ifname)
49: XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
50:
51: if (dist->list[DISTRIBUTE_IN])
52: free (dist->list[DISTRIBUTE_IN]);
53: if (dist->list[DISTRIBUTE_OUT])
54: free (dist->list[DISTRIBUTE_OUT]);
55:
56: if (dist->prefix[DISTRIBUTE_IN])
57: free (dist->prefix[DISTRIBUTE_IN]);
58: if (dist->prefix[DISTRIBUTE_OUT])
59: free (dist->prefix[DISTRIBUTE_OUT]);
60:
61: XFREE (MTYPE_DISTRIBUTE, dist);
62: }
63:
64: /* Lookup interface's distribute list. */
65: struct distribute *
66: distribute_lookup (const char *ifname)
67: {
68: struct distribute key;
69: struct distribute *dist;
70:
71: /* temporary reference */
72: key.ifname = (char *)ifname;
73:
74: dist = hash_lookup (disthash, &key);
75:
76: return dist;
77: }
78:
79: void
80: distribute_list_add_hook (void (*func) (struct distribute *))
81: {
82: distribute_add_hook = func;
83: }
84:
85: void
86: distribute_list_delete_hook (void (*func) (struct distribute *))
87: {
88: distribute_delete_hook = func;
89: }
90:
91: static void *
92: distribute_hash_alloc (struct distribute *arg)
93: {
94: struct distribute *dist;
95:
96: dist = distribute_new ();
97: if (arg->ifname)
98: dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
99: else
100: dist->ifname = NULL;
101: return dist;
102: }
103:
104: /* Make new distribute list and push into hash. */
105: static struct distribute *
106: distribute_get (const char *ifname)
107: {
108: struct distribute key;
109:
110: /* temporary reference */
111: key.ifname = (char *)ifname;
112:
113: return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
114: }
115:
116: static unsigned int
117: distribute_hash_make (void *arg)
118: {
119: const struct distribute *dist = arg;
120:
121: return dist->ifname ? string_hash_make (dist->ifname) : 0;
122: }
123:
124: /* If two distribute-list have same value then return 1 else return
125: 0. This function is used by hash package. */
126: static int
127: distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
128: {
129: if (dist1->ifname && dist2->ifname)
130: if (strcmp (dist1->ifname, dist2->ifname) == 0)
131: return 1;
132: if (! dist1->ifname && ! dist2->ifname)
133: return 1;
134: return 0;
135: }
136:
137: /* Set access-list name to the distribute list. */
138: static struct distribute *
139: distribute_list_set (const char *ifname, enum distribute_type type,
140: const char *alist_name)
141: {
142: struct distribute *dist;
143:
144: dist = distribute_get (ifname);
145:
146: if (type == DISTRIBUTE_IN)
147: {
148: if (dist->list[DISTRIBUTE_IN])
149: free (dist->list[DISTRIBUTE_IN]);
150: dist->list[DISTRIBUTE_IN] = strdup (alist_name);
151: }
152: if (type == DISTRIBUTE_OUT)
153: {
154: if (dist->list[DISTRIBUTE_OUT])
155: free (dist->list[DISTRIBUTE_OUT]);
156: dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
157: }
158:
159: /* Apply this distribute-list to the interface. */
160: (*distribute_add_hook) (dist);
161:
162: return dist;
163: }
164:
165: /* Unset distribute-list. If matched distribute-list exist then
166: return 1. */
167: static int
168: distribute_list_unset (const char *ifname, enum distribute_type type,
169: const char *alist_name)
170: {
171: struct distribute *dist;
172:
173: dist = distribute_lookup (ifname);
174: if (!dist)
175: return 0;
176:
177: if (type == DISTRIBUTE_IN)
178: {
179: if (!dist->list[DISTRIBUTE_IN])
180: return 0;
181: if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
182: return 0;
183:
184: free (dist->list[DISTRIBUTE_IN]);
185: dist->list[DISTRIBUTE_IN] = NULL;
186: }
187:
188: if (type == DISTRIBUTE_OUT)
189: {
190: if (!dist->list[DISTRIBUTE_OUT])
191: return 0;
192: if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
193: return 0;
194:
195: free (dist->list[DISTRIBUTE_OUT]);
196: dist->list[DISTRIBUTE_OUT] = NULL;
197: }
198:
199: /* Apply this distribute-list to the interface. */
200: (*distribute_delete_hook) (dist);
201:
202: /* If both out and in is NULL then free distribute list. */
203: if (dist->list[DISTRIBUTE_IN] == NULL &&
204: dist->list[DISTRIBUTE_OUT] == NULL &&
205: dist->prefix[DISTRIBUTE_IN] == NULL &&
206: dist->prefix[DISTRIBUTE_OUT] == NULL)
207: {
208: hash_release (disthash, dist);
209: distribute_free (dist);
210: }
211:
212: return 1;
213: }
214:
215: /* Set access-list name to the distribute list. */
216: static struct distribute *
217: distribute_list_prefix_set (const char *ifname, enum distribute_type type,
218: const char *plist_name)
219: {
220: struct distribute *dist;
221:
222: dist = distribute_get (ifname);
223:
224: if (type == DISTRIBUTE_IN)
225: {
226: if (dist->prefix[DISTRIBUTE_IN])
227: free (dist->prefix[DISTRIBUTE_IN]);
228: dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
229: }
230: if (type == DISTRIBUTE_OUT)
231: {
232: if (dist->prefix[DISTRIBUTE_OUT])
233: free (dist->prefix[DISTRIBUTE_OUT]);
234: dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
235: }
236:
237: /* Apply this distribute-list to the interface. */
238: (*distribute_add_hook) (dist);
239:
240: return dist;
241: }
242:
243: /* Unset distribute-list. If matched distribute-list exist then
244: return 1. */
245: static int
246: distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
247: const char *plist_name)
248: {
249: struct distribute *dist;
250:
251: dist = distribute_lookup (ifname);
252: if (!dist)
253: return 0;
254:
255: if (type == DISTRIBUTE_IN)
256: {
257: if (!dist->prefix[DISTRIBUTE_IN])
258: return 0;
259: if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
260: return 0;
261:
262: free (dist->prefix[DISTRIBUTE_IN]);
263: dist->prefix[DISTRIBUTE_IN] = NULL;
264: }
265:
266: if (type == DISTRIBUTE_OUT)
267: {
268: if (!dist->prefix[DISTRIBUTE_OUT])
269: return 0;
270: if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
271: return 0;
272:
273: free (dist->prefix[DISTRIBUTE_OUT]);
274: dist->prefix[DISTRIBUTE_OUT] = NULL;
275: }
276:
277: /* Apply this distribute-list to the interface. */
278: (*distribute_delete_hook) (dist);
279:
280: /* If both out and in is NULL then free distribute list. */
281: if (dist->list[DISTRIBUTE_IN] == NULL &&
282: dist->list[DISTRIBUTE_OUT] == NULL &&
283: dist->prefix[DISTRIBUTE_IN] == NULL &&
284: dist->prefix[DISTRIBUTE_OUT] == NULL)
285: {
286: hash_release (disthash, dist);
287: distribute_free (dist);
288: }
289:
290: return 1;
291: }
292:
293: DEFUN (distribute_list_all,
294: distribute_list_all_cmd,
295: "distribute-list WORD (in|out)",
296: "Filter networks in routing updates\n"
297: "Access-list name\n"
298: "Filter incoming routing updates\n"
299: "Filter outgoing routing updates\n")
300: {
301: enum distribute_type type;
302: struct distribute *dist;
303:
304: /* Check of distribute list type. */
305: if (strncmp (argv[1], "i", 1) == 0)
306: type = DISTRIBUTE_IN;
307: else if (strncmp (argv[1], "o", 1) == 0)
308: type = DISTRIBUTE_OUT;
309: else
310: {
311: vty_out (vty, "distribute list direction must be [in|out]%s",
312: VTY_NEWLINE);
313: return CMD_WARNING;
314: }
315:
316: /* Get interface name corresponding distribute list. */
317: dist = distribute_list_set (NULL, type, argv[0]);
318:
319: return CMD_SUCCESS;
320: }
321:
322: ALIAS (distribute_list_all,
323: ipv6_distribute_list_all_cmd,
324: "distribute-list WORD (in|out)",
325: "Filter networks in routing updates\n"
326: "Access-list name\n"
327: "Filter incoming routing updates\n"
328: "Filter outgoing routing updates\n")
329:
330: DEFUN (no_distribute_list_all,
331: no_distribute_list_all_cmd,
332: "no distribute-list WORD (in|out)",
333: NO_STR
334: "Filter networks in routing updates\n"
335: "Access-list name\n"
336: "Filter incoming routing updates\n"
337: "Filter outgoing routing updates\n")
338: {
339: int ret;
340: enum distribute_type type;
341:
342: /* Check of distribute list type. */
343: if (strncmp (argv[1], "i", 1) == 0)
344: type = DISTRIBUTE_IN;
345: else if (strncmp (argv[1], "o", 1) == 0)
346: type = DISTRIBUTE_OUT;
347: else
348: {
349: vty_out (vty, "distribute list direction must be [in|out]%s",
350: VTY_NEWLINE);
351: return CMD_WARNING;
352: }
353:
354: ret = distribute_list_unset (NULL, type, argv[0]);
355: if (! ret)
356: {
357: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
358: return CMD_WARNING;
359: }
360: return CMD_SUCCESS;
361: }
362:
363: ALIAS (no_distribute_list_all,
364: no_ipv6_distribute_list_all_cmd,
365: "no distribute-list WORD (in|out)",
366: NO_STR
367: "Filter networks in routing updates\n"
368: "Access-list name\n"
369: "Filter incoming routing updates\n"
370: "Filter outgoing routing updates\n")
371:
372: DEFUN (distribute_list,
373: distribute_list_cmd,
374: "distribute-list WORD (in|out) WORD",
375: "Filter networks in routing updates\n"
376: "Access-list name\n"
377: "Filter incoming routing updates\n"
378: "Filter outgoing routing updates\n"
379: "Interface name\n")
380: {
381: enum distribute_type type;
382: struct distribute *dist;
383:
384: /* Check of distribute list type. */
385: if (strncmp (argv[1], "i", 1) == 0)
386: type = DISTRIBUTE_IN;
387: else if (strncmp (argv[1], "o", 1) == 0)
388: type = DISTRIBUTE_OUT;
389: else
390: {
391: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
392: return CMD_WARNING;
393: }
394:
395: /* Get interface name corresponding distribute list. */
396: dist = distribute_list_set (argv[2], type, argv[0]);
397:
398: return CMD_SUCCESS;
399: }
400:
401: ALIAS (distribute_list,
402: ipv6_distribute_list_cmd,
403: "distribute-list WORD (in|out) WORD",
404: "Filter networks in routing updates\n"
405: "Access-list name\n"
406: "Filter incoming routing updates\n"
407: "Filter outgoing routing updates\n"
408: "Interface name\n")
409:
410: DEFUN (no_districute_list, no_distribute_list_cmd,
411: "no distribute-list WORD (in|out) WORD",
412: NO_STR
413: "Filter networks in routing updates\n"
414: "Access-list name\n"
415: "Filter incoming routing updates\n"
416: "Filter outgoing routing updates\n"
417: "Interface name\n")
418: {
419: int ret;
420: enum distribute_type type;
421:
422: /* Check of distribute list type. */
423: if (strncmp (argv[1], "i", 1) == 0)
424: type = DISTRIBUTE_IN;
425: else if (strncmp (argv[1], "o", 1) == 0)
426: type = DISTRIBUTE_OUT;
427: else
428: {
429: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
430: return CMD_WARNING;
431: }
432:
433: ret = distribute_list_unset (argv[2], type, argv[0]);
434: if (! ret)
435: {
436: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
437: return CMD_WARNING;
438: }
439: return CMD_SUCCESS;
440: }
441:
442: ALIAS (no_districute_list, no_ipv6_distribute_list_cmd,
443: "no distribute-list WORD (in|out) WORD",
444: NO_STR
445: "Filter networks in routing updates\n"
446: "Access-list name\n"
447: "Filter incoming routing updates\n"
448: "Filter outgoing routing updates\n"
449: "Interface name\n")
450:
451: DEFUN (districute_list_prefix_all,
452: distribute_list_prefix_all_cmd,
453: "distribute-list prefix WORD (in|out)",
454: "Filter networks in routing updates\n"
455: "Filter prefixes in routing updates\n"
456: "Name of an IP prefix-list\n"
457: "Filter incoming routing updates\n"
458: "Filter outgoing routing updates\n")
459: {
460: enum distribute_type type;
461: struct distribute *dist;
462:
463: /* Check of distribute list type. */
464: if (strncmp (argv[1], "i", 1) == 0)
465: type = DISTRIBUTE_IN;
466: else if (strncmp (argv[1], "o", 1) == 0)
467: type = DISTRIBUTE_OUT;
468: else
469: {
470: vty_out (vty, "distribute list direction must be [in|out]%s",
471: VTY_NEWLINE);
472: return CMD_WARNING;
473: }
474:
475: /* Get interface name corresponding distribute list. */
476: dist = distribute_list_prefix_set (NULL, type, argv[0]);
477:
478: return CMD_SUCCESS;
479: }
480:
481: ALIAS (districute_list_prefix_all,
482: ipv6_distribute_list_prefix_all_cmd,
483: "distribute-list prefix WORD (in|out)",
484: "Filter networks in routing updates\n"
485: "Filter prefixes in routing updates\n"
486: "Name of an IP prefix-list\n"
487: "Filter incoming routing updates\n"
488: "Filter outgoing routing updates\n")
489:
490: DEFUN (no_districute_list_prefix_all,
491: no_distribute_list_prefix_all_cmd,
492: "no distribute-list prefix WORD (in|out)",
493: NO_STR
494: "Filter networks in routing updates\n"
495: "Filter prefixes in routing updates\n"
496: "Name of an IP prefix-list\n"
497: "Filter incoming routing updates\n"
498: "Filter outgoing routing updates\n")
499: {
500: int ret;
501: enum distribute_type type;
502:
503: /* Check of distribute list type. */
504: if (strncmp (argv[1], "i", 1) == 0)
505: type = DISTRIBUTE_IN;
506: else if (strncmp (argv[1], "o", 1) == 0)
507: type = DISTRIBUTE_OUT;
508: else
509: {
510: vty_out (vty, "distribute list direction must be [in|out]%s",
511: VTY_NEWLINE);
512: return CMD_WARNING;
513: }
514:
515: ret = distribute_list_prefix_unset (NULL, type, argv[0]);
516: if (! ret)
517: {
518: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
519: return CMD_WARNING;
520: }
521: return CMD_SUCCESS;
522: }
523:
524: ALIAS (no_districute_list_prefix_all,
525: no_ipv6_distribute_list_prefix_all_cmd,
526: "no distribute-list prefix WORD (in|out)",
527: NO_STR
528: "Filter networks in routing updates\n"
529: "Filter prefixes in routing updates\n"
530: "Name of an IP prefix-list\n"
531: "Filter incoming routing updates\n"
532: "Filter outgoing routing updates\n")
533:
534: DEFUN (districute_list_prefix, distribute_list_prefix_cmd,
535: "distribute-list prefix WORD (in|out) WORD",
536: "Filter networks in routing updates\n"
537: "Filter prefixes in routing updates\n"
538: "Name of an IP prefix-list\n"
539: "Filter incoming routing updates\n"
540: "Filter outgoing routing updates\n"
541: "Interface name\n")
542: {
543: enum distribute_type type;
544: struct distribute *dist;
545:
546: /* Check of distribute list type. */
547: if (strncmp (argv[1], "i", 1) == 0)
548: type = DISTRIBUTE_IN;
549: else if (strncmp (argv[1], "o", 1) == 0)
550: type = DISTRIBUTE_OUT;
551: else
552: {
553: vty_out (vty, "distribute list direction must be [in|out]%s",
554: VTY_NEWLINE);
555: return CMD_WARNING;
556: }
557:
558: /* Get interface name corresponding distribute list. */
559: dist = distribute_list_prefix_set (argv[2], type, argv[0]);
560:
561: return CMD_SUCCESS;
562: }
563:
564: ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd,
565: "distribute-list prefix WORD (in|out) WORD",
566: "Filter networks in routing updates\n"
567: "Filter prefixes in routing updates\n"
568: "Name of an IP prefix-list\n"
569: "Filter incoming routing updates\n"
570: "Filter outgoing routing updates\n"
571: "Interface name\n")
572:
573: DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd,
574: "no distribute-list prefix WORD (in|out) WORD",
575: NO_STR
576: "Filter networks in routing updates\n"
577: "Filter prefixes in routing updates\n"
578: "Name of an IP prefix-list\n"
579: "Filter incoming routing updates\n"
580: "Filter outgoing routing updates\n"
581: "Interface name\n")
582: {
583: int ret;
584: enum distribute_type type;
585:
586: /* Check of distribute list type. */
587: if (strncmp (argv[1], "i", 1) == 0)
588: type = DISTRIBUTE_IN;
589: else if (strncmp (argv[1], "o", 1) == 0)
590: type = DISTRIBUTE_OUT;
591: else
592: {
593: vty_out (vty, "distribute list direction must be [in|out]%s",
594: VTY_NEWLINE);
595: return CMD_WARNING;
596: }
597:
598: ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
599: if (! ret)
600: {
601: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
602: return CMD_WARNING;
603: }
604: return CMD_SUCCESS;
605: }
606:
607: ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
608: "no distribute-list prefix WORD (in|out) WORD",
609: NO_STR
610: "Filter networks in routing updates\n"
611: "Filter prefixes in routing updates\n"
612: "Name of an IP prefix-list\n"
613: "Filter incoming routing updates\n"
614: "Filter outgoing routing updates\n"
615: "Interface name\n")
616:
617: int
618: config_show_distribute (struct vty *vty)
619: {
620: unsigned int i;
621: struct hash_backet *mp;
622: struct distribute *dist;
623:
624: /* Output filter configuration. */
625: dist = distribute_lookup (NULL);
626: if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
627: {
628: vty_out (vty, " Outgoing update filter list for all interface is");
629: if (dist->list[DISTRIBUTE_OUT])
630: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
631: if (dist->prefix[DISTRIBUTE_OUT])
632: vty_out (vty, "%s (prefix-list) %s",
633: dist->list[DISTRIBUTE_OUT] ? "," : "",
634: dist->prefix[DISTRIBUTE_OUT]);
635: vty_out (vty, "%s", VTY_NEWLINE);
636: }
637: else
638: vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
639:
640: for (i = 0; i < disthash->size; i++)
641: for (mp = disthash->index[i]; mp; mp = mp->next)
642: {
643: dist = mp->data;
644: if (dist->ifname)
645: if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
646: {
647: vty_out (vty, " %s filtered by", dist->ifname);
648: if (dist->list[DISTRIBUTE_OUT])
649: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
650: if (dist->prefix[DISTRIBUTE_OUT])
651: vty_out (vty, "%s (prefix-list) %s",
652: dist->list[DISTRIBUTE_OUT] ? "," : "",
653: dist->prefix[DISTRIBUTE_OUT]);
654: vty_out (vty, "%s", VTY_NEWLINE);
655: }
656: }
657:
658:
659: /* Input filter configuration. */
660: dist = distribute_lookup (NULL);
661: if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
662: {
663: vty_out (vty, " Incoming update filter list for all interface is");
664: if (dist->list[DISTRIBUTE_IN])
665: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
666: if (dist->prefix[DISTRIBUTE_IN])
667: vty_out (vty, "%s (prefix-list) %s",
668: dist->list[DISTRIBUTE_IN] ? "," : "",
669: dist->prefix[DISTRIBUTE_IN]);
670: vty_out (vty, "%s", VTY_NEWLINE);
671: }
672: else
673: vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
674:
675: for (i = 0; i < disthash->size; i++)
676: for (mp = disthash->index[i]; mp; mp = mp->next)
677: {
678: dist = mp->data;
679: if (dist->ifname)
680: if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
681: {
682: vty_out (vty, " %s filtered by", dist->ifname);
683: if (dist->list[DISTRIBUTE_IN])
684: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
685: if (dist->prefix[DISTRIBUTE_IN])
686: vty_out (vty, "%s (prefix-list) %s",
687: dist->list[DISTRIBUTE_IN] ? "," : "",
688: dist->prefix[DISTRIBUTE_IN]);
689: vty_out (vty, "%s", VTY_NEWLINE);
690: }
691: }
692: return 0;
693: }
694:
695: /* Configuration write function. */
696: int
697: config_write_distribute (struct vty *vty)
698: {
699: unsigned int i;
700: struct hash_backet *mp;
701: int write = 0;
702:
703: for (i = 0; i < disthash->size; i++)
704: for (mp = disthash->index[i]; mp; mp = mp->next)
705: {
706: struct distribute *dist;
707:
708: dist = mp->data;
709:
710: if (dist->list[DISTRIBUTE_IN])
711: {
712: vty_out (vty, " distribute-list %s in %s%s",
713: dist->list[DISTRIBUTE_IN],
714: dist->ifname ? dist->ifname : "",
715: VTY_NEWLINE);
716: write++;
717: }
718:
719: if (dist->list[DISTRIBUTE_OUT])
720: {
721: vty_out (vty, " distribute-list %s out %s%s",
722:
723: dist->list[DISTRIBUTE_OUT],
724: dist->ifname ? dist->ifname : "",
725: VTY_NEWLINE);
726: write++;
727: }
728:
729: if (dist->prefix[DISTRIBUTE_IN])
730: {
731: vty_out (vty, " distribute-list prefix %s in %s%s",
732: dist->prefix[DISTRIBUTE_IN],
733: dist->ifname ? dist->ifname : "",
734: VTY_NEWLINE);
735: write++;
736: }
737:
738: if (dist->prefix[DISTRIBUTE_OUT])
739: {
740: vty_out (vty, " distribute-list prefix %s out %s%s",
741: dist->prefix[DISTRIBUTE_OUT],
742: dist->ifname ? dist->ifname : "",
743: VTY_NEWLINE);
744: write++;
745: }
746: }
747: return write;
748: }
749:
750: /* Clear all distribute list. */
751: void
752: distribute_list_reset ()
753: {
754: hash_clean (disthash, (void (*) (void *)) distribute_free);
755: }
756:
757: /* Initialize distribute list related hash. */
758: void
759: distribute_list_init (int node)
760: {
761: disthash = hash_create (distribute_hash_make,
762: (int (*) (const void *, const void *)) distribute_cmp);
763:
764: if(node==RIP_NODE) {
765: install_element (RIP_NODE, &distribute_list_all_cmd);
766: install_element (RIP_NODE, &no_distribute_list_all_cmd);
767: install_element (RIP_NODE, &distribute_list_cmd);
768: install_element (RIP_NODE, &no_distribute_list_cmd);
769: install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
770: install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
771: install_element (RIP_NODE, &distribute_list_prefix_cmd);
772: install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
773: } else {
774: install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
775: install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
776: install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
777: install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
778: install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
779: install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
780: install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
781: install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
782: }
783: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>