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