Line data Source code
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. */
32 : struct hash *disthash;
33 :
34 : /* Hook functions. */
35 : void (*distribute_add_hook) (struct distribute *);
36 : void (*distribute_delete_hook) (struct distribute *);
37 :
38 : static struct distribute *
39 0 : distribute_new (void)
40 : {
41 0 : return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
42 : }
43 :
44 : /* Free distribute object. */
45 : static void
46 0 : distribute_free (struct distribute *dist)
47 : {
48 0 : if (dist->ifname)
49 0 : XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
50 :
51 0 : if (dist->list[DISTRIBUTE_IN])
52 0 : free (dist->list[DISTRIBUTE_IN]);
53 0 : if (dist->list[DISTRIBUTE_OUT])
54 0 : free (dist->list[DISTRIBUTE_OUT]);
55 :
56 0 : if (dist->prefix[DISTRIBUTE_IN])
57 0 : free (dist->prefix[DISTRIBUTE_IN]);
58 0 : if (dist->prefix[DISTRIBUTE_OUT])
59 0 : free (dist->prefix[DISTRIBUTE_OUT]);
60 :
61 0 : XFREE (MTYPE_DISTRIBUTE, dist);
62 0 : }
63 :
64 : /* Lookup interface's distribute list. */
65 : struct distribute *
66 0 : distribute_lookup (const char *ifname)
67 : {
68 : struct distribute key;
69 : struct distribute *dist;
70 :
71 : /* temporary reference */
72 0 : key.ifname = (char *)ifname;
73 :
74 0 : dist = hash_lookup (disthash, &key);
75 :
76 0 : return dist;
77 : }
78 :
79 : void
80 0 : distribute_list_add_hook (void (*func) (struct distribute *))
81 : {
82 0 : distribute_add_hook = func;
83 0 : }
84 :
85 : void
86 0 : distribute_list_delete_hook (void (*func) (struct distribute *))
87 : {
88 0 : distribute_delete_hook = func;
89 0 : }
90 :
91 : static void *
92 0 : distribute_hash_alloc (struct distribute *arg)
93 : {
94 : struct distribute *dist;
95 :
96 0 : dist = distribute_new ();
97 0 : if (arg->ifname)
98 0 : dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
99 : else
100 0 : dist->ifname = NULL;
101 0 : return dist;
102 : }
103 :
104 : /* Make new distribute list and push into hash. */
105 : static struct distribute *
106 0 : distribute_get (const char *ifname)
107 : {
108 : struct distribute key;
109 :
110 : /* temporary reference */
111 0 : key.ifname = (char *)ifname;
112 :
113 0 : return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
114 : }
115 :
116 : static unsigned int
117 0 : distribute_hash_make (void *arg)
118 : {
119 0 : const struct distribute *dist = arg;
120 :
121 0 : return dist->ifname ? string_hash_make (dist->ifname) : 0;
122 : }
123 :
124 : /* If two distribute-list have same value then return 1 else return
125 : 0. This function is used by hash package. */
126 : static int
127 0 : distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
128 : {
129 0 : if (dist1->ifname && dist2->ifname)
130 0 : if (strcmp (dist1->ifname, dist2->ifname) == 0)
131 0 : return 1;
132 0 : if (! dist1->ifname && ! dist2->ifname)
133 0 : return 1;
134 0 : return 0;
135 : }
136 :
137 : /* Set access-list name to the distribute list. */
138 : static struct distribute *
139 0 : distribute_list_set (const char *ifname, enum distribute_type type,
140 : const char *alist_name)
141 : {
142 : struct distribute *dist;
143 :
144 0 : dist = distribute_get (ifname);
145 :
146 0 : if (type == DISTRIBUTE_IN)
147 : {
148 0 : if (dist->list[DISTRIBUTE_IN])
149 0 : free (dist->list[DISTRIBUTE_IN]);
150 0 : dist->list[DISTRIBUTE_IN] = strdup (alist_name);
151 : }
152 0 : if (type == DISTRIBUTE_OUT)
153 : {
154 0 : if (dist->list[DISTRIBUTE_OUT])
155 0 : free (dist->list[DISTRIBUTE_OUT]);
156 0 : dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
157 : }
158 :
159 : /* Apply this distribute-list to the interface. */
160 0 : (*distribute_add_hook) (dist);
161 :
162 0 : return dist;
163 : }
164 :
165 : /* Unset distribute-list. If matched distribute-list exist then
166 : return 1. */
167 : static int
168 0 : distribute_list_unset (const char *ifname, enum distribute_type type,
169 : const char *alist_name)
170 : {
171 : struct distribute *dist;
172 :
173 0 : dist = distribute_lookup (ifname);
174 0 : if (!dist)
175 0 : return 0;
176 :
177 0 : if (type == DISTRIBUTE_IN)
178 : {
179 0 : if (!dist->list[DISTRIBUTE_IN])
180 0 : return 0;
181 0 : if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
182 0 : return 0;
183 :
184 0 : free (dist->list[DISTRIBUTE_IN]);
185 0 : dist->list[DISTRIBUTE_IN] = NULL;
186 : }
187 :
188 0 : if (type == DISTRIBUTE_OUT)
189 : {
190 0 : if (!dist->list[DISTRIBUTE_OUT])
191 0 : return 0;
192 0 : if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
193 0 : return 0;
194 :
195 0 : free (dist->list[DISTRIBUTE_OUT]);
196 0 : dist->list[DISTRIBUTE_OUT] = NULL;
197 : }
198 :
199 : /* Apply this distribute-list to the interface. */
200 0 : (*distribute_delete_hook) (dist);
201 :
202 : /* If both out and in is NULL then free distribute list. */
203 0 : if (dist->list[DISTRIBUTE_IN] == NULL &&
204 0 : dist->list[DISTRIBUTE_OUT] == NULL &&
205 0 : dist->prefix[DISTRIBUTE_IN] == NULL &&
206 0 : dist->prefix[DISTRIBUTE_OUT] == NULL)
207 : {
208 0 : hash_release (disthash, dist);
209 0 : distribute_free (dist);
210 : }
211 :
212 0 : return 1;
213 : }
214 :
215 : /* Set access-list name to the distribute list. */
216 : static struct distribute *
217 0 : distribute_list_prefix_set (const char *ifname, enum distribute_type type,
218 : const char *plist_name)
219 : {
220 : struct distribute *dist;
221 :
222 0 : dist = distribute_get (ifname);
223 :
224 0 : if (type == DISTRIBUTE_IN)
225 : {
226 0 : if (dist->prefix[DISTRIBUTE_IN])
227 0 : free (dist->prefix[DISTRIBUTE_IN]);
228 0 : dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
229 : }
230 0 : if (type == DISTRIBUTE_OUT)
231 : {
232 0 : if (dist->prefix[DISTRIBUTE_OUT])
233 0 : free (dist->prefix[DISTRIBUTE_OUT]);
234 0 : dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
235 : }
236 :
237 : /* Apply this distribute-list to the interface. */
238 0 : (*distribute_add_hook) (dist);
239 :
240 0 : return dist;
241 : }
242 :
243 : /* Unset distribute-list. If matched distribute-list exist then
244 : return 1. */
245 : static int
246 0 : distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
247 : const char *plist_name)
248 : {
249 : struct distribute *dist;
250 :
251 0 : dist = distribute_lookup (ifname);
252 0 : if (!dist)
253 0 : return 0;
254 :
255 0 : if (type == DISTRIBUTE_IN)
256 : {
257 0 : if (!dist->prefix[DISTRIBUTE_IN])
258 0 : return 0;
259 0 : if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
260 0 : return 0;
261 :
262 0 : free (dist->prefix[DISTRIBUTE_IN]);
263 0 : dist->prefix[DISTRIBUTE_IN] = NULL;
264 : }
265 :
266 0 : if (type == DISTRIBUTE_OUT)
267 : {
268 0 : if (!dist->prefix[DISTRIBUTE_OUT])
269 0 : return 0;
270 0 : if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
271 0 : return 0;
272 :
273 0 : free (dist->prefix[DISTRIBUTE_OUT]);
274 0 : dist->prefix[DISTRIBUTE_OUT] = NULL;
275 : }
276 :
277 : /* Apply this distribute-list to the interface. */
278 0 : (*distribute_delete_hook) (dist);
279 :
280 : /* If both out and in is NULL then free distribute list. */
281 0 : if (dist->list[DISTRIBUTE_IN] == NULL &&
282 0 : dist->list[DISTRIBUTE_OUT] == NULL &&
283 0 : dist->prefix[DISTRIBUTE_IN] == NULL &&
284 0 : dist->prefix[DISTRIBUTE_OUT] == NULL)
285 : {
286 0 : hash_release (disthash, dist);
287 0 : distribute_free (dist);
288 : }
289 :
290 0 : return 1;
291 : }
292 :
293 0 : DEFUN (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;
302 :
303 : /* Check of distribute list type. */
304 0 : if (strncmp (argv[1], "i", 1) == 0)
305 0 : type = DISTRIBUTE_IN;
306 0 : else if (strncmp (argv[1], "o", 1) == 0)
307 0 : type = DISTRIBUTE_OUT;
308 : else
309 : {
310 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
311 0 : VTY_NEWLINE);
312 0 : return CMD_WARNING;
313 : }
314 :
315 : /* Get interface name corresponding distribute list. */
316 0 : distribute_list_set (NULL, type, argv[0]);
317 :
318 0 : return CMD_SUCCESS;
319 : }
320 :
321 : ALIAS (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 :
329 0 : DEFUN (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 0 : if (strncmp (argv[1], "i", 1) == 0)
343 0 : type = DISTRIBUTE_IN;
344 0 : else if (strncmp (argv[1], "o", 1) == 0)
345 0 : type = DISTRIBUTE_OUT;
346 : else
347 : {
348 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
349 0 : VTY_NEWLINE);
350 0 : return CMD_WARNING;
351 : }
352 :
353 0 : ret = distribute_list_unset (NULL, type, argv[0]);
354 0 : if (! ret)
355 : {
356 0 : vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
357 0 : return CMD_WARNING;
358 : }
359 0 : return CMD_SUCCESS;
360 : }
361 :
362 : ALIAS (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 :
371 0 : DEFUN (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;
381 :
382 : /* Check of distribute list type. */
383 0 : if (strncmp (argv[1], "i", 1) == 0)
384 0 : type = DISTRIBUTE_IN;
385 0 : else if (strncmp (argv[1], "o", 1) == 0)
386 0 : type = DISTRIBUTE_OUT;
387 : else
388 : {
389 0 : vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
390 0 : return CMD_WARNING;
391 : }
392 :
393 : /* Get interface name corresponding distribute list. */
394 0 : distribute_list_set (argv[2], type, argv[0]);
395 :
396 0 : return CMD_SUCCESS;
397 : }
398 :
399 : ALIAS (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 :
408 0 : DEFUN (no_distribute_list, no_distribute_list_cmd,
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 0 : if (strncmp (argv[1], "i", 1) == 0)
422 0 : type = DISTRIBUTE_IN;
423 0 : else if (strncmp (argv[1], "o", 1) == 0)
424 0 : type = DISTRIBUTE_OUT;
425 : else
426 : {
427 0 : vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
428 0 : return CMD_WARNING;
429 : }
430 :
431 0 : ret = distribute_list_unset (argv[2], type, argv[0]);
432 0 : if (! ret)
433 : {
434 0 : vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
435 0 : return CMD_WARNING;
436 : }
437 0 : return CMD_SUCCESS;
438 : }
439 :
440 : ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
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 :
449 0 : DEFUN (distribute_list_prefix_all,
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;
459 :
460 : /* Check of distribute list type. */
461 0 : if (strncmp (argv[1], "i", 1) == 0)
462 0 : type = DISTRIBUTE_IN;
463 0 : else if (strncmp (argv[1], "o", 1) == 0)
464 0 : type = DISTRIBUTE_OUT;
465 : else
466 : {
467 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
468 0 : VTY_NEWLINE);
469 0 : return CMD_WARNING;
470 : }
471 :
472 : /* Get interface name corresponding distribute list. */
473 0 : distribute_list_prefix_set (NULL, type, argv[0]);
474 :
475 0 : return CMD_SUCCESS;
476 : }
477 :
478 : ALIAS (distribute_list_prefix_all,
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 :
487 0 : DEFUN (no_distribute_list_prefix_all,
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 0 : if (strncmp (argv[1], "i", 1) == 0)
502 0 : type = DISTRIBUTE_IN;
503 0 : else if (strncmp (argv[1], "o", 1) == 0)
504 0 : type = DISTRIBUTE_OUT;
505 : else
506 : {
507 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
508 0 : VTY_NEWLINE);
509 0 : return CMD_WARNING;
510 : }
511 :
512 0 : ret = distribute_list_prefix_unset (NULL, type, argv[0]);
513 0 : if (! ret)
514 : {
515 0 : vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
516 0 : return CMD_WARNING;
517 : }
518 0 : return CMD_SUCCESS;
519 : }
520 :
521 : ALIAS (no_distribute_list_prefix_all,
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 :
531 0 : DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
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;
541 :
542 : /* Check of distribute list type. */
543 0 : if (strncmp (argv[1], "i", 1) == 0)
544 0 : type = DISTRIBUTE_IN;
545 0 : else if (strncmp (argv[1], "o", 1) == 0)
546 0 : type = DISTRIBUTE_OUT;
547 : else
548 : {
549 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
550 0 : VTY_NEWLINE);
551 0 : return CMD_WARNING;
552 : }
553 :
554 : /* Get interface name corresponding distribute list. */
555 0 : distribute_list_prefix_set (argv[2], type, argv[0]);
556 :
557 0 : return CMD_SUCCESS;
558 : }
559 :
560 : ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
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 :
569 0 : DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
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 0 : if (strncmp (argv[1], "i", 1) == 0)
584 0 : type = DISTRIBUTE_IN;
585 0 : else if (strncmp (argv[1], "o", 1) == 0)
586 0 : type = DISTRIBUTE_OUT;
587 : else
588 : {
589 0 : vty_out (vty, "distribute list direction must be [in|out]%s",
590 0 : VTY_NEWLINE);
591 0 : return CMD_WARNING;
592 : }
593 :
594 0 : ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
595 0 : if (! ret)
596 : {
597 0 : vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
598 0 : return CMD_WARNING;
599 : }
600 0 : return CMD_SUCCESS;
601 : }
602 :
603 : ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
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 :
613 : int
614 0 : config_show_distribute (struct vty *vty)
615 : {
616 : unsigned int i;
617 : struct hash_backet *mp;
618 : struct distribute *dist;
619 :
620 : /* Output filter configuration. */
621 0 : dist = distribute_lookup (NULL);
622 0 : if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
623 : {
624 0 : vty_out (vty, " Outgoing update filter list for all interface is");
625 0 : if (dist->list[DISTRIBUTE_OUT])
626 0 : vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
627 0 : if (dist->prefix[DISTRIBUTE_OUT])
628 0 : vty_out (vty, "%s (prefix-list) %s",
629 0 : dist->list[DISTRIBUTE_OUT] ? "," : "",
630 : dist->prefix[DISTRIBUTE_OUT]);
631 0 : vty_out (vty, "%s", VTY_NEWLINE);
632 : }
633 : else
634 0 : vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
635 :
636 0 : for (i = 0; i < disthash->size; i++)
637 0 : for (mp = disthash->index[i]; mp; mp = mp->next)
638 : {
639 0 : dist = mp->data;
640 0 : if (dist->ifname)
641 0 : if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
642 : {
643 0 : vty_out (vty, " %s filtered by", dist->ifname);
644 0 : if (dist->list[DISTRIBUTE_OUT])
645 0 : vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
646 0 : if (dist->prefix[DISTRIBUTE_OUT])
647 0 : vty_out (vty, "%s (prefix-list) %s",
648 0 : dist->list[DISTRIBUTE_OUT] ? "," : "",
649 : dist->prefix[DISTRIBUTE_OUT]);
650 0 : vty_out (vty, "%s", VTY_NEWLINE);
651 : }
652 : }
653 :
654 :
655 : /* Input filter configuration. */
656 0 : dist = distribute_lookup (NULL);
657 0 : if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
658 : {
659 0 : vty_out (vty, " Incoming update filter list for all interface is");
660 0 : if (dist->list[DISTRIBUTE_IN])
661 0 : vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
662 0 : if (dist->prefix[DISTRIBUTE_IN])
663 0 : vty_out (vty, "%s (prefix-list) %s",
664 0 : dist->list[DISTRIBUTE_IN] ? "," : "",
665 : dist->prefix[DISTRIBUTE_IN]);
666 0 : vty_out (vty, "%s", VTY_NEWLINE);
667 : }
668 : else
669 0 : vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
670 :
671 0 : for (i = 0; i < disthash->size; i++)
672 0 : for (mp = disthash->index[i]; mp; mp = mp->next)
673 : {
674 0 : dist = mp->data;
675 0 : if (dist->ifname)
676 0 : if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
677 : {
678 0 : vty_out (vty, " %s filtered by", dist->ifname);
679 0 : if (dist->list[DISTRIBUTE_IN])
680 0 : vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
681 0 : if (dist->prefix[DISTRIBUTE_IN])
682 0 : vty_out (vty, "%s (prefix-list) %s",
683 0 : dist->list[DISTRIBUTE_IN] ? "," : "",
684 : dist->prefix[DISTRIBUTE_IN]);
685 0 : vty_out (vty, "%s", VTY_NEWLINE);
686 : }
687 : }
688 0 : return 0;
689 : }
690 :
691 : /* Configuration write function. */
692 : int
693 0 : config_write_distribute (struct vty *vty)
694 : {
695 : unsigned int i;
696 : struct hash_backet *mp;
697 0 : int write = 0;
698 :
699 0 : for (i = 0; i < disthash->size; i++)
700 0 : for (mp = disthash->index[i]; mp; mp = mp->next)
701 : {
702 : struct distribute *dist;
703 :
704 0 : dist = mp->data;
705 :
706 0 : if (dist->list[DISTRIBUTE_IN])
707 : {
708 0 : vty_out (vty, " distribute-list %s in %s%s",
709 : dist->list[DISTRIBUTE_IN],
710 0 : dist->ifname ? dist->ifname : "",
711 0 : VTY_NEWLINE);
712 0 : write++;
713 : }
714 :
715 0 : if (dist->list[DISTRIBUTE_OUT])
716 : {
717 0 : vty_out (vty, " distribute-list %s out %s%s",
718 :
719 : dist->list[DISTRIBUTE_OUT],
720 0 : dist->ifname ? dist->ifname : "",
721 0 : VTY_NEWLINE);
722 0 : write++;
723 : }
724 :
725 0 : if (dist->prefix[DISTRIBUTE_IN])
726 : {
727 0 : vty_out (vty, " distribute-list prefix %s in %s%s",
728 : dist->prefix[DISTRIBUTE_IN],
729 0 : dist->ifname ? dist->ifname : "",
730 0 : VTY_NEWLINE);
731 0 : write++;
732 : }
733 :
734 0 : if (dist->prefix[DISTRIBUTE_OUT])
735 : {
736 0 : vty_out (vty, " distribute-list prefix %s out %s%s",
737 : dist->prefix[DISTRIBUTE_OUT],
738 0 : dist->ifname ? dist->ifname : "",
739 0 : VTY_NEWLINE);
740 0 : write++;
741 : }
742 : }
743 0 : return write;
744 : }
745 :
746 : /* Clear all distribute list. */
747 : void
748 0 : distribute_list_reset ()
749 : {
750 0 : hash_clean (disthash, (void (*) (void *)) distribute_free);
751 0 : }
752 :
753 : /* Initialize distribute list related hash. */
754 : void
755 0 : distribute_list_init (int node)
756 : {
757 0 : disthash = hash_create (distribute_hash_make,
758 : (int (*) (const void *, const void *)) distribute_cmp);
759 :
760 0 : if(node==RIP_NODE) {
761 0 : install_element (node, &distribute_list_all_cmd);
762 0 : install_element (node, &no_distribute_list_all_cmd);
763 0 : install_element (node, &distribute_list_cmd);
764 0 : install_element (node, &no_distribute_list_cmd);
765 0 : install_element (node, &distribute_list_prefix_all_cmd);
766 0 : install_element (node, &no_distribute_list_prefix_all_cmd);
767 0 : install_element (node, &distribute_list_prefix_cmd);
768 0 : install_element (node, &no_distribute_list_prefix_cmd);
769 0 : } 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 0 : install_element (node, &ipv6_distribute_list_all_cmd);
774 0 : install_element (node, &no_ipv6_distribute_list_all_cmd);
775 0 : install_element (node, &ipv6_distribute_list_cmd);
776 0 : install_element (node, &no_ipv6_distribute_list_cmd);
777 0 : install_element (node, &ipv6_distribute_list_prefix_all_cmd);
778 0 : install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
779 0 : install_element (node, &ipv6_distribute_list_prefix_cmd);
780 0 : install_element (node, &no_ipv6_distribute_list_prefix_cmd);
781 : }
782 0 : }
|