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

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

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