Annotation of embedaddon/quagga/lib/distribute.c, revision 1.1.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>