Annotation of embedaddon/quagga/bgpd/bgp_filter.c, revision 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>