Annotation of embedaddon/quagga/bgpd/bgp_filter.c, revision 1.1.1.2

1.1       misho       1: /* AS path filter list.
                      2:    Copyright (C) 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 it
                      7: under the terms of the GNU General Public License as published by the
                      8: Free Software Foundation; either version 2, or (at your option) any
                      9: 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 Free
                     18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     19: 02111-1307, USA.  */
                     20: 
                     21: #include <zebra.h>
                     22: 
                     23: #include "command.h"
                     24: #include "log.h"
                     25: #include "memory.h"
                     26: #include "buffer.h"
1.1.1.2 ! misho      27: #include "filter.h"
1.1       misho      28: 
                     29: #include "bgpd/bgpd.h"
                     30: #include "bgpd/bgp_aspath.h"
                     31: #include "bgpd/bgp_regex.h"
                     32: #include "bgpd/bgp_filter.h"
                     33: 
                     34: /* List of AS filter list. */
                     35: struct as_list_list
                     36: {
                     37:   struct as_list *head;
                     38:   struct as_list *tail;
                     39: };
                     40: 
                     41: /* AS path filter master. */
                     42: struct as_list_master
                     43: {
                     44:   /* List of access_list which name is number. */
                     45:   struct as_list_list num;
                     46: 
                     47:   /* List of access_list which name is string. */
                     48:   struct as_list_list str;
                     49: 
                     50:   /* Hook function which is executed when new access_list is added. */
                     51:   void (*add_hook) (void);
                     52: 
                     53:   /* Hook function which is executed when access_list is deleted. */
                     54:   void (*delete_hook) (void);
                     55: };
                     56: 
                     57: /* Element of AS path filter. */
                     58: struct as_filter
                     59: {
                     60:   struct as_filter *next;
                     61:   struct as_filter *prev;
                     62: 
                     63:   enum as_filter_type type;
                     64: 
                     65:   regex_t *reg;
                     66:   char *reg_str;
                     67: };
                     68: 
                     69: /* AS path filter list. */
                     70: struct as_list
                     71: {
                     72:   char *name;
                     73: 
1.1.1.2 ! misho      74:   enum access_type type;
1.1       misho      75: 
                     76:   struct as_list *next;
                     77:   struct as_list *prev;
                     78: 
                     79:   struct as_filter *head;
                     80:   struct as_filter *tail;
                     81: };
