blob: ba426b6649461e05a420c75790fa67611c3a18fe [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
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700117distribute_hash_make (void *arg)
paul718e3742002-12-13 20:15:29 +0000118{
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700119 const struct distribute *dist = arg;
paul718e3742002-12-13 20:15:29 +0000120
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700121 return dist->ifname ? string_hash_make (dist->ifname) : 0;
paul718e3742002-12-13 20:15:29 +0000122}
123
124/* If two distribute-list have same value then return 1 else return
125 0. This function is used by hash package. */
paul8cc41982005-05-06 21:25:49 +0000126static int
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100127distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
paul718e3742002-12-13 20:15:29 +0000128{
129 if (dist1->ifname && dist2->ifname)
130 if (strcmp (dist1->ifname, dist2->ifname) == 0)
131 return 1;
132 if (! dist1->ifname && ! dist2->ifname)
133 return 1;
134 return 0;
135}
136
137/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000138static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000139distribute_list_set (const char *ifname, enum distribute_type type,
140 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000141{
142 struct distribute *dist;
143
144 dist = distribute_get (ifname);
145
146 if (type == DISTRIBUTE_IN)
147 {
148 if (dist->list[DISTRIBUTE_IN])
149 free (dist->list[DISTRIBUTE_IN]);
150 dist->list[DISTRIBUTE_IN] = strdup (alist_name);
151 }
152 if (type == DISTRIBUTE_OUT)
153 {
154 if (dist->list[DISTRIBUTE_OUT])
155 free (dist->list[DISTRIBUTE_OUT]);
156 dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
157 }
158
159 /* Apply this distribute-list to the interface. */
160 (*distribute_add_hook) (dist);
161
162 return dist;
163}
164
165/* Unset distribute-list. If matched distribute-list exist then
166 return 1. */
paul8cc41982005-05-06 21:25:49 +0000167static int
paul9035efa2004-10-10 11:56:56 +0000168distribute_list_unset (const char *ifname, enum distribute_type type,
169 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000170{
171 struct distribute *dist;
172
173 dist = distribute_lookup (ifname);
174 if (!dist)
175 return 0;
176
177 if (type == DISTRIBUTE_IN)
178 {
179 if (!dist->list[DISTRIBUTE_IN])
180 return 0;
181 if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
182 return 0;
183
184 free (dist->list[DISTRIBUTE_IN]);
185 dist->list[DISTRIBUTE_IN] = NULL;
186 }
187
188 if (type == DISTRIBUTE_OUT)
189 {
190 if (!dist->list[DISTRIBUTE_OUT])
191 return 0;
192 if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
193 return 0;
194
195 free (dist->list[DISTRIBUTE_OUT]);
196 dist->list[DISTRIBUTE_OUT] = NULL;
197 }
198
199 /* Apply this distribute-list to the interface. */
200 (*distribute_delete_hook) (dist);
201
202 /* If both out and in is NULL then free distribute list. */
203 if (dist->list[DISTRIBUTE_IN] == NULL &&
204 dist->list[DISTRIBUTE_OUT] == NULL &&
205 dist->prefix[DISTRIBUTE_IN] == NULL &&
206 dist->prefix[DISTRIBUTE_OUT] == NULL)
207 {
208 hash_release (disthash, dist);
209 distribute_free (dist);
210 }
211
212 return 1;
213}
214
215/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000216static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000217distribute_list_prefix_set (const char *ifname, enum distribute_type type,
218 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000219{
220 struct distribute *dist;
221
222 dist = distribute_get (ifname);
223
224 if (type == DISTRIBUTE_IN)
225 {
226 if (dist->prefix[DISTRIBUTE_IN])
227 free (dist->prefix[DISTRIBUTE_IN]);
228 dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
229 }
230 if (type == DISTRIBUTE_OUT)
231 {
232 if (dist->prefix[DISTRIBUTE_OUT])
233 free (dist->prefix[DISTRIBUTE_OUT]);
234 dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
235 }
236
237 /* Apply this distribute-list to the interface. */
238 (*distribute_add_hook) (dist);
239
240 return dist;
241}
242
243/* Unset distribute-list. If matched distribute-list exist then
244 return 1. */
paul8cc41982005-05-06 21:25:49 +0000245static int
paul9035efa2004-10-10 11:56:56 +0000246distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
247 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000248{
249 struct distribute *dist;
250
251 dist = distribute_lookup (ifname);
252 if (!dist)
253 return 0;
254
255 if (type == DISTRIBUTE_IN)
256 {
257 if (!dist->prefix[DISTRIBUTE_IN])
258 return 0;
259 if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
260 return 0;
261
262 free (dist->prefix[DISTRIBUTE_IN]);
263 dist->prefix[DISTRIBUTE_IN] = NULL;
264 }
265
266 if (type == DISTRIBUTE_OUT)
267 {
268 if (!dist->prefix[DISTRIBUTE_OUT])
269 return 0;
270 if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
271 return 0;
272
273 free (dist->prefix[DISTRIBUTE_OUT]);
274 dist->prefix[DISTRIBUTE_OUT] = NULL;
275 }
276
277 /* Apply this distribute-list to the interface. */
278 (*distribute_delete_hook) (dist);
279
280 /* If both out and in is NULL then free distribute list. */
281 if (dist->list[DISTRIBUTE_IN] == NULL &&
282 dist->list[DISTRIBUTE_OUT] == NULL &&
283 dist->prefix[DISTRIBUTE_IN] == NULL &&
284 dist->prefix[DISTRIBUTE_OUT] == NULL)
285 {
286 hash_release (disthash, dist);
287 distribute_free (dist);
288 }
289
290 return 1;
291}
292
293DEFUN (distribute_list_all,
294 distribute_list_all_cmd,
295 "distribute-list WORD (in|out)",
296 "Filter networks in routing updates\n"
297 "Access-list name\n"
298 "Filter incoming routing updates\n"
299 "Filter outgoing routing updates\n")
300{
301 enum distribute_type type;
302 struct distribute *dist;
303
304 /* Check of distribute list type. */
305 if (strncmp (argv[1], "i", 1) == 0)
306 type = DISTRIBUTE_IN;
307 else if (strncmp (argv[1], "o", 1) == 0)
308 type = DISTRIBUTE_OUT;
309 else
310 {
311 vty_out (vty, "distribute list direction must be [in|out]%s",
312 VTY_NEWLINE);
313 return CMD_WARNING;
314 }
315
316 /* Get interface name corresponding distribute list. */
317 dist = distribute_list_set (NULL, type, argv[0]);
318
319 return CMD_SUCCESS;
320}
321
paulba23a692003-04-19 15:55:08 +0000322ALIAS (distribute_list_all,
323 ipv6_distribute_list_all_cmd,
324 "distribute-list WORD (in|out)",
325 "Filter networks in routing updates\n"
326 "Access-list name\n"
327 "Filter incoming routing updates\n"
328 "Filter outgoing routing updates\n")
329
paul718e3742002-12-13 20:15:29 +0000330DEFUN (no_distribute_list_all,
331 no_distribute_list_all_cmd,
332 "no distribute-list WORD (in|out)",
333 NO_STR
334 "Filter networks in routing updates\n"
335 "Access-list name\n"
336 "Filter incoming routing updates\n"
337 "Filter outgoing routing updates\n")
338{
339 int ret;
340 enum distribute_type type;
341
342 /* Check of distribute list type. */
343 if (strncmp (argv[1], "i", 1) == 0)
344 type = DISTRIBUTE_IN;
345 else if (strncmp (argv[1], "o", 1) == 0)
346 type = DISTRIBUTE_OUT;
347 else
348 {
349 vty_out (vty, "distribute list direction must be [in|out]%s",
350 VTY_NEWLINE);
351 return CMD_WARNING;
352 }
353
354 ret = distribute_list_unset (NULL, type, argv[0]);
355 if (! ret)
356 {
357 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
358 return CMD_WARNING;
359 }
360 return CMD_SUCCESS;
361}
362
paulba23a692003-04-19 15:55:08 +0000363ALIAS (no_distribute_list_all,
364 no_ipv6_distribute_list_all_cmd,
365 "no distribute-list WORD (in|out)",
366 NO_STR
367 "Filter networks in routing updates\n"
368 "Access-list name\n"
369 "Filter incoming routing updates\n"
370 "Filter outgoing routing updates\n")
371
paul718e3742002-12-13 20:15:29 +0000372DEFUN (distribute_list,
373 distribute_list_cmd,
374 "distribute-list WORD (in|out) WORD",
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 "Interface name\n")
380{
381 enum distribute_type type;
382 struct distribute *dist;
383
384 /* Check of distribute list type. */
385 if (strncmp (argv[1], "i", 1) == 0)
386 type = DISTRIBUTE_IN;
387 else if (strncmp (argv[1], "o", 1) == 0)
388 type = DISTRIBUTE_OUT;
389 else
390 {
391 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
392 return CMD_WARNING;
393 }
394
395 /* Get interface name corresponding distribute list. */
396 dist = distribute_list_set (argv[2], type, argv[0]);
397
398 return CMD_SUCCESS;
399}
400
paulba23a692003-04-19 15:55:08 +0000401ALIAS (distribute_list,
402 ipv6_distribute_list_cmd,
403 "distribute-list WORD (in|out) WORD",
404 "Filter networks in routing updates\n"
405 "Access-list name\n"
406 "Filter incoming routing updates\n"
407 "Filter outgoing routing updates\n"
408 "Interface name\n")
409
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400410DEFUN (no_distribute_list, no_distribute_list_cmd,
paul718e3742002-12-13 20:15:29 +0000411 "no distribute-list WORD (in|out) WORD",
412 NO_STR
413 "Filter networks in routing updates\n"
414 "Access-list name\n"
415 "Filter incoming routing updates\n"
416 "Filter outgoing routing updates\n"
417 "Interface name\n")
418{
419 int ret;
420 enum distribute_type type;
421
422 /* Check of distribute list type. */
423 if (strncmp (argv[1], "i", 1) == 0)
424 type = DISTRIBUTE_IN;
425 else if (strncmp (argv[1], "o", 1) == 0)
426 type = DISTRIBUTE_OUT;
427 else
428 {
429 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
430 return CMD_WARNING;
431 }
432
433 ret = distribute_list_unset (argv[2], type, argv[0]);
434 if (! ret)
435 {
436 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
437 return CMD_WARNING;
438 }
439 return CMD_SUCCESS;
440}
441
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400442ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
paulba23a692003-04-19 15:55:08 +0000443 "no distribute-list WORD (in|out) WORD",
444 NO_STR
445 "Filter networks in routing updates\n"
446 "Access-list name\n"
447 "Filter incoming routing updates\n"
448 "Filter outgoing routing updates\n"
449 "Interface name\n")
450
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400451DEFUN (distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000452 distribute_list_prefix_all_cmd,
453 "distribute-list prefix WORD (in|out)",
454 "Filter networks in routing updates\n"
455 "Filter prefixes in routing updates\n"
456 "Name of an IP prefix-list\n"
457 "Filter incoming routing updates\n"
458 "Filter outgoing routing updates\n")
459{
460 enum distribute_type type;
461 struct distribute *dist;
462
463 /* Check of distribute list type. */
464 if (strncmp (argv[1], "i", 1) == 0)
465 type = DISTRIBUTE_IN;
466 else if (strncmp (argv[1], "o", 1) == 0)
467 type = DISTRIBUTE_OUT;
468 else
469 {
470 vty_out (vty, "distribute list direction must be [in|out]%s",
471 VTY_NEWLINE);
472 return CMD_WARNING;
473 }
474
475 /* Get interface name corresponding distribute list. */
476 dist = distribute_list_prefix_set (NULL, type, argv[0]);
477
478 return CMD_SUCCESS;
479}
480
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400481ALIAS (distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000482 ipv6_distribute_list_prefix_all_cmd,
483 "distribute-list prefix WORD (in|out)",
484 "Filter networks in routing updates\n"
485 "Filter prefixes in routing updates\n"
486 "Name of an IP prefix-list\n"
487 "Filter incoming routing updates\n"
488 "Filter outgoing routing updates\n")
489
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400490DEFUN (no_distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000491 no_distribute_list_prefix_all_cmd,
492 "no distribute-list prefix WORD (in|out)",
493 NO_STR
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{
500 int ret;
501 enum distribute_type type;
502
503 /* Check of distribute list type. */
504 if (strncmp (argv[1], "i", 1) == 0)
505 type = DISTRIBUTE_IN;
506 else if (strncmp (argv[1], "o", 1) == 0)
507 type = DISTRIBUTE_OUT;
508 else
509 {
510 vty_out (vty, "distribute list direction must be [in|out]%s",
511 VTY_NEWLINE);
512 return CMD_WARNING;
513 }
514
515 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
516 if (! ret)
517 {
518 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
519 return CMD_WARNING;
520 }
521 return CMD_SUCCESS;
522}
523
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400524ALIAS (no_distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000525 no_ipv6_distribute_list_prefix_all_cmd,
526 "no distribute-list prefix WORD (in|out)",
527 NO_STR
528 "Filter networks in routing updates\n"
529 "Filter prefixes in routing updates\n"
530 "Name of an IP prefix-list\n"
531 "Filter incoming routing updates\n"
532 "Filter outgoing routing updates\n")
533
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400534DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000535 "distribute-list prefix WORD (in|out) WORD",
536 "Filter networks in routing updates\n"
537 "Filter prefixes in routing updates\n"
538 "Name of an IP prefix-list\n"
539 "Filter incoming routing updates\n"
540 "Filter outgoing routing updates\n"
541 "Interface name\n")
542{
543 enum distribute_type type;
544 struct distribute *dist;
545
546 /* Check of distribute list type. */
547 if (strncmp (argv[1], "i", 1) == 0)
548 type = DISTRIBUTE_IN;
549 else if (strncmp (argv[1], "o", 1) == 0)
550 type = DISTRIBUTE_OUT;
551 else
552 {
553 vty_out (vty, "distribute list direction must be [in|out]%s",
554 VTY_NEWLINE);
555 return CMD_WARNING;
556 }
557
558 /* Get interface name corresponding distribute list. */
559 dist = distribute_list_prefix_set (argv[2], type, argv[0]);
560
561 return CMD_SUCCESS;
562}
563
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400564ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000565 "distribute-list prefix WORD (in|out) WORD",
566 "Filter networks in routing updates\n"
567 "Filter prefixes in routing updates\n"
568 "Name of an IP prefix-list\n"
569 "Filter incoming routing updates\n"
570 "Filter outgoing routing updates\n"
571 "Interface name\n")
572
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400573DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000574 "no distribute-list prefix WORD (in|out) WORD",
575 NO_STR
576 "Filter networks in routing updates\n"
577 "Filter prefixes in routing updates\n"
578 "Name of an IP prefix-list\n"
579 "Filter incoming routing updates\n"
580 "Filter outgoing routing updates\n"
581 "Interface name\n")
582{
583 int ret;
584 enum distribute_type type;
585
586 /* Check of distribute list type. */
587 if (strncmp (argv[1], "i", 1) == 0)
588 type = DISTRIBUTE_IN;
589 else if (strncmp (argv[1], "o", 1) == 0)
590 type = DISTRIBUTE_OUT;
591 else
592 {
593 vty_out (vty, "distribute list direction must be [in|out]%s",
594 VTY_NEWLINE);
595 return CMD_WARNING;
596 }
597
598 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
599 if (! ret)
600 {
601 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
602 return CMD_WARNING;
603 }
604 return CMD_SUCCESS;
605}
606
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400607ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000608 "no distribute-list prefix WORD (in|out) WORD",
609 NO_STR
610 "Filter networks in routing updates\n"
611 "Filter prefixes in routing updates\n"
612 "Name of an IP prefix-list\n"
613 "Filter incoming routing updates\n"
614 "Filter outgoing routing updates\n"
615 "Interface name\n")
616
paul718e3742002-12-13 20:15:29 +0000617int
618config_show_distribute (struct vty *vty)
619{
hasso8c328f12004-10-05 21:01:23 +0000620 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000621 struct hash_backet *mp;
622 struct distribute *dist;
623
624 /* Output filter configuration. */
625 dist = distribute_lookup (NULL);
626 if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
627 {
628 vty_out (vty, " Outgoing update filter list for all interface is");
629 if (dist->list[DISTRIBUTE_OUT])
630 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
631 if (dist->prefix[DISTRIBUTE_OUT])
632 vty_out (vty, "%s (prefix-list) %s",
633 dist->list[DISTRIBUTE_OUT] ? "," : "",
634 dist->prefix[DISTRIBUTE_OUT]);
635 vty_out (vty, "%s", VTY_NEWLINE);
636 }
637 else
638 vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
639
640 for (i = 0; i < disthash->size; i++)
641 for (mp = disthash->index[i]; mp; mp = mp->next)
642 {
643 dist = mp->data;
644 if (dist->ifname)
645 if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
646 {
647 vty_out (vty, " %s filtered by", dist->ifname);
648 if (dist->list[DISTRIBUTE_OUT])
649 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
650 if (dist->prefix[DISTRIBUTE_OUT])
651 vty_out (vty, "%s (prefix-list) %s",
652 dist->list[DISTRIBUTE_OUT] ? "," : "",
653 dist->prefix[DISTRIBUTE_OUT]);
654 vty_out (vty, "%s", VTY_NEWLINE);
655 }
656 }
657
658
659 /* Input filter configuration. */
660 dist = distribute_lookup (NULL);
661 if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
662 {
663 vty_out (vty, " Incoming update filter list for all interface is");
664 if (dist->list[DISTRIBUTE_IN])
665 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
666 if (dist->prefix[DISTRIBUTE_IN])
667 vty_out (vty, "%s (prefix-list) %s",
668 dist->list[DISTRIBUTE_IN] ? "," : "",
669 dist->prefix[DISTRIBUTE_IN]);
670 vty_out (vty, "%s", VTY_NEWLINE);
671 }
672 else
673 vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
674
675 for (i = 0; i < disthash->size; i++)
676 for (mp = disthash->index[i]; mp; mp = mp->next)
677 {
678 dist = mp->data;
679 if (dist->ifname)
680 if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
681 {
682 vty_out (vty, " %s filtered by", dist->ifname);
683 if (dist->list[DISTRIBUTE_IN])
684 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
685 if (dist->prefix[DISTRIBUTE_IN])
686 vty_out (vty, "%s (prefix-list) %s",
687 dist->list[DISTRIBUTE_IN] ? "," : "",
688 dist->prefix[DISTRIBUTE_IN]);
689 vty_out (vty, "%s", VTY_NEWLINE);
690 }
691 }
692 return 0;
693}
694
695/* Configuration write function. */
696int
697config_write_distribute (struct vty *vty)
698{
hasso8c328f12004-10-05 21:01:23 +0000699 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000700 struct hash_backet *mp;
701 int write = 0;
702
703 for (i = 0; i < disthash->size; i++)
704 for (mp = disthash->index[i]; mp; mp = mp->next)
705 {
706 struct distribute *dist;
707
708 dist = mp->data;
709
710 if (dist->list[DISTRIBUTE_IN])
711 {
712 vty_out (vty, " distribute-list %s in %s%s",
713 dist->list[DISTRIBUTE_IN],
714 dist->ifname ? dist->ifname : "",
715 VTY_NEWLINE);
716 write++;
717 }
718
719 if (dist->list[DISTRIBUTE_OUT])
720 {
721 vty_out (vty, " distribute-list %s out %s%s",
722
723 dist->list[DISTRIBUTE_OUT],
724 dist->ifname ? dist->ifname : "",
725 VTY_NEWLINE);
726 write++;
727 }
728
729 if (dist->prefix[DISTRIBUTE_IN])
730 {
731 vty_out (vty, " distribute-list prefix %s in %s%s",
732 dist->prefix[DISTRIBUTE_IN],
733 dist->ifname ? dist->ifname : "",
734 VTY_NEWLINE);
735 write++;
736 }
737
738 if (dist->prefix[DISTRIBUTE_OUT])
739 {
740 vty_out (vty, " distribute-list prefix %s out %s%s",
741 dist->prefix[DISTRIBUTE_OUT],
742 dist->ifname ? dist->ifname : "",
743 VTY_NEWLINE);
744 write++;
745 }
746 }
747 return write;
748}
749
750/* Clear all distribute list. */
751void
752distribute_list_reset ()
753{
754 hash_clean (disthash, (void (*) (void *)) distribute_free);
755}
756
757/* Initialize distribute list related hash. */
758void
759distribute_list_init (int node)
760{
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700761 disthash = hash_create (distribute_hash_make,
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100762 (int (*) (const void *, const void *)) distribute_cmp);
paul718e3742002-12-13 20:15:29 +0000763
paulba23a692003-04-19 15:55:08 +0000764 if(node==RIP_NODE) {
765 install_element (RIP_NODE, &distribute_list_all_cmd);
766 install_element (RIP_NODE, &no_distribute_list_all_cmd);
767 install_element (RIP_NODE, &distribute_list_cmd);
768 install_element (RIP_NODE, &no_distribute_list_cmd);
769 install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
770 install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
771 install_element (RIP_NODE, &distribute_list_prefix_cmd);
772 install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
773 } else {
774 install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
775 install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
776 install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
777 install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
778 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
779 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
780 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
781 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
782 }
paul718e3742002-12-13 20:15:29 +0000783}