blob: 4603e13ef20cb12cd75b0ea2a1086d278c1644ed [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 *);
David Lamparter6b0655a2014-06-04 06:53:35 +020037
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{
Matthieu Boutier2074d672014-09-10 16:50:42 +020048 int i = 0;
paul718e3742002-12-13 20:15:29 +000049 if (dist->ifname)
paul9035efa2004-10-10 11:56:56 +000050 XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
paul718e3742002-12-13 20:15:29 +000051
Matthieu Boutier2074d672014-09-10 16:50:42 +020052 for (i=0; i < DISTRIBUTE_MAX; i++)
53 if (dist->list[i])
54 free(dist->list[i]);
paul718e3742002-12-13 20:15:29 +000055
Matthieu Boutier2074d672014-09-10 16:50:42 +020056 for (i=0; i < DISTRIBUTE_MAX; i++)
57 if (dist->prefix[i])
58 free(dist->prefix[i]);
paul718e3742002-12-13 20:15:29 +000059
60 XFREE (MTYPE_DISTRIBUTE, dist);
61}
62
Matthieu Boutier2074d672014-09-10 16:50:42 +020063static void
64distribute_free_if_empty(struct distribute *dist)
65{
66 int i;
67 for (i=0; i < DISTRIBUTE_MAX; i++)
68 if (dist->list[i] != NULL || dist->prefix[i] != NULL)
69 return;
70
71 hash_release (disthash, dist);
72 distribute_free (dist);
73}
74
paul718e3742002-12-13 20:15:29 +000075/* Lookup interface's distribute list. */
76struct distribute *
paul9035efa2004-10-10 11:56:56 +000077distribute_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +000078{
79 struct distribute key;
80 struct distribute *dist;
81
paul9035efa2004-10-10 11:56:56 +000082 /* temporary reference */
83 key.ifname = (char *)ifname;
paul718e3742002-12-13 20:15:29 +000084
85 dist = hash_lookup (disthash, &key);
86
87 return dist;
88}
89
90void
91distribute_list_add_hook (void (*func) (struct distribute *))
92{
93 distribute_add_hook = func;
94}
95
96void
97distribute_list_delete_hook (void (*func) (struct distribute *))
98{
99 distribute_delete_hook = func;
100}
101
paul8cc41982005-05-06 21:25:49 +0000102static void *
paul718e3742002-12-13 20:15:29 +0000103distribute_hash_alloc (struct distribute *arg)
104{
105 struct distribute *dist;
106
107 dist = distribute_new ();
108 if (arg->ifname)
paul9035efa2004-10-10 11:56:56 +0000109 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
paul718e3742002-12-13 20:15:29 +0000110 else
111 dist->ifname = NULL;
112 return dist;
113}
114
115/* Make new distribute list and push into hash. */
paul8cc41982005-05-06 21:25:49 +0000116static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000117distribute_get (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000118{
119 struct distribute key;
120
paul9035efa2004-10-10 11:56:56 +0000121 /* temporary reference */
122 key.ifname = (char *)ifname;
123
paul8cc41982005-05-06 21:25:49 +0000124 return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
paul718e3742002-12-13 20:15:29 +0000125}
126
paul8cc41982005-05-06 21:25:49 +0000127static unsigned int
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700128distribute_hash_make (void *arg)
paul718e3742002-12-13 20:15:29 +0000129{
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700130 const struct distribute *dist = arg;
paul718e3742002-12-13 20:15:29 +0000131
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700132 return dist->ifname ? string_hash_make (dist->ifname) : 0;
paul718e3742002-12-13 20:15:29 +0000133}
134
135/* If two distribute-list have same value then return 1 else return
136 0. This function is used by hash package. */
paul8cc41982005-05-06 21:25:49 +0000137static int
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100138distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
paul718e3742002-12-13 20:15:29 +0000139{
140 if (dist1->ifname && dist2->ifname)
141 if (strcmp (dist1->ifname, dist2->ifname) == 0)
142 return 1;
143 if (! dist1->ifname && ! dist2->ifname)
144 return 1;
145 return 0;
146}
David Lamparter6b0655a2014-06-04 06:53:35 +0200147
paul718e3742002-12-13 20:15:29 +0000148/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000149static struct distribute *
Matthieu Boutier2074d672014-09-10 16:50:42 +0200150distribute_list_set (const char *ifname, enum distribute_type type,
paul9035efa2004-10-10 11:56:56 +0000151 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000152{
153 struct distribute *dist;
154
155 dist = distribute_get (ifname);
156
Matthieu Boutier2074d672014-09-10 16:50:42 +0200157 if (dist->list[type])
158 free (dist->list[type]);
159 dist->list[type] = strdup (alist_name);
paul718e3742002-12-13 20:15:29 +0000160
161 /* Apply this distribute-list to the interface. */
162 (*distribute_add_hook) (dist);
Matthieu Boutier2074d672014-09-10 16:50:42 +0200163
paul718e3742002-12-13 20:15:29 +0000164 return dist;
165}
166
167/* Unset distribute-list. If matched distribute-list exist then
168 return 1. */
paul8cc41982005-05-06 21:25:49 +0000169static int
Matthieu Boutier2074d672014-09-10 16:50:42 +0200170distribute_list_unset (const char *ifname, enum distribute_type type,
paul9035efa2004-10-10 11:56:56 +0000171 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000172{
173 struct distribute *dist;
174
175 dist = distribute_lookup (ifname);
176 if (!dist)
177 return 0;
178
Matthieu Boutier2074d672014-09-10 16:50:42 +0200179 if (!dist->list[type])
180 return 0;
181 if (strcmp (dist->list[type], alist_name) != 0)
182 return 0;
paul718e3742002-12-13 20:15:29 +0000183
Matthieu Boutier2074d672014-09-10 16:50:42 +0200184 free (dist->list[type]);
185 dist->list[type] = NULL;
paul718e3742002-12-13 20:15:29 +0000186
187 /* Apply this distribute-list to the interface. */
188 (*distribute_delete_hook) (dist);
189
Matthieu Boutier2074d672014-09-10 16:50:42 +0200190 /* If all dist are NULL, then free distribute list. */
191 distribute_free_if_empty(dist);
paul718e3742002-12-13 20:15:29 +0000192 return 1;
193}
194
195/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000196static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000197distribute_list_prefix_set (const char *ifname, enum distribute_type type,
198 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000199{
200 struct distribute *dist;
201
202 dist = distribute_get (ifname);
203
Matthieu Boutier2074d672014-09-10 16:50:42 +0200204 if (dist->prefix[type])
205 free (dist->prefix[type]);
206 dist->prefix[type] = strdup (plist_name);
paul718e3742002-12-13 20:15:29 +0000207
208 /* Apply this distribute-list to the interface. */
209 (*distribute_add_hook) (dist);
210
211 return dist;
212}
213
214/* Unset distribute-list. If matched distribute-list exist then
215 return 1. */
paul8cc41982005-05-06 21:25:49 +0000216static int
paul9035efa2004-10-10 11:56:56 +0000217distribute_list_prefix_unset (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_lookup (ifname);
223 if (!dist)
224 return 0;
225
Matthieu Boutier2074d672014-09-10 16:50:42 +0200226 if (!dist->prefix[type])
227 return 0;
228 if (strcmp (dist->prefix[type], plist_name) != 0)
229 return 0;
paul718e3742002-12-13 20:15:29 +0000230
Matthieu Boutier2074d672014-09-10 16:50:42 +0200231 free (dist->prefix[type]);
232 dist->prefix[type] = NULL;
paul718e3742002-12-13 20:15:29 +0000233
234 /* Apply this distribute-list to the interface. */
235 (*distribute_delete_hook) (dist);
236
Matthieu Boutier2074d672014-09-10 16:50:42 +0200237 /* If all dist are NULL, then free distribute list. */
238 distribute_free_if_empty(dist);
paul718e3742002-12-13 20:15:29 +0000239 return 1;
240}
241
242DEFUN (distribute_list_all,
243 distribute_list_all_cmd,
244 "distribute-list WORD (in|out)",
245 "Filter networks in routing updates\n"
246 "Access-list name\n"
247 "Filter incoming routing updates\n"
248 "Filter outgoing routing updates\n")
249{
250 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000251
252 /* Check of distribute list type. */
253 if (strncmp (argv[1], "i", 1) == 0)
254 type = DISTRIBUTE_IN;
255 else if (strncmp (argv[1], "o", 1) == 0)
256 type = DISTRIBUTE_OUT;
257 else
258 {
259 vty_out (vty, "distribute list direction must be [in|out]%s",
260 VTY_NEWLINE);
261 return CMD_WARNING;
262 }
263
264 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400265 distribute_list_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000266
267 return CMD_SUCCESS;
268}
269
paulba23a692003-04-19 15:55:08 +0000270ALIAS (distribute_list_all,
271 ipv6_distribute_list_all_cmd,
272 "distribute-list WORD (in|out)",
273 "Filter networks in routing updates\n"
274 "Access-list name\n"
275 "Filter incoming routing updates\n"
276 "Filter outgoing routing updates\n")
277
paul718e3742002-12-13 20:15:29 +0000278DEFUN (no_distribute_list_all,
279 no_distribute_list_all_cmd,
280 "no distribute-list WORD (in|out)",
281 NO_STR
282 "Filter networks in routing updates\n"
283 "Access-list name\n"
284 "Filter incoming routing updates\n"
285 "Filter outgoing routing updates\n")
286{
287 int ret;
288 enum distribute_type type;
289
290 /* Check of distribute list type. */
291 if (strncmp (argv[1], "i", 1) == 0)
292 type = DISTRIBUTE_IN;
293 else if (strncmp (argv[1], "o", 1) == 0)
294 type = DISTRIBUTE_OUT;
295 else
296 {
297 vty_out (vty, "distribute list direction must be [in|out]%s",
298 VTY_NEWLINE);
299 return CMD_WARNING;
300 }
301
302 ret = distribute_list_unset (NULL, type, argv[0]);
303 if (! ret)
304 {
305 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
306 return CMD_WARNING;
307 }
308 return CMD_SUCCESS;
309}
310
paulba23a692003-04-19 15:55:08 +0000311ALIAS (no_distribute_list_all,
312 no_ipv6_distribute_list_all_cmd,
313 "no distribute-list WORD (in|out)",
314 NO_STR
315 "Filter networks in routing updates\n"
316 "Access-list name\n"
317 "Filter incoming routing updates\n"
318 "Filter outgoing routing updates\n")
319
paul718e3742002-12-13 20:15:29 +0000320DEFUN (distribute_list,
321 distribute_list_cmd,
322 "distribute-list WORD (in|out) WORD",
323 "Filter networks in routing updates\n"
324 "Access-list name\n"
325 "Filter incoming routing updates\n"
326 "Filter outgoing routing updates\n"
327 "Interface name\n")
328{
329 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000330
331 /* Check of distribute list type. */
332 if (strncmp (argv[1], "i", 1) == 0)
333 type = DISTRIBUTE_IN;
334 else if (strncmp (argv[1], "o", 1) == 0)
335 type = DISTRIBUTE_OUT;
336 else
337 {
338 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
339 return CMD_WARNING;
340 }
341
342 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400343 distribute_list_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000344
345 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200346}
paul718e3742002-12-13 20:15:29 +0000347
paulba23a692003-04-19 15:55:08 +0000348ALIAS (distribute_list,
349 ipv6_distribute_list_cmd,
350 "distribute-list WORD (in|out) WORD",
351 "Filter networks in routing updates\n"
352 "Access-list name\n"
353 "Filter incoming routing updates\n"
354 "Filter outgoing routing updates\n"
355 "Interface name\n")
356
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400357DEFUN (no_distribute_list, no_distribute_list_cmd,
paul718e3742002-12-13 20:15:29 +0000358 "no distribute-list WORD (in|out) WORD",
359 NO_STR
360 "Filter networks in routing updates\n"
361 "Access-list name\n"
362 "Filter incoming routing updates\n"
363 "Filter outgoing routing updates\n"
364 "Interface name\n")
365{
366 int ret;
367 enum distribute_type type;
368
369 /* Check of distribute list type. */
370 if (strncmp (argv[1], "i", 1) == 0)
371 type = DISTRIBUTE_IN;
372 else if (strncmp (argv[1], "o", 1) == 0)
373 type = DISTRIBUTE_OUT;
374 else
375 {
376 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
377 return CMD_WARNING;
378 }
379
380 ret = distribute_list_unset (argv[2], type, argv[0]);
381 if (! ret)
382 {
383 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
384 return CMD_WARNING;
385 }
386 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200387}
paul718e3742002-12-13 20:15:29 +0000388
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400389ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
paulba23a692003-04-19 15:55:08 +0000390 "no distribute-list WORD (in|out) WORD",
391 NO_STR
392 "Filter networks in routing updates\n"
393 "Access-list name\n"
394 "Filter incoming routing updates\n"
395 "Filter outgoing routing updates\n"
396 "Interface name\n")
397
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400398DEFUN (distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000399 distribute_list_prefix_all_cmd,
400 "distribute-list prefix WORD (in|out)",
401 "Filter networks in routing updates\n"
402 "Filter prefixes in routing updates\n"
403 "Name of an IP prefix-list\n"
404 "Filter incoming routing updates\n"
405 "Filter outgoing routing updates\n")
406{
407 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000408
409 /* Check of distribute list type. */
410 if (strncmp (argv[1], "i", 1) == 0)
411 type = DISTRIBUTE_IN;
412 else if (strncmp (argv[1], "o", 1) == 0)
413 type = DISTRIBUTE_OUT;
414 else
415 {
416 vty_out (vty, "distribute list direction must be [in|out]%s",
417 VTY_NEWLINE);
418 return CMD_WARNING;
419 }
420
421 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400422 distribute_list_prefix_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000423
424 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200425}
paul718e3742002-12-13 20:15:29 +0000426
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400427ALIAS (distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000428 ipv6_distribute_list_prefix_all_cmd,
429 "distribute-list prefix WORD (in|out)",
430 "Filter networks in routing updates\n"
431 "Filter prefixes in routing updates\n"
432 "Name of an IP prefix-list\n"
433 "Filter incoming routing updates\n"
434 "Filter outgoing routing updates\n")
435
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400436DEFUN (no_distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000437 no_distribute_list_prefix_all_cmd,
438 "no distribute-list prefix WORD (in|out)",
439 NO_STR
440 "Filter networks in routing updates\n"
441 "Filter prefixes in routing updates\n"
442 "Name of an IP prefix-list\n"
443 "Filter incoming routing updates\n"
444 "Filter outgoing routing updates\n")
445{
446 int ret;
447 enum distribute_type type;
448
449 /* Check of distribute list type. */
450 if (strncmp (argv[1], "i", 1) == 0)
451 type = DISTRIBUTE_IN;
452 else if (strncmp (argv[1], "o", 1) == 0)
453 type = DISTRIBUTE_OUT;
454 else
455 {
456 vty_out (vty, "distribute list direction must be [in|out]%s",
457 VTY_NEWLINE);
458 return CMD_WARNING;
459 }
460
461 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
462 if (! ret)
463 {
464 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
465 return CMD_WARNING;
466 }
467 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200468}
paul718e3742002-12-13 20:15:29 +0000469
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400470ALIAS (no_distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000471 no_ipv6_distribute_list_prefix_all_cmd,
472 "no distribute-list prefix WORD (in|out)",
473 NO_STR
474 "Filter networks in routing updates\n"
475 "Filter prefixes in routing updates\n"
476 "Name of an IP prefix-list\n"
477 "Filter incoming routing updates\n"
478 "Filter outgoing routing updates\n")
479
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400480DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000481 "distribute-list prefix WORD (in|out) WORD",
482 "Filter networks in routing updates\n"
483 "Filter prefixes in routing updates\n"
484 "Name of an IP prefix-list\n"
485 "Filter incoming routing updates\n"
486 "Filter outgoing routing updates\n"
487 "Interface name\n")
488{
489 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000490
491 /* Check of distribute list type. */
492 if (strncmp (argv[1], "i", 1) == 0)
493 type = DISTRIBUTE_IN;
494 else if (strncmp (argv[1], "o", 1) == 0)
495 type = DISTRIBUTE_OUT;
496 else
497 {
498 vty_out (vty, "distribute list direction must be [in|out]%s",
499 VTY_NEWLINE);
500 return CMD_WARNING;
501 }
502
503 /* Get interface name corresponding distribute list. */
Stephen Hemminger9206f9e2011-12-18 19:43:40 +0400504 distribute_list_prefix_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000505
506 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200507}
paul718e3742002-12-13 20:15:29 +0000508
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400509ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000510 "distribute-list prefix WORD (in|out) WORD",
511 "Filter networks in routing updates\n"
512 "Filter prefixes in routing updates\n"
513 "Name of an IP prefix-list\n"
514 "Filter incoming routing updates\n"
515 "Filter outgoing routing updates\n"
516 "Interface name\n")
517
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400518DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000519 "no distribute-list prefix WORD (in|out) WORD",
520 NO_STR
521 "Filter networks in routing updates\n"
522 "Filter prefixes in routing updates\n"
523 "Name of an IP prefix-list\n"
524 "Filter incoming routing updates\n"
525 "Filter outgoing routing updates\n"
526 "Interface name\n")
527{
528 int ret;
529 enum distribute_type type;
530
531 /* Check of distribute list type. */
532 if (strncmp (argv[1], "i", 1) == 0)
533 type = DISTRIBUTE_IN;
534 else if (strncmp (argv[1], "o", 1) == 0)
535 type = DISTRIBUTE_OUT;
536 else
537 {
538 vty_out (vty, "distribute list direction must be [in|out]%s",
539 VTY_NEWLINE);
540 return CMD_WARNING;
541 }
542
543 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
544 if (! ret)
545 {
546 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
547 return CMD_WARNING;
548 }
549 return CMD_SUCCESS;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200550}
paul718e3742002-12-13 20:15:29 +0000551
Denis Ovsienko0ead5c12011-10-14 20:56:19 +0400552ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000553 "no distribute-list prefix WORD (in|out) WORD",
554 NO_STR
555 "Filter networks in routing updates\n"
556 "Filter prefixes in routing updates\n"
557 "Name of an IP prefix-list\n"
558 "Filter incoming routing updates\n"
559 "Filter outgoing routing updates\n"
560 "Interface name\n")
561
Matthieu Boutier2074d672014-09-10 16:50:42 +0200562static int
563distribute_print (struct vty *vty, char *tab[], int is_prefix,
564 enum distribute_type type, int has_print)
565{
566 if (tab[type]) {
567 vty_out (vty, "%s %s%s",
568 has_print ? "," : "",
569 is_prefix ? "(prefix-list) " : "",
570 tab[type]);
571 return 1;
572 }
573 return has_print;
574}
575
paul718e3742002-12-13 20:15:29 +0000576int
577config_show_distribute (struct vty *vty)
578{
hasso8c328f12004-10-05 21:01:23 +0000579 unsigned int i;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200580 int has_print = 0;
paul718e3742002-12-13 20:15:29 +0000581 struct hash_backet *mp;
582 struct distribute *dist;
583
584 /* Output filter configuration. */
585 dist = distribute_lookup (NULL);
Matthieu Boutier2074d672014-09-10 16:50:42 +0200586 vty_out(vty, " Outgoing update filter list for all interface is");
587 has_print = 0;
588 if (dist)
paul718e3742002-12-13 20:15:29 +0000589 {
Matthieu Boutier2074d672014-09-10 16:50:42 +0200590 has_print = distribute_print(vty, dist->list, 0,
591 DISTRIBUTE_OUT, has_print);
592 has_print = distribute_print(vty, dist->prefix, 1,
593 DISTRIBUTE_OUT, has_print);
paul718e3742002-12-13 20:15:29 +0000594 }
Matthieu Boutier2074d672014-09-10 16:50:42 +0200595 if (has_print)
596 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000597 else
Matthieu Boutier2074d672014-09-10 16:50:42 +0200598 vty_out (vty, " not set%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000599
600 for (i = 0; i < disthash->size; i++)
601 for (mp = disthash->index[i]; mp; mp = mp->next)
602 {
603 dist = mp->data;
604 if (dist->ifname)
Matthieu Boutier2074d672014-09-10 16:50:42 +0200605 {
606 vty_out (vty, " %s filtered by", dist->ifname);
607 has_print = 0;
608 has_print = distribute_print(vty, dist->list, 0,
609 DISTRIBUTE_OUT, has_print);
610 has_print = distribute_print(vty, dist->prefix, 1,
611 DISTRIBUTE_OUT, has_print);
612 if (has_print)
613 vty_out (vty, "%s", VTY_NEWLINE);
614 else
615 vty_out(vty, " nothing%s", VTY_NEWLINE);
616 }
paul718e3742002-12-13 20:15:29 +0000617 }
618
619
620 /* Input filter configuration. */
621 dist = distribute_lookup (NULL);
Matthieu Boutier2074d672014-09-10 16:50:42 +0200622 vty_out(vty, " Incoming update filter list for all interface is");
623 has_print = 0;
624 if (dist)
paul718e3742002-12-13 20:15:29 +0000625 {
Matthieu Boutier2074d672014-09-10 16:50:42 +0200626 has_print = distribute_print(vty, dist->list, 0,
627 DISTRIBUTE_IN, has_print);
628 has_print = distribute_print(vty, dist->prefix, 1,
629 DISTRIBUTE_IN, has_print); }
630 if (has_print)
631 vty_out (vty, "%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000632 else
Matthieu Boutier2074d672014-09-10 16:50:42 +0200633 vty_out (vty, " not set%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +0000634
635 for (i = 0; i < disthash->size; i++)
636 for (mp = disthash->index[i]; mp; mp = mp->next)
637 {
638 dist = mp->data;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200639 if (dist->ifname)
640 {
641 vty_out (vty, " %s filtered by", dist->ifname);
642 has_print = 0;
643 has_print = distribute_print(vty, dist->list, 0,
644 DISTRIBUTE_IN, has_print);
645 has_print = distribute_print(vty, dist->prefix, 1,
646 DISTRIBUTE_IN, has_print);
647 if (has_print)
648 vty_out (vty, "%s", VTY_NEWLINE);
649 else
650 vty_out(vty, " nothing%s", VTY_NEWLINE);
651 }
paul718e3742002-12-13 20:15:29 +0000652 }
653 return 0;
654}
655
656/* Configuration write function. */
657int
658config_write_distribute (struct vty *vty)
659{
hasso8c328f12004-10-05 21:01:23 +0000660 unsigned int i;
Matthieu Boutier2074d672014-09-10 16:50:42 +0200661 int j;
662 int output;
paul718e3742002-12-13 20:15:29 +0000663 struct hash_backet *mp;
664 int write = 0;
665
666 for (i = 0; i < disthash->size; i++)
667 for (mp = disthash->index[i]; mp; mp = mp->next)
668 {
669 struct distribute *dist;
670
671 dist = mp->data;
672
Matthieu Boutier2074d672014-09-10 16:50:42 +0200673 for (j=0; j < DISTRIBUTE_MAX; j++)
674 if (dist->list[j]) {
675 output = j == DISTRIBUTE_OUT;
676 vty_out (vty, " distribute-list %s %s %s%s",
677 dist->list[j],
678 output ? "out" : "in",
paul718e3742002-12-13 20:15:29 +0000679 dist->ifname ? dist->ifname : "",
680 VTY_NEWLINE);
681 write++;
682 }
683
Matthieu Boutier2074d672014-09-10 16:50:42 +0200684 for (j=0; j < DISTRIBUTE_MAX; j++)
685 if (dist->prefix[j]) {
686 output = j == DISTRIBUTE_OUT;
687 vty_out (vty, " distribute-list prefix %s %s %s%s",
688 dist->prefix[j],
689 output ? "out" : "in",
paul718e3742002-12-13 20:15:29 +0000690 dist->ifname ? dist->ifname : "",
691 VTY_NEWLINE);
692 write++;
693 }
694 }
695 return write;
696}
697
698/* Clear all distribute list. */
699void
700distribute_list_reset ()
701{
702 hash_clean (disthash, (void (*) (void *)) distribute_free);
703}
704
705/* Initialize distribute list related hash. */
706void
707distribute_list_init (int node)
708{
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700709 disthash = hash_create (distribute_hash_make,
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100710 (int (*) (const void *, const void *)) distribute_cmp);
paul718e3742002-12-13 20:15:29 +0000711
paulba23a692003-04-19 15:55:08 +0000712 if(node==RIP_NODE) {
Paul Jakma57345092011-12-25 17:52:09 +0100713 install_element (node, &distribute_list_all_cmd);
714 install_element (node, &no_distribute_list_all_cmd);
715 install_element (node, &distribute_list_cmd);
716 install_element (node, &no_distribute_list_cmd);
717 install_element (node, &distribute_list_prefix_all_cmd);
718 install_element (node, &no_distribute_list_prefix_all_cmd);
719 install_element (node, &distribute_list_prefix_cmd);
720 install_element (node, &no_distribute_list_prefix_cmd);
721 } else if (node == RIPNG_NODE || node == BABEL_NODE) {
722 /* WARNING: two identical commands installed do a crash, so be worry with
723 aliases. For this reason, and because all these commands are aliases, Babel
724 is not set with RIP. */
725 install_element (node, &ipv6_distribute_list_all_cmd);
726 install_element (node, &no_ipv6_distribute_list_all_cmd);
727 install_element (node, &ipv6_distribute_list_cmd);
728 install_element (node, &no_ipv6_distribute_list_cmd);
729 install_element (node, &ipv6_distribute_list_prefix_all_cmd);
730 install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
731 install_element (node, &ipv6_distribute_list_prefix_cmd);
732 install_element (node, &no_ipv6_distribute_list_prefix_cmd);
paulba23a692003-04-19 15:55:08 +0000733 }
paul718e3742002-12-13 20:15:29 +0000734}