1.1.1.2 ! misho      82: 
1.1       misho      83: /* ip as-path access-list 10 permit AS1. */
                     84: 
                     85: static struct as_list_master as_list_master =
                     86: {
                     87:   {NULL, NULL},
                     88:   {NULL, NULL},
                     89:   NULL,
                     90:   NULL
                     91: };
                     92: 
                     93: /* Allocate new AS filter. */
                     94: static struct as_filter *
                     95: as_filter_new (void)
                     96: {
                     97:   return XCALLOC (MTYPE_AS_FILTER, sizeof (struct as_filter));
                     98: }
                     99: 
                    100: /* Free allocated AS filter. */
                    101: static void
                    102: as_filter_free (struct as_filter *asfilter)
                    103: {
                    104:   if (asfilter->reg)
                    105:     bgp_regex_free (asfilter->reg);
                    106:   if (asfilter->reg_str)
                    107:     XFREE (MTYPE_AS_FILTER_STR, asfilter->reg_str);
                    108:   XFREE (MTYPE_AS_FILTER, asfilter);
                    109: }
                    110: 
                    111: /* Make new AS filter. */
                    112: static struct as_filter *
                    113: as_filter_make (regex_t *reg, const char *reg_str, enum as_filter_type type)
                    114: {
                    115:   struct as_filter *asfilter;
                    116: 
                    117:   asfilter = as_filter_new ();
                    118:   asfilter->reg = reg;
                    119:   asfilter->type = type;
                    120:   asfilter->reg_str = XSTRDUP (MTYPE_AS_FILTER_STR, reg_str);
                    121: 
                    122:   return asfilter;
                    123: }
                    124: 
                    125: static struct as_filter *
                    126: as_filter_lookup (struct as_list *aslist, const char *reg_str,
                    127:                  enum as_filter_type type)
                    128: {
                    129:   struct as_filter *asfilter;
                    130: 
                    131:   for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    132:     if (strcmp (reg_str, asfilter->reg_str) == 0)
                    133:       return asfilter;
                    134:   return NULL;
                    135: }
                    136: 
                    137: static void
                    138: as_list_filter_add (struct as_list *aslist, struct as_filter *asfilter)
                    139: {
                    140:   asfilter->next = NULL;
                    141:   asfilter->prev = aslist->tail;
                    142: 
                    143:   if (aslist->tail)
                    144:     aslist->tail->next = asfilter;
                    145:   else
                    146:     aslist->head = asfilter;
                    147:   aslist->tail = asfilter;
                    148: }
                    149: 
                    150: /* Lookup as_list from list of as_list by name. */
                    151: struct as_list *
                    152: as_list_lookup (const char *name)
                    153: {
                    154:   struct as_list *aslist;
                    155: 
                    156:   if (name == NULL)
                    157:     return NULL;
                    158: 
                    159:   for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
                    160:     if (strcmp (aslist->name, name) == 0)
                    161:       return aslist;
                    162: 
                    163:   for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
                    164:     if (strcmp (aslist->name, name) == 0)
                    165:       return aslist;
                    166: 
                    167:   return NULL;
                    168: }
                    169: 
                    170: static struct as_list *
                    171: as_list_new (void)
                    172: {
                    173:   return XCALLOC (MTYPE_AS_LIST, sizeof (struct as_list));
                    174: }
                    175: 
                    176: static void
                    177: as_list_free (struct as_list *aslist)
                    178: {
                    179:   if (aslist->name)
                    180:     {
                    181:       free (aslist->name);
                    182:       aslist->name = NULL;
                    183:     }
                    184:   XFREE (MTYPE_AS_LIST, aslist);
                    185: }
                    186: 
                    187: /* Insert new AS list to list of as_list.  Each as_list is sorted by
                    188:    the name. */
                    189: static struct as_list *
                    190: as_list_insert (const char *name)
                    191: {
                    192:   size_t i;
                    193:   long number;
                    194:   struct as_list *aslist;
                    195:   struct as_list *point;
                    196:   struct as_list_list *list;
                    197: 
                    198:   /* Allocate new access_list and copy given name. */
                    199:   aslist = as_list_new ();
                    200:   aslist->name = strdup (name);
                    201:   assert (aslist->name);
                    202: 
                    203:   /* If name is made by all digit character.  We treat it as
                    204:      number. */
                    205:   for (number = 0, i = 0; i < strlen (name); i++)
                    206:     {
                    207:       if (isdigit ((int) name[i]))
                    208:        number = (number * 10) + (name[i] - '0');
                    209:       else
                    210:        break;
                    211:     }
                    212: 
                    213:   /* In case of name is all digit character */
                    214:   if (i == strlen (name))
                    215:     {
                    216:       aslist->type = ACCESS_TYPE_NUMBER;
                    217: 
                    218:       /* Set access_list to number list. */
                    219:       list = &as_list_master.num;
                    220: 
                    221:       for (point = list->head; point; point = point->next)
                    222:        if (atol (point->name) >= number)
                    223:          break;
                    224:     }
                    225:   else
                    226:     {
                    227:       aslist->type = ACCESS_TYPE_STRING;
                    228: 
                    229:       /* Set access_list to string list. */
                    230:       list = &as_list_master.str;
                    231:   
                    232:       /* Set point to insertion point. */
                    233:       for (point = list->head; point; point = point->next)
                    234:        if (strcmp (point->name, name) >= 0)
                    235:          break;
                    236:     }
                    237: 
                    238:   /* In case of this is the first element of master. */
                    239:   if (list->head == NULL)
                    240:     {
                    241:       list->head = list->tail = aslist;
                    242:       return aslist;
                    243:     }
                    244: 
                    245:   /* In case of insertion is made at the tail of access_list. */
                    246:   if (point == NULL)
                    247:     {
                    248:       aslist->prev = list->tail;
                    249:       list->tail->next = aslist;
                    250:       list->tail = aslist;
                    251:       return aslist;
                    252:     }
                    253: 
                    254:   /* In case of insertion is made at the head of access_list. */
                    255:   if (point == list->head)
                    256:     {
                    257:       aslist->next = list->head;
                    258:       list->head->prev = aslist;
                    259:       list->head = aslist;
                    260:       return aslist;
                    261:     }
                    262: 
                    263:   /* Insertion is made at middle of the access_list. */
                    264:   aslist->next = point;
                    265:   aslist->prev = point->prev;
                    266: 
                    267:   if (point->prev)
                    268:     point->prev->next = aslist;
                    269:   point->prev = aslist;
                    270: 
                    271:   return aslist;
                    272: }
                    273: 
                    274: static struct as_list *
                    275: as_list_get (const char *name)
                    276: {
                    277:   struct as_list *aslist;
                    278: 
                    279:   aslist = as_list_lookup (name);
                    280:   if (aslist == NULL)
                    281:     {
                    282:       aslist = as_list_insert (name);
                    283: 
                    284:       /* Run hook function. */
                    285:       if (as_list_master.add_hook)
                    286:        (*as_list_master.add_hook) ();
                    287:     }
                    288: 
                    289:   return aslist;
                    290: }
                    291: 
                    292: static const char *
                    293: filter_type_str (enum as_filter_type type)
                    294: {
                    295:   switch (type)
                    296:     {
                    297:     case AS_FILTER_PERMIT:
                    298:       return "permit";
                    299:     case AS_FILTER_DENY:
                    300:       return "deny";
                    301:     default:
                    302:       return "";
                    303:     }
                    304: }
                    305: 
                    306: static void
                    307: as_list_delete (struct as_list *aslist)
                    308: {
                    309:   struct as_list_list *list;
                    310:   struct as_filter *filter, *next;
                    311: 
                    312:   for (filter = aslist->head; filter; filter = next)
                    313:     {
                    314:       next = filter->next;
                    315:       as_filter_free (filter);
                    316:     }
                    317: 
                    318:   if (aslist->type == ACCESS_TYPE_NUMBER)
                    319:     list = &as_list_master.num;
                    320:   else
                    321:     list = &as_list_master.str;
                    322: 
                    323:   if (aslist->next)
                    324:     aslist->next->prev = aslist->prev;
                    325:   else
                    326:     list->tail = aslist->prev;
                    327: 
                    328:   if (aslist->prev)
                    329:     aslist->prev->next = aslist->next;
                    330:   else
                    331:     list->head = aslist->next;
                    332: 
                    333:   as_list_free (aslist);
                    334: }
                    335: 
                    336: static int
                    337: as_list_empty (struct as_list *aslist)
                    338: {
                    339:   if (aslist->head == NULL && aslist->tail == NULL)
                    340:     return 1;
                    341:   else
                    342:     return 0;
                    343: }
                    344: 
                    345: static void
                    346: as_list_filter_delete (struct as_list *aslist, struct as_filter *asfilter)
                    347: {
                    348:   if (asfilter->next)
                    349:     asfilter->next->prev = asfilter->prev;
                    350:   else
                    351:     aslist->tail = asfilter->prev;
                    352: 
                    353:   if (asfilter->prev)
                    354:     asfilter->prev->next = asfilter->next;
                    355:   else
                    356:     aslist->head = asfilter->next;
                    357: 
                    358:   as_filter_free (asfilter);
                    359: 
                    360:   /* If access_list becomes empty delete it from access_master. */
                    361:   if (as_list_empty (aslist))
                    362:     as_list_delete (aslist);
                    363: 
                    364:   /* Run hook function. */
                    365:   if (as_list_master.delete_hook)
                    366:     (*as_list_master.delete_hook) ();
                    367: }
