File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / distribute.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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: 
  303:   /* Check of distribute list type. */
  304:   if (strncmp (argv[1], "i", 1) == 0)
  305:     type = DISTRIBUTE_IN;
  306:   else if (strncmp (argv[1], "o", 1) == 0)
  307:     type = DISTRIBUTE_OUT;
  308:   else
  309:     {
  310:       vty_out (vty, "distribute list direction must be [in|out]%s",
  311: 	       VTY_NEWLINE);
  312:       return CMD_WARNING;
  313:     }
  314: 
  315:   /* Get interface name corresponding distribute list. */
  316:   distribute_list_set (NULL, type, argv[0]);
  317: 
  318:   return CMD_SUCCESS;
  319: }
  320: 
  321: ALIAS (distribute_list_all,
  322:        ipv6_distribute_list_all_cmd,
  323:        "distribute-list WORD (in|out)",
  324:        "Filter networks in routing updates\n"
  325:        "Access-list name\n"
  326:        "Filter incoming routing updates\n"
  327:        "Filter outgoing routing updates\n")
  328: 
  329: DEFUN (no_distribute_list_all,
  330:        no_distribute_list_all_cmd,
  331:        "no distribute-list WORD (in|out)",
  332:        NO_STR
  333:        "Filter networks in routing updates\n"
  334:        "Access-list name\n"
  335:        "Filter incoming routing updates\n"
  336:        "Filter outgoing routing updates\n")
  337: {
  338:   int ret;
  339:   enum distribute_type type;
  340: 
  341:   /* Check of distribute list type. */
  342:   if (strncmp (argv[1], "i", 1) == 0)
  343:     type = DISTRIBUTE_IN;
  344:   else if (strncmp (argv[1], "o", 1) == 0)
  345:     type = DISTRIBUTE_OUT;
  346:   else
  347:     {
  348:       vty_out (vty, "distribute list direction must be [in|out]%s",
  349: 	       VTY_NEWLINE);
  350:       return CMD_WARNING;
  351:     }
  352: 
  353:   ret = distribute_list_unset (NULL, type, argv[0]);
  354:   if (! ret)
  355:     {
  356:       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  357:       return CMD_WARNING;
  358:     }
  359:   return CMD_SUCCESS;
  360: }
  361: 
  362: ALIAS (no_distribute_list_all,
  363:        no_ipv6_distribute_list_all_cmd,
  364:        "no distribute-list WORD (in|out)",
  365:        NO_STR
  366:        "Filter networks in routing updates\n"
  367:        "Access-list name\n"
  368:        "Filter incoming routing updates\n"
  369:        "Filter outgoing routing updates\n")
  370: 
  371: DEFUN (distribute_list,
  372:        distribute_list_cmd,
  373:        "distribute-list WORD (in|out) WORD",
  374:        "Filter networks in routing updates\n"
  375:        "Access-list name\n"
  376:        "Filter incoming routing updates\n"
  377:        "Filter outgoing routing updates\n"
  378:        "Interface name\n")
  379: {
  380:   enum distribute_type type;
  381: 
  382:   /* Check of distribute list type. */
  383:   if (strncmp (argv[1], "i", 1) == 0)
  384:     type = DISTRIBUTE_IN;
  385:   else if (strncmp (argv[1], "o", 1) == 0)
  386:     type = DISTRIBUTE_OUT;
  387:   else
  388:     {
  389:       vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
  390:       return CMD_WARNING;
  391:     }
  392: 
  393:   /* Get interface name corresponding distribute list. */
  394:   distribute_list_set (argv[2], type, argv[0]);
  395: 
  396:   return CMD_SUCCESS;
  397: }       
  398: 
  399: ALIAS (distribute_list,
  400:        ipv6_distribute_list_cmd,
  401:        "distribute-list WORD (in|out) WORD",
  402:        "Filter networks in routing updates\n"
  403:        "Access-list name\n"
  404:        "Filter incoming routing updates\n"
  405:        "Filter outgoing routing updates\n"
  406:        "Interface name\n")
  407: 
  408: DEFUN (no_distribute_list, no_distribute_list_cmd,
  409:        "no distribute-list WORD (in|out) WORD",
  410:        NO_STR
  411:        "Filter networks in routing updates\n"
  412:        "Access-list name\n"
  413:        "Filter incoming routing updates\n"
  414:        "Filter outgoing routing updates\n"
  415:        "Interface name\n")
  416: {
  417:   int ret;
  418:   enum distribute_type type;
  419: 
  420:   /* Check of distribute list type. */
  421:   if (strncmp (argv[1], "i", 1) == 0)
  422:     type = DISTRIBUTE_IN;
  423:   else if (strncmp (argv[1], "o", 1) == 0)
  424:     type = DISTRIBUTE_OUT;
  425:   else
  426:     {
  427:       vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
  428:       return CMD_WARNING;
  429:     }
  430: 
  431:   ret = distribute_list_unset (argv[2], type, argv[0]);
  432:   if (! ret)
  433:     {
  434:       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  435:       return CMD_WARNING;
  436:     }
  437:   return CMD_SUCCESS;
  438: }       
  439: 
  440: ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
  441:        "no distribute-list WORD (in|out) WORD",
  442:        NO_STR
  443:        "Filter networks in routing updates\n"
  444:        "Access-list name\n"
  445:        "Filter incoming routing updates\n"
  446:        "Filter outgoing routing updates\n"
  447:        "Interface name\n")
  448: 
  449: DEFUN (distribute_list_prefix_all,
  450:        distribute_list_prefix_all_cmd,
  451:        "distribute-list prefix WORD (in|out)",
  452:        "Filter networks in routing updates\n"
  453:        "Filter prefixes in routing updates\n"
  454:        "Name of an IP prefix-list\n"
  455:        "Filter incoming routing updates\n"
  456:        "Filter outgoing routing updates\n")
  457: {
  458:   enum distribute_type type;
  459: 
  460:   /* Check of distribute list type. */
  461:   if (strncmp (argv[1], "i", 1) == 0)
  462:     type = DISTRIBUTE_IN;
  463:   else if (strncmp (argv[1], "o", 1) == 0)
  464:     type = DISTRIBUTE_OUT;
  465:   else
  466:     {
  467:       vty_out (vty, "distribute list direction must be [in|out]%s", 
  468: 	       VTY_NEWLINE);
  469:       return CMD_WARNING;
  470:     }
  471: 
  472:   /* Get interface name corresponding distribute list. */
  473:   distribute_list_prefix_set (NULL, type, argv[0]);
  474: 
  475:   return CMD_SUCCESS;
  476: }       
  477: 
  478: ALIAS (distribute_list_prefix_all,
  479:        ipv6_distribute_list_prefix_all_cmd,
  480:        "distribute-list prefix WORD (in|out)",
  481:        "Filter networks in routing updates\n"
  482:        "Filter prefixes in routing updates\n"
  483:        "Name of an IP prefix-list\n"
  484:        "Filter incoming routing updates\n"
  485:        "Filter outgoing routing updates\n")
  486: 
  487: DEFUN (no_distribute_list_prefix_all,
  488:        no_distribute_list_prefix_all_cmd,
  489:        "no distribute-list prefix WORD (in|out)",
  490:        NO_STR
  491:        "Filter networks in routing updates\n"
  492:        "Filter prefixes in routing updates\n"
  493:        "Name of an IP prefix-list\n"
  494:        "Filter incoming routing updates\n"
  495:        "Filter outgoing routing updates\n")
  496: {
  497:   int ret;
  498:   enum distribute_type type;
  499: 
  500:   /* Check of distribute list type. */
  501:   if (strncmp (argv[1], "i", 1) == 0)
  502:     type = DISTRIBUTE_IN;
  503:   else if (strncmp (argv[1], "o", 1) == 0)
  504:     type = DISTRIBUTE_OUT;
  505:   else
  506:     {
  507:       vty_out (vty, "distribute list direction must be [in|out]%s", 
  508: 	       VTY_NEWLINE);
  509:       return CMD_WARNING;
  510:     }
  511: 
  512:   ret = distribute_list_prefix_unset (NULL, type, argv[0]);
  513:   if (! ret)
  514:     {
  515:       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  516:       return CMD_WARNING;
  517:     }
  518:   return CMD_SUCCESS;
  519: }       
  520: 
  521: ALIAS (no_distribute_list_prefix_all,
  522:        no_ipv6_distribute_list_prefix_all_cmd,
  523:        "no distribute-list prefix WORD (in|out)",
  524:        NO_STR
  525:        "Filter networks in routing updates\n"
  526:        "Filter prefixes in routing updates\n"
  527:        "Name of an IP prefix-list\n"
  528:        "Filter incoming routing updates\n"
  529:        "Filter outgoing routing updates\n")
  530: 
  531: DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
  532:        "distribute-list prefix WORD (in|out) WORD",
  533:        "Filter networks in routing updates\n"
  534:        "Filter prefixes in routing updates\n"
  535:        "Name of an IP prefix-list\n"
  536:        "Filter incoming routing updates\n"
  537:        "Filter outgoing routing updates\n"
  538:        "Interface name\n")
  539: {
  540:   enum distribute_type type;
  541: 
  542:   /* Check of distribute list type. */
  543:   if (strncmp (argv[1], "i", 1) == 0)
  544:     type = DISTRIBUTE_IN;
  545:   else if (strncmp (argv[1], "o", 1) == 0)
  546:     type = DISTRIBUTE_OUT;
  547:   else
  548:     {
  549:       vty_out (vty, "distribute list direction must be [in|out]%s", 
  550: 	       VTY_NEWLINE);
  551:       return CMD_WARNING;
  552:     }
  553: 
  554:   /* Get interface name corresponding distribute list. */
  555:   distribute_list_prefix_set (argv[2], type, argv[0]);
  556: 
  557:   return CMD_SUCCESS;
  558: }       
  559: 
  560: ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
  561:        "distribute-list prefix WORD (in|out) WORD",
  562:        "Filter networks in routing updates\n"
  563:        "Filter prefixes in routing updates\n"
  564:        "Name of an IP prefix-list\n"
  565:        "Filter incoming routing updates\n"
  566:        "Filter outgoing routing updates\n"
  567:        "Interface name\n")
  568: 
  569: DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
  570:        "no distribute-list prefix WORD (in|out) WORD",
  571:        NO_STR
  572:        "Filter networks in routing updates\n"
  573:        "Filter prefixes in routing updates\n"
  574:        "Name of an IP prefix-list\n"
  575:        "Filter incoming routing updates\n"
  576:        "Filter outgoing routing updates\n"
  577:        "Interface name\n")
  578: {
  579:   int ret;
  580:   enum distribute_type type;
  581: 
  582:   /* Check of distribute list type. */
  583:   if (strncmp (argv[1], "i", 1) == 0)
  584:     type = DISTRIBUTE_IN;
  585:   else if (strncmp (argv[1], "o", 1) == 0)
  586:     type = DISTRIBUTE_OUT;
  587:   else
  588:     {
  589:       vty_out (vty, "distribute list direction must be [in|out]%s", 
  590: 	       VTY_NEWLINE);
  591:       return CMD_WARNING;
  592:     }
  593: 
  594:   ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
  595:   if (! ret)
  596:     {
  597:       vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  598:       return CMD_WARNING;
  599:     }
  600:   return CMD_SUCCESS;
  601: }       
  602: 
  603: ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
  604:        "no distribute-list prefix WORD (in|out) WORD",
  605:        NO_STR
  606:        "Filter networks in routing updates\n"
  607:        "Filter prefixes in routing updates\n"
  608:        "Name of an IP prefix-list\n"
  609:        "Filter incoming routing updates\n"
  610:        "Filter outgoing routing updates\n"
  611:        "Interface name\n")
  612: 
  613: int
  614: config_show_distribute (struct vty *vty)
  615: {
  616:   unsigned int i;
  617:   struct hash_backet *mp;
  618:   struct distribute *dist;
  619: 
  620:   /* Output filter configuration. */
  621:   dist = distribute_lookup (NULL);
  622:   if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
  623:     {
  624:       vty_out (vty, "  Outgoing update filter list for all interface is");
  625:       if (dist->list[DISTRIBUTE_OUT])
  626: 	vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
  627:       if (dist->prefix[DISTRIBUTE_OUT])
  628: 	vty_out (vty, "%s (prefix-list) %s",
  629: 		 dist->list[DISTRIBUTE_OUT] ? "," : "",
  630: 		 dist->prefix[DISTRIBUTE_OUT]);
  631:       vty_out (vty, "%s", VTY_NEWLINE);
  632:     }
  633:   else
  634:     vty_out (vty, "  Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
  635: 
  636:   for (i = 0; i < disthash->size; i++)
  637:     for (mp = disthash->index[i]; mp; mp = mp->next)
  638:       {
  639: 	dist = mp->data;
  640: 	if (dist->ifname)
  641: 	  if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
  642: 	    {
  643: 	      vty_out (vty, "    %s filtered by", dist->ifname);
  644: 	      if (dist->list[DISTRIBUTE_OUT])
  645: 		vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
  646: 	      if (dist->prefix[DISTRIBUTE_OUT])
  647: 		vty_out (vty, "%s (prefix-list) %s",
  648: 			 dist->list[DISTRIBUTE_OUT] ? "," : "",
  649: 			 dist->prefix[DISTRIBUTE_OUT]);
  650: 	      vty_out (vty, "%s", VTY_NEWLINE);
  651: 	    }
  652:       }
  653: 
  654: 
  655:   /* Input filter configuration. */
  656:   dist = distribute_lookup (NULL);
  657:   if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
  658:     {
  659:       vty_out (vty, "  Incoming update filter list for all interface is");
  660:       if (dist->list[DISTRIBUTE_IN])
  661: 	vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
  662:       if (dist->prefix[DISTRIBUTE_IN])
  663: 	vty_out (vty, "%s (prefix-list) %s",
  664: 		 dist->list[DISTRIBUTE_IN] ? "," : "",
  665: 		 dist->prefix[DISTRIBUTE_IN]);
  666:       vty_out (vty, "%s", VTY_NEWLINE);
  667:     }
  668:   else
  669:     vty_out (vty, "  Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
  670: 
  671:   for (i = 0; i < disthash->size; i++)
  672:     for (mp = disthash->index[i]; mp; mp = mp->next)
  673:       {
  674: 	dist = mp->data;
  675: 	if (dist->ifname)
  676: 	  if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
  677: 	    {
  678: 	      vty_out (vty, "    %s filtered by", dist->ifname);
  679: 	      if (dist->list[DISTRIBUTE_IN])
  680: 		vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
  681: 	      if (dist->prefix[DISTRIBUTE_IN])
  682: 		vty_out (vty, "%s (prefix-list) %s",
  683: 			 dist->list[DISTRIBUTE_IN] ? "," : "",
  684: 			 dist->prefix[DISTRIBUTE_IN]);
  685: 	      vty_out (vty, "%s", VTY_NEWLINE);
  686: 	    }
  687:       }
  688:   return 0;
  689: }
  690: 
  691: /* Configuration write function. */
  692: int
  693: config_write_distribute (struct vty *vty)
  694: {
  695:   unsigned int i;
  696:   struct hash_backet *mp;
  697:   int write = 0;
  698: 
  699:   for (i = 0; i < disthash->size; i++)
  700:     for (mp = disthash->index[i]; mp; mp = mp->next)
  701:       {
  702: 	struct distribute *dist;
  703: 
  704: 	dist = mp->data;
  705: 
  706: 	if (dist->list[DISTRIBUTE_IN])
  707: 	  {
  708: 	    vty_out (vty, " distribute-list %s in %s%s", 
  709: 		     dist->list[DISTRIBUTE_IN],
  710: 		     dist->ifname ? dist->ifname : "",
  711: 		     VTY_NEWLINE);
  712: 	    write++;
  713: 	  }
  714: 
  715: 	if (dist->list[DISTRIBUTE_OUT])
  716: 	  {
  717: 	    vty_out (vty, " distribute-list %s out %s%s", 
  718: 
  719: 		     dist->list[DISTRIBUTE_OUT],
  720: 		     dist->ifname ? dist->ifname : "",
  721: 		     VTY_NEWLINE);
  722: 	    write++;
  723: 	  }
  724: 
  725: 	if (dist->prefix[DISTRIBUTE_IN])
  726: 	  {
  727: 	    vty_out (vty, " distribute-list prefix %s in %s%s",
  728: 		     dist->prefix[DISTRIBUTE_IN],
  729: 		     dist->ifname ? dist->ifname : "",
  730: 		     VTY_NEWLINE);
  731: 	    write++;
  732: 	  }
  733: 
  734: 	if (dist->prefix[DISTRIBUTE_OUT])
  735: 	  {
  736: 	    vty_out (vty, " distribute-list prefix %s out %s%s",
  737: 		     dist->prefix[DISTRIBUTE_OUT],
  738: 		     dist->ifname ? dist->ifname : "",
  739: 		     VTY_NEWLINE);
  740: 	    write++;
  741: 	  }
  742:       }
  743:   return write;
  744: }
  745: 
  746: /* Clear all distribute list. */
  747: void
  748: distribute_list_reset ()
  749: {
  750:   hash_clean (disthash, (void (*) (void *)) distribute_free);
  751: }
  752: 
  753: /* Initialize distribute list related hash. */
  754: void
  755: distribute_list_init (int node)
  756: {
  757:   disthash = hash_create (distribute_hash_make,
  758:                           (int (*) (const void *, const void *)) distribute_cmp);
  759: 
  760:   if(node==RIP_NODE) {
  761:     install_element (node, &distribute_list_all_cmd);
  762:     install_element (node, &no_distribute_list_all_cmd);
  763:     install_element (node, &distribute_list_cmd);
  764:     install_element (node, &no_distribute_list_cmd);
  765:     install_element (node, &distribute_list_prefix_all_cmd);
  766:     install_element (node, &no_distribute_list_prefix_all_cmd);
  767:     install_element (node, &distribute_list_prefix_cmd);
  768:     install_element (node, &no_distribute_list_prefix_cmd);
  769:   } else if (node == RIPNG_NODE || node == BABEL_NODE) {
  770:     /* WARNING: two identical commands installed do a crash, so be worry with
  771:      aliases. For this reason, and because all these commands are aliases, Babel
  772:      is not set with RIP. */
  773:     install_element (node, &ipv6_distribute_list_all_cmd);
  774:     install_element (node, &no_ipv6_distribute_list_all_cmd);
  775:     install_element (node, &ipv6_distribute_list_cmd);
  776:     install_element (node, &no_ipv6_distribute_list_cmd);
  777:     install_element (node, &ipv6_distribute_list_prefix_all_cmd);
  778:     install_element (node, &no_ipv6_distribute_list_prefix_all_cmd);
  779:     install_element (node, &ipv6_distribute_list_prefix_cmd);
  780:     install_element (node, &no_ipv6_distribute_list_prefix_cmd);
  781:   }
  782: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>