blob: 78de4bfbc8526b3f17460c76ffbacf0738034acb [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{
hasso8c328f12004-10-05 21:01:23 +0000122 unsigned int i, key;
paul718e3742002-12-13 20:15:29 +0000123
124 key = 0;
125 if (dist->ifname)
126 for (i = 0; i < strlen (dist->ifname); i++)
127 key += dist->ifname[i];
128
129 return key;
130}
131
132/* If two distribute-list have same value then return 1 else return
133 0. This function is used by hash package. */
134int
135distribute_cmp (struct distribute *dist1, struct distribute *dist2)
136{
137 if (dist1->ifname && dist2->ifname)
138 if (strcmp (dist1->ifname, dist2->ifname) == 0)
139 return 1;
140 if (! dist1->ifname && ! dist2->ifname)
141 return 1;
142 return 0;
143}
144
145/* Set access-list name to the distribute list. */
146struct distribute *
147distribute_list_set (char *ifname, enum distribute_type type, char *alist_name)
148{
149 struct distribute *dist;
150
151 dist = distribute_get (ifname);
152
153 if (type == DISTRIBUTE_IN)
154 {
155 if (dist->list[DISTRIBUTE_IN])
156 free (dist->list[DISTRIBUTE_IN]);
157 dist->list[DISTRIBUTE_IN] = strdup (alist_name);
158 }
159 if (type == DISTRIBUTE_OUT)
160 {
161 if (dist->list[DISTRIBUTE_OUT])
162 free (dist->list[DISTRIBUTE_OUT]);
163 dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
164 }
165
166 /* Apply this distribute-list to the interface. */
167 (*distribute_add_hook) (dist);
168
169 return dist;
170}
171
172/* Unset distribute-list. If matched distribute-list exist then
173 return 1. */
174int
175distribute_list_unset (char *ifname, enum distribute_type type,
176 char *alist_name)
177{
178 struct distribute *dist;
179
180 dist = distribute_lookup (ifname);
181 if (!dist)
182 return 0;
183
184 if (type == DISTRIBUTE_IN)
185 {
186 if (!dist->list[DISTRIBUTE_IN])
187 return 0;
188 if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
189 return 0;
190
191 free (dist->list[DISTRIBUTE_IN]);
192 dist->list[DISTRIBUTE_IN] = NULL;
193 }
194
195 if (type == DISTRIBUTE_OUT)
196 {
197 if (!dist->list[DISTRIBUTE_OUT])
198 return 0;
199 if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
200 return 0;
201
202 free (dist->list[DISTRIBUTE_OUT]);
203 dist->list[DISTRIBUTE_OUT] = NULL;
204 }
205
206 /* Apply this distribute-list to the interface. */
207 (*distribute_delete_hook) (dist);
208
209 /* If both out and in is NULL then free distribute list. */
210 if (dist->list[DISTRIBUTE_IN] == NULL &&
211 dist->list[DISTRIBUTE_OUT] == NULL &&
212 dist->prefix[DISTRIBUTE_IN] == NULL &&
213 dist->prefix[DISTRIBUTE_OUT] == NULL)
214 {
215 hash_release (disthash, dist);
216 distribute_free (dist);
217 }
218
219 return 1;
220}
221
222/* Set access-list name to the distribute list. */
223struct distribute *
224distribute_list_prefix_set (char *ifname, enum distribute_type type,
225 char *plist_name)
226{
227 struct distribute *dist;
228
229 dist = distribute_get (ifname);
230
231 if (type == DISTRIBUTE_IN)
232 {
233 if (dist->prefix[DISTRIBUTE_IN])
234 free (dist->prefix[DISTRIBUTE_IN]);
235 dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
236 }
237 if (type == DISTRIBUTE_OUT)
238 {
239 if (dist->prefix[DISTRIBUTE_OUT])
240 free (dist->prefix[DISTRIBUTE_OUT]);
241 dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
242 }
243
244 /* Apply this distribute-list to the interface. */
245 (*distribute_add_hook) (dist);
246
247 return dist;
248}
249
250/* Unset distribute-list. If matched distribute-list exist then
251 return 1. */
252int
253distribute_list_prefix_unset (char *ifname, enum distribute_type type,
254 char *plist_name)
255{
256 struct distribute *dist;
257
258 dist = distribute_lookup (ifname);
259 if (!dist)
260 return 0;
261
262 if (type == DISTRIBUTE_IN)
263 {
264 if (!dist->prefix[DISTRIBUTE_IN])
265 return 0;
266 if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
267 return 0;
268
269 free (dist->prefix[DISTRIBUTE_IN]);
270 dist->prefix[DISTRIBUTE_IN] = NULL;
271 }
272
273 if (type == DISTRIBUTE_OUT)
274 {
275 if (!dist->prefix[DISTRIBUTE_OUT])
276 return 0;
277 if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
278 return 0;
279
280 free (dist->prefix[DISTRIBUTE_OUT]);
281 dist->prefix[DISTRIBUTE_OUT] = NULL;
282 }
283
284 /* Apply this distribute-list to the interface. */
285 (*distribute_delete_hook) (dist);
286
287 /* If both out and in is NULL then free distribute list. */
288 if (dist->list[DISTRIBUTE_IN] == NULL &&
289 dist->list[DISTRIBUTE_OUT] == NULL &&
290 dist->prefix[DISTRIBUTE_IN] == NULL &&
291 dist->prefix[DISTRIBUTE_OUT] == NULL)
292 {
293 hash_release (disthash, dist);
294 distribute_free (dist);
295 }
296
297 return 1;
298}
299
300DEFUN (distribute_list_all,
301 distribute_list_all_cmd,
302 "distribute-list WORD (in|out)",
303 "Filter networks in routing updates\n"
304 "Access-list name\n"
305 "Filter incoming routing updates\n"
306 "Filter outgoing routing updates\n")
307{
308 enum distribute_type type;
309 struct distribute *dist;
310
311 /* Check of distribute list type. */
312 if (strncmp (argv[1], "i", 1) == 0)
313 type = DISTRIBUTE_IN;
314 else if (strncmp (argv[1], "o", 1) == 0)
315 type = DISTRIBUTE_OUT;
316 else
317 {
318 vty_out (vty, "distribute list direction must be [in|out]%s",
319 VTY_NEWLINE);
320 return CMD_WARNING;
321 }
322
323 /* Get interface name corresponding distribute list. */
324 dist = distribute_list_set (NULL, type, argv[0]);
325
326 return CMD_SUCCESS;
327}
328
paulba23a692003-04-19 15:55:08 +0000329ALIAS (distribute_list_all,
330 ipv6_distribute_list_all_cmd,
331 "distribute-list WORD (in|out)",
332 "Filter networks in routing updates\n"
333 "Access-list name\n"
334 "Filter incoming routing updates\n"
335 "Filter outgoing routing updates\n")
336
paul718e3742002-12-13 20:15:29 +0000337DEFUN (no_distribute_list_all,
338 no_distribute_list_all_cmd,
339 "no distribute-list WORD (in|out)",
340 NO_STR
341 "Filter networks in routing updates\n"
342 "Access-list name\n"
343 "Filter incoming routing updates\n"
344 "Filter outgoing routing updates\n")
345{
346 int ret;
347 enum distribute_type type;
348
349 /* Check of distribute list type. */
350 if (strncmp (argv[1], "i", 1) == 0)
351 type = DISTRIBUTE_IN;
352 else if (strncmp (argv[1], "o", 1) == 0)
353 type = DISTRIBUTE_OUT;
354 else
355 {
356 vty_out (vty, "distribute list direction must be [in|out]%s",
357 VTY_NEWLINE);
358 return CMD_WARNING;
359 }
360
361 ret = distribute_list_unset (NULL, type, argv[0]);
362 if (! ret)
363 {
364 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
365 return CMD_WARNING;
366 }
367 return CMD_SUCCESS;
368}
369
paulba23a692003-04-19 15:55:08 +0000370ALIAS (no_distribute_list_all,
371 no_ipv6_distribute_list_all_cmd,
372 "no distribute-list WORD (in|out)",
373 NO_STR
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
paul718e3742002-12-13 20:15:29 +0000379DEFUN (distribute_list,
380 distribute_list_cmd,
381 "distribute-list WORD (in|out) WORD",
382 "Filter networks in routing updates\n"
383 "Access-list name\n"
384 "Filter incoming routing updates\n"
385 "Filter outgoing routing updates\n"
386 "Interface name\n")
387{
388 enum distribute_type type;
389 struct distribute *dist;
390
391 /* Check of distribute list type. */
392 if (strncmp (argv[1], "i", 1) == 0)
393 type = DISTRIBUTE_IN;
394 else if (strncmp (argv[1], "o", 1) == 0)
395 type = DISTRIBUTE_OUT;
396 else
397 {
398 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
399 return CMD_WARNING;
400 }
401
402 /* Get interface name corresponding distribute list. */
403 dist = distribute_list_set (argv[2], type, argv[0]);
404
405 return CMD_SUCCESS;
406}
407
paulba23a692003-04-19 15:55:08 +0000408ALIAS (distribute_list,
409 ipv6_distribute_list_cmd,
410 "distribute-list WORD (in|out) WORD",
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
paul718e3742002-12-13 20:15:29 +0000417DEFUN (no_districute_list, no_distribute_list_cmd,
418 "no distribute-list WORD (in|out) WORD",
419 NO_STR
420 "Filter networks in routing updates\n"
421 "Access-list name\n"
422 "Filter incoming routing updates\n"
423 "Filter outgoing routing updates\n"
424 "Interface name\n")
425{
426 int ret;
427 enum distribute_type type;
428
429 /* Check of distribute list type. */
430 if (strncmp (argv[1], "i", 1) == 0)
431 type = DISTRIBUTE_IN;
432 else if (strncmp (argv[1], "o", 1) == 0)
433 type = DISTRIBUTE_OUT;
434 else
435 {
436 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
437 return CMD_WARNING;
438 }
439
440 ret = distribute_list_unset (argv[2], type, argv[0]);
441 if (! ret)
442 {
443 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
444 return CMD_WARNING;
445 }
446 return CMD_SUCCESS;
447}
448
paulba23a692003-04-19 15:55:08 +0000449ALIAS (no_districute_list, no_ipv6_distribute_list_cmd,
450 "no distribute-list WORD (in|out) WORD",
451 NO_STR
452 "Filter networks in routing updates\n"
453 "Access-list name\n"
454 "Filter incoming routing updates\n"
455 "Filter outgoing routing updates\n"
456 "Interface name\n")
457
paul718e3742002-12-13 20:15:29 +0000458DEFUN (districute_list_prefix_all,
459 distribute_list_prefix_all_cmd,
460 "distribute-list prefix WORD (in|out)",
461 "Filter networks in routing updates\n"
462 "Filter prefixes in routing updates\n"
463 "Name of an IP prefix-list\n"
464 "Filter incoming routing updates\n"
465 "Filter outgoing routing updates\n")
466{
467 enum distribute_type type;
468 struct distribute *dist;
469
470 /* Check of distribute list type. */
471 if (strncmp (argv[1], "i", 1) == 0)
472 type = DISTRIBUTE_IN;
473 else if (strncmp (argv[1], "o", 1) == 0)
474 type = DISTRIBUTE_OUT;
475 else
476 {
477 vty_out (vty, "distribute list direction must be [in|out]%s",
478 VTY_NEWLINE);
479 return CMD_WARNING;
480 }
481
482 /* Get interface name corresponding distribute list. */
483 dist = distribute_list_prefix_set (NULL, type, argv[0]);
484
485 return CMD_SUCCESS;
486}
487
paulba23a692003-04-19 15:55:08 +0000488ALIAS (districute_list_prefix_all,
489 ipv6_distribute_list_prefix_all_cmd,
490 "distribute-list prefix WORD (in|out)",
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
paul718e3742002-12-13 20:15:29 +0000497DEFUN (no_districute_list_prefix_all,
498 no_distribute_list_prefix_all_cmd,
499 "no distribute-list prefix WORD (in|out)",
500 NO_STR
501 "Filter networks in routing updates\n"
502 "Filter prefixes in routing updates\n"
503 "Name of an IP prefix-list\n"
504 "Filter incoming routing updates\n"
505 "Filter outgoing routing updates\n")
506{
507 int ret;
508 enum distribute_type type;
509
510 /* Check of distribute list type. */
511 if (strncmp (argv[1], "i", 1) == 0)
512 type = DISTRIBUTE_IN;
513 else if (strncmp (argv[1], "o", 1) == 0)
514 type = DISTRIBUTE_OUT;
515 else
516 {
517 vty_out (vty, "distribute list direction must be [in|out]%s",
518 VTY_NEWLINE);
519 return CMD_WARNING;
520 }
521
522 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
523 if (! ret)
524 {
525 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
526 return CMD_WARNING;
527 }
528 return CMD_SUCCESS;
529}
530
paulba23a692003-04-19 15:55:08 +0000531ALIAS (no_districute_list_prefix_all,
532 no_ipv6_distribute_list_prefix_all_cmd,
533 "no distribute-list prefix WORD (in|out)",
534 NO_STR
535 "Filter networks in routing updates\n"
536 "Filter prefixes in routing updates\n"
537 "Name of an IP prefix-list\n"
538 "Filter incoming routing updates\n"
539 "Filter outgoing routing updates\n")
540
paul718e3742002-12-13 20:15:29 +0000541DEFUN (districute_list_prefix, distribute_list_prefix_cmd,
542 "distribute-list prefix WORD (in|out) WORD",
543 "Filter networks in routing updates\n"
544 "Filter prefixes in routing updates\n"
545 "Name of an IP prefix-list\n"
546 "Filter incoming routing updates\n"
547 "Filter outgoing routing updates\n"
548 "Interface name\n")
549{
550 enum distribute_type type;
551 struct distribute *dist;
552
553 /* Check of distribute list type. */
554 if (strncmp (argv[1], "i", 1) == 0)
555 type = DISTRIBUTE_IN;
556 else if (strncmp (argv[1], "o", 1) == 0)
557 type = DISTRIBUTE_OUT;
558 else
559 {
560 vty_out (vty, "distribute list direction must be [in|out]%s",
561 VTY_NEWLINE);
562 return CMD_WARNING;
563 }
564
565 /* Get interface name corresponding distribute list. */
566 dist = distribute_list_prefix_set (argv[2], type, argv[0]);
567
568 return CMD_SUCCESS;
569}
570
paulba23a692003-04-19 15:55:08 +0000571ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd,
572 "distribute-list prefix WORD (in|out) WORD",
573 "Filter networks in routing updates\n"
574 "Filter prefixes in routing updates\n"
575 "Name of an IP prefix-list\n"
576 "Filter incoming routing updates\n"
577 "Filter outgoing routing updates\n"
578 "Interface name\n")
579
paul718e3742002-12-13 20:15:29 +0000580DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd,
581 "no distribute-list prefix WORD (in|out) WORD",
582 NO_STR
583 "Filter networks in routing updates\n"
584 "Filter prefixes in routing updates\n"
585 "Name of an IP prefix-list\n"
586 "Filter incoming routing updates\n"
587 "Filter outgoing routing updates\n"
588 "Interface name\n")
589{
590 int ret;
591 enum distribute_type type;
592
593 /* Check of distribute list type. */
594 if (strncmp (argv[1], "i", 1) == 0)
595 type = DISTRIBUTE_IN;
596 else if (strncmp (argv[1], "o", 1) == 0)
597 type = DISTRIBUTE_OUT;
598 else
599 {
600 vty_out (vty, "distribute list direction must be [in|out]%s",
601 VTY_NEWLINE);
602 return CMD_WARNING;
603 }
604
605 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
606 if (! ret)
607 {
608 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
609 return CMD_WARNING;
610 }
611 return CMD_SUCCESS;
612}
613
paulba23a692003-04-19 15:55:08 +0000614ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
615 "no distribute-list prefix WORD (in|out) WORD",
616 NO_STR
617 "Filter networks in routing updates\n"
618 "Filter prefixes in routing updates\n"
619 "Name of an IP prefix-list\n"
620 "Filter incoming routing updates\n"
621 "Filter outgoing routing updates\n"
622 "Interface name\n")
623
paul718e3742002-12-13 20:15:29 +0000624int
625config_show_distribute (struct vty *vty)
626{
hasso8c328f12004-10-05 21:01:23 +0000627 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000628 struct hash_backet *mp;
629 struct distribute *dist;
630
631 /* Output filter configuration. */
632 dist = distribute_lookup (NULL);
633 if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
634 {
635 vty_out (vty, " Outgoing update filter list for all interface is");
636 if (dist->list[DISTRIBUTE_OUT])
637 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
638 if (dist->prefix[DISTRIBUTE_OUT])
639 vty_out (vty, "%s (prefix-list) %s",
640 dist->list[DISTRIBUTE_OUT] ? "," : "",
641 dist->prefix[DISTRIBUTE_OUT]);
642 vty_out (vty, "%s", VTY_NEWLINE);
643 }
644 else
645 vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
646
647 for (i = 0; i < disthash->size; i++)
648 for (mp = disthash->index[i]; mp; mp = mp->next)
649 {
650 dist = mp->data;
651 if (dist->ifname)
652 if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
653 {
654 vty_out (vty, " %s filtered by", dist->ifname);
655 if (dist->list[DISTRIBUTE_OUT])
656 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
657 if (dist->prefix[DISTRIBUTE_OUT])
658 vty_out (vty, "%s (prefix-list) %s",
659 dist->list[DISTRIBUTE_OUT] ? "," : "",
660 dist->prefix[DISTRIBUTE_OUT]);
661 vty_out (vty, "%s", VTY_NEWLINE);
662 }
663 }
664
665
666 /* Input filter configuration. */
667 dist = distribute_lookup (NULL);
668 if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
669 {
670 vty_out (vty, " Incoming update filter list for all interface is");
671 if (dist->list[DISTRIBUTE_IN])
672 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
673 if (dist->prefix[DISTRIBUTE_IN])
674 vty_out (vty, "%s (prefix-list) %s",
675 dist->list[DISTRIBUTE_IN] ? "," : "",
676 dist->prefix[DISTRIBUTE_IN]);
677 vty_out (vty, "%s", VTY_NEWLINE);
678 }
679 else
680 vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
681
682 for (i = 0; i < disthash->size; i++)
683 for (mp = disthash->index[i]; mp; mp = mp->next)
684 {
685 dist = mp->data;
686 if (dist->ifname)
687 if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
688 {
689 vty_out (vty, " %s filtered by", dist->ifname);
690 if (dist->list[DISTRIBUTE_IN])
691 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
692 if (dist->prefix[DISTRIBUTE_IN])
693 vty_out (vty, "%s (prefix-list) %s",
694 dist->list[DISTRIBUTE_IN] ? "," : "",
695 dist->prefix[DISTRIBUTE_IN]);
696 vty_out (vty, "%s", VTY_NEWLINE);
697 }
698 }
699 return 0;
700}
701
702/* Configuration write function. */
703int
704config_write_distribute (struct vty *vty)
705{
hasso8c328f12004-10-05 21:01:23 +0000706 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000707 struct hash_backet *mp;
708 int write = 0;
709
710 for (i = 0; i < disthash->size; i++)
711 for (mp = disthash->index[i]; mp; mp = mp->next)
712 {
713 struct distribute *dist;
714
715 dist = mp->data;
716
717 if (dist->list[DISTRIBUTE_IN])
718 {
719 vty_out (vty, " distribute-list %s in %s%s",
720 dist->list[DISTRIBUTE_IN],
721 dist->ifname ? dist->ifname : "",
722 VTY_NEWLINE);
723 write++;
724 }
725
726 if (dist->list[DISTRIBUTE_OUT])
727 {
728 vty_out (vty, " distribute-list %s out %s%s",
729
730 dist->list[DISTRIBUTE_OUT],
731 dist->ifname ? dist->ifname : "",
732 VTY_NEWLINE);
733 write++;
734 }
735
736 if (dist->prefix[DISTRIBUTE_IN])
737 {
738 vty_out (vty, " distribute-list prefix %s in %s%s",
739 dist->prefix[DISTRIBUTE_IN],
740 dist->ifname ? dist->ifname : "",
741 VTY_NEWLINE);
742 write++;
743 }
744
745 if (dist->prefix[DISTRIBUTE_OUT])
746 {
747 vty_out (vty, " distribute-list prefix %s out %s%s",
748 dist->prefix[DISTRIBUTE_OUT],
749 dist->ifname ? dist->ifname : "",
750 VTY_NEWLINE);
751 write++;
752 }
753 }
754 return write;
755}
756
757/* Clear all distribute list. */
758void
759distribute_list_reset ()
760{
761 hash_clean (disthash, (void (*) (void *)) distribute_free);
762}
763
764/* Initialize distribute list related hash. */
765void
766distribute_list_init (int node)
767{
768 disthash = hash_create (distribute_hash_make, distribute_cmp);
769
paulba23a692003-04-19 15:55:08 +0000770 if(node==RIP_NODE) {
771 install_element (RIP_NODE, &distribute_list_all_cmd);
772 install_element (RIP_NODE, &no_distribute_list_all_cmd);
773 install_element (RIP_NODE, &distribute_list_cmd);
774 install_element (RIP_NODE, &no_distribute_list_cmd);
775 install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
776 install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
777 install_element (RIP_NODE, &distribute_list_prefix_cmd);
778 install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
779 } else {
780 install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
781 install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
782 install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
783 install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
784 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
785 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
786 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
787 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
788 }
paul718e3742002-12-13 20:15:29 +0000789}