1.1.1.2 ! misho     368: 
1.1       misho     369: static int
                    370: as_filter_match (struct as_filter *asfilter, struct aspath *aspath)
                    371: {
                    372:   if (bgp_regexec (asfilter->reg, aspath) != REG_NOMATCH)
                    373:     return 1;
                    374:   return 0;
                    375: }
                    376: 
                    377: /* Apply AS path filter to AS. */
                    378: enum as_filter_type
                    379: as_list_apply (struct as_list *aslist, void *object)
                    380: {
                    381:   struct as_filter *asfilter;
                    382:   struct aspath *aspath;
                    383: 
                    384:   aspath = (struct aspath *) object;
                    385: 
                    386:   if (aslist == NULL)
                    387:     return AS_FILTER_DENY;
                    388: 
                    389:   for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    390:     {
                    391:       if (as_filter_match (asfilter, aspath))
                    392:        return asfilter->type;
                    393:     }
                    394:   return AS_FILTER_DENY;
                    395: }
                    396: 
                    397: /* Add hook function. */
                    398: void
                    399: as_list_add_hook (void (*func) (void))
                    400: {
                    401:   as_list_master.add_hook = func;
                    402: }
                    403: 
                    404: /* Delete hook function. */
                    405: void
                    406: as_list_delete_hook (void (*func) (void))
                    407: {
                    408:   as_list_master.delete_hook = func;
                    409: }
