Annotation of embedaddon/quagga/lib/distribute.c, revision 1.1
1.1 ! misho 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:
! 31: /* Hash of distribute list. */
! 32: struct hash *disthash;
! 33:
! 34: /* Hook functions. */
! 35: void (*distribute_add_hook) (struct distribute *);
! 36: void (*distribute_delete_hook) (struct distribute *);
! 37:
! 38: static struct distribute *
! 39: distribute_new (void)
! 40: {
! 41: return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
! 42: }
! 43:
! 44: /* Free distribute object. */
! 45: static void
! 46: distribute_free (struct distribute *dist)
! 47: {
! 48: if (dist->ifname)
! 49: XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
! 50:
! 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. */
! 65: struct distribute *
! 66: distribute_lookup (const char *ifname)
! 67: {
! 68: struct distribute key;
! 69: struct distribute *dist;
! 70:
! 71: /* temporary reference */
! 72: key.ifname = (char *)ifname;
! 73:
! 74: dist = hash_lookup (disthash, &key);
! 75:
! 76: return dist;
! 77: }
! 78:
! 79: void
! 80: distribute_list_add_hook (void (*func) (struct distribute *))
! 81: {
! 82: distribute_add_hook = func;
! 83: }
! 84:
! 85: void
! 86: distribute_list_delete_hook (void (*func) (struct distribute *))
! 87: {
! 88: distribute_delete_hook = func;
! 89: }
! 90:
! 91: static void *
! 92: distribute_hash_alloc (struct distribute *arg)
! 93: {
! 94: struct distribute *dist;
! 95:
! 96: dist = distribute_new ();
! 97: if (arg->ifname)
! 98: dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
! 99: else
! 100: dist->ifname = NULL;
! 101: return dist;
! 102: }
! 103:
! 104: /* Make new distribute list and push into hash. */
! 105: static struct distribute *
! 106: distribute_get (const char *ifname)
! 107: {
! 108: struct distribute key;
! 109:
! 110: /* temporary reference */
! 111: key.ifname = (char *)ifname;
! 112:
! 113: return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
! 114: }
! 115:
! 116: static unsigned int
! 117: distribute_hash_make (void *arg)
! 118: {
! 119: const struct distribute *dist = arg;
! 120:
! 121: return dist->ifname ? string_hash_make (dist->ifname) : 0;
! 122: }
! 123:
! 124: /* If two distribute-list have same value then return 1 else return
! 125: 0. This function is used by hash package. */
! 126: static int
! 127: distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
! 128: {
! 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. */
! 138: static struct distribute *
! 139: distribute_list_set (const char *ifname, enum distribute_type type,
! 140: const char *alist_name)
! 141: {
! 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. */
! 167: static int
! 168: distribute_list_unset (const char *ifname, enum distribute_type type,
! 169: const char *alist_name)
! 170: {
! 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. */
! 216: static struct distribute *
! 217: distribute_list_prefix_set (const char *ifname, enum distribute_type type,
! 218: const char *plist_name)
! 219: {
! 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. */
! 245: static int
! 246: distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
! 247: const char *plist_name)
! 248: {
! 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:
! 293: DEFUN (distribute_list_all,
! 294: distribute_list_all_cmd,
! 295: "distribute-list WORD (in|out)",
! 296: "Filter networks in routing updates\n"
! 297: "Access-list name\n"
! 298: "Filter incoming routing updates\n"
! 299: "Filter outgoing routing updates\n")
! 300: {
! 301: enum distribute_type type;
! 302: struct distribute *dist;
! 303:
! 304: /* Check of distribute list type. */
! 305: if (strncmp (argv[1], "i", 1) == 0)
! 306: type = DISTRIBUTE_IN;
! 307: else if (strncmp (argv[1], "o", 1) == 0)
! 308: type = DISTRIBUTE_OUT;
! 309: else
! 310: {
! 311: vty_out (vty, "distribute list direction must be [in|out]%s",
! 312: VTY_NEWLINE);
! 313: return CMD_WARNING;
! 314: }
! 315:
! 316: /* Get interface name corresponding distribute list. */
! 317: dist = distribute_list_set (NULL, type, argv[0]);
! 318:
! 319: return CMD_SUCCESS;
! 320: }
! 321:
! 322: ALIAS (distribute_list_all,
! 323: ipv6_distribute_list_all_cmd,
! 324: "distribute-list WORD (in|out)",
! 325: "Filter networks in routing updates\n"
! 326: "Access-list name\n"
! 327: "Filter incoming routing updates\n"
! 328: "Filter outgoing routing updates\n")
! 329:
! 330: DEFUN (no_distribute_list_all,
! 331: no_distribute_list_all_cmd,
! 332: "no distribute-list WORD (in|out)",
! 333: NO_STR
! 334: "Filter networks in routing updates\n"
! 335: "Access-list name\n"
! 336: "Filter incoming routing updates\n"
! 337: "Filter outgoing routing updates\n")
! 338: {
! 339: int ret;
! 340: enum distribute_type type;
! 341:
! 342: /* Check of distribute list type. */
! 343: if (strncmp (argv[1], "i", 1) == 0)
! 344: type = DISTRIBUTE_IN;
! 345: else if (strncmp (argv[1], "o", 1) == 0)
! 346: type = DISTRIBUTE_OUT;
! 347: else
! 348: {
! 349: vty_out (vty, "distribute list direction must be [in|out]%s",
! 350: VTY_NEWLINE);
! 351: return CMD_WARNING;
! 352: }
! 353:
! 354: ret = distribute_list_unset (NULL, type, argv[0]);
! 355: if (! ret)
! 356: {
! 357: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
! 358: return CMD_WARNING;
! 359: }
! 360: return CMD_SUCCESS;
! 361: }
! 362:
! 363: ALIAS (no_distribute_list_all,
! 364: no_ipv6_distribute_list_all_cmd,
! 365: "no distribute-list WORD (in|out)",
! 366: NO_STR
! 367: "Filter networks in routing updates\n"
! 368: "Access-list name\n"
! 369: "Filter incoming routing updates\n"
! 370: "Filter outgoing routing updates\n")
! 371:
! 372: DEFUN (distribute_list,
! 373: distribute_list_cmd,
! 374: "distribute-list WORD (in|out) WORD",
! 375: "Filter networks in routing updates\n"
! 376: "Access-list name\n"
! 377: "Filter incoming routing updates\n"
! 378: "Filter outgoing routing updates\n"
! 379: "Interface name\n")
! 380: {
! 381: enum distribute_type type;
! 382: struct distribute *dist;
! 383:
! 384: /* Check of distribute list type. */
! 385: if (strncmp (argv[1], "i", 1) == 0)
! 386: type = DISTRIBUTE_IN;
! 387: else if (strncmp (argv[1], "o", 1) == 0)
! 388: type = DISTRIBUTE_OUT;
! 389: else
! 390: {
! 391: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
! 392: return CMD_WARNING;
! 393: }
! 394:
! 395: /* Get interface name corresponding distribute list. */
! 396: dist = distribute_list_set (argv[2], type, argv[0]);
! 397:
! 398: return CMD_SUCCESS;
! 399: }
! 400:
! 401: ALIAS (distribute_list,
! 402: ipv6_distribute_list_cmd,
! 403: "distribute-list WORD (in|out) WORD",
! 404: "Filter networks in routing updates\n"
! 405: "Access-list name\n"
! 406: "Filter incoming routing updates\n"
! 407: "Filter outgoing routing updates\n"
! 408: "Interface name\n")
! 409:
! 410: DEFUN (no_districute_list, no_distribute_list_cmd,
! 411: "no distribute-list WORD (in|out) WORD",
! 412: NO_STR
! 413: "Filter networks in routing updates\n"
! 414: "Access-list name\n"
! 415: "Filter incoming routing updates\n"
! 416: "Filter outgoing routing updates\n"
! 417: "Interface name\n")
! 418: {
! 419: int ret;
! 420: enum distribute_type type;
! 421:
! 422: /* Check of distribute list type. */
! 423: if (strncmp (argv[1], "i", 1) == 0)
! 424: type = DISTRIBUTE_IN;
! 425: else if (strncmp (argv[1], "o", 1) == 0)
! 426: type = DISTRIBUTE_OUT;
! 427: else
! 428: {
! 429: vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
! 430: return CMD_WARNING;
! 431: }
! 432:
! 433: ret = distribute_list_unset (argv[2], type, argv[0]);
! 434: if (! ret)
! 435: {
! 436: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
! 437: return CMD_WARNING;
! 438: }
! 439: return CMD_SUCCESS;
! 440: }
! 441:
! 442: ALIAS (no_districute_list, no_ipv6_distribute_list_cmd,
! 443: "no distribute-list WORD (in|out) WORD",
! 444: NO_STR
! 445: "Filter networks in routing updates\n"
! 446: "Access-list name\n"
! 447: "Filter incoming routing updates\n"
! 448: "Filter outgoing routing updates\n"
! 449: "Interface name\n")
! 450:
! 451: DEFUN (districute_list_prefix_all,
! 452: distribute_list_prefix_all_cmd,
! 453: "distribute-list prefix WORD (in|out)",
! 454: "Filter networks in routing updates\n"
! 455: "Filter prefixes in routing updates\n"
! 456: "Name of an IP prefix-list\n"
! 457: "Filter incoming routing updates\n"
! 458: "Filter outgoing routing updates\n")
! 459: {
! 460: enum distribute_type type;
! 461: struct distribute *dist;
! 462:
! 463: /* Check of distribute list type. */
! 464: if (strncmp (argv[1], "i", 1) == 0)
! 465: type = DISTRIBUTE_IN;
! 466: else if (strncmp (argv[1], "o", 1) == 0)
! 467: type = DISTRIBUTE_OUT;
! 468: else
! 469: {
! 470: vty_out (vty, "distribute list direction must be [in|out]%s",
! 471: VTY_NEWLINE);
! 472: return CMD_WARNING;
! 473: }
! 474:
! 475: /* Get interface name corresponding distribute list. */
! 476: dist = distribute_list_prefix_set (NULL, type, argv[0]);
! 477:
! 478: return CMD_SUCCESS;
! 479: }
! 480:
! 481: ALIAS (districute_list_prefix_all,
! 482: ipv6_distribute_list_prefix_all_cmd,
! 483: "distribute-list prefix WORD (in|out)",
! 484: "Filter networks in routing updates\n"
! 485: "Filter prefixes in routing updates\n"
! 486: "Name of an IP prefix-list\n"
! 487: "Filter incoming routing updates\n"
! 488: "Filter outgoing routing updates\n")
! 489:
! 490: DEFUN (no_districute_list_prefix_all,
! 491: no_distribute_list_prefix_all_cmd,
! 492: "no distribute-list prefix WORD (in|out)",
! 493: NO_STR
! 494: "Filter networks in routing updates\n"
! 495: "Filter prefixes in routing updates\n"
! 496: "Name of an IP prefix-list\n"
! 497: "Filter incoming routing updates\n"
! 498: "Filter outgoing routing updates\n")
! 499: {
! 500: int ret;
! 501: enum distribute_type type;
! 502:
! 503: /* Check of distribute list type. */
! 504: if (strncmp (argv[1], "i", 1) == 0)
! 505: type = DISTRIBUTE_IN;
! 506: else if (strncmp (argv[1], "o", 1) == 0)
! 507: type = DISTRIBUTE_OUT;
! 508: else
! 509: {
! 510: vty_out (vty, "distribute list direction must be [in|out]%s",
! 511: VTY_NEWLINE);
! 512: return CMD_WARNING;
! 513: }
! 514:
! 515: ret = distribute_list_prefix_unset (NULL, type, argv[0]);
! 516: if (! ret)
! 517: {
! 518: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
! 519: return CMD_WARNING;
! 520: }
! 521: return CMD_SUCCESS;
! 522: }
! 523:
! 524: ALIAS (no_districute_list_prefix_all,
! 525: no_ipv6_distribute_list_prefix_all_cmd,
! 526: "no distribute-list prefix WORD (in|out)",
! 527: NO_STR
! 528: "Filter networks in routing updates\n"
! 529: "Filter prefixes in routing updates\n"
! 530: "Name of an IP prefix-list\n"
! 531: "Filter incoming routing updates\n"
! 532: "Filter outgoing routing updates\n")
! 533:
! 534: DEFUN (districute_list_prefix, distribute_list_prefix_cmd,
! 535: "distribute-list prefix WORD (in|out) WORD",
! 536: "Filter networks in routing updates\n"
! 537: "Filter prefixes in routing updates\n"
! 538: "Name of an IP prefix-list\n"
! 539: "Filter incoming routing updates\n"
! 540: "Filter outgoing routing updates\n"
! 541: "Interface name\n")
! 542: {
! 543: enum distribute_type type;
! 544: struct distribute *dist;
! 545:
! 546: /* Check of distribute list type. */
! 547: if (strncmp (argv[1], "i", 1) == 0)
! 548: type = DISTRIBUTE_IN;
! 549: else if (strncmp (argv[1], "o", 1) == 0)
! 550: type = DISTRIBUTE_OUT;
! 551: else
! 552: {
! 553: vty_out (vty, "distribute list direction must be [in|out]%s",
! 554: VTY_NEWLINE);
! 555: return CMD_WARNING;
! 556: }
! 557:
! 558: /* Get interface name corresponding distribute list. */
! 559: dist = distribute_list_prefix_set (argv[2], type, argv[0]);
! 560:
! 561: return CMD_SUCCESS;
! 562: }
! 563:
! 564: ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd,
! 565: "distribute-list prefix WORD (in|out) WORD",
! 566: "Filter networks in routing updates\n"
! 567: "Filter prefixes in routing updates\n"
! 568: "Name of an IP prefix-list\n"
! 569: "Filter incoming routing updates\n"
! 570: "Filter outgoing routing updates\n"
! 571: "Interface name\n")
! 572:
! 573: DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd,
! 574: "no distribute-list prefix WORD (in|out) WORD",
! 575: NO_STR
! 576: "Filter networks in routing updates\n"
! 577: "Filter prefixes in routing updates\n"
! 578: "Name of an IP prefix-list\n"
! 579: "Filter incoming routing updates\n"
! 580: "Filter outgoing routing updates\n"
! 581: "Interface name\n")
! 582: {
! 583: int ret;
! 584: enum distribute_type type;
! 585:
! 586: /* Check of distribute list type. */
! 587: if (strncmp (argv[1], "i", 1) == 0)
! 588: type = DISTRIBUTE_IN;
! 589: else if (strncmp (argv[1], "o", 1) == 0)
! 590: type = DISTRIBUTE_OUT;
! 591: else
! 592: {
! 593: vty_out (vty, "distribute list direction must be [in|out]%s",
! 594: VTY_NEWLINE);
! 595: return CMD_WARNING;
! 596: }
! 597:
! 598: ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
! 599: if (! ret)
! 600: {
! 601: vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
! 602: return CMD_WARNING;
! 603: }
! 604: return CMD_SUCCESS;
! 605: }
! 606:
! 607: ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
! 608: "no distribute-list prefix WORD (in|out) WORD",
! 609: NO_STR
! 610: "Filter networks in routing updates\n"
! 611: "Filter prefixes in routing updates\n"
! 612: "Name of an IP prefix-list\n"
! 613: "Filter incoming routing updates\n"
! 614: "Filter outgoing routing updates\n"
! 615: "Interface name\n")
! 616:
! 617: int
! 618: config_show_distribute (struct vty *vty)
! 619: {
! 620: unsigned int i;
! 621: struct hash_backet *mp;
! 622: struct distribute *dist;
! 623:
! 624: /* Output filter configuration. */
! 625: dist = distribute_lookup (NULL);
! 626: if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
! 627: {
! 628: vty_out (vty, " Outgoing update filter list for all interface is");
! 629: if (dist->list[DISTRIBUTE_OUT])
! 630: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
! 631: if (dist->prefix[DISTRIBUTE_OUT])
! 632: vty_out (vty, "%s (prefix-list) %s",
! 633: dist->list[DISTRIBUTE_OUT] ? "," : "",
! 634: dist->prefix[DISTRIBUTE_OUT]);
! 635: vty_out (vty, "%s", VTY_NEWLINE);
! 636: }
! 637: else
! 638: vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
! 639:
! 640: for (i = 0; i < disthash->size; i++)
! 641: for (mp = disthash->index[i]; mp; mp = mp->next)
! 642: {
! 643: dist = mp->data;
! 644: if (dist->ifname)
! 645: if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
! 646: {
! 647: vty_out (vty, " %s filtered by", dist->ifname);
! 648: if (dist->list[DISTRIBUTE_OUT])
! 649: vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
! 650: if (dist->prefix[DISTRIBUTE_OUT])
! 651: vty_out (vty, "%s (prefix-list) %s",
! 652: dist->list[DISTRIBUTE_OUT] ? "," : "",
! 653: dist->prefix[DISTRIBUTE_OUT]);
! 654: vty_out (vty, "%s", VTY_NEWLINE);
! 655: }
! 656: }
! 657:
! 658:
! 659: /* Input filter configuration. */
! 660: dist = distribute_lookup (NULL);
! 661: if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
! 662: {
! 663: vty_out (vty, " Incoming update filter list for all interface is");
! 664: if (dist->list[DISTRIBUTE_IN])
! 665: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
! 666: if (dist->prefix[DISTRIBUTE_IN])
! 667: vty_out (vty, "%s (prefix-list) %s",
! 668: dist->list[DISTRIBUTE_IN] ? "," : "",
! 669: dist->prefix[DISTRIBUTE_IN]);
! 670: vty_out (vty, "%s", VTY_NEWLINE);
! 671: }
! 672: else
! 673: vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
! 674:
! 675: for (i = 0; i < disthash->size; i++)
! 676: for (mp = disthash->index[i]; mp; mp = mp->next)
! 677: {
! 678: dist = mp->data;
! 679: if (dist->ifname)
! 680: if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
! 681: {
! 682: vty_out (vty, " %s filtered by", dist->ifname);
! 683: if (dist->list[DISTRIBUTE_IN])
! 684: vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
! 685: if (dist->prefix[DISTRIBUTE_IN])
! 686: vty_out (vty, "%s (prefix-list) %s",
! 687: dist->list[DISTRIBUTE_IN] ? "," : "",
! 688: dist->prefix[DISTRIBUTE_IN]);
! 689: vty_out (vty, "%s", VTY_NEWLINE);
! 690: }
! 691: }
! 692: return 0;
! 693: }
! 694:
! 695: /* Configuration write function. */
! 696: int
! 697: config_write_distribute (struct vty *vty)
! 698: {
! 699: unsigned int i;
! 700: struct hash_backet *mp;
! 701: int write = 0;
! 702:
! 703: for (i = 0; i < disthash->size; i++)
! 704: for (mp = disthash->index[i]; mp; mp = mp->next)
! 705: {
! 706: struct distribute *dist;
! 707:
! 708: dist = mp->data;
! 709:
! 710: if (dist->list[DISTRIBUTE_IN])
! 711: {
! 712: vty_out (vty, " distribute-list %s in %s%s",
! 713: dist->list[DISTRIBUTE_IN],
! 714: dist->ifname ? dist->ifname : "",
! 715: VTY_NEWLINE);
! 716: write++;
! 717: }
! 718:
! 719: if (dist->list[DISTRIBUTE_OUT])
! 720: {
! 721: vty_out (vty, " distribute-list %s out %s%s",
! 722:
! 723: dist->list[DISTRIBUTE_OUT],
! 724: dist->ifname ? dist->ifname : "",
! 725: VTY_NEWLINE);
! 726: write++;
! 727: }
! 728:
! 729: if (dist->prefix[DISTRIBUTE_IN])
! 730: {
! 731: vty_out (vty, " distribute-list prefix %s in %s%s",
! 732: dist->prefix[DISTRIBUTE_IN],
! 733: dist->ifname ? dist->ifname : "",
! 734: VTY_NEWLINE);
! 735: write++;
! 736: }
! 737:
! 738: if (dist->prefix[DISTRIBUTE_OUT])
! 739: {
! 740: vty_out (vty, " distribute-list prefix %s out %s%s",
! 741: dist->prefix[DISTRIBUTE_OUT],
! 742: dist->ifname ? dist->ifname : "",
! 743: VTY_NEWLINE);
! 744: write++;
! 745: }
! 746: }
! 747: return write;
! 748: }
! 749:
! 750: /* Clear all distribute list. */
! 751: void
! 752: distribute_list_reset ()
! 753: {
! 754: hash_clean (disthash, (void (*) (void *)) distribute_free);
! 755: }
! 756:
! 757: /* Initialize distribute list related hash. */
! 758: void
! 759: distribute_list_init (int node)
! 760: {
! 761: disthash = hash_create (distribute_hash_make,
! 762: (int (*) (const void *, const void *)) distribute_cmp);
! 763:
! 764: if(node==RIP_NODE) {
! 765: install_element (RIP_NODE, &distribute_list_all_cmd);
! 766: install_element (RIP_NODE, &no_distribute_list_all_cmd);
! 767: install_element (RIP_NODE, &distribute_list_cmd);
! 768: install_element (RIP_NODE, &no_distribute_list_cmd);
! 769: install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
! 770: install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
! 771: install_element (RIP_NODE, &distribute_list_prefix_cmd);
! 772: install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
! 773: } else {
! 774: install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
! 775: install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
! 776: install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
! 777: install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
! 778: install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
! 779: install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
! 780: install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
! 781: install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
! 782: }
! 783: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>