blob: 8d6f637749692c026813f4fe6138780fdd574ecb [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;
paul718e3742002-12-13 20:15:29 +0000302
303 /* Check of distribute list type. */
304 if (strncmp (argv[1], "i", 1) == 0)
305 type = DISTRIBUTE_IN;
306 else if (strncmp (argv[1], "o", 1) == 0)
307 type = DISTRIBUTE_OUT;
308 else
309 {
310 vty_out (vty, "distribute list direction must be [in|out]%s",
311 VTY_NEWLINE);
312 return CMD_WARNING;
313 }
314
315 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400316 distribute_list_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000317
318 return CMD_SUCCESS;
319}
320
paulba23a692003-04-19 15:55:08 +0000321ALIAS (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
paul718e3742002-12-13 20:15:29 +0000329DEFUN (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 if (strncmp (argv[1], "i", 1) == 0)
343 type = DISTRIBUTE_IN;
344 else if (strncmp (argv[1], "o", 1) == 0)
345 type = DISTRIBUTE_OUT;
346 else
347 {
348 vty_out (vty, "distribute list direction must be [in|out]%s",
349 VTY_NEWLINE);
350 return CMD_WARNING;
351 }
352
353 ret = distribute_list_unset (NULL, type, argv[0]);
354 if (! ret)
355 {
356 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
357 return CMD_WARNING;
358 }
359 return CMD_SUCCESS;
360}
361
paulba23a692003-04-19 15:55:08 +0000362ALIAS (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
paul718e3742002-12-13 20:15:29 +0000371DEFUN (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;
paul718e3742002-12-13 20:15:29 +0000381
382 /* Check of distribute list type. */
383 if (strncmp (argv[1], "i", 1) == 0)
384 type = DISTRIBUTE_IN;
385 else if (strncmp (argv[1], "o", 1) == 0)
386 type = DISTRIBUTE_OUT;
387 else
388 {
389 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
390 return CMD_WARNING;
391 }
392
393 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400394 distribute_list_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000395
396 return CMD_SUCCESS;
397}
398
paulba23a692003-04-19 15:55:08 +0000399ALIAS (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
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400408DEFUN (no_distribute_list, no_distribute_list_cmd,
paul718e3742002-12-13 20:15:29 +0000409 "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 if (strncmp (argv[1], "i", 1) == 0)
422 type = DISTRIBUTE_IN;
423 else if (strncmp (argv[1], "o", 1) == 0)
424 type = DISTRIBUTE_OUT;
425 else
426 {
427 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
428 return CMD_WARNING;
429 }
430
431 ret = distribute_list_unset (argv[2], type, argv[0]);
432 if (! ret)
433 {
434 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
435 return CMD_WARNING;
436 }
437 return CMD_SUCCESS;
438}
439
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400440ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
paulba23a692003-04-19 15:55:08 +0000441 "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
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400449DEFUN (distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000450 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;
paul718e3742002-12-13 20:15:29 +0000459
460 /* Check of distribute list type. */
461 if (strncmp (argv[1], "i", 1) == 0)
462 type = DISTRIBUTE_IN;
463 else if (strncmp (argv[1], "o", 1) == 0)
464 type = DISTRIBUTE_OUT;
465 else
466 {
467 vty_out (vty, "distribute list direction must be [in|out]%s",
468 VTY_NEWLINE);
469 return CMD_WARNING;
470 }
471
472 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400473 distribute_list_prefix_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000474
475 return CMD_SUCCESS;
476}
477
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400478ALIAS (distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000479 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
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400487DEFUN (no_distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000488 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 if (strncmp (argv[1], "i", 1) == 0)
502 type = DISTRIBUTE_IN;
503 else if (strncmp (argv[1], "o", 1) == 0)
504 type = DISTRIBUTE_OUT;
505 else
506 {
507 vty_out (vty, "distribute list direction must be [in|out]%s",
508 VTY_NEWLINE);
509 return CMD_WARNING;
510 }
511
512 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
513 if (! ret)
514 {
515 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
516 return CMD_WARNING;
517 }
518 return CMD_SUCCESS;
519}
520
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400521ALIAS (no_distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000522 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
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400531DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000532 "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;
paul718e3742002-12-13 20:15:29 +0000541
542 /* Check of distribute list type. */
543 if (strncmp (argv[1], "i", 1) == 0)
544 type = DISTRIBUTE_IN;
545 else if (strncmp (argv[1], "o", 1) == 0)
546 type = DISTRIBUTE_OUT;
547 else
548 {
549 vty_out (vty, "distribute list direction must be [in|out]%s",
550 VTY_NEWLINE);
551 return CMD_WARNING;
552 }
553
554 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400555 distribute_list_prefix_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000556
557 return CMD_SUCCESS;
558}
559
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400560ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000561 "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
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400569DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000570 "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 if (strncmp (argv[1], "i", 1) == 0)
584 type = DISTRIBUTE_IN;
585 else if (strncmp (argv[1], "o", 1) == 0)
586 type = DISTRIBUTE_OUT;
587 else
588 {
589 vty_out (vty, "distribute list direction must be [in|out]%s",
590 VTY_NEWLINE);
591 return CMD_WARNING;
592 }
593
594 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
595 if (! ret)
596 {
597 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
598 return CMD_WARNING;
599 }
600 return CMD_SUCCESS;
601}
602
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400603ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000604 "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
paul718e3742002-12-13 20:15:29 +0000613int
614config_show_distribute (struct vty *vty)
615{
hasso8c328f12004-10-05 21:01:23 +0000616 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000617 struct hash_backet *mp;
618 struct distribute *dist;
619
620 /* Output filter configuration. */
621 dist = distribute_lookup (NULL);
622 if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
623 {
624 vty_out (vty, " Outgoing update filter list for all interface is");
625 if (dist->list[DISTRIBUTE_OUT])
626 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
627 if (dist->prefix[DISTRIBUTE_OUT])
628 vty_out (vty, "%s (prefix-list) %s",
629 dist->list[DISTRIBUTE_OUT] ? "," : "",
630 dist->prefix[DISTRIBUTE_OUT]);
631 vty_out (vty, "%s", VTY_NEWLINE);
632 }
633 else
634 vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
635
636 for (i = 0; i < disthash->size; i++)
637 for (mp = disthash->index[i]; mp; mp = mp->next)
638 {
639 dist = mp->data;
640 if (dist->ifname)
641 if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
642 {
643 vty_out (vty, " %s filtered by", dist->ifname);
644 if (dist->list[DISTRIBUTE_OUT])
645 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
646 if (dist->prefix[DISTRIBUTE_OUT])
647 vty_out (vty, "%s (prefix-list) %s",
648 dist->list[DISTRIBUTE_OUT] ? "," : "",
649 dist->prefix[DISTRIBUTE_OUT]);
650 vty_out (vty, "%s", VTY_NEWLINE);
651 }
652 }
653
654
655 /* Input filter configuration. */
656 dist = distribute_lookup (NULL);
657 if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
658 {
659 vty_out (vty, " Incoming update filter list for all interface is");
660 if (dist->list[DISTRIBUTE_IN])
661 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
662 if (dist->prefix[DISTRIBUTE_IN])
663 vty_out (vty, "%s (prefix-list) %s",
664 dist->list[DISTRIBUTE_IN] ? "," : "",
665 dist->prefix[DISTRIBUTE_IN]);
666 vty_out (vty, "%s", VTY_NEWLINE);
667 }
668 else
669 vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
670
671 for (i = 0; i < disthash->size; i++)
672 for (mp = disthash->index[i]; mp; mp = mp->next)
673 {
674 dist = mp->data;
675 if (dist->ifname)
676 if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
677 {
678 vty_out (vty, " %s filtered by", dist->ifname);
679 if (dist->list[DISTRIBUTE_IN])
680 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
681 if (dist->prefix[DISTRIBUTE_IN])
682 vty_out (vty, "%s (prefix-list) %s",
683 dist->list[DISTRIBUTE_IN] ? "," : "",
684 dist->prefix[DISTRIBUTE_IN]);
685 vty_out (vty, "%s", VTY_NEWLINE);
686 }
687 }
688 return 0;
689}
690
691/* Configuration write function. */
692int
693config_write_distribute (struct vty *vty)
694{
hasso8c328f12004-10-05 21:01:23 +0000695 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000696 struct hash_backet *mp;
697 int write = 0;
698
699 for (i = 0; i < disthash->size; i++)
700 for (mp = disthash->index[i]; mp; mp = mp->next)
701 {
702 struct distribute *dist;
703
704 dist = mp->data;
705
706 if (dist->list[DISTRIBUTE_IN])
707 {
708 vty_out (vty, " distribute-list %s in %s%s",
709 dist->list[DISTRIBUTE_IN],
710 dist->ifname ? dist->ifname : "",
711 VTY_NEWLINE);
712 write++;
713 }
714
715 if (dist->list[DISTRIBUTE_OUT])
716 {
717 vty_out (vty, " distribute-list %s out %s%s",
718
719 dist->list[DISTRIBUTE_OUT],
720 dist->ifname ? dist->ifname : "",
721 VTY_NEWLINE);
722 write++;
723 }
724
725 if (dist->prefix[DISTRIBUTE_IN])
726 {
727 vty_out (vty, " distribute-list prefix %s in %s%s",
728 dist->prefix[DISTRIBUTE_IN],
729 dist->ifname ? dist->ifname : "",
730 VTY_NEWLINE);
731 write++;
732 }
733
734 if (dist->prefix[DISTRIBUTE_OUT])
735 {
736 vty_out (vty, " distribute-list prefix %s out %s%s",
737 dist->prefix[DISTRIBUTE_OUT],
738 dist->ifname ? dist->ifname : "",
739 VTY_NEWLINE);
740 write++;
741 }
742 }
743 return write;
744}
745
746/* Clear all distribute list. */
747void
748distribute_list_reset ()
749{
750 hash_clean (disthash, (void (*) (void *)) distribute_free);
751}
752
753/* Initialize distribute list related hash. */
754void
755distribute_list_init (int node)
756{
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700757 disthash = hash_create (distribute_hash_make,
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100758 (int (*) (const void *, const void *)) distribute_cmp);
paul718e3742002-12-13 20:15:29 +0000759
paulba23a692003-04-19 15:55:08 +0000760 if(node==RIP_NODE) {
Paul Jakma57345092011-12-25 17:52:09 +0100761 install_element (node, &distribute_list_all_cmd);
762 install_element (node, &no_distribute_list_all_cmd);
763 install_element (node, &distribute_list_cmd);
764 install_element (node, &no_distribute_list_cmd);
765 install_element (node, &distribute_list_prefix_all_cmd);
766 install_element (node, &no_distribute_list_prefix_all_cmd);
767 install_element (node, &distribute_list_prefix_cmd);
768 install_element (node, &no_distribute_list_prefix_cmd);
769 } 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 install_element (node, &ipv6_distribute_list_all_cmd);
774 install_element (node, &no_ipv6_distribute_list_all_cmd);
775 install_element (node, &ipv6_distribute_list_cmd);
776 install_element (node, &no_ipv6_distribute_list_cmd);
777 install_element (node, &ipv6_distribute_list_prefix_all_cmd);
778 install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
779 install_element (node, &ipv6_distribute_list_prefix_cmd);
780 install_element (node, &no_ipv6_distribute_list_prefix_cmd);
paulba23a692003-04-19 15:55:08 +0000781 }
paul718e3742002-12-13 20:15:29 +0000782}