1.1.1.2 ! misho     410: 
1.1       misho     411: static int
                    412: as_list_dup_check (struct as_list *aslist, struct as_filter *new)
                    413: {
                    414:   struct as_filter *asfilter;
                    415: 
                    416:   for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    417:     {
                    418:       if (asfilter->type == new->type
                    419:          && strcmp (asfilter->reg_str, new->reg_str) == 0)
                    420:        return 1;
                    421:     }
                    422:   return 0;
                    423: }
                    424: 
                    425: DEFUN (ip_as_path, ip_as_path_cmd,
                    426:        "ip as-path access-list WORD (deny|permit) .LINE",
                    427:        IP_STR
                    428:        "BGP autonomous system path filter\n"
                    429:        "Specify an access list name\n"
                    430:        "Regular expression access list name\n"
                    431:        "Specify packets to reject\n"
                    432:        "Specify packets to forward\n"
                    433:        "A regular-expression to match the BGP AS paths\n")
                    434: {
                    435:   enum as_filter_type type;
                    436:   struct as_filter *asfilter;
                    437:   struct as_list *aslist;
                    438:   regex_t *regex;
                    439:   char *regstr;
                    440: 
                    441:   /* Check the filter type. */
                    442:   if (strncmp (argv[1], "p", 1) == 0)
                    443:     type = AS_FILTER_PERMIT;
                    444:   else if (strncmp (argv[1], "d", 1) == 0)
                    445:     type = AS_FILTER_DENY;
                    446:   else
                    447:     {
                    448:       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
                    449:       return CMD_WARNING;
                    450:     }
                    451: 
                    452:   /* Check AS path regex. */
                    453:   regstr = argv_concat(argv, argc, 2);
                    454: 
                    455:   regex = bgp_regcomp (regstr);
                    456:   if (!regex)
                    457:     {
                    458:       XFREE (MTYPE_TMP, regstr);
                    459:       vty_out (vty, "can't compile regexp %s%s", argv[0],
                    460:               VTY_NEWLINE);
                    461:       return CMD_WARNING;
                    462:     }
                    463: 
                    464:   asfilter = as_filter_make (regex, regstr, type);
                    465:   
                    466:   XFREE (MTYPE_TMP, regstr);
                    467: 
                    468:   /* Install new filter to the access_list. */
                    469:   aslist = as_list_get (argv[0]);
                    470: 
                    471:   /* Duplicate insertion check. */;
                    472:   if (as_list_dup_check (aslist, asfilter))
                    473:     as_filter_free (asfilter);
                    474:   else
                    475:     as_list_filter_add (aslist, asfilter);
                    476: 
                    477:   return CMD_SUCCESS;
                    478: }
                    479: 
                    480: DEFUN (no_ip_as_path,
                    481:        no_ip_as_path_cmd,
                    482:        "no ip as-path access-list WORD (deny|permit) .LINE",
                    483:        NO_STR
                    484:        IP_STR
                    485:        "BGP autonomous system path filter\n"
                    486:        "Specify an access list name\n"
                    487:        "Regular expression access list name\n"
                    488:        "Specify packets to reject\n"
                    489:        "Specify packets to forward\n"
                    490:        "A regular-expression to match the BGP AS paths\n")
                    491: {
                    492:   enum as_filter_type type;
                    493:   struct as_filter *asfilter;
                    494:   struct as_list *aslist;
                    495:   char *regstr;
                    496:   regex_t *regex;
                    497: 
                    498:   /* Lookup AS list from AS path list. */
                    499:   aslist = as_list_lookup (argv[0]);
                    500:   if (aslist == NULL)
                    501:     {
                    502:       vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
                    503:               VTY_NEWLINE);
                    504:       return CMD_WARNING;
                    505:     }
                    506: 
                    507:   /* Check the filter type. */
                    508:   if (strncmp (argv[1], "p", 1) == 0)
                    509:     type = AS_FILTER_PERMIT;
                    510:   else if (strncmp (argv[1], "d", 1) == 0)
                    511:     type = AS_FILTER_DENY;
                    512:   else
                    513:     {
                    514:       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
                    515:       return CMD_WARNING;
                    516:     }
                    517:   
                    518:   /* Compile AS path. */
                    519:   regstr = argv_concat(argv, argc, 2);
                    520: 
                    521:   regex = bgp_regcomp (regstr);
                    522:   if (!regex)
                    523:     {
                    524:       XFREE (MTYPE_TMP, regstr);
                    525:       vty_out (vty, "can't compile regexp %s%s", argv[0],
                    526:               VTY_NEWLINE);
                    527:       return CMD_WARNING;
                    528:     }
                    529: 
                    530:   /* Lookup asfilter. */
                    531:   asfilter = as_filter_lookup (aslist, regstr, type);
                    532: 
                    533:   XFREE (MTYPE_TMP, regstr);
                    534:   bgp_regex_free (regex);
                    535: 
                    536:   if (asfilter == NULL)
                    537:     {
                    538:       vty_out (vty, "%s", VTY_NEWLINE);
                    539:       return CMD_WARNING;
                    540:     }
                    541: 
                    542:   as_list_filter_delete (aslist, asfilter);
                    543: 
                    544:   return CMD_SUCCESS;
                    545: }
                    546: 
                    547: DEFUN (no_ip_as_path_all,
                    548:        no_ip_as_path_all_cmd,
                    549:        "no ip as-path access-list WORD",
                    550:        NO_STR
                    551:        IP_STR
                    552:        "BGP autonomous system path filter\n"
                    553:        "Specify an access list name\n"
                    554:        "Regular expression access list name\n")
                    555: {
                    556:   struct as_list *aslist;
                    557: 
                    558:   aslist = as_list_lookup (argv[0]);
                    559:   if (aslist == NULL)
                    560:     {
                    561:       vty_out (vty, "ip as-path access-list %s doesn't exist%s", argv[0],
                    562:               VTY_NEWLINE);
                    563:       return CMD_WARNING;
                    564:     }
                    565: 
                    566:   as_list_delete (aslist);
                    567: 
                    568:   /* Run hook function. */
                    569:   if (as_list_master.delete_hook)
                    570:     (*as_list_master.delete_hook) ();
                    571: 
                    572:   return CMD_SUCCESS;
                    573: }
                    574: 
                    575: static void
                    576: as_list_show (struct vty *vty, struct as_list *aslist)
                    577: {
                    578:   struct as_filter *asfilter;
                    579: 
                    580:   vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
                    581: 
                    582:   for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    583:     {
                    584:       vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
                    585:               asfilter->reg_str, VTY_NEWLINE);
                    586:     }
                    587: }
                    588: 
                    589: static void
                    590: as_list_show_all (struct vty *vty)
                    591: {
                    592:   struct as_list *aslist;
                    593:   struct as_filter *asfilter;
                    594: 
                    595:   for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
                    596:     {
                    597:       vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
                    598: 
                    599:       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    600:        {
                    601:          vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
                    602:                   asfilter->reg_str, VTY_NEWLINE);
                    603:        }
                    604:     }
                    605: 
                    606:   for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
                    607:     {
                    608:       vty_out (vty, "AS path access list %s%s", aslist->name, VTY_NEWLINE);
                    609: 
                    610:       for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    611:        {
                    612:          vty_out (vty, "    %s %s%s", filter_type_str (asfilter->type),
                    613:                   asfilter->reg_str, VTY_NEWLINE);
                    614:        }
                    615:     }
                    616: }
                    617: 
                    618: DEFUN (show_ip_as_path_access_list,
                    619:        show_ip_as_path_access_list_cmd,
                    620:        "show ip as-path-access-list WORD",
                    621:        SHOW_STR
                    622:        IP_STR
                    623:        "List AS path access lists\n"
                    624:        "AS path access list name\n")
                    625: {
                    626:   struct as_list *aslist;
                    627: 
                    628:   aslist = as_list_lookup (argv[0]);
                    629:   if (aslist)
                    630:     as_list_show (vty, aslist);
                    631: 
                    632:   return CMD_SUCCESS;
                    633: }
                    634: 
                    635: DEFUN (show_ip_as_path_access_list_all,
                    636:        show_ip_as_path_access_list_all_cmd,
                    637:        "show ip as-path-access-list",
                    638:        SHOW_STR
                    639:        IP_STR
                    640:        "List AS path access lists\n")
                    641: {
                    642:   as_list_show_all (vty);
                    643:   return CMD_SUCCESS;
                    644: }
                    645: 
                    646: static int
                    647: config_write_as_list (struct vty *vty)
                    648: {
                    649:   struct as_list *aslist;
                    650:   struct as_filter *asfilter;
                    651:   int write = 0;
                    652: 
                    653:   for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
                    654:     for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    655:       {
                    656:        vty_out (vty, "ip as-path access-list %s %s %s%s",
                    657:                 aslist->name, filter_type_str (asfilter->type), 
                    658:                 asfilter->reg_str,
                    659:                 VTY_NEWLINE);
                    660:        write++;
                    661:       }
                    662: 
                    663:   for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
                    664:     for (asfilter = aslist->head; asfilter; asfilter = asfilter->next)
                    665:       {
                    666:        vty_out (vty, "ip as-path access-list %s %s %s%s",
                    667:                 aslist->name, filter_type_str (asfilter->type), 
                    668:                 asfilter->reg_str,
                    669:                 VTY_NEWLINE);
                    670:        write++;
                    671:       }
                    672:   return write;
                    673: }
                    674: 
                    675: static struct cmd_node as_list_node =
                    676: {
                    677:   AS_LIST_NODE,
                    678:   "",
                    679:   1
                    680: };
                    681: 
                    682: /* Register functions. */
                    683: void
                    684: bgp_filter_init (void)
                    685: {
                    686:   install_node (&as_list_node, config_write_as_list);
                    687: 
                    688:   install_element (CONFIG_NODE, &ip_as_path_cmd);
                    689:   install_element (CONFIG_NODE, &no_ip_as_path_cmd);
                    690:   install_element (CONFIG_NODE, &no_ip_as_path_all_cmd);
                    691: 
                    692:   install_element (VIEW_NODE, &show_ip_as_path_access_list_cmd);
                    693:   install_element (VIEW_NODE, &show_ip_as_path_access_list_all_cmd);
                    694:   install_element (ENABLE_NODE, &show_ip_as_path_access_list_cmd);
                    695:   install_element (ENABLE_NODE, &show_ip_as_path_access_list_all_cmd);
                    696: }
                    697: 
                    698: void
                    699: bgp_filter_reset (void)
                    700: {
                    701:   struct as_list *aslist;
                    702:   struct as_list *next;
                    703: 
                    704:   for (aslist = as_list_master.num.head; aslist; aslist = next)
                    705:     {
                    706:       next = aslist->next;
                    707:       as_list_delete (aslist);
                    708:     }
                    709: 
                    710:   for (aslist = as_list_master.str.head; aslist; aslist = next)
                    711:     {
                    712:       next = aslist->next;
                    713:       as_list_delete (aslist);
                    714:     }
                    715: 
                    716:   assert (as_list_master.num.head == NULL);
                    717:   assert (as_list_master.num.tail == NULL);
                    718: 
                    719:   assert (as_list_master.str.head == NULL);
                    720:   assert (as_list_master.str.tail == NULL);
                    721: }

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