]> git.proxmox.com Git - mirror_frr.git/blame - lib/distribute.c
Merge pull request #429 from hwchiu/fix_clang_sa
[mirror_frr.git] / lib / distribute.c
CommitLineData
718e3744 1/* Distribute list functions
2 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "hash.h"
25#include "if.h"
26#include "filter.h"
27#include "command.h"
28#include "distribute.h"
29#include "memory.h"
30
4a1ab8e4
DL
31DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list")
32DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname")
33DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name")
34
718e3744 35/* Hash of distribute list. */
36struct hash *disthash;
37
38/* Hook functions. */
39void (*distribute_add_hook) (struct distribute *);
40void (*distribute_delete_hook) (struct distribute *);
6b0655a2 41
8cc4198f 42static struct distribute *
43distribute_new (void)
718e3744 44{
393deb9b 45 return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
718e3744 46}
47
48/* Free distribute object. */
8cc4198f 49static void
718e3744 50distribute_free (struct distribute *dist)
51{
ee5bb561
MB
52 int i = 0;
53
718e3744 54 if (dist->ifname)
9035efaa 55 XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
718e3744 56
ee5bb561
MB
57 for (i = 0; i < DISTRIBUTE_MAX; i++)
58 if (dist->list[i])
59 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[i]);
718e3744 60
ee5bb561
MB
61 for (i = 0; i < DISTRIBUTE_MAX; i++)
62 if (dist->prefix[i])
63 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[i]);
718e3744 64
65 XFREE (MTYPE_DISTRIBUTE, dist);
66}
67
ee5bb561
MB
68static void
69distribute_free_if_empty(struct distribute *dist)
70{
71 int i;
72
73 for (i = 0; i < DISTRIBUTE_MAX; i++)
74 if (dist->list[i] != NULL || dist->prefix[i] != NULL)
75 return;
76
77 hash_release (disthash, dist);
78 distribute_free (dist);
79}
80
718e3744 81/* Lookup interface's distribute list. */
82struct distribute *
9035efaa 83distribute_lookup (const char *ifname)
718e3744 84{
85 struct distribute key;
86 struct distribute *dist;
87
9035efaa 88 /* temporary reference */
3a7c85d1 89 key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
718e3744 90
91 dist = hash_lookup (disthash, &key);
3a7c85d1
DS
92
93 if (key.ifname)
94 XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
24873f0c 95
718e3744 96 return dist;
97}
98
99void
100distribute_list_add_hook (void (*func) (struct distribute *))
101{
102 distribute_add_hook = func;
103}
104
105void
106distribute_list_delete_hook (void (*func) (struct distribute *))
107{
108 distribute_delete_hook = func;
109}
110
8cc4198f 111static void *
718e3744 112distribute_hash_alloc (struct distribute *arg)
113{
114 struct distribute *dist;
115
116 dist = distribute_new ();
117 if (arg->ifname)
9035efaa 118 dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
718e3744 119 else
120 dist->ifname = NULL;
121 return dist;
122}
123
124/* Make new distribute list and push into hash. */
8cc4198f 125static struct distribute *
9035efaa 126distribute_get (const char *ifname)
718e3744 127{
128 struct distribute key;
24873f0c 129 struct distribute *ret;
718e3744 130
9035efaa 131 /* temporary reference */
3a7c85d1 132 key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
9035efaa 133
24873f0c
DS
134 ret = hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
135
3a7c85d1
DS
136 if (key.ifname)
137 XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
138
24873f0c 139 return ret;
718e3744 140}
141
8cc4198f 142static unsigned int
6392aa83 143distribute_hash_make (void *arg)
718e3744 144{
6392aa83 145 const struct distribute *dist = arg;
718e3744 146
6392aa83 147 return dist->ifname ? string_hash_make (dist->ifname) : 0;
718e3744 148}
149
150/* If two distribute-list have same value then return 1 else return
151 0. This function is used by hash package. */
8cc4198f 152static int
ffe11cfb 153distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
718e3744 154{
155 if (dist1->ifname && dist2->ifname)
156 if (strcmp (dist1->ifname, dist2->ifname) == 0)
157 return 1;
158 if (! dist1->ifname && ! dist2->ifname)
159 return 1;
160 return 0;
161}
6b0655a2 162
718e3744 163/* Set access-list name to the distribute list. */
8cc4198f 164static struct distribute *
ee5bb561 165distribute_list_set (const char *ifname, enum distribute_type type,
9035efaa 166 const char *alist_name)
718e3744 167{
168 struct distribute *dist;
169
170 dist = distribute_get (ifname);
171
ee5bb561
MB
172 if (dist->list[type])
173 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
174 dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
718e3744 175
176 /* Apply this distribute-list to the interface. */
177 (*distribute_add_hook) (dist);
ee5bb561 178
718e3744 179 return dist;
180}
181
182/* Unset distribute-list. If matched distribute-list exist then
183 return 1. */
8cc4198f 184static int
ee5bb561 185distribute_list_unset (const char *ifname, enum distribute_type type,
9035efaa 186 const char *alist_name)
718e3744 187{
188 struct distribute *dist;
189
190 dist = distribute_lookup (ifname);
191 if (!dist)
192 return 0;
193
ee5bb561
MB
194 if (!dist->list[type])
195 return 0;
196 if (strcmp (dist->list[type], alist_name) != 0)
197 return 0;
718e3744 198
ee5bb561
MB
199 XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
200 dist->list[type] = NULL;
718e3744 201
202 /* Apply this distribute-list to the interface. */
203 (*distribute_delete_hook) (dist);
204
ee5bb561
MB
205 /* If all dist are NULL, then free distribute list. */
206 distribute_free_if_empty(dist);
718e3744 207 return 1;
208}
209
210/* Set access-list name to the distribute list. */
8cc4198f 211static struct distribute *
9035efaa 212distribute_list_prefix_set (const char *ifname, enum distribute_type type,
213 const char *plist_name)
718e3744 214{
215 struct distribute *dist;
216
217 dist = distribute_get (ifname);
218
ee5bb561
MB
219 if (dist->prefix[type])
220 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
221 dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
718e3744 222
223 /* Apply this distribute-list to the interface. */
224 (*distribute_add_hook) (dist);
225
226 return dist;
227}
228
229/* Unset distribute-list. If matched distribute-list exist then
230 return 1. */
8cc4198f 231static int
9035efaa 232distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
233 const char *plist_name)
718e3744 234{
235 struct distribute *dist;
236
237 dist = distribute_lookup (ifname);
238 if (!dist)
239 return 0;
240
ee5bb561
MB
241 if (!dist->prefix[type])
242 return 0;
243 if (strcmp (dist->prefix[type], plist_name) != 0)
244 return 0;
718e3744 245
ee5bb561
MB
246 XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
247 dist->prefix[type] = NULL;
718e3744 248
249 /* Apply this distribute-list to the interface. */
250 (*distribute_delete_hook) (dist);
251
ee5bb561
MB
252 /* If all dist are NULL, then free distribute list. */
253 distribute_free_if_empty(dist);
718e3744 254 return 1;
255}
256
257DEFUN (distribute_list_all,
258 distribute_list_all_cmd,
259 "distribute-list WORD (in|out)",
260 "Filter networks in routing updates\n"
261 "Access-list name\n"
262 "Filter incoming routing updates\n"
263 "Filter outgoing routing updates\n")
264{
265 enum distribute_type type;
718e3744 266
267 /* Check of distribute list type. */
268 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 269 type = DISTRIBUTE_V4_IN;
718e3744 270 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 271 type = DISTRIBUTE_V4_OUT;
718e3744 272 else
273 {
274 vty_out (vty, "distribute list direction must be [in|out]%s",
275 VTY_NEWLINE);
276 return CMD_WARNING;
277 }
278
279 /* Get interface name corresponding distribute list. */
9206f9ec 280 distribute_list_set (NULL, type, argv[0]);
718e3744 281
282 return CMD_SUCCESS;
283}
284
fb23cf4a 285DEFUN (ipv6_distribute_list_all,
ba23a691 286 ipv6_distribute_list_all_cmd,
fb23cf4a
MB
287 "ipv6 distribute-list WORD (in|out)",
288 "Filter networks in routing updates\n"
289 "Access-list name\n"
290 "Filter incoming routing updates\n"
291 "Filter outgoing routing updates\n")
292{
293 enum distribute_type type;
294
295 /* Check of distribute list type. */
296 if (strncmp (argv[1], "i", 1) == 0)
297 type = DISTRIBUTE_V6_IN;
298 else if (strncmp (argv[1], "o", 1) == 0)
299 type = DISTRIBUTE_V6_OUT;
300 else
301 {
302 vty_out (vty, "distribute list direction must be [in|out]%s",
303 VTY_NEWLINE);
304 return CMD_WARNING;
305 }
306
307 /* Get interface name corresponding distribute list. */
308 distribute_list_set (NULL, type, argv[0]);
309
310 return CMD_SUCCESS;
311}
312
313ALIAS (ipv6_distribute_list_all,
314 ipv6_as_v4_distribute_list_all_cmd,
ba23a691 315 "distribute-list WORD (in|out)",
316 "Filter networks in routing updates\n"
317 "Access-list name\n"
318 "Filter incoming routing updates\n"
319 "Filter outgoing routing updates\n")
320
718e3744 321DEFUN (no_distribute_list_all,
322 no_distribute_list_all_cmd,
323 "no distribute-list WORD (in|out)",
324 NO_STR
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{
330 int ret;
331 enum distribute_type type;
332
333 /* Check of distribute list type. */
334 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 335 type = DISTRIBUTE_V4_IN;
718e3744 336 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 337 type = DISTRIBUTE_V4_OUT;
718e3744 338 else
339 {
340 vty_out (vty, "distribute list direction must be [in|out]%s",
341 VTY_NEWLINE);
342 return CMD_WARNING;
343 }
344
345 ret = distribute_list_unset (NULL, type, argv[0]);
346 if (! ret)
347 {
348 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
349 return CMD_WARNING;
350 }
351 return CMD_SUCCESS;
352}
353
fb23cf4a 354DEFUN (no_ipv6_distribute_list_all,
ba23a691 355 no_ipv6_distribute_list_all_cmd,
fb23cf4a
MB
356 "no ipv6 distribute-list WORD (in|out)",
357 NO_STR
358 "Filter networks in routing updates\n"
359 "Access-list name\n"
360 "Filter incoming routing updates\n"
361 "Filter outgoing routing updates\n")
362{
363 int ret;
364 enum distribute_type type;
365
366 /* Check of distribute list type. */
367 if (strncmp (argv[1], "i", 1) == 0)
368 type = DISTRIBUTE_V6_IN;
369 else if (strncmp (argv[1], "o", 1) == 0)
370 type = DISTRIBUTE_V6_OUT;
371 else
372 {
373 vty_out (vty, "distribute list direction must be [in|out]%s",
374 VTY_NEWLINE);
375 return CMD_WARNING;
376 }
377
378 ret = distribute_list_unset (NULL, type, argv[0]);
379 if (! ret)
380 {
381 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
382 return CMD_WARNING;
383 }
384 return CMD_SUCCESS;
385}
386
387ALIAS (no_ipv6_distribute_list_all,
388 no_ipv6_as_v4_distribute_list_all_cmd,
ba23a691 389 "no distribute-list WORD (in|out)",
390 NO_STR
391 "Filter networks in routing updates\n"
392 "Access-list name\n"
393 "Filter incoming routing updates\n"
394 "Filter outgoing routing updates\n")
395
718e3744 396DEFUN (distribute_list,
397 distribute_list_cmd,
398 "distribute-list WORD (in|out) WORD",
399 "Filter networks in routing updates\n"
400 "Access-list name\n"
401 "Filter incoming routing updates\n"
402 "Filter outgoing routing updates\n"
403 "Interface name\n")
404{
405 enum distribute_type type;
718e3744 406
407 /* Check of distribute list type. */
408 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 409 type = DISTRIBUTE_V4_IN;
718e3744 410 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 411 type = DISTRIBUTE_V4_OUT;
718e3744 412 else
413 {
414 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
415 return CMD_WARNING;
416 }
417
418 /* Get interface name corresponding distribute list. */
9206f9ec 419 distribute_list_set (argv[2], type, argv[0]);
718e3744 420
421 return CMD_SUCCESS;
ee5bb561 422}
718e3744 423
fb23cf4a 424DEFUN (ipv6_distribute_list,
ba23a691 425 ipv6_distribute_list_cmd,
fb23cf4a
MB
426 "ipv6 distribute-list WORD (in|out) WORD",
427 "Filter networks in routing updates\n"
428 "Access-list name\n"
429 "Filter incoming routing updates\n"
430 "Filter outgoing routing updates\n"
431 "Interface name\n")
432{
433 enum distribute_type type;
434
435 /* Check of distribute list type. */
436 if (strncmp (argv[1], "i", 1) == 0)
437 type = DISTRIBUTE_V6_IN;
438 else if (strncmp (argv[1], "o", 1) == 0)
439 type = DISTRIBUTE_V6_OUT;
440 else
441 {
442 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
443 return CMD_WARNING;
444 }
445
446 /* Get interface name corresponding distribute list. */
447 distribute_list_set (argv[2], type, argv[0]);
448
449 return CMD_SUCCESS;
450}
451
452ALIAS (ipv6_distribute_list,
453 ipv6_as_v4_distribute_list_cmd,
ba23a691 454 "distribute-list WORD (in|out) WORD",
455 "Filter networks in routing updates\n"
456 "Access-list name\n"
457 "Filter incoming routing updates\n"
458 "Filter outgoing routing updates\n"
459 "Interface name\n")
460
0ead5c18 461DEFUN (no_distribute_list, no_distribute_list_cmd,
718e3744 462 "no distribute-list WORD (in|out) WORD",
463 NO_STR
464 "Filter networks in routing updates\n"
465 "Access-list name\n"
466 "Filter incoming routing updates\n"
467 "Filter outgoing routing updates\n"
468 "Interface name\n")
469{
470 int ret;
471 enum distribute_type type;
472
473 /* Check of distribute list type. */
474 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 475 type = DISTRIBUTE_V4_IN;
718e3744 476 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 477 type = DISTRIBUTE_V4_OUT;
718e3744 478 else
479 {
480 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
481 return CMD_WARNING;
482 }
483
484 ret = distribute_list_unset (argv[2], type, argv[0]);
485 if (! ret)
486 {
487 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
488 return CMD_WARNING;
489 }
490 return CMD_SUCCESS;
ee5bb561 491}
718e3744 492
fb23cf4a
MB
493DEFUN (no_ipv6_distribute_list,
494 no_ipv6_distribute_list_cmd,
495 "no ipv6 distribute-list WORD (in|out) WORD",
496 NO_STR
497 "Filter networks in routing updates\n"
498 "Access-list name\n"
499 "Filter incoming routing updates\n"
500 "Filter outgoing routing updates\n"
501 "Interface name\n")
502{
503 int ret;
504 enum distribute_type type;
505
506 /* Check of distribute list type. */
507 if (strncmp (argv[1], "i", 1) == 0)
508 type = DISTRIBUTE_V6_IN;
509 else if (strncmp (argv[1], "o", 1) == 0)
510 type = DISTRIBUTE_V6_OUT;
511 else
512 {
513 vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
514 return CMD_WARNING;
515 }
516
517 ret = distribute_list_unset (argv[2], 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
526ALIAS (no_ipv6_distribute_list,
527 no_ipv6_as_v4_distribute_list_cmd,
ba23a691 528 "no distribute-list WORD (in|out) WORD",
529 NO_STR
530 "Filter networks in routing updates\n"
531 "Access-list name\n"
532 "Filter incoming routing updates\n"
533 "Filter outgoing routing updates\n"
534 "Interface name\n")
535
0ead5c18 536DEFUN (distribute_list_prefix_all,
718e3744 537 distribute_list_prefix_all_cmd,
538 "distribute-list prefix WORD (in|out)",
539 "Filter networks in routing updates\n"
540 "Filter prefixes in routing updates\n"
541 "Name of an IP prefix-list\n"
542 "Filter incoming routing updates\n"
543 "Filter outgoing routing updates\n")
544{
545 enum distribute_type type;
718e3744 546
547 /* Check of distribute list type. */
548 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 549 type = DISTRIBUTE_V4_IN;
718e3744 550 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 551 type = DISTRIBUTE_V4_OUT;
718e3744 552 else
553 {
fb23cf4a 554 vty_out (vty, "distribute list direction must be [in|out]%s",
718e3744 555 VTY_NEWLINE);
556 return CMD_WARNING;
557 }
558
559 /* Get interface name corresponding distribute list. */
9206f9ec 560 distribute_list_prefix_set (NULL, type, argv[0]);
718e3744 561
562 return CMD_SUCCESS;
ee5bb561 563}
718e3744 564
fb23cf4a 565DEFUN (ipv6_distribute_list_prefix_all,
ba23a691 566 ipv6_distribute_list_prefix_all_cmd,
fb23cf4a
MB
567 "ipv6 distribute-list prefix WORD (in|out)",
568 "Filter networks in routing updates\n"
569 "Filter prefixes in routing updates\n"
570 "Name of an IP prefix-list\n"
571 "Filter incoming routing updates\n"
572 "Filter outgoing routing updates\n")
573{
574 enum distribute_type type;
575
576 /* Check of distribute list type. */
577 if (strncmp (argv[1], "i", 1) == 0)
578 type = DISTRIBUTE_V6_IN;
579 else if (strncmp (argv[1], "o", 1) == 0)
580 type = DISTRIBUTE_V6_OUT;
581 else
582 {
583 vty_out (vty, "distribute list direction must be [in|out]%s",
584 VTY_NEWLINE);
585 return CMD_WARNING;
586 }
587
588 /* Get interface name corresponding distribute list. */
589 distribute_list_prefix_set (NULL, type, argv[0]);
590
591 return CMD_SUCCESS;
592}
593
594ALIAS (ipv6_distribute_list_prefix_all,
595 ipv6_as_v4_distribute_list_prefix_all_cmd,
ba23a691 596 "distribute-list prefix WORD (in|out)",
597 "Filter networks in routing updates\n"
598 "Filter prefixes in routing updates\n"
599 "Name of an IP prefix-list\n"
600 "Filter incoming routing updates\n"
601 "Filter outgoing routing updates\n")
602
0ead5c18 603DEFUN (no_distribute_list_prefix_all,
718e3744 604 no_distribute_list_prefix_all_cmd,
605 "no distribute-list prefix WORD (in|out)",
606 NO_STR
607 "Filter networks in routing updates\n"
608 "Filter prefixes in routing updates\n"
609 "Name of an IP prefix-list\n"
610 "Filter incoming routing updates\n"
611 "Filter outgoing routing updates\n")
612{
613 int ret;
614 enum distribute_type type;
615
616 /* Check of distribute list type. */
617 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 618 type = DISTRIBUTE_V4_IN;
718e3744 619 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 620 type = DISTRIBUTE_V4_OUT;
718e3744 621 else
622 {
fb23cf4a 623 vty_out (vty, "distribute list direction must be [in|out]%s",
718e3744 624 VTY_NEWLINE);
625 return CMD_WARNING;
626 }
627
628 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
629 if (! ret)
630 {
631 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
632 return CMD_WARNING;
633 }
634 return CMD_SUCCESS;
ee5bb561 635}
718e3744 636
fb23cf4a 637DEFUN (no_ipv6_distribute_list_prefix_all,
ba23a691 638 no_ipv6_distribute_list_prefix_all_cmd,
fb23cf4a
MB
639 "no ipv6 distribute-list prefix WORD (in|out)",
640 NO_STR
641 "Filter networks in routing updates\n"
642 "Filter prefixes in routing updates\n"
643 "Name of an IP prefix-list\n"
644 "Filter incoming routing updates\n"
645 "Filter outgoing routing updates\n")
646{
647 int ret;
648 enum distribute_type type;
649
650 /* Check of distribute list type. */
651 if (strncmp (argv[1], "i", 1) == 0)
652 type = DISTRIBUTE_V6_IN;
653 else if (strncmp (argv[1], "o", 1) == 0)
654 type = DISTRIBUTE_V6_OUT;
655 else
656 {
657 vty_out (vty, "distribute list direction must be [in|out]%s",
658 VTY_NEWLINE);
659 return CMD_WARNING;
660 }
661
662 ret = distribute_list_prefix_unset (NULL, type, argv[0]);
663 if (! ret)
664 {
665 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
666 return CMD_WARNING;
667 }
668 return CMD_SUCCESS;
669}
670
671ALIAS (no_ipv6_distribute_list_prefix_all,
672 no_ipv6_as_v4_distribute_list_prefix_all_cmd,
ba23a691 673 "no distribute-list prefix WORD (in|out)",
674 NO_STR
675 "Filter networks in routing updates\n"
676 "Filter prefixes in routing updates\n"
677 "Name of an IP prefix-list\n"
678 "Filter incoming routing updates\n"
679 "Filter outgoing routing updates\n")
680
0ead5c18 681DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
718e3744 682 "distribute-list prefix WORD (in|out) WORD",
683 "Filter networks in routing updates\n"
684 "Filter prefixes in routing updates\n"
685 "Name of an IP prefix-list\n"
686 "Filter incoming routing updates\n"
687 "Filter outgoing routing updates\n"
688 "Interface name\n")
689{
690 enum distribute_type type;
718e3744 691
692 /* Check of distribute list type. */
693 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 694 type = DISTRIBUTE_V4_IN;
718e3744 695 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 696 type = DISTRIBUTE_V4_OUT;
718e3744 697 else
698 {
fb23cf4a 699 vty_out (vty, "distribute list direction must be [in|out]%s",
718e3744 700 VTY_NEWLINE);
701 return CMD_WARNING;
702 }
703
704 /* Get interface name corresponding distribute list. */
9206f9ec 705 distribute_list_prefix_set (argv[2], type, argv[0]);
718e3744 706
707 return CMD_SUCCESS;
ee5bb561 708}
718e3744 709
fb23cf4a
MB
710DEFUN (ipv6_distribute_list_prefix,
711 ipv6_distribute_list_prefix_cmd,
712 "ipv6 distribute-list prefix WORD (in|out) WORD",
713 "Filter networks in routing updates\n"
714 "Filter prefixes in routing updates\n"
715 "Name of an IP prefix-list\n"
716 "Filter incoming routing updates\n"
717 "Filter outgoing routing updates\n"
718 "Interface name\n")
719{
720 enum distribute_type type;
721
722 /* Check of distribute list type. */
723 if (strncmp (argv[1], "i", 1) == 0)
724 type = DISTRIBUTE_V6_IN;
725 else if (strncmp (argv[1], "o", 1) == 0)
726 type = DISTRIBUTE_V6_OUT;
727 else
728 {
729 vty_out (vty, "distribute list direction must be [in|out]%s",
730 VTY_NEWLINE);
731 return CMD_WARNING;
732 }
733
734 /* Get interface name corresponding distribute list. */
735 distribute_list_prefix_set (argv[2], type, argv[0]);
736
737 return CMD_SUCCESS;
738}
739
740ALIAS (ipv6_distribute_list_prefix,
741 ipv6_as_v4_distribute_list_prefix_cmd,
ba23a691 742 "distribute-list prefix WORD (in|out) WORD",
743 "Filter networks in routing updates\n"
744 "Filter prefixes in routing updates\n"
745 "Name of an IP prefix-list\n"
746 "Filter incoming routing updates\n"
747 "Filter outgoing routing updates\n"
748 "Interface name\n")
749
0ead5c18 750DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
718e3744 751 "no distribute-list prefix WORD (in|out) WORD",
752 NO_STR
753 "Filter networks in routing updates\n"
754 "Filter prefixes in routing updates\n"
755 "Name of an IP prefix-list\n"
756 "Filter incoming routing updates\n"
757 "Filter outgoing routing updates\n"
758 "Interface name\n")
759{
760 int ret;
761 enum distribute_type type;
762
763 /* Check of distribute list type. */
764 if (strncmp (argv[1], "i", 1) == 0)
fb23cf4a 765 type = DISTRIBUTE_V4_IN;
718e3744 766 else if (strncmp (argv[1], "o", 1) == 0)
fb23cf4a 767 type = DISTRIBUTE_V4_OUT;
718e3744 768 else
769 {
fb23cf4a 770 vty_out (vty, "distribute list direction must be [in|out]%s",
718e3744 771 VTY_NEWLINE);
772 return CMD_WARNING;
773 }
774
775 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
776 if (! ret)
777 {
778 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
779 return CMD_WARNING;
780 }
781 return CMD_SUCCESS;
ee5bb561 782}
718e3744 783
fb23cf4a
MB
784DEFUN (no_ipv6_distribute_list_prefix,
785 no_ipv6_distribute_list_prefix_cmd,
786 "no ipv6 distribute-list prefix WORD (in|out) WORD",
787 NO_STR
788 "Filter networks in routing updates\n"
789 "Filter prefixes in routing updates\n"
790 "Name of an IP prefix-list\n"
791 "Filter incoming routing updates\n"
792 "Filter outgoing routing updates\n"
793 "Interface name\n")
794{
795 int ret;
796 enum distribute_type type;
797
798 /* Check of distribute list type. */
799 if (strncmp (argv[1], "i", 1) == 0)
800 type = DISTRIBUTE_V6_IN;
801 else if (strncmp (argv[1], "o", 1) == 0)
802 type = DISTRIBUTE_V6_OUT;
803 else
804 {
805 vty_out (vty, "distribute list direction must be [in|out]%s",
806 VTY_NEWLINE);
807 return CMD_WARNING;
808 }
809
810 ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
811 if (! ret)
812 {
813 vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
814 return CMD_WARNING;
815 }
816 return CMD_SUCCESS;
817}
818
819ALIAS (no_ipv6_distribute_list_prefix,
820 no_ipv6_as_v4_distribute_list_prefix_cmd,
ba23a691 821 "no distribute-list prefix WORD (in|out) WORD",
822 NO_STR
823 "Filter networks in routing updates\n"
824 "Filter prefixes in routing updates\n"
825 "Name of an IP prefix-list\n"
826 "Filter incoming routing updates\n"
827 "Filter outgoing routing updates\n"
828 "Interface name\n")
829
ee5bb561
MB
830static int
831distribute_print (struct vty *vty, char *tab[], int is_prefix,
832 enum distribute_type type, int has_print)
833{
834 if (tab[type]) {
835 vty_out (vty, "%s %s%s",
836 has_print ? "," : "",
837 is_prefix ? "(prefix-list) " : "",
838 tab[type]);
839 return 1;
840 }
841 return has_print;
842}
843
718e3744 844int
845config_show_distribute (struct vty *vty)
846{
8c328f11 847 unsigned int i;
ee5bb561 848 int has_print = 0;
718e3744 849 struct hash_backet *mp;
850 struct distribute *dist;
851
852 /* Output filter configuration. */
853 dist = distribute_lookup (NULL);
ee5bb561
MB
854 vty_out(vty, " Outgoing update filter list for all interface is");
855 has_print = 0;
856 if (dist)
718e3744 857 {
ee5bb561 858 has_print = distribute_print(vty, dist->list, 0,
fb23cf4a 859 DISTRIBUTE_V4_OUT, has_print);
ee5bb561 860 has_print = distribute_print(vty, dist->prefix, 1,
fb23cf4a
MB
861 DISTRIBUTE_V4_OUT, has_print);
862 has_print = distribute_print(vty, dist->list, 0,
863 DISTRIBUTE_V6_OUT, has_print);
864 has_print = distribute_print(vty, dist->prefix, 1,
865 DISTRIBUTE_V6_OUT, has_print);
718e3744 866 }
ee5bb561
MB
867 if (has_print)
868 vty_out (vty, "%s", VTY_NEWLINE);
718e3744 869 else
ee5bb561 870 vty_out (vty, " not set%s", VTY_NEWLINE);
718e3744 871
872 for (i = 0; i < disthash->size; i++)
873 for (mp = disthash->index[i]; mp; mp = mp->next)
874 {
875 dist = mp->data;
876 if (dist->ifname)
ee5bb561
MB
877 {
878 vty_out (vty, " %s filtered by", dist->ifname);
879 has_print = 0;
880 has_print = distribute_print(vty, dist->list, 0,
fb23cf4a 881 DISTRIBUTE_V4_OUT, has_print);
ee5bb561 882 has_print = distribute_print(vty, dist->prefix, 1,
fb23cf4a
MB
883 DISTRIBUTE_V4_OUT, has_print);
884 has_print = distribute_print(vty, dist->list, 0,
885 DISTRIBUTE_V6_OUT, has_print);
886 has_print = distribute_print(vty, dist->prefix, 1,
887 DISTRIBUTE_V6_OUT, has_print);
ee5bb561
MB
888 if (has_print)
889 vty_out (vty, "%s", VTY_NEWLINE);
890 else
891 vty_out(vty, " nothing%s", VTY_NEWLINE);
892 }
718e3744 893 }
894
895
896 /* Input filter configuration. */
897 dist = distribute_lookup (NULL);
ee5bb561
MB
898 vty_out(vty, " Incoming update filter list for all interface is");
899 has_print = 0;
900 if (dist)
718e3744 901 {
ee5bb561 902 has_print = distribute_print(vty, dist->list, 0,
fb23cf4a
MB
903 DISTRIBUTE_V4_IN, has_print);
904 has_print = distribute_print(vty, dist->prefix, 1,
905 DISTRIBUTE_V4_IN, has_print);
906 has_print = distribute_print(vty, dist->list, 0,
907 DISTRIBUTE_V6_IN, has_print);
ee5bb561 908 has_print = distribute_print(vty, dist->prefix, 1,
fb23cf4a
MB
909 DISTRIBUTE_V6_IN, has_print);
910 }
ee5bb561
MB
911 if (has_print)
912 vty_out (vty, "%s", VTY_NEWLINE);
718e3744 913 else
ee5bb561 914 vty_out (vty, " not set%s", VTY_NEWLINE);
718e3744 915
916 for (i = 0; i < disthash->size; i++)
917 for (mp = disthash->index[i]; mp; mp = mp->next)
918 {
919 dist = mp->data;
ee5bb561
MB
920 if (dist->ifname)
921 {
922 vty_out (vty, " %s filtered by", dist->ifname);
923 has_print = 0;
924 has_print = distribute_print(vty, dist->list, 0,
fb23cf4a
MB
925 DISTRIBUTE_V4_IN, has_print);
926 has_print = distribute_print(vty, dist->prefix, 1,
927 DISTRIBUTE_V4_IN, has_print);
928 has_print = distribute_print(vty, dist->list, 0,
929 DISTRIBUTE_V6_IN, has_print);
ee5bb561 930 has_print = distribute_print(vty, dist->prefix, 1,
fb23cf4a 931 DISTRIBUTE_V6_IN, has_print);
ee5bb561
MB
932 if (has_print)
933 vty_out (vty, "%s", VTY_NEWLINE);
934 else
935 vty_out(vty, " nothing%s", VTY_NEWLINE);
936 }
718e3744 937 }
938 return 0;
939}
940
941/* Configuration write function. */
942int
943config_write_distribute (struct vty *vty)
944{
8c328f11 945 unsigned int i;
ee5bb561 946 int j;
fb23cf4a 947 int output, v6;
718e3744 948 struct hash_backet *mp;
949 int write = 0;
950
951 for (i = 0; i < disthash->size; i++)
952 for (mp = disthash->index[i]; mp; mp = mp->next)
953 {
954 struct distribute *dist;
955
956 dist = mp->data;
957
ee5bb561
MB
958 for (j = 0; j < DISTRIBUTE_MAX; j++)
959 if (dist->list[j]) {
fb23cf4a
MB
960 output = j == DISTRIBUTE_V4_OUT || j == DISTRIBUTE_V6_OUT;
961 v6 = j == DISTRIBUTE_V6_IN || j == DISTRIBUTE_V6_OUT;
962 vty_out (vty, " %sdistribute-list %s %s %s%s",
963 v6 ? "ipv6 " : "",
ee5bb561
MB
964 dist->list[j],
965 output ? "out" : "in",
718e3744 966 dist->ifname ? dist->ifname : "",
967 VTY_NEWLINE);
968 write++;
969 }
970
ee5bb561
MB
971 for (j = 0; j < DISTRIBUTE_MAX; j++)
972 if (dist->prefix[j]) {
fb23cf4a
MB
973 output = j == DISTRIBUTE_V4_OUT || j == DISTRIBUTE_V6_OUT;
974 v6 = j == DISTRIBUTE_V6_IN || j == DISTRIBUTE_V6_OUT;
975 vty_out (vty, " %sdistribute-list prefix %s %s %s%s",
976 v6 ? "ipv6 " : "",
ee5bb561
MB
977 dist->prefix[j],
978 output ? "out" : "in",
718e3744 979 dist->ifname ? dist->ifname : "",
980 VTY_NEWLINE);
981 write++;
982 }
983 }
984 return write;
985}
986
987/* Clear all distribute list. */
988void
989distribute_list_reset ()
990{
991 hash_clean (disthash, (void (*) (void *)) distribute_free);
992}
993
994/* Initialize distribute list related hash. */
995void
996distribute_list_init (int node)
997{
6392aa83 998 disthash = hash_create (distribute_hash_make,
ffe11cfb 999 (int (*) (const void *, const void *)) distribute_cmp);
fb23cf4a
MB
1000 /* install v4 */
1001 if (node == RIP_NODE) {
5734509c
PJ
1002 install_element (node, &distribute_list_all_cmd);
1003 install_element (node, &no_distribute_list_all_cmd);
1004 install_element (node, &distribute_list_cmd);
1005 install_element (node, &no_distribute_list_cmd);
1006 install_element (node, &distribute_list_prefix_all_cmd);
1007 install_element (node, &no_distribute_list_prefix_all_cmd);
1008 install_element (node, &distribute_list_prefix_cmd);
1009 install_element (node, &no_distribute_list_prefix_cmd);
fb23cf4a
MB
1010 }
1011
1012 /* install v6 */
1013 if (node == RIPNG_NODE) {
5734509c
PJ
1014 install_element (node, &ipv6_distribute_list_all_cmd);
1015 install_element (node, &no_ipv6_distribute_list_all_cmd);
1016 install_element (node, &ipv6_distribute_list_cmd);
1017 install_element (node, &no_ipv6_distribute_list_cmd);
1018 install_element (node, &ipv6_distribute_list_prefix_all_cmd);
1019 install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
1020 install_element (node, &ipv6_distribute_list_prefix_cmd);
1021 install_element (node, &no_ipv6_distribute_list_prefix_cmd);
ba23a691 1022 }
fb23cf4a
MB
1023
1024 /* install v4 syntax command for v6 only protocols. */
1025 if (node == RIPNG_NODE) {
1026 install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
1027 install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
1028 install_element (node, &ipv6_as_v4_distribute_list_cmd);
1029 install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
1030 install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
1031 install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
1032 install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
1033 install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
1034 }
718e3744 1035}