Annotation of embedaddon/quagga/lib/distribute.c, revision 1.1.1.3

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 *);
1.1.1.3 ! misho      37: 
1.1       misho      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: }
1.1.1.3 ! misho     136: 
1.1       misho     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. */
1.1.1.2   misho     316:   distribute_list_set (NULL, type, argv[0]);
1.1       misho     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. */
1.1.1.2   misho     394:   distribute_list_set (argv[2], type, argv[0]);
1.1       misho     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: 
1.1.1.2   misho     408: DEFUN (no_distribute_list, no_distribute_list_cmd,
1.1       misho     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: 
1.1.1.2   misho     440: ALIAS (no_distribute_list, no_ipv6_distribute_list_cmd,
1.1       misho     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: 
1.1.1.2   misho     449: DEFUN (distribute_list_prefix_all,
1.1       misho     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. */
1.1.1.2   misho     473:   distribute_list_prefix_set (NULL, type, argv[0]);
1.1       misho     474: 
                    475:   return CMD_SUCCESS;
                    476: }       
                    477: 
1.1.1.2   misho     478: ALIAS (distribute_list_prefix_all,
1.1       misho     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: 
1.1.1.2   misho     487: DEFUN (no_distribute_list_prefix_all,
1.1       misho     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: 
1.1.1.2   misho     521: ALIAS (no_distribute_list_prefix_all,
1.1       misho     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: 
1.1.1.2   misho     531: DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
1.1       misho     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. */
1.1.1.2   misho     555:   distribute_list_prefix_set (argv[2], type, argv[0]);
1.1       misho     556: 
                    557:   return CMD_SUCCESS;
                    558: }       
                    559: 
1.1.1.2   misho     560: ALIAS (distribute_list_prefix, ipv6_distribute_list_prefix_cmd,
1.1       misho     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: 
1.1.1.2   misho     569: DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd,
1.1       misho     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: 
1.1.1.2   misho     603: ALIAS (no_distribute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
1.1       misho     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) {
1.1.1.2   misho     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);
1.1       misho     781:   }
                    782: }

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