]> git.proxmox.com Git - mirror_frr.git/blame - lib/distribute.c
HACKING: rename to HACKING.md in prep for conversion to MarkDown
[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 *);
6b0655a2 37
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])
6e919709 52 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_IN]);
718e3744 53 if (dist->list[DISTRIBUTE_OUT])
6e919709 54 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_OUT]);
718e3744 55
56 if (dist->prefix[DISTRIBUTE_IN])
6e919709 57 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_IN]);
718e3744 58 if (dist->prefix[DISTRIBUTE_OUT])
6e919709 59 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_OUT]);
718e3744 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 */
3a7c85d1 72 key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
718e3744 73
74 dist = hash_lookup (disthash, &key);
3a7c85d1
DS
75
76 if (key.ifname)
77 XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
24873f0c 78
718e3744 79 return dist;
80}
81
82void
83distribute_list_add_hook (void (*func) (struct distribute *))
84{
85 distribute_add_hook = func;
86}
87
88void
89distribute_list_delete_hook (void (*func) (struct distribute *))
90{
91 distribute_delete_hook = func;
92}
93
8cc4198f 94static void *
718e3744 95distribute_hash_alloc (struct distribute *arg)
96{
97 struct distribute *dist;
98
99 dist = distribute_new ();
100 if (arg->ifname)
9035efaa 101 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
718e3744 102 else
103 dist->ifname = NULL;
104 return dist;
105}
106
107/* Make new distribute list and push into hash. */
8cc4198f 108static struct distribute *
9035efaa 109distribute_get (const char *ifname)
718e3744 110{
111 struct distribute key;
24873f0c 112 struct distribute *ret;
718e3744 113
9035efaa 114 /* temporary reference */
3a7c85d1 115 key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
9035efaa 116
24873f0c
DS
117 ret = hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
118
3a7c85d1
DS
119 if (key.ifname)
120 XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
121
24873f0c 122 return ret;
718e3744 123}
124
8cc4198f 125static unsigned int
6392aa83 126distribute_hash_make (void *arg)
718e3744 127{
6392aa83 128 const struct distribute *dist = arg;
718e3744 129
6392aa83 130 return dist->ifname ? string_hash_make (dist->ifname) : 0;
718e3744 131}
132
133/* If two distribute-list have same value then return 1 else return
134 0. This function is used by hash package. */
8cc4198f 135static int
ffe11cfb 136distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
718e3744 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}
6b0655a2 145
718e3744 146/* Set access-list name to the distribute list. */
8cc4198f 147static struct distribute *
9035efaa 148distribute_list_set (const char *ifname, enum distribute_type type,
149 const char *alist_name)
718e3744 150{
151 struct distribute *dist;
152
153 dist = distribute_get (ifname);
154
155 if (type == DISTRIBUTE_IN)
156 {
157 if (dist->list[DISTRIBUTE_IN])
6e919709
DS
158 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_IN]);
159 dist->list[DISTRIBUTE_IN] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
718e3744 160 }
161 if (type == DISTRIBUTE_OUT)
162 {
163 if (dist->list[DISTRIBUTE_OUT])
6e919709
DS
164 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_OUT]);
165 dist->list[DISTRIBUTE_OUT] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
718e3744 166 }
167
168 /* Apply this distribute-list to the interface. */
169 (*distribute_add_hook) (dist);
170
171 return dist;
172}
173
174/* Unset distribute-list. If matched distribute-list exist then
175 return 1. */
8cc4198f 176static int
9035efaa 177distribute_list_unset (const char *ifname, enum distribute_type type,
178 const char *alist_name)
718e3744 179{
180 struct distribute *dist;
181
182 dist = distribute_lookup (ifname);
183 if (!dist)
184 return 0;
185
186 if (type == DISTRIBUTE_IN)
187 {
188 if (!dist->list[DISTRIBUTE_IN])
189 return 0;
190 if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
191 return 0;
192
6e919709 193 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_IN]);
718e3744 194 dist->list[DISTRIBUTE_IN] = NULL;
195 }
196
197 if (type == DISTRIBUTE_OUT)
198 {
199 if (!dist->list[DISTRIBUTE_OUT])
200 return 0;
201 if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
202 return 0;
203
6e919709 204 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_OUT]);
718e3744 205 dist->list[DISTRIBUTE_OUT] = NULL;
206 }
207
208 /* Apply this distribute-list to the interface. */
209 (*distribute_delete_hook) (dist);
210
211 /* If both out and in is NULL then free distribute list. */
212 if (dist->list[DISTRIBUTE_IN] == NULL &&
213 dist->list[DISTRIBUTE_OUT] == NULL &&
214 dist->prefix[DISTRIBUTE_IN] == NULL &&
215 dist->prefix[DISTRIBUTE_OUT] == NULL)
216 {
217 hash_release (disthash, dist);
218 distribute_free (dist);
219 }
220
221 return 1;
222}
223
224/* Set access-list name to the distribute list. */
8cc4198f 225static struct distribute *
9035efaa 226distribute_list_prefix_set (const char *ifname, enum distribute_type type,
227 const char *plist_name)
718e3744 228{
229 struct distribute *dist;
230
231 dist = distribute_get (ifname);
232
233 if (type == DISTRIBUTE_IN)
234 {
235 if (dist->prefix[DISTRIBUTE_IN])
6e919709
DS
236 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_IN]);
237 dist->prefix[DISTRIBUTE_IN] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
718e3744 238 }
239 if (type == DISTRIBUTE_OUT)
240 {
241 if (dist->prefix[DISTRIBUTE_OUT])
6e919709
DS
242 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_OUT]);
243 dist->prefix[DISTRIBUTE_OUT] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
718e3744 244 }
245
246 /* Apply this distribute-list to the interface. */
247 (*distribute_add_hook) (dist);
248
249 return dist;
250}
251
252/* Unset distribute-list. If matched distribute-list exist then
253 return 1. */
8cc4198f 254static int
9035efaa 255distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
256 const char *plist_name)
718e3744 257{
258 struct distribute *dist;
259
260 dist = distribute_lookup (ifname);
261 if (!dist)
262 return 0;
263
264 if (type == DISTRIBUTE_IN)
265 {
266 if (!dist->prefix[DISTRIBUTE_IN])
267 return 0;
268 if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
269 return 0;
270
6e919709
DS
271 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_IN]);
272 dist->prefix[DISTRIBUTE_IN] = NULL;
718e3744 273 }
274
275 if (type == DISTRIBUTE_OUT)
276 {
277 if (!dist->prefix[DISTRIBUTE_OUT])
278 return 0;
279 if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
280 return 0;
281
6e919709
DS
282 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_OUT]);
283 dist->prefix[DISTRIBUTE_OUT] = NULL;
718e3744 284 }
285
286 /* Apply this distribute-list to the interface. */
287 (*distribute_delete_hook) (dist);
288
289 /* If both out and in is NULL then free distribute list. */
290 if (dist->list[DISTRIBUTE_IN] == NULL &&
291 dist->list[DISTRIBUTE_OUT] == NULL &&
292 dist->prefix[DISTRIBUTE_IN] == NULL &&
293 dist->prefix[DISTRIBUTE_OUT] == NULL)
294 {
295 hash_release (disthash, dist);
296 distribute_free (dist);
297 }
298
299 return 1;
300}
301
302DEFUN (distribute_list_all,
303 distribute_list_all_cmd,
304 "distribute-list WORD (in|out)",
305 "Filter networks in routing updates\n"
306 "Access-list name\n"
307 "Filter incoming routing updates\n"
308 "Filter outgoing routing updates\n")
309{
310 enum distribute_type type;
718e3744 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. */
9206f9ec 325 distribute_list_set (NULL, type, argv[0]);
718e3744 326
327 return CMD_SUCCESS;
328}
329
ba23a691 330ALIAS (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
718e3744 338DEFUN (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
ba23a691 371ALIAS (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
718e3744 380DEFUN (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;
718e3744 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. */
9206f9ec 403 distribute_list_set (argv[2], type, argv[0]);
718e3744 404
405 return CMD_SUCCESS;
406}
407
ba23a691 408ALIAS (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
0ead5c18 417DEFUN (no_distribute_list, no_distribute_list_cmd,
718e3744 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
0ead5c18 449ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
ba23a691 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
0ead5c18 458DEFUN (distribute_list_prefix_all,
718e3744 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;
718e3744 468
469 /* Check of distribute list type. */
470 if (strncmp (argv[1], "i", 1) == 0)
471 type = DISTRIBUTE_IN;
472 else if (strncmp (argv[1], "o", 1) == 0)
473 type = DISTRIBUTE_OUT;
474 else
475 {
476 vty_out (vty, "distribute list direction must be [in|out]%s",
477 VTY_NEWLINE);
478 return CMD_WARNING;
479 }
480
481 /* Get interface name corresponding distribute list. */
9206f9ec 482 distribute_list_prefix_set (NULL, type, argv[0]);
718e3744 483
484 return CMD_SUCCESS;
485}
486
0ead5c18 487ALIAS (distribute_list_prefix_all,
ba23a691 488 ipv6_distribute_list_prefix_all_cmd,
489 "distribute-list prefix WORD (in|out)",
490 "Filter networks in routing updates\n"
491 "Filter prefixes in routing updates\n"
492 "Name of an IP prefix-list\n"
493 "Filter incoming routing updates\n"
494 "Filter outgoing routing updates\n")
495
0ead5c18 496DEFUN (no_distribute_list_prefix_all,
718e3744 497 no_distribute_list_prefix_all_cmd,
498 "no distribute-list prefix WORD (in|out)",
499 NO_STR
500 "Filter networks in routing updates\n"
501 "Filter prefixes in routing updates\n"
502 "Name of an IP prefix-list\n"
503 "Filter incoming routing updates\n"
504 "Filter outgoing routing updates\n")
505{
506 int ret;
507 enum distribute_type type;
508
509 /* Check of distribute list type. */
510 if (strncmp (argv[1], "i", 1) == 0)
511 type = DISTRIBUTE_IN;
512 else if (strncmp (argv[1], "o", 1) == 0)
513 type = DISTRIBUTE_OUT;
514 else
515 {
516 vty_out (vty, "distribute list direction must be [in|out]%s",
517 VTY_NEWLINE);
518 return CMD_WARNING;
519 }
520
521 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
522 if (! ret)
523 {
524 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
525 return CMD_WARNING;
526 }
527 return CMD_SUCCESS;
528}
529
0ead5c18 530ALIAS (no_distribute_list_prefix_all,
ba23a691 531 no_ipv6_distribute_list_prefix_all_cmd,
532 "no distribute-list prefix WORD (in|out)",
533 NO_STR
534 "Filter networks in routing updates\n"
535 "Filter prefixes in routing updates\n"
536 "Name of an IP prefix-list\n"
537 "Filter incoming routing updates\n"
538 "Filter outgoing routing updates\n")
539
0ead5c18 540DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
718e3744 541 "distribute-list prefix WORD (in|out) WORD",
542 "Filter networks in routing updates\n"
543 "Filter prefixes in routing updates\n"
544 "Name of an IP prefix-list\n"
545 "Filter incoming routing updates\n"
546 "Filter outgoing routing updates\n"
547 "Interface name\n")
548{
549 enum distribute_type type;
718e3744 550
551 /* Check of distribute list type. */
552 if (strncmp (argv[1], "i", 1) == 0)
553 type = DISTRIBUTE_IN;
554 else if (strncmp (argv[1], "o", 1) == 0)
555 type = DISTRIBUTE_OUT;
556 else
557 {
558 vty_out (vty, "distribute list direction must be [in|out]%s",
559 VTY_NEWLINE);
560 return CMD_WARNING;
561 }
562
563 /* Get interface name corresponding distribute list. */
9206f9ec 564 distribute_list_prefix_set (argv[2], type, argv[0]);
718e3744 565
566 return CMD_SUCCESS;
567}
568
0ead5c18 569ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
ba23a691 570 "distribute-list prefix WORD (in|out) WORD",
571 "Filter networks in routing updates\n"
572 "Filter prefixes in routing updates\n"
573 "Name of an IP prefix-list\n"
574 "Filter incoming routing updates\n"
575 "Filter outgoing routing updates\n"
576 "Interface name\n")
577
0ead5c18 578DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
718e3744 579 "no distribute-list prefix WORD (in|out) WORD",
580 NO_STR
581 "Filter networks in routing updates\n"
582 "Filter prefixes in routing updates\n"
583 "Name of an IP prefix-list\n"
584 "Filter incoming routing updates\n"
585 "Filter outgoing routing updates\n"
586 "Interface name\n")
587{
588 int ret;
589 enum distribute_type type;
590
591 /* Check of distribute list type. */
592 if (strncmp (argv[1], "i", 1) == 0)
593 type = DISTRIBUTE_IN;
594 else if (strncmp (argv[1], "o", 1) == 0)
595 type = DISTRIBUTE_OUT;
596 else
597 {
598 vty_out (vty, "distribute list direction must be [in|out]%s",
599 VTY_NEWLINE);
600 return CMD_WARNING;
601 }
602
603 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
604 if (! ret)
605 {
606 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
607 return CMD_WARNING;
608 }
609 return CMD_SUCCESS;
610}
611
0ead5c18 612ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
ba23a691 613 "no distribute-list prefix WORD (in|out) WORD",
614 NO_STR
615 "Filter networks in routing updates\n"
616 "Filter prefixes in routing updates\n"
617 "Name of an IP prefix-list\n"
618 "Filter incoming routing updates\n"
619 "Filter outgoing routing updates\n"
620 "Interface name\n")
621
718e3744 622int
623config_show_distribute (struct vty *vty)
624{
8c328f11 625 unsigned int i;
718e3744 626 struct hash_backet *mp;
627 struct distribute *dist;
628
629 /* Output filter configuration. */
630 dist = distribute_lookup (NULL);
631 if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
632 {
633 vty_out (vty, " Outgoing update filter list for all interface is");
634 if (dist->list[DISTRIBUTE_OUT])
635 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
636 if (dist->prefix[DISTRIBUTE_OUT])
637 vty_out (vty, "%s (prefix-list) %s",
638 dist->list[DISTRIBUTE_OUT] ? "," : "",
639 dist->prefix[DISTRIBUTE_OUT]);
640 vty_out (vty, "%s", VTY_NEWLINE);
641 }
642 else
643 vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
644
645 for (i = 0; i < disthash->size; i++)
646 for (mp = disthash->index[i]; mp; mp = mp->next)
647 {
648 dist = mp->data;
649 if (dist->ifname)
650 if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
651 {
652 vty_out (vty, " %s filtered by", dist->ifname);
653 if (dist->list[DISTRIBUTE_OUT])
654 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
655 if (dist->prefix[DISTRIBUTE_OUT])
656 vty_out (vty, "%s (prefix-list) %s",
657 dist->list[DISTRIBUTE_OUT] ? "," : "",
658 dist->prefix[DISTRIBUTE_OUT]);
659 vty_out (vty, "%s", VTY_NEWLINE);
660 }
661 }
662
663
664 /* Input filter configuration. */
665 dist = distribute_lookup (NULL);
666 if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
667 {
668 vty_out (vty, " Incoming update filter list for all interface is");
669 if (dist->list[DISTRIBUTE_IN])
670 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
671 if (dist->prefix[DISTRIBUTE_IN])
672 vty_out (vty, "%s (prefix-list) %s",
673 dist->list[DISTRIBUTE_IN] ? "," : "",
674 dist->prefix[DISTRIBUTE_IN]);
675 vty_out (vty, "%s", VTY_NEWLINE);
676 }
677 else
678 vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
679
680 for (i = 0; i < disthash->size; i++)
681 for (mp = disthash->index[i]; mp; mp = mp->next)
682 {
683 dist = mp->data;
684 if (dist->ifname)
685 if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
686 {
687 vty_out (vty, " %s filtered by", dist->ifname);
688 if (dist->list[DISTRIBUTE_IN])
689 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
690 if (dist->prefix[DISTRIBUTE_IN])
691 vty_out (vty, "%s (prefix-list) %s",
692 dist->list[DISTRIBUTE_IN] ? "," : "",
693 dist->prefix[DISTRIBUTE_IN]);
694 vty_out (vty, "%s", VTY_NEWLINE);
695 }
696 }
697 return 0;
698}
699
700/* Configuration write function. */
701int
702config_write_distribute (struct vty *vty)
703{
8c328f11 704 unsigned int i;
718e3744 705 struct hash_backet *mp;
706 int write = 0;
707
708 for (i = 0; i < disthash->size; i++)
709 for (mp = disthash->index[i]; mp; mp = mp->next)
710 {
711 struct distribute *dist;
712
713 dist = mp->data;
714
715 if (dist->list[DISTRIBUTE_IN])
716 {
717 vty_out (vty, " distribute-list %s in %s%s",
718 dist->list[DISTRIBUTE_IN],
719 dist->ifname ? dist->ifname : "",
720 VTY_NEWLINE);
721 write++;
722 }
723
724 if (dist->list[DISTRIBUTE_OUT])
725 {
726 vty_out (vty, " distribute-list %s out %s%s",
727
728 dist->list[DISTRIBUTE_OUT],
729 dist->ifname ? dist->ifname : "",
730 VTY_NEWLINE);
731 write++;
732 }
733
734 if (dist->prefix[DISTRIBUTE_IN])
735 {
736 vty_out (vty, " distribute-list prefix %s in %s%s",
737 dist->prefix[DISTRIBUTE_IN],
738 dist->ifname ? dist->ifname : "",
739 VTY_NEWLINE);
740 write++;
741 }
742
743 if (dist->prefix[DISTRIBUTE_OUT])
744 {
745 vty_out (vty, " distribute-list prefix %s out %s%s",
746 dist->prefix[DISTRIBUTE_OUT],
747 dist->ifname ? dist->ifname : "",
748 VTY_NEWLINE);
749 write++;
750 }
751 }
752 return write;
753}
754
755/* Clear all distribute list. */
756void
757distribute_list_reset ()
758{
759 hash_clean (disthash, (void (*) (void *)) distribute_free);
760}
761
762/* Initialize distribute list related hash. */
763void
764distribute_list_init (int node)
765{
6392aa83 766 disthash = hash_create (distribute_hash_make,
ffe11cfb 767 (int (*) (const void *, const void *)) distribute_cmp);
718e3744 768
ba23a691 769 if(node==RIP_NODE) {
5734509c
PJ
770 install_element (node, &distribute_list_all_cmd);
771 install_element (node, &no_distribute_list_all_cmd);
772 install_element (node, &distribute_list_cmd);
773 install_element (node, &no_distribute_list_cmd);
774 install_element (node, &distribute_list_prefix_all_cmd);
775 install_element (node, &no_distribute_list_prefix_all_cmd);
776 install_element (node, &distribute_list_prefix_cmd);
777 install_element (node, &no_distribute_list_prefix_cmd);
41d9cc6a 778 } else if (node == RIPNG_NODE) {
5734509c 779 /* WARNING: two identical commands installed do a crash, so be worry with
41d9cc6a 780 * aliases */
5734509c
PJ
781 install_element (node, &ipv6_distribute_list_all_cmd);
782 install_element (node, &no_ipv6_distribute_list_all_cmd);
783 install_element (node, &ipv6_distribute_list_cmd);
784 install_element (node, &no_ipv6_distribute_list_cmd);
785 install_element (node, &ipv6_distribute_list_prefix_all_cmd);
786 install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
787 install_element (node, &ipv6_distribute_list_prefix_cmd);
788 install_element (node, &no_ipv6_distribute_list_prefix_cmd);
ba23a691 789 }
718e3744 790}