]> git.proxmox.com Git - mirror_frr.git/blame - lib/distribute.c
build: Quagga 0.99.23-rc1
[mirror_frr.git] / lib / distribute.c
CommitLineData
718e3744 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. */
32struct hash *disthash;
33
34/* Hook functions. */
35void (*distribute_add_hook) (struct distribute *);
36void (*distribute_delete_hook) (struct distribute *);
37\f
8cc4198f 38static struct distribute *
39distribute_new (void)
718e3744 40{
393deb9b 41 return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
718e3744 42}
43
44/* Free distribute object. */
8cc4198f 45static void
718e3744 46distribute_free (struct distribute *dist)
47{
48 if (dist->ifname)
9035efaa 49 XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
718e3744 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. */
65struct distribute *
9035efaa 66distribute_lookup (const char *ifname)
718e3744 67{
68 struct distribute key;
69 struct distribute *dist;
70
9035efaa 71 /* temporary reference */
72 key.ifname = (char *)ifname;
718e3744 73
74 dist = hash_lookup (disthash, &key);
75
76 return dist;
77}
78
79void
80distribute_list_add_hook (void (*func) (struct distribute *))
81{
82 distribute_add_hook = func;
83}
84
85void
86distribute_list_delete_hook (void (*func) (struct distribute *))
87{
88 distribute_delete_hook = func;
89}
90
8cc4198f 91static void *
718e3744 92distribute_hash_alloc (struct distribute *arg)
93{
94 struct distribute *dist;
95
96 dist = distribute_new ();
97 if (arg->ifname)
9035efaa 98 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
718e3744 99 else
100 dist->ifname = NULL;
101 return dist;
102}
103
104/* Make new distribute list and push into hash. */
8cc4198f 105static struct distribute *
9035efaa 106distribute_get (const char *ifname)
718e3744 107{
108 struct distribute key;
109
9035efaa 110 /* temporary reference */
111 key.ifname = (char *)ifname;
112
8cc4198f 113 return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
718e3744 114}
115
8cc4198f 116static unsigned int
6392aa83 117distribute_hash_make (void *arg)
718e3744 118{
6392aa83 119 const struct distribute *dist = arg;
718e3744 120
6392aa83 121 return dist->ifname ? string_hash_make (dist->ifname) : 0;
718e3744 122}
123
124/* If two distribute-list have same value then return 1 else return
125 0. This function is used by hash package. */
8cc4198f 126static int
ffe11cfb 127distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
718e3744 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. */
8cc4198f 138static struct distribute *
9035efaa 139distribute_list_set (const char *ifname, enum distribute_type type,
140 const char *alist_name)
718e3744 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. */
8cc4198f 167static int
9035efaa 168distribute_list_unset (const char *ifname, enum distribute_type type,
169 const char *alist_name)
718e3744 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. */
8cc4198f 216static struct distribute *
9035efaa 217distribute_list_prefix_set (const char *ifname, enum distribute_type type,
218 const char *plist_name)
718e3744 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. */
8cc4198f 245static int
9035efaa 246distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
247 const char *plist_name)
718e3744 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
293DEFUN (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;
718e3744 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. */
9206f9ec 316 distribute_list_set (NULL, type, argv[0]);
718e3744 317
318 return CMD_SUCCESS;
319}
320
ba23a691 321ALIAS (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
718e3744 329DEFUN (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
ba23a691 362ALIAS (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
718e3744 371DEFUN (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;
718e3744 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. */
9206f9ec 394 distribute_list_set (argv[2], type, argv[0]);
718e3744 395
396 return CMD_SUCCESS;
397}
398
ba23a691 399ALIAS (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
0ead5c18 408DEFUN (no_distribute_list, no_distribute_list_cmd,
718e3744 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
0ead5c18 440ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
ba23a691 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
0ead5c18 449DEFUN (distribute_list_prefix_all,
718e3744 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;
718e3744 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. */
9206f9ec 473 distribute_list_prefix_set (NULL, type, argv[0]);
718e3744 474
475 return CMD_SUCCESS;
476}
477
0ead5c18 478ALIAS (distribute_list_prefix_all,
ba23a691 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
0ead5c18 487DEFUN (no_distribute_list_prefix_all,
718e3744 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
0ead5c18 521ALIAS (no_distribute_list_prefix_all,
ba23a691 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
0ead5c18 531DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
718e3744 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;
718e3744 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. */
9206f9ec 555 distribute_list_prefix_set (argv[2], type, argv[0]);
718e3744 556
557 return CMD_SUCCESS;
558}
559
0ead5c18 560ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
ba23a691 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
0ead5c18 569DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
718e3744 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
0ead5c18 603ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
ba23a691 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
718e3744 613int
614config_show_distribute (struct vty *vty)
615{
8c328f11 616 unsigned int i;
718e3744 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. */
692int
693config_write_distribute (struct vty *vty)
694{
8c328f11 695 unsigned int i;
718e3744 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. */
747void
748distribute_list_reset ()
749{
750 hash_clean (disthash, (void (*) (void *)) distribute_free);
751}
752
753/* Initialize distribute list related hash. */
754void
755distribute_list_init (int node)
756{
6392aa83 757 disthash = hash_create (distribute_hash_make,
ffe11cfb 758 (int (*) (const void *, const void *)) distribute_cmp);
718e3744 759
ba23a691 760 if(node==RIP_NODE) {
5734509c
PJ
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);
ba23a691 781 }
718e3744 782}