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