blob: 056cd40131ca5700fc896e505f39f9174cbd270f [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Distribute list functions
2 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "hash.h"
25#include "if.h"
26#include "filter.h"
27#include "command.h"
28#include "distribute.h"
29#include "memory.h"
30
31/* Hash of distribute list. */
32struct hash *disthash;
33
34/* Hook functions. */
35void (*distribute_add_hook) (struct distribute *);
36void (*distribute_delete_hook) (struct distribute *);
37
paul8cc41982005-05-06 21:25:49 +000038static struct distribute *
39distribute_new (void)
paul718e3742002-12-13 20:15:29 +000040{
Stephen Hemminger393deb92008-08-18 14:13:29 -070041 return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
paul718e3742002-12-13 20:15:29 +000042}
43
44/* Free distribute object. */
paul8cc41982005-05-06 21:25:49 +000045static void
paul718e3742002-12-13 20:15:29 +000046distribute_free (struct distribute *dist)
47{
48 if (dist->ifname)
paul9035efa2004-10-10 11:56:56 +000049 XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
paul718e3742002-12-13 20:15:29 +000050
51 if (dist->list[DISTRIBUTE_IN])
52 free (dist->list[DISTRIBUTE_IN]);
53 if (dist->list[DISTRIBUTE_OUT])
54 free (dist->list[DISTRIBUTE_OUT]);
55
56 if (dist->prefix[DISTRIBUTE_IN])
57 free (dist->prefix[DISTRIBUTE_IN]);
58 if (dist->prefix[DISTRIBUTE_OUT])
59 free (dist->prefix[DISTRIBUTE_OUT]);
60
61 XFREE (MTYPE_DISTRIBUTE, dist);
62}
63
64/* Lookup interface's distribute list. */
65struct distribute *
paul9035efa2004-10-10 11:56:56 +000066distribute_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +000067{
68 struct distribute key;
69 struct distribute *dist;
70
paul9035efa2004-10-10 11:56:56 +000071 /* temporary reference */
72 key.ifname = (char *)ifname;
paul718e3742002-12-13 20:15:29 +000073
74 dist = hash_lookup (disthash, &key);
75
76 return dist;
77}
78
79void
80distribute_list_add_hook (void (*func) (struct distribute *))
81{
82 distribute_add_hook = func;
83}
84
85void
86distribute_list_delete_hook (void (*func) (struct distribute *))
87{
88 distribute_delete_hook = func;
89}
90
paul8cc41982005-05-06 21:25:49 +000091static void *
paul718e3742002-12-13 20:15:29 +000092distribute_hash_alloc (struct distribute *arg)
93{
94 struct distribute *dist;
95
96 dist = distribute_new ();
97 if (arg->ifname)
paul9035efa2004-10-10 11:56:56 +000098 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
paul718e3742002-12-13 20:15:29 +000099 else
100 dist->ifname = NULL;
101 return dist;
102}
103
104/* Make new distribute list and push into hash. */
paul8cc41982005-05-06 21:25:49 +0000105static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000106distribute_get (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000107{
108 struct distribute key;
109
paul9035efa2004-10-10 11:56:56 +0000110 /* temporary reference */
111 key.ifname = (char *)ifname;
112
paul8cc41982005-05-06 21:25:49 +0000113 return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
paul718e3742002-12-13 20:15:29 +0000114}
115
paul8cc41982005-05-06 21:25:49 +0000116static unsigned int
paul718e3742002-12-13 20:15:29 +0000117distribute_hash_make (struct distribute *dist)
118{
hasso8c328f12004-10-05 21:01:23 +0000119 unsigned int i, key;
paul718e3742002-12-13 20:15:29 +0000120
121 key = 0;
122 if (dist->ifname)
123 for (i = 0; i < strlen (dist->ifname); i++)
124 key += dist->ifname[i];
125
126 return key;
127}
128
129/* If two distribute-list have same value then return 1 else return
130 0. This function is used by hash package. */
paul8cc41982005-05-06 21:25:49 +0000131static int
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100132distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
paul718e3742002-12-13 20:15:29 +0000133{
134 if (dist1->ifname && dist2->ifname)
135 if (strcmp (dist1->ifname, dist2->ifname) == 0)
136 return 1;
137 if (! dist1->ifname && ! dist2->ifname)
138 return 1;
139 return 0;
140}
141
142/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000143static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000144distribute_list_set (const char *ifname, enum distribute_type type,
145 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000146{
147 struct distribute *dist;
148
149 dist = distribute_get (ifname);
150
151 if (type == DISTRIBUTE_IN)
152 {
153 if (dist->list[DISTRIBUTE_IN])
154 free (dist->list[DISTRIBUTE_IN]);
155 dist->list[DISTRIBUTE_IN] = strdup (alist_name);
156 }
157 if (type == DISTRIBUTE_OUT)
158 {
159 if (dist->list[DISTRIBUTE_OUT])
160 free (dist->list[DISTRIBUTE_OUT]);
161 dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
162 }
163
164 /* Apply this distribute-list to the interface. */
165 (*distribute_add_hook) (dist);
166
167 return dist;
168}
169
170/* Unset distribute-list. If matched distribute-list exist then
171 return 1. */
paul8cc41982005-05-06 21:25:49 +0000172static int
paul9035efa2004-10-10 11:56:56 +0000173distribute_list_unset (const char *ifname, enum distribute_type type,
174 const char *alist_name)
paul718e3742002-12-13 20:15:29 +0000175{
176 struct distribute *dist;
177
178 dist = distribute_lookup (ifname);
179 if (!dist)
180 return 0;
181
182 if (type == DISTRIBUTE_IN)
183 {
184 if (!dist->list[DISTRIBUTE_IN])
185 return 0;
186 if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
187 return 0;
188
189 free (dist->list[DISTRIBUTE_IN]);
190 dist->list[DISTRIBUTE_IN] = NULL;
191 }
192
193 if (type == DISTRIBUTE_OUT)
194 {
195 if (!dist->list[DISTRIBUTE_OUT])
196 return 0;
197 if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
198 return 0;
199
200 free (dist->list[DISTRIBUTE_OUT]);
201 dist->list[DISTRIBUTE_OUT] = NULL;
202 }
203
204 /* Apply this distribute-list to the interface. */
205 (*distribute_delete_hook) (dist);
206
207 /* If both out and in is NULL then free distribute list. */
208 if (dist->list[DISTRIBUTE_IN] == NULL &&
209 dist->list[DISTRIBUTE_OUT] == NULL &&
210 dist->prefix[DISTRIBUTE_IN] == NULL &&
211 dist->prefix[DISTRIBUTE_OUT] == NULL)
212 {
213 hash_release (disthash, dist);
214 distribute_free (dist);
215 }
216
217 return 1;
218}
219
220/* Set access-list name to the distribute list. */
paul8cc41982005-05-06 21:25:49 +0000221static struct distribute *
paul9035efa2004-10-10 11:56:56 +0000222distribute_list_prefix_set (const char *ifname, enum distribute_type type,
223 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000224{
225 struct distribute *dist;
226
227 dist = distribute_get (ifname);
228
229 if (type == DISTRIBUTE_IN)
230 {
231 if (dist->prefix[DISTRIBUTE_IN])
232 free (dist->prefix[DISTRIBUTE_IN]);
233 dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
234 }
235 if (type == DISTRIBUTE_OUT)
236 {
237 if (dist->prefix[DISTRIBUTE_OUT])
238 free (dist->prefix[DISTRIBUTE_OUT]);
239 dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
240 }
241
242 /* Apply this distribute-list to the interface. */
243 (*distribute_add_hook) (dist);
244
245 return dist;
246}
247
248/* Unset distribute-list. If matched distribute-list exist then
249 return 1. */
paul8cc41982005-05-06 21:25:49 +0000250static int
paul9035efa2004-10-10 11:56:56 +0000251distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
252 const char *plist_name)
paul718e3742002-12-13 20:15:29 +0000253{
254 struct distribute *dist;
255
256 dist = distribute_lookup (ifname);
257 if (!dist)
258 return 0;
259
260 if (type == DISTRIBUTE_IN)
261 {
262 if (!dist->prefix[DISTRIBUTE_IN])
263 return 0;
264 if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
265 return 0;
266
267 free (dist->prefix[DISTRIBUTE_IN]);
268 dist->prefix[DISTRIBUTE_IN] = NULL;
269 }
270
271 if (type == DISTRIBUTE_OUT)
272 {
273 if (!dist->prefix[DISTRIBUTE_OUT])
274 return 0;
275 if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
276 return 0;
277
278 free (dist->prefix[DISTRIBUTE_OUT]);
279 dist->prefix[DISTRIBUTE_OUT] = NULL;
280 }
281
282 /* Apply this distribute-list to the interface. */
283 (*distribute_delete_hook) (dist);
284
285 /* If both out and in is NULL then free distribute list. */
286 if (dist->list[DISTRIBUTE_IN] == NULL &&
287 dist->list[DISTRIBUTE_OUT] == NULL &&
288 dist->prefix[DISTRIBUTE_IN] == NULL &&
289 dist->prefix[DISTRIBUTE_OUT] == NULL)
290 {
291 hash_release (disthash, dist);
292 distribute_free (dist);
293 }
294
295 return 1;
296}
297
298DEFUN (distribute_list_all,
299 distribute_list_all_cmd,
300 "distribute-list WORD (in|out)",
301 "Filter networks in routing updates\n"
302 "Access-list name\n"
303 "Filter incoming routing updates\n"
304 "Filter outgoing routing updates\n")
305{
306 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000307
308 /* Check of distribute list type. */
309 if (strncmp (argv[1], "i", 1) == 0)
310 type = DISTRIBUTE_IN;
311 else if (strncmp (argv[1], "o", 1) == 0)
312 type = DISTRIBUTE_OUT;
313 else
314 {
315 vty_out (vty, "distribute list direction must be [in|out]%s",
316 VTY_NEWLINE);
317 return CMD_WARNING;
318 }
319
320 /* Get interface name corresponding distribute list. */
Denis Ovsienko8fee9272011-10-14 20:59:43 +0400321 distribute_list_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000322
323 return CMD_SUCCESS;
324}
325
paulba23a692003-04-19 15:55:08 +0000326ALIAS (distribute_list_all,
327 ipv6_distribute_list_all_cmd,
328 "distribute-list WORD (in|out)",
329 "Filter networks in routing updates\n"
330 "Access-list name\n"
331 "Filter incoming routing updates\n"
332 "Filter outgoing routing updates\n")
333
paul718e3742002-12-13 20:15:29 +0000334DEFUN (no_distribute_list_all,
335 no_distribute_list_all_cmd,
336 "no distribute-list WORD (in|out)",
337 NO_STR
338 "Filter networks in routing updates\n"
339 "Access-list name\n"
340 "Filter incoming routing updates\n"
341 "Filter outgoing routing updates\n")
342{
343 int ret;
344 enum distribute_type type;
345
346 /* Check of distribute list type. */
347 if (strncmp (argv[1], "i", 1) == 0)
348 type = DISTRIBUTE_IN;
349 else if (strncmp (argv[1], "o", 1) == 0)
350 type = DISTRIBUTE_OUT;
351 else
352 {
353 vty_out (vty, "distribute list direction must be [in|out]%s",
354 VTY_NEWLINE);
355 return CMD_WARNING;
356 }
357
358 ret = distribute_list_unset (NULL, type, argv[0]);
359 if (! ret)
360 {
361 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
362 return CMD_WARNING;
363 }
364 return CMD_SUCCESS;
365}
366
paulba23a692003-04-19 15:55:08 +0000367ALIAS (no_distribute_list_all,
368 no_ipv6_distribute_list_all_cmd,
369 "no distribute-list WORD (in|out)",
370 NO_STR
371 "Filter networks in routing updates\n"
372 "Access-list name\n"
373 "Filter incoming routing updates\n"
374 "Filter outgoing routing updates\n")
375
paul718e3742002-12-13 20:15:29 +0000376DEFUN (distribute_list,
377 distribute_list_cmd,
378 "distribute-list WORD (in|out) WORD",
379 "Filter networks in routing updates\n"
380 "Access-list name\n"
381 "Filter incoming routing updates\n"
382 "Filter outgoing routing updates\n"
383 "Interface name\n")
384{
385 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000386
387 /* Check of distribute list type. */
388 if (strncmp (argv[1], "i", 1) == 0)
389 type = DISTRIBUTE_IN;
390 else if (strncmp (argv[1], "o", 1) == 0)
391 type = DISTRIBUTE_OUT;
392 else
393 {
394 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
395 return CMD_WARNING;
396 }
397
398 /* Get interface name corresponding distribute list. */
Denis Ovsienko8fee9272011-10-14 20:59:43 +0400399 distribute_list_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000400
401 return CMD_SUCCESS;
402}
403
paulba23a692003-04-19 15:55:08 +0000404ALIAS (distribute_list,
405 ipv6_distribute_list_cmd,
406 "distribute-list WORD (in|out) WORD",
407 "Filter networks in routing updates\n"
408 "Access-list name\n"
409 "Filter incoming routing updates\n"
410 "Filter outgoing routing updates\n"
411 "Interface name\n")
412
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400413DEFUN (no_distribute_list, no_distribute_list_cmd,
paul718e3742002-12-13 20:15:29 +0000414 "no distribute-list WORD (in|out) WORD",
415 NO_STR
416 "Filter networks in routing updates\n"
417 "Access-list name\n"
418 "Filter incoming routing updates\n"
419 "Filter outgoing routing updates\n"
420 "Interface name\n")
421{
422 int ret;
423 enum distribute_type type;
424
425 /* Check of distribute list type. */
426 if (strncmp (argv[1], "i", 1) == 0)
427 type = DISTRIBUTE_IN;
428 else if (strncmp (argv[1], "o", 1) == 0)
429 type = DISTRIBUTE_OUT;
430 else
431 {
432 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
433 return CMD_WARNING;
434 }
435
436 ret = distribute_list_unset (argv[2], type, argv[0]);
437 if (! ret)
438 {
439 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
440 return CMD_WARNING;
441 }
442 return CMD_SUCCESS;
443}
444
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400445ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
paulba23a692003-04-19 15:55:08 +0000446 "no distribute-list WORD (in|out) WORD",
447 NO_STR
448 "Filter networks in routing updates\n"
449 "Access-list name\n"
450 "Filter incoming routing updates\n"
451 "Filter outgoing routing updates\n"
452 "Interface name\n")
453
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400454DEFUN (distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000455 distribute_list_prefix_all_cmd,
456 "distribute-list prefix WORD (in|out)",
457 "Filter networks in routing updates\n"
458 "Filter prefixes in routing updates\n"
459 "Name of an IP prefix-list\n"
460 "Filter incoming routing updates\n"
461 "Filter outgoing routing updates\n")
462{
463 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000464
465 /* Check of distribute list type. */
466 if (strncmp (argv[1], "i", 1) == 0)
467 type = DISTRIBUTE_IN;
468 else if (strncmp (argv[1], "o", 1) == 0)
469 type = DISTRIBUTE_OUT;
470 else
471 {
472 vty_out (vty, "distribute list direction must be [in|out]%s",
473 VTY_NEWLINE);
474 return CMD_WARNING;
475 }
476
477 /* Get interface name corresponding distribute list. */
Denis Ovsienko8fee9272011-10-14 20:59:43 +0400478 distribute_list_prefix_set (NULL, type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000479
480 return CMD_SUCCESS;
481}
482
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400483ALIAS (distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000484 ipv6_distribute_list_prefix_all_cmd,
485 "distribute-list prefix WORD (in|out)",
486 "Filter networks in routing updates\n"
487 "Filter prefixes in routing updates\n"
488 "Name of an IP prefix-list\n"
489 "Filter incoming routing updates\n"
490 "Filter outgoing routing updates\n")
491
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400492DEFUN (no_distribute_list_prefix_all,
paul718e3742002-12-13 20:15:29 +0000493 no_distribute_list_prefix_all_cmd,
494 "no distribute-list prefix WORD (in|out)",
495 NO_STR
496 "Filter networks in routing updates\n"
497 "Filter prefixes in routing updates\n"
498 "Name of an IP prefix-list\n"
499 "Filter incoming routing updates\n"
500 "Filter outgoing routing updates\n")
501{
502 int ret;
503 enum distribute_type type;
504
505 /* Check of distribute list type. */
506 if (strncmp (argv[1], "i", 1) == 0)
507 type = DISTRIBUTE_IN;
508 else if (strncmp (argv[1], "o", 1) == 0)
509 type = DISTRIBUTE_OUT;
510 else
511 {
512 vty_out (vty, "distribute list direction must be [in|out]%s",
513 VTY_NEWLINE);
514 return CMD_WARNING;
515 }
516
517 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
518 if (! ret)
519 {
520 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
521 return CMD_WARNING;
522 }
523 return CMD_SUCCESS;
524}
525
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400526ALIAS (no_distribute_list_prefix_all,
paulba23a692003-04-19 15:55:08 +0000527 no_ipv6_distribute_list_prefix_all_cmd,
528 "no distribute-list prefix WORD (in|out)",
529 NO_STR
530 "Filter networks in routing updates\n"
531 "Filter prefixes in routing updates\n"
532 "Name of an IP prefix-list\n"
533 "Filter incoming routing updates\n"
534 "Filter outgoing routing updates\n")
535
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400536DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000537 "distribute-list prefix WORD (in|out) WORD",
538 "Filter networks in routing updates\n"
539 "Filter prefixes in routing updates\n"
540 "Name of an IP prefix-list\n"
541 "Filter incoming routing updates\n"
542 "Filter outgoing routing updates\n"
543 "Interface name\n")
544{
545 enum distribute_type type;
paul718e3742002-12-13 20:15:29 +0000546
547 /* Check of distribute list type. */
548 if (strncmp (argv[1], "i", 1) == 0)
549 type = DISTRIBUTE_IN;
550 else if (strncmp (argv[1], "o", 1) == 0)
551 type = DISTRIBUTE_OUT;
552 else
553 {
554 vty_out (vty, "distribute list direction must be [in|out]%s",
555 VTY_NEWLINE);
556 return CMD_WARNING;
557 }
558
559 /* Get interface name corresponding distribute list. */
Denis Ovsienko8fee9272011-10-14 20:59:43 +0400560 distribute_list_prefix_set (argv[2], type, argv[0]);
paul718e3742002-12-13 20:15:29 +0000561
562 return CMD_SUCCESS;
563}
564
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400565ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000566 "distribute-list prefix WORD (in|out) WORD",
567 "Filter networks in routing updates\n"
568 "Filter prefixes in routing updates\n"
569 "Name of an IP prefix-list\n"
570 "Filter incoming routing updates\n"
571 "Filter outgoing routing updates\n"
572 "Interface name\n")
573
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400574DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
paul718e3742002-12-13 20:15:29 +0000575 "no distribute-list prefix WORD (in|out) WORD",
576 NO_STR
577 "Filter networks in routing updates\n"
578 "Filter prefixes in routing updates\n"
579 "Name of an IP prefix-list\n"
580 "Filter incoming routing updates\n"
581 "Filter outgoing routing updates\n"
582 "Interface name\n")
583{
584 int ret;
585 enum distribute_type type;
586
587 /* Check of distribute list type. */
588 if (strncmp (argv[1], "i", 1) == 0)
589 type = DISTRIBUTE_IN;
590 else if (strncmp (argv[1], "o", 1) == 0)
591 type = DISTRIBUTE_OUT;
592 else
593 {
594 vty_out (vty, "distribute list direction must be [in|out]%s",
595 VTY_NEWLINE);
596 return CMD_WARNING;
597 }
598
599 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
600 if (! ret)
601 {
602 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
603 return CMD_WARNING;
604 }
605 return CMD_SUCCESS;
606}
607
Denis Ovsienkobb6ef3e2011-10-14 20:56:19 +0400608ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
paulba23a692003-04-19 15:55:08 +0000609 "no distribute-list prefix WORD (in|out) WORD",
610 NO_STR
611 "Filter networks in routing updates\n"
612 "Filter prefixes in routing updates\n"
613 "Name of an IP prefix-list\n"
614 "Filter incoming routing updates\n"
615 "Filter outgoing routing updates\n"
616 "Interface name\n")
617
paul718e3742002-12-13 20:15:29 +0000618int
619config_show_distribute (struct vty *vty)
620{
hasso8c328f12004-10-05 21:01:23 +0000621 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000622 struct hash_backet *mp;
623 struct distribute *dist;
624
625 /* Output filter configuration. */
626 dist = distribute_lookup (NULL);
627 if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
628 {
629 vty_out (vty, " Outgoing update filter list for all interface is");
630 if (dist->list[DISTRIBUTE_OUT])
631 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
632 if (dist->prefix[DISTRIBUTE_OUT])
633 vty_out (vty, "%s (prefix-list) %s",
634 dist->list[DISTRIBUTE_OUT] ? "," : "",
635 dist->prefix[DISTRIBUTE_OUT]);
636 vty_out (vty, "%s", VTY_NEWLINE);
637 }
638 else
639 vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
640
641 for (i = 0; i < disthash->size; i++)
642 for (mp = disthash->index[i]; mp; mp = mp->next)
643 {
644 dist = mp->data;
645 if (dist->ifname)
646 if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
647 {
648 vty_out (vty, " %s filtered by", dist->ifname);
649 if (dist->list[DISTRIBUTE_OUT])
650 vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
651 if (dist->prefix[DISTRIBUTE_OUT])
652 vty_out (vty, "%s (prefix-list) %s",
653 dist->list[DISTRIBUTE_OUT] ? "," : "",
654 dist->prefix[DISTRIBUTE_OUT]);
655 vty_out (vty, "%s", VTY_NEWLINE);
656 }
657 }
658
659
660 /* Input filter configuration. */
661 dist = distribute_lookup (NULL);
662 if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
663 {
664 vty_out (vty, " Incoming update filter list for all interface is");
665 if (dist->list[DISTRIBUTE_IN])
666 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
667 if (dist->prefix[DISTRIBUTE_IN])
668 vty_out (vty, "%s (prefix-list) %s",
669 dist->list[DISTRIBUTE_IN] ? "," : "",
670 dist->prefix[DISTRIBUTE_IN]);
671 vty_out (vty, "%s", VTY_NEWLINE);
672 }
673 else
674 vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
675
676 for (i = 0; i < disthash->size; i++)
677 for (mp = disthash->index[i]; mp; mp = mp->next)
678 {
679 dist = mp->data;
680 if (dist->ifname)
681 if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
682 {
683 vty_out (vty, " %s filtered by", dist->ifname);
684 if (dist->list[DISTRIBUTE_IN])
685 vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
686 if (dist->prefix[DISTRIBUTE_IN])
687 vty_out (vty, "%s (prefix-list) %s",
688 dist->list[DISTRIBUTE_IN] ? "," : "",
689 dist->prefix[DISTRIBUTE_IN]);
690 vty_out (vty, "%s", VTY_NEWLINE);
691 }
692 }
693 return 0;
694}
695
696/* Configuration write function. */
697int
698config_write_distribute (struct vty *vty)
699{
hasso8c328f12004-10-05 21:01:23 +0000700 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000701 struct hash_backet *mp;
702 int write = 0;
703
704 for (i = 0; i < disthash->size; i++)
705 for (mp = disthash->index[i]; mp; mp = mp->next)
706 {
707 struct distribute *dist;
708
709 dist = mp->data;
710
711 if (dist->list[DISTRIBUTE_IN])
712 {
713 vty_out (vty, " distribute-list %s in %s%s",
714 dist->list[DISTRIBUTE_IN],
715 dist->ifname ? dist->ifname : "",
716 VTY_NEWLINE);
717 write++;
718 }
719
720 if (dist->list[DISTRIBUTE_OUT])
721 {
722 vty_out (vty, " distribute-list %s out %s%s",
723
724 dist->list[DISTRIBUTE_OUT],
725 dist->ifname ? dist->ifname : "",
726 VTY_NEWLINE);
727 write++;
728 }
729
730 if (dist->prefix[DISTRIBUTE_IN])
731 {
732 vty_out (vty, " distribute-list prefix %s in %s%s",
733 dist->prefix[DISTRIBUTE_IN],
734 dist->ifname ? dist->ifname : "",
735 VTY_NEWLINE);
736 write++;
737 }
738
739 if (dist->prefix[DISTRIBUTE_OUT])
740 {
741 vty_out (vty, " distribute-list prefix %s out %s%s",
742 dist->prefix[DISTRIBUTE_OUT],
743 dist->ifname ? dist->ifname : "",
744 VTY_NEWLINE);
745 write++;
746 }
747 }
748 return write;
749}
750
751/* Clear all distribute list. */
752void
753distribute_list_reset ()
754{
755 hash_clean (disthash, (void (*) (void *)) distribute_free);
756}
757
758/* Initialize distribute list related hash. */
759void
760distribute_list_init (int node)
761{
paul8cc41982005-05-06 21:25:49 +0000762 disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +0100763 (int (*) (const void *, const void *)) distribute_cmp);
paul718e3742002-12-13 20:15:29 +0000764
paulba23a692003-04-19 15:55:08 +0000765 if(node==RIP_NODE) {
766 install_element (RIP_NODE, &distribute_list_all_cmd);
767 install_element (RIP_NODE, &no_distribute_list_all_cmd);
768 install_element (RIP_NODE, &distribute_list_cmd);
769 install_element (RIP_NODE, &no_distribute_list_cmd);
770 install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
771 install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
772 install_element (RIP_NODE, &distribute_list_prefix_cmd);
773 install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
774 } else {
775 install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
776 install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
777 install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
778 install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
779 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
780 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
781 install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
782 install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
783 }
paul718e3742002-12-13 20:15:29 +0000784}