blob: 242a225c2a32e6ebbaff2c01f0dc2ce54aeb8d78 [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
paul8cc41982005-05-06 21:25:49 +000038static struct distribute *
39distribute_new (void)
paul718e3742002-12-13 20:15:29 +000040{
Stephen Hemminger393deb92008-08-18 14:13:29 -070041 return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
paul718e3742002-12-13 20:15:29 +000042}
43
44/* Free distribute object. */
paul8cc41982005-05-06 21:25:49 +000045static void
paul718e3742002-12-13 20:15:29 +000046distribute_free (struct distribute *dist)
47{
48 if (dist->ifname)
paul9035efa2004-10-10 11:56:56 +000049 XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
paul718e3742002-12-13 20:15:29 +000050
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 *
paul9035efa2004-10-10 11:56:56 +000066distribute_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +000067{
68 struct distribute key;
69 struct distribute *dist;
70
paul9035efa2004-10-10 11:56:56 +000071 /* temporary reference */
72 key.ifname = (char *)ifname;
paul718e3742002-12-13 20:15:29 +000073
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
paul8cc41982005-05-06 21:25:49 +000091static void *
paul718e3742002-12-13 20:15:29 +000092distribute_hash_alloc (struct distribute *arg)
93{
94 struct distribute *dist;
95
96 dist = distribute_new ();
97 if (arg->ifname)
paul9035efa2004-10-10 11:56:56 +000098 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
paul718e3742002-12-13 20:15:29 +000099 else
100 dist->ifname = NULL;
101 return dist;
102}
103
104/* Make new distribute list and push into hash. */
paul8cc41982005-05-06 21:25:49 +0000105static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000106distribute_get (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000107{
108 struct distribute key;
109
paul9035efa2004-10-10 11:56:56 +0000110 /* temporary reference */
111 key.ifname = (char *)ifname;
112
paul8cc41982005-05-06 21:25:49 +0000113 return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
paul718e3742002-12-13 20:15:29 +0000114}
115
paul8cc41982005-05-06 21:25:49 +0000116static unsigned int
paul718e3742002-12-13 20:15:29 +0000117distribute_hash_make (struct distribute *dist)
118{
hasso8c328f12004-10-05 21:01:23 +0000119 unsigned int i, key;
paul718e3742002-12-13 20:15:29 +0000120
121 key = 0;
122 if (dist->ifname)
123 for (i = 0; i < strlen (dist->ifname); i++)
124 key += dist->ifname[i];
125
126 return key;
127}
128
129/* If two distribute-list have same value then return 1 else return
130 0. This function is used by hash package. */
paul8cc41982005-05-06 21:25:49 +0000131static int
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100132distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
paul718e3742002-12-13 20:15:29 +0000133{
134 if (dist1->ifname && dist2->ifname)
135 if (strcmp (dist1->ifname, dist2->ifname) == 0)
136 return 1;
137 if (! dist1->ifname && ! dist2->ifname)
138 return 1;
139 return 0;
140}
141
142/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000143static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000144distribute_list_set (const char *ifname, enum distribute_type type,
145 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000146{
147 struct distribute *dist;
148
149 dist = distribute_get (ifname);
150
151 if (type == DISTRIBUTE_IN)
152 {
153 if (dist->list[DISTRIBUTE_IN])
154 free (dist->list[DISTRIBUTE_IN]);
155 dist->list[DISTRIBUTE_IN] = strdup (alist_name);
156 }
157 if (type == DISTRIBUTE_OUT)
158 {
159 if (dist->list[DISTRIBUTE_OUT])
160 free (dist->list[DISTRIBUTE_OUT]);
161 dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
162 }
163
164 /* Apply this distribute-list to the interface. */
165 (*distribute_add_hook) (dist);
166
167 return dist;
168}
169
170/* Unset distribute-list. If matched distribute-list exist then
171 return 1. */
paul8cc41982005-05-06 21:25:49 +0000172static int
paul9035efa2004-10-10 11:56:56 +0000173distribute_list_unset (const char *ifname, enum distribute_type type,
174 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000175{
176 struct distribute *dist;
177
178 dist = distribute_lookup (ifname);
179 if (!dist)
180 return 0;
181
182 if (type == DISTRIBUTE_IN)
183 {
184 if (!dist->list[DISTRIBUTE_IN])
185 return 0;
186 if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
187 return 0;
188
189 free (dist->list[DISTRIBUTE_IN]);
190 dist->list[DISTRIBUTE_IN] = NULL;
191 }
192
193 if (type == DISTRIBUTE_OUT)
194 {
195 if (!dist->list[DISTRIBUTE_OUT])
196 return 0;
197 if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
198 return 0;
199
200 free (dist->list[DISTRIBUTE_OUT]);
201 dist->list[DISTRIBUTE_OUT] = NULL;
202 }
203
204 /* Apply this distribute-list to the interface. */
205 (*distribute_delete_hook) (dist);
206
207 /* If both out and in is NULL then free distribute list. */
208 if (dist->list[DISTRIBUTE_IN] == NULL &&
209 dist->list[DISTRIBUTE_OUT] == NULL &&
210 dist->prefix[DISTRIBUTE_IN] == NULL &&
211 dist->prefix[DISTRIBUTE_OUT] == NULL)
212 {
213 hash_release (disthash, dist);
214 distribute_free (dist);
215 }
216
217 return 1;
218}
219
220/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000221static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000222distribute_list_prefix_set (const char *ifname, enum distribute_type type,
223 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000224{
225 struct distribute *dist;
226
227 dist = distribute_get (ifname);
228
229 if (type == DISTRIBUTE_IN)
230 {
231 if (dist->prefix[DISTRIBUTE_IN])
232 free (dist->prefix[DISTRIBUTE_IN]);
233 dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
234 }
235 if (type == DISTRIBUTE_OUT)
236 {
237 if (dist->prefix[DISTRIBUTE_OUT])
238 free (dist->prefix[DISTRIBUTE_OUT]);
239 dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
240 }
241
242 /* Apply this distribute-list to the interface. */
243 (*distribute_add_hook) (dist);
244
245 return dist;
246}
247
248/* Unset distribute-list. If matched distribute-list exist then
249 return 1. */
paul8cc41982005-05-06 21:25:49 +0000250static int
paul9035efa2004-10-10 11:56:56 +0000251distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
252 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000253{
254 struct distribute *dist;
255
256 dist = distribute_lookup (ifname);
257 if (!dist)
258 return 0;
259
260 if (type == DISTRIBUTE_IN)
261 {
262 if (!dist->prefix[DISTRIBUTE_IN])
263 return 0;
264 if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
265 return 0;
266
267 free (dist->prefix[DISTRIBUTE_IN]);
268 dist->prefix[DISTRIBUTE_IN] = NULL;
269 }
270
271 if (type == DISTRIBUTE_OUT)
272 {
273 if (!dist->prefix[DISTRIBUTE_OUT])
274 return 0;
275 if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
276 return 0;
277
278 free (dist->prefix[DISTRIBUTE_OUT]);
279 dist->prefix[DISTRIBUTE_OUT] = NULL;
280 }
281
282 /* Apply this distribute-list to the interface. */
283 (*distribute_delete_hook) (dist);
284
285 /* If both out and in is NULL then free distribute list. */
286 if (dist->list[DISTRIBUTE_IN] == NULL &&
287 dist->list[DISTRIBUTE_OUT] == NULL &&
288 dist->prefix[DISTRIBUTE_IN] == NULL &&
289 dist->prefix[DISTRIBUTE_OUT] == NULL)
290 {
291 hash_release (disthash, dist);
292 distribute_free (dist);
293 }
294
295 return 1;
296}
297
298DEFUN (distribute_list_all,
299 distribute_list_all_cmd,
300 "distribute-list WORD (in|out)",
301 "Filter networks in routing updates\n"
302 "Access-list name\n"
303 "Filter incoming routing updates\n"
304 "Filter outgoing routing updates\n")
305{
306 enum distribute_type type;
307 struct distribute *dist;
308
309 /* Check of distribute list type. */
310 if (strncmp (argv[1], "i", 1) == 0)
311 type = DISTRIBUTE_IN;
312 else if (strncmp (argv[1], "o", 1) == 0)
313 type = DISTRIBUTE_OUT;
314 else
315 {
316 vty_out (vty, "distribute list direction must be [in|out]%s",
317 VTY_NEWLINE);
318 return CMD_WARNING;
319 }
320
321 /* Get interface name corresponding distribute list. */
322 dist = distribute_list_set (NULL, type, argv[0]);
323
324 return CMD_SUCCESS;
325}
326
paulba23a692003-04-19 15:55:08 +0000327ALIAS (distribute_list_all,
328 ipv6_distribute_list_all_cmd,
329 "distribute-list WORD (in|out)",
330 "Filter networks in routing updates\n"
331 "Access-list name\n"
332 "Filter incoming routing updates\n"
333 "Filter outgoing routing updates\n")
334
paul718e3742002-12-13 20:15:29 +0000335DEFUN (no_distribute_list_all,
336 no_distribute_list_all_cmd,
337 "no distribute-list WORD (in|out)",
338 NO_STR
339 "Filter networks in routing updates\n"
340 "Access-list name\n"
341 "Filter incoming routing updates\n"
342 "Filter outgoing routing updates\n")
343{
344 int ret;
345 enum distribute_type type;
346
347 /* Check of distribute list type. */
348 if (strncmp (argv[1], "i", 1) == 0)
349 type = DISTRIBUTE_IN;
350 else if (strncmp (argv[1], "o", 1) == 0)
351 type = DISTRIBUTE_OUT;
352 else
353 {
354 vty_out (vty, "distribute list direction must be [in|out]%s",
355 VTY_NEWLINE);
356 return CMD_WARNING;
357 }
358
359 ret = distribute_list_unset (NULL, type, argv[0]);
360 if (! ret)
361 {
362 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
363 return CMD_WARNING;
364 }
365 return CMD_SUCCESS;
366}
367
paulba23a692003-04-19 15:55:08 +0000368ALIAS (no_distribute_list_all,
369 no_ipv6_distribute_list_all_cmd,
370 "no distribute-list WORD (in|out)",
371 NO_STR
372 "Filter networks in routing updates\n"
373 "Access-list name\n"
374 "Filter incoming routing updates\n"
375 "Filter outgoing routing updates\n")
376
paul718e3742002-12-13 20:15:29 +0000377DEFUN (distribute_list,
378 distribute_list_cmd,
379 "distribute-list WORD (in|out) WORD",
380 "Filter networks in routing updates\n"
381 "Access-list name\n"
382 "Filter incoming routing updates\n"
383 "Filter outgoing routing updates\n"
384 "Interface name\n")
385{
386 enum distribute_type type;
387 struct distribute *dist;
388
389 /* Check of distribute list type. */
390 if (strncmp (argv[1], "i", 1) == 0)
391 type = DISTRIBUTE_IN;
392 else if (strncmp (argv[1], "o", 1) == 0)
393 type = DISTRIBUTE_OUT;
394 else
395 {
396 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
397 return CMD_WARNING;
398 }
399
400 /* Get interface name corresponding distribute list. */
401 dist = distribute_list_set (argv[2], type, argv[0]);
402
403 return CMD_SUCCESS;
404}
405
paulba23a692003-04-19 15:55:08 +0000406ALIAS (distribute_list,
407 ipv6_distribute_list_cmd,
408 "distribute-list WORD (in|out) WORD",
409 "Filter networks in routing updates\n"
410 "Access-list name\n"
411 "Filter incoming routing updates\n"
412 "Filter outgoing routing updates\n"
413 "Interface name\n")
414
paul718e3742002-12-13 20:15:29 +0000415DEFUN (no_districute_list, no_distribute_list_cmd,
416 "no distribute-list WORD (in|out) WORD",
417 NO_STR
418 "Filter networks in routing updates\n"
419 "Access-list name\n"
420 "Filter incoming routing updates\n"
421 "Filter outgoing routing updates\n"
422 "Interface name\n")
423{
424 int ret;
425 enum distribute_type type;
426
427 /* Check of distribute list type. */
428 if (strncmp (argv[1], "i", 1) == 0)
429 type = DISTRIBUTE_IN;
430 else if (strncmp (argv[1], "o", 1) == 0)
431 type = DISTRIBUTE_OUT;
432 else
433 {
434 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
435 return CMD_WARNING;
436 }
437
438 ret = distribute_list_unset (argv[2], type, argv[0]);
439 if (! ret)
440 {
441 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
442 return CMD_WARNING;
443 }
444 return CMD_SUCCESS;
445}
446
paulba23a692003-04-19 15:55:08 +0000447ALIAS (no_districute_list, no_ipv6_distribute_list_cmd,
448 "no distribute-list WORD (in|out) WORD",
449 NO_STR
450 "Filter networks in routing updates\n"
451 "Access-list name\n"
452 "Filter incoming routing updates\n"
453 "Filter outgoing routing updates\n"
454 "Interface name\n")
455
paul718e3742002-12-13 20:15:29 +0000456DEFUN (districute_list_prefix_all,
457 distribute_list_prefix_all_cmd,
458 "distribute-list prefix WORD (in|out)",
459 "Filter networks in routing updates\n"
460 "Filter prefixes in routing updates\n"
461 "Name of an IP prefix-list\n"
462 "Filter incoming routing updates\n"
463 "Filter outgoing routing updates\n")
464{
465 enum distribute_type type;
466 struct distribute *dist;
467
468 /* Check of distribute list type. */
469 if (strncmp (argv[1], "i", 1) == 0)
470 type = DISTRIBUTE_IN;
471 else if (strncmp (argv[1], "o", 1) == 0)
472 type = DISTRIBUTE_OUT;
473 else
474 {
475 vty_out (vty, "distribute list direction must be [in|out]%s",
476 VTY_NEWLINE);
477 return CMD_WARNING;
478 }
479
480 /* Get interface name corresponding distribute list. */
481 dist = distribute_list_prefix_set (NULL, type, argv[0]);
482
483 return CMD_SUCCESS;
484}
485
paulba23a692003-04-19 15:55:08 +0000486ALIAS (districute_list_prefix_all,
487 ipv6_distribute_list_prefix_all_cmd,
488 "distribute-list prefix WORD (in|out)",
489 "Filter networks in routing updates\n"
490 "Filter prefixes in routing updates\n"
491 "Name of an IP prefix-list\n"
492 "Filter incoming routing updates\n"
493 "Filter outgoing routing updates\n")
494
paul718e3742002-12-13 20:15:29 +0000495DEFUN (no_districute_list_prefix_all,
496 no_distribute_list_prefix_all_cmd,
497 "no distribute-list prefix WORD (in|out)",
498 NO_STR
499 "Filter networks in routing updates\n"
500 "Filter prefixes in routing updates\n"
501 "Name of an IP prefix-list\n"
502 "Filter incoming routing updates\n"
503 "Filter outgoing routing updates\n")
504{
505 int ret;
506 enum distribute_type type;
507
508 /* Check of distribute list type. */
509 if (strncmp (argv[1], "i", 1) == 0)
510 type = DISTRIBUTE_IN;
511 else if (strncmp (argv[1], "o", 1) == 0)
512 type = DISTRIBUTE_OUT;
513 else
514 {
515 vty_out (vty, "distribute list direction must be [in|out]%s",
516 VTY_NEWLINE);
517 return CMD_WARNING;
518 }
519
520 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
521 if (! ret)
522 {
523 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
524 return CMD_WARNING;
525 }
526 return CMD_SUCCESS;
527}
528
paulba23a692003-04-19 15:55:08 +0000529ALIAS (no_districute_list_prefix_all,
530 no_ipv6_distribute_list_prefix_all_cmd,
531 "no distribute-list prefix WORD (in|out)",
532 NO_STR
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
paul718e3742002-12-13 20:15:29 +0000539DEFUN (districute_list_prefix, distribute_list_prefix_cmd,
540 "distribute-list prefix WORD (in|out) WORD",
541 "Filter networks in routing updates\n"
542 "Filter prefixes in routing updates\n"
543 "Name of an IP prefix-list\n"
544 "Filter incoming routing updates\n"
545 "Filter outgoing routing updates\n"
546 "Interface name\n")
547{
548 enum distribute_type type;
549 struct distribute *dist;
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. */
564 dist = distribute_list_prefix_set (argv[2], type, argv[0]);
565
566 return CMD_SUCCESS;
567}
568
paulba23a692003-04-19 15:55:08 +0000569ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd,
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
paul718e3742002-12-13 20:15:29 +0000578DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd,
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
paulba23a692003-04-19 15:55:08 +0000612ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
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
paul718e3742002-12-13 20:15:29 +0000622int
623config_show_distribute (struct vty *vty)
624{
hasso8c328f12004-10-05 21:01:23 +0000625 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000626 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{
hasso8c328f12004-10-05 21:01:23 +0000704 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000705 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{
paul8cc41982005-05-06 21:25:49 +0000766 disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100767 (int (*) (const void *, const void *)) distribute_cmp);
paul718e3742002-12-13 20:15:29 +0000768
paulba23a692003-04-19 15:55:08 +0000769 if(node==RIP_NODE) {
770 install_element (RIP_NODE, &distribute_list_all_cmd);
771 install_element (RIP_NODE, &no_distribute_list_all_cmd);
772 install_element (RIP_NODE, &distribute_list_cmd);
773 install_element (RIP_NODE, &no_distribute_list_cmd);
774 install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
775 install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
776 install_element (RIP_NODE, &distribute_list_prefix_cmd);
777 install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
778 } else {
779 install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
780 install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
781 install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
782 install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
783 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
784 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
785 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
786 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
787 }
paul718e3742002-12-13 20:15:29 +0000788}