Annotation of embedaddon/quagga/lib/distribute.c, revision 1.1.1.3
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 *);
1.1.1.3 ! misho 37:
1.1 misho 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: }
1.1.1.3 ! misho 136:
1.1 misho 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:
303: /* Check of distribute list type. */
304: if (strncmp (argv[1], "i", 1) == 0)
305: type = DISTRIBUTE_IN;
306: else if (strncmp (argv[1], "o", 1) == 0)
307: type = DISTRIBUTE_OUT;
308: else
309: {
310: vty_out (vty, "distribute list direction must be [in|out]%s",
311: VTY_NEWLINE);
312: return CMD_WARNING;
313: }
314:
315: /* Get interface name corresponding distribute list. */
1.1.1.2 misho 316: distribute_list_set (NULL, type, argv[0]);
1.1 misho 317:
318: return CMD_SUCCESS;
319: }
320:
321: ALIAS (distribute_list_all,
322: ipv6_distribute_list_all_cmd,
323: "distribute-list WORD (in|out)",
324: "Filter networks in routing updates\n"
325: "Access-list name\n"
326: "Filter incoming routing updates\n"
327: "Filter outgoing routing updates\n")
328:
329: DEFUN (no_distribute_list_all,
330: no_distribute_list_all_cmd,
331: "no distribute-list WORD (in|out)",
332: NO_STR
333: "Filter networks in routing updates\n"
334: "Access-list name\n"
335: "Filter incoming routing updates\n"
336: "Filter outgoing routing updates\n")
337: {
338: int ret;
339: enum distribute_type type;
340:
341: /* Check of distribute list type. */
342: if (strncmp (argv[1], "i", 1) == 0)
343: type = DISTRIBUTE_IN;
344: else if (strncmp (argv[1], "o", 1) == 0)
345: type = DISTRIBUTE_OUT;
346: else
347: {
348: vty_out (vty, "distribute list direction must be [in|out]%s",
349: VTY_NEWLINE);
350: return CMD_WARNING;
351: }
352:
353: ret = distribute_list_unset (NULL, type, argv[0]);
354: if (! ret)
355: {
356: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
357: return CMD_WARNING;
358: }
359: return CMD_SUCCESS;
360: }
361:
362: ALIAS (no_distribute_list_all,
363: no_ipv6_distribute_list_all_cmd,
364: "no distribute-list WORD (in|out)",
365: NO_STR
366: "Filter networks in routing updates\n"
367: "Access-list name\n"
368: "Filter incoming routing updates\n"
369: "Filter outgoing routing updates\n")
370:
371: DEFUN (distribute_list,
372: distribute_list_cmd,
373: "distribute-list WORD (in|out) WORD",
374: "Filter networks in routing updates\n"
375: "Access-list name\n"
376: "Filter incoming routing updates\n"
377: "Filter outgoing routing updates\n"
378: "Interface name\n")
379: {
380: enum distribute_type type;
381:
382: /* Check of distribute list type. */
383: if (strncmp (argv[1], "i", 1) == 0)
384: type = DISTRIBUTE_IN;
385: else if (strncmp (argv[1], "o", 1) == 0)
386: type = DISTRIBUTE_OUT;
387: else
388: {
389: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
390: return CMD_WARNING;
391: }
392:
393: /* Get interface name corresponding distribute list. */
1.1.1.2 misho 394: distribute_list_set (argv[2], type, argv[0]);
1.1 misho 395:
396: return CMD_SUCCESS;
397: }
398:
399: ALIAS (distribute_list,
400: ipv6_distribute_list_cmd,
401: "distribute-list WORD (in|out) WORD",
402: "Filter networks in routing updates\n"
403: "Access-list name\n"
404: "Filter incoming routing updates\n"
405: "Filter outgoing routing updates\n"
406: "Interface name\n")
407:
1.1.1.2 misho 408: DEFUN (no_distribute_list, no_distribute_list_cmd,
1.1 misho 409: "no distribute-list WORD (in|out) WORD",
410: NO_STR
411: "Filter networks in routing updates\n"
412: "Access-list name\n"
413: "Filter incoming routing updates\n"
414: "Filter outgoing routing updates\n"
415: "Interface name\n")
416: {
417: int ret;
418: enum distribute_type type;
419:
420: /* Check of distribute list type. */
421: if (strncmp (argv[1], "i", 1) == 0)
422: type = DISTRIBUTE_IN;
423: else if (strncmp (argv[1], "o", 1) == 0)
424: type = DISTRIBUTE_OUT;
425: else
426: {
427: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
428: return CMD_WARNING;
429: }
430:
431: ret = distribute_list_unset (argv[2], type, argv[0]);
432: if (! ret)
433: {
434: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
435: return CMD_WARNING;
436: }
437: return CMD_SUCCESS;
438: }
439:
1.1.1.2 misho 440: ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
1.1 misho 441: "no distribute-list WORD (in|out) WORD",
442: NO_STR
443: "Filter networks in routing updates\n"
444: "Access-list name\n"
445: "Filter incoming routing updates\n"
446: "Filter outgoing routing updates\n"
447: "Interface name\n")
448:
1.1.1.2 misho 449: DEFUN (distribute_list_prefix_all,
1.1 misho 450: distribute_list_prefix_all_cmd,
451: "distribute-list prefix WORD (in|out)",
452: "Filter networks in routing updates\n"
453: "Filter prefixes in routing updates\n"
454: "Name of an IP prefix-list\n"
455: "Filter incoming routing updates\n"
456: "Filter outgoing routing updates\n")
457: {
458: enum distribute_type type;
459:
460: /* Check of distribute list type. */
461: if (strncmp (argv[1], "i", 1) == 0)
462: type = DISTRIBUTE_IN;
463: else if (strncmp (argv[1], "o", 1) == 0)
464: type = DISTRIBUTE_OUT;
465: else
466: {
467: vty_out (vty, "distribute list direction must be [in|out]%s",
468: VTY_NEWLINE);
469: return CMD_WARNING;
470: }
471:
472: /* Get interface name corresponding distribute list. */
1.1.1.2 misho 473: distribute_list_prefix_set (NULL, type, argv[0]);
1.1 misho 474:
475: return CMD_SUCCESS;
476: }
477:
1.1.1.2 misho 478: ALIAS (distribute_list_prefix_all,
1.1 misho 479: ipv6_distribute_list_prefix_all_cmd,
480: "distribute-list prefix WORD (in|out)",
481: "Filter networks in routing updates\n"
482: "Filter prefixes in routing updates\n"
483: "Name of an IP prefix-list\n"
484: "Filter incoming routing updates\n"
485: "Filter outgoing routing updates\n")
486:
1.1.1.2 misho 487: DEFUN (no_distribute_list_prefix_all,
1.1 misho 488: no_distribute_list_prefix_all_cmd,
489: "no distribute-list prefix WORD (in|out)",
490: NO_STR
491: "Filter networks in routing updates\n"
492: "Filter prefixes in routing updates\n"
493: "Name of an IP prefix-list\n"
494: "Filter incoming routing updates\n"
495: "Filter outgoing routing updates\n")
496: {
497: int ret;
498: enum distribute_type type;
499:
500: /* Check of distribute list type. */
501: if (strncmp (argv[1], "i", 1) == 0)
502: type = DISTRIBUTE_IN;
503: else if (strncmp (argv[1], "o", 1) == 0)
504: type = DISTRIBUTE_OUT;
505: else
506: {
507: vty_out (vty, "distribute list direction must be [in|out]%s",
508: VTY_NEWLINE);
509: return CMD_WARNING;
510: }
511:
512: ret = distribute_list_prefix_unset (NULL, type, argv[0]);
513: if (! ret)
514: {
515: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
516: return CMD_WARNING;
517: }
518: return CMD_SUCCESS;
519: }
520:
1.1.1.2 misho 521: ALIAS (no_distribute_list_prefix_all,
1.1 misho 522: no_ipv6_distribute_list_prefix_all_cmd,
523: "no distribute-list prefix WORD (in|out)",
524: NO_STR
525: "Filter networks in routing updates\n"
526: "Filter prefixes in routing updates\n"
527: "Name of an IP prefix-list\n"
528: "Filter incoming routing updates\n"
529: "Filter outgoing routing updates\n")
530:
1.1.1.2 misho 531: DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
1.1 misho 532: "distribute-list prefix WORD (in|out) WORD",
533: "Filter networks in routing updates\n"
534: "Filter prefixes in routing updates\n"
535: "Name of an IP prefix-list\n"
536: "Filter incoming routing updates\n"
537: "Filter outgoing routing updates\n"
538: "Interface name\n")
539: {
540: enum distribute_type type;
541:
542: /* Check of distribute list type. */
543: if (strncmp (argv[1], "i", 1) == 0)
544: type = DISTRIBUTE_IN;
545: else if (strncmp (argv[1], "o", 1) == 0)
546: type = DISTRIBUTE_OUT;
547: else
548: {
549: vty_out (vty, "distribute list direction must be [in|out]%s",
550: VTY_NEWLINE);
551: return CMD_WARNING;
552: }
553:
554: /* Get interface name corresponding distribute list. */
1.1.1.2 misho 555: distribute_list_prefix_set (argv[2], type, argv[0]);
1.1 misho 556:
557: return CMD_SUCCESS;
558: }
559:
1.1.1.2 misho 560: ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
1.1 misho 561: "distribute-list prefix WORD (in|out) WORD",
562: "Filter networks in routing updates\n"
563: "Filter prefixes in routing updates\n"
564: "Name of an IP prefix-list\n"
565: "Filter incoming routing updates\n"
566: "Filter outgoing routing updates\n"
567: "Interface name\n")
568:
1.1.1.2 misho 569: DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
1.1 misho 570: "no distribute-list prefix WORD (in|out) WORD",
571: NO_STR
572: "Filter networks in routing updates\n"
573: "Filter prefixes in routing updates\n"
574: "Name of an IP prefix-list\n"
575: "Filter incoming routing updates\n"
576: "Filter outgoing routing updates\n"
577: "Interface name\n")
578: {
579: int ret;
580: enum distribute_type type;
581:
582: /* Check of distribute list type. */
583: if (strncmp (argv[1], "i", 1) == 0)
584: type = DISTRIBUTE_IN;
585: else if (strncmp (argv[1], "o", 1) == 0)
586: type = DISTRIBUTE_OUT;
587: else
588: {
589: vty_out (vty, "distribute list direction must be [in|out]%s",
590: VTY_NEWLINE);
591: return CMD_WARNING;
592: }
593:
594: ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
595: if (! ret)
596: {
597: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
598: return CMD_WARNING;
599: }
600: return CMD_SUCCESS;
601: }
602:
1.1.1.2 misho 603: ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
1.1 misho 604: "no distribute-list prefix WORD (in|out) WORD",
605: NO_STR
606: "Filter networks in routing updates\n"
607: "Filter prefixes in routing updates\n"
608: "Name of an IP prefix-list\n"
609: "Filter incoming routing updates\n"
610: "Filter outgoing routing updates\n"
611: "Interface name\n")
612:
613: int
614: config_show_distribute (struct vty *vty)
615: {
616: unsigned int i;
617: struct hash_backet *mp;
618: struct distribute *dist;
619:
620: /* Output filter configuration. */
621: dist = distribute_lookup (NULL);
622: if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
623: {
624: vty_out (vty, " Outgoing update filter list for all interface is");
625: if (dist->list[DISTRIBUTE_OUT])
626: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
627: if (dist->prefix[DISTRIBUTE_OUT])
628: vty_out (vty, "%s (prefix-list) %s",
629: dist->list[DISTRIBUTE_OUT] ? "," : "",
630: dist->prefix[DISTRIBUTE_OUT]);
631: vty_out (vty, "%s", VTY_NEWLINE);
632: }
633: else
634: vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
635:
636: for (i = 0; i < disthash->size; i++)
637: for (mp = disthash->index[i]; mp; mp = mp->next)
638: {
639: dist = mp->data;
640: if (dist->ifname)
641: if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
642: {
643: vty_out (vty, " %s filtered by", dist->ifname);
644: if (dist->list[DISTRIBUTE_OUT])
645: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
646: if (dist->prefix[DISTRIBUTE_OUT])
647: vty_out (vty, "%s (prefix-list) %s",
648: dist->list[DISTRIBUTE_OUT] ? "," : "",
649: dist->prefix[DISTRIBUTE_OUT]);
650: vty_out (vty, "%s", VTY_NEWLINE);
651: }
652: }
653:
654:
655: /* Input filter configuration. */
656: dist = distribute_lookup (NULL);
657: if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
658: {
659: vty_out (vty, " Incoming update filter list for all interface is");
660: if (dist->list[DISTRIBUTE_IN])
661: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
662: if (dist->prefix[DISTRIBUTE_IN])
663: vty_out (vty, "%s (prefix-list) %s",
664: dist->list[DISTRIBUTE_IN] ? "," : "",
665: dist->prefix[DISTRIBUTE_IN]);
666: vty_out (vty, "%s", VTY_NEWLINE);
667: }
668: else
669: vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
670:
671: for (i = 0; i < disthash->size; i++)
672: for (mp = disthash->index[i]; mp; mp = mp->next)
673: {
674: dist = mp->data;
675: if (dist->ifname)
676: if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
677: {
678: vty_out (vty, " %s filtered by", dist->ifname);
679: if (dist->list[DISTRIBUTE_IN])
680: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
681: if (dist->prefix[DISTRIBUTE_IN])
682: vty_out (vty, "%s (prefix-list) %s",
683: dist->list[DISTRIBUTE_IN] ? "," : "",
684: dist->prefix[DISTRIBUTE_IN]);
685: vty_out (vty, "%s", VTY_NEWLINE);
686: }
687: }
688: return 0;
689: }
690:
691: /* Configuration write function. */
692: int
693: config_write_distribute (struct vty *vty)
694: {
695: unsigned int i;
696: struct hash_backet *mp;
697: int write = 0;
698:
699: for (i = 0; i < disthash->size; i++)
700: for (mp = disthash->index[i]; mp; mp = mp->next)
701: {
702: struct distribute *dist;
703:
704: dist = mp->data;
705:
706: if (dist->list[DISTRIBUTE_IN])
707: {
708: vty_out (vty, " distribute-list %s in %s%s",
709: dist->list[DISTRIBUTE_IN],
710: dist->ifname ? dist->ifname : "",
711: VTY_NEWLINE);
712: write++;
713: }
714:
715: if (dist->list[DISTRIBUTE_OUT])
716: {
717: vty_out (vty, " distribute-list %s out %s%s",
718:
719: dist->list[DISTRIBUTE_OUT],
720: dist->ifname ? dist->ifname : "",
721: VTY_NEWLINE);
722: write++;
723: }
724:
725: if (dist->prefix[DISTRIBUTE_IN])
726: {
727: vty_out (vty, " distribute-list prefix %s in %s%s",
728: dist->prefix[DISTRIBUTE_IN],
729: dist->ifname ? dist->ifname : "",
730: VTY_NEWLINE);
731: write++;
732: }
733:
734: if (dist->prefix[DISTRIBUTE_OUT])
735: {
736: vty_out (vty, " distribute-list prefix %s out %s%s",
737: dist->prefix[DISTRIBUTE_OUT],
738: dist->ifname ? dist->ifname : "",
739: VTY_NEWLINE);
740: write++;
741: }
742: }
743: return write;
744: }
745:
746: /* Clear all distribute list. */
747: void
748: distribute_list_reset ()
749: {
750: hash_clean (disthash, (void (*) (void *)) distribute_free);
751: }
752:
753: /* Initialize distribute list related hash. */
754: void
755: distribute_list_init (int node)
756: {
757: disthash = hash_create (distribute_hash_make,
758: (int (*) (const void *, const void *)) distribute_cmp);
759:
760: if(node==RIP_NODE) {
1.1.1.2 misho 761: install_element (node, &distribute_list_all_cmd);
762: install_element (node, &no_distribute_list_all_cmd);
763: install_element (node, &distribute_list_cmd);
764: install_element (node, &no_distribute_list_cmd);
765: install_element (node, &distribute_list_prefix_all_cmd);
766: install_element (node, &no_distribute_list_prefix_all_cmd);
767: install_element (node, &distribute_list_prefix_cmd);
768: install_element (node, &no_distribute_list_prefix_cmd);
769: } else if (node == RIPNG_NODE || node == BABEL_NODE) {
770: /* WARNING: two identical commands installed do a crash, so be worry with
771: aliases. For this reason, and because all these commands are aliases, Babel
772: is not set with RIP. */
773: install_element (node, &ipv6_distribute_list_all_cmd);
774: install_element (node, &no_ipv6_distribute_list_all_cmd);
775: install_element (node, &ipv6_distribute_list_cmd);
776: install_element (node, &no_ipv6_distribute_list_cmd);
777: install_element (node, &ipv6_distribute_list_prefix_all_cmd);
778: install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
779: install_element (node, &ipv6_distribute_list_prefix_cmd);
780: install_element (node, &no_ipv6_distribute_list_prefix_cmd);
1.1 misho 781: }
782: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>