File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / distribute.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_20_1, v0_99_20, HEAD
quagga

    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>