]> git.proxmox.com Git - mirror_frr.git/blob - lib/distribute.c
Merge quagga mainline into the google ISIS code.
[mirror_frr.git] / lib / distribute.c
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 \f
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 \f
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. */
316 distribute_list_set (NULL, type, argv[0]);
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. */
394 distribute_list_set (argv[2], type, argv[0]);
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
408 DEFUN (no_distribute_list, no_distribute_list_cmd,
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
440 ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
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
449 DEFUN (distribute_list_prefix_all,
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. */
473 distribute_list_prefix_set (NULL, type, argv[0]);
474
475 return CMD_SUCCESS;
476 }
477
478 ALIAS (distribute_list_prefix_all,
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
487 DEFUN (no_distribute_list_prefix_all,
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
521 ALIAS (no_distribute_list_prefix_all,
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
531 DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
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. */
555 distribute_list_prefix_set (argv[2], type, argv[0]);
556
557 return CMD_SUCCESS;
558 }
559
560 ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
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
569 DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
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
603 ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
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) {
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);
781 }
782 }