Annotation of embedaddon/quagga/lib/filter.c, revision 1.1

1.1     ! misho       1: /* Route filtering function.
        !             2:  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
        !             3:  *
        !             4:  * This file is part of GNU Zebra.
        !             5:  *
        !             6:  * GNU Zebra is free software; you can redistribute it and/or modify
        !             7:  * it under the terms of the GNU General Public License as published
        !             8:  * by the Free Software Foundation; either version 2, or (at your
        !             9:  * option) any later version.
        !            10:  *
        !            11:  * GNU Zebra is distributed in the hope that it will be useful, but
        !            12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            14:  * General Public License for more details.
        !            15:  *
        !            16:  * You should have received a copy of the GNU General Public License
        !            17:  * along with GNU Zebra; see the file COPYING.  If not, write to the
        !            18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
        !            19:  * Boston, MA 02111-1307, USA.
        !            20:  */
        !            21: 
        !            22: #include <zebra.h>
        !            23: 
        !            24: #include "prefix.h"
        !            25: #include "filter.h"
        !            26: #include "memory.h"
        !            27: #include "command.h"
        !            28: #include "sockunion.h"
        !            29: #include "buffer.h"
        !            30: #include "log.h"
        !            31: 
        !            32: struct filter_cisco
        !            33: {
        !            34:   /* Cisco access-list */
        !            35:   int extended;
        !            36:   struct in_addr addr;
        !            37:   struct in_addr addr_mask;
        !            38:   struct in_addr mask;
        !            39:   struct in_addr mask_mask;
        !            40: };
        !            41: 
        !            42: struct filter_zebra
        !            43: {
        !            44:   /* If this filter is "exact" match then this flag is set. */
        !            45:   int exact;
        !            46: 
        !            47:   /* Prefix information. */
        !            48:   struct prefix prefix;
        !            49: };
        !            50: 
        !            51: /* Filter element of access list */
        !            52: struct filter
        !            53: {
        !            54:   /* For doubly linked list. */
        !            55:   struct filter *next;
        !            56:   struct filter *prev;
        !            57: 
        !            58:   /* Filter type information. */
        !            59:   enum filter_type type;
        !            60: 
        !            61:   /* Cisco access-list */
        !            62:   int cisco;
        !            63: 
        !            64:   union
        !            65:     {
        !            66:       struct filter_cisco cfilter;
        !            67:       struct filter_zebra zfilter;
        !            68:     } u;
        !            69: };
        !            70: 
        !            71: /* List of access_list. */
        !            72: struct access_list_list
        !            73: {
        !            74:   struct access_list *head;
        !            75:   struct access_list *tail;
        !            76: };
        !            77: 
        !            78: /* Master structure of access_list. */
        !            79: struct access_master
        !            80: {
        !            81:   /* List of access_list which name is number. */
        !            82:   struct access_list_list num;
        !            83: 
        !            84:   /* List of access_list which name is string. */
        !            85:   struct access_list_list str;
        !            86: 
        !            87:   /* Hook function which is executed when new access_list is added. */
        !            88:   void (*add_hook) (struct access_list *);
        !            89: 
        !            90:   /* Hook function which is executed when access_list is deleted. */
        !            91:   void (*delete_hook) (struct access_list *);
        !            92: };
        !            93: 
        !            94: /* Static structure for IPv4 access_list's master. */
        !            95: static struct access_master access_master_ipv4 = 
        !            96: { 
        !            97:   {NULL, NULL},
        !            98:   {NULL, NULL},
        !            99:   NULL,
        !           100:   NULL,
        !           101: };
        !           102: 
        !           103: #ifdef HAVE_IPV6
        !           104: /* Static structure for IPv6 access_list's master. */
        !           105: static struct access_master access_master_ipv6 = 
        !           106: { 
        !           107:   {NULL, NULL},
        !           108:   {NULL, NULL},
        !           109:   NULL,
        !           110:   NULL,
        !           111: };
        !           112: #endif /* HAVE_IPV6 */
        !           113: 
        !           114: static struct access_master *
        !           115: access_master_get (afi_t afi)
        !           116: {
        !           117:   if (afi == AFI_IP)
        !           118:     return &access_master_ipv4;
        !           119: #ifdef HAVE_IPV6
        !           120:   else if (afi == AFI_IP6)
        !           121:     return &access_master_ipv6;
        !           122: #endif /* HAVE_IPV6 */
        !           123:   return NULL;
        !           124: }
        !           125: 
        !           126: /* Allocate new filter structure. */
        !           127: static struct filter *
        !           128: filter_new (void)
        !           129: {
        !           130:   return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
        !           131:                                    sizeof (struct filter));
        !           132: }
        !           133: 
        !           134: static void
        !           135: filter_free (struct filter *filter)
        !           136: {
        !           137:   XFREE (MTYPE_ACCESS_FILTER, filter);
        !           138: }
        !           139: 
        !           140: /* Return string of filter_type. */
        !           141: static const char *
        !           142: filter_type_str (struct filter *filter)
        !           143: {
        !           144:   switch (filter->type)
        !           145:     {
        !           146:     case FILTER_PERMIT:
        !           147:       return "permit";
        !           148:       break;
        !           149:     case FILTER_DENY:
        !           150:       return "deny";
        !           151:       break;
        !           152:     case FILTER_DYNAMIC:
        !           153:       return "dynamic";
        !           154:       break;
        !           155:     default:
        !           156:       return "";
        !           157:       break;
        !           158:     }
        !           159: }
        !           160: 
        !           161: /* If filter match to the prefix then return 1. */
        !           162: static int
        !           163: filter_match_cisco (struct filter *mfilter, struct prefix *p)
        !           164: {
        !           165:   struct filter_cisco *filter;
        !           166:   struct in_addr mask;
        !           167:   u_int32_t check_addr;
        !           168:   u_int32_t check_mask;
        !           169: 
        !           170:   filter = &mfilter->u.cfilter;
        !           171:   check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
        !           172: 
        !           173:   if (filter->extended)
        !           174:     {
        !           175:       masklen2ip (p->prefixlen, &mask);
        !           176:       check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
        !           177: 
        !           178:       if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
        !           179:           && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
        !           180:        return 1;
        !           181:     }
        !           182:   else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
        !           183:     return 1;
        !           184: 
        !           185:   return 0;
        !           186: }
        !           187: 
        !           188: /* If filter match to the prefix then return 1. */
        !           189: static int
        !           190: filter_match_zebra (struct filter *mfilter, struct prefix *p)
        !           191: {
        !           192:   struct filter_zebra *filter;
        !           193: 
        !           194:   filter = &mfilter->u.zfilter;
        !           195: 
        !           196:   if (filter->prefix.family == p->family)
        !           197:     {
        !           198:       if (filter->exact)
        !           199:        {
        !           200:          if (filter->prefix.prefixlen == p->prefixlen)
        !           201:            return prefix_match (&filter->prefix, p);
        !           202:          else
        !           203:            return 0;
        !           204:        }
        !           205:       else
        !           206:        return prefix_match (&filter->prefix, p);
        !           207:     }
        !           208:   else
        !           209:     return 0;
        !           210: }
        !           211: 
        !           212: /* Allocate new access list structure. */
        !           213: static struct access_list *
        !           214: access_list_new (void)
        !           215: {
        !           216:   return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
        !           217:                                         sizeof (struct access_list));
        !           218: }
        !           219: 
        !           220: /* Free allocated access_list. */
        !           221: static void
        !           222: access_list_free (struct access_list *access)
        !           223: {
        !           224:   XFREE (MTYPE_ACCESS_LIST, access);
        !           225: }
        !           226: 
        !           227: /* Delete access_list from access_master and free it. */
        !           228: static void
        !           229: access_list_delete (struct access_list *access)
        !           230: {
        !           231:   struct filter *filter;
        !           232:   struct filter *next;
        !           233:   struct access_list_list *list;
        !           234:   struct access_master *master;
        !           235: 
        !           236:   for (filter = access->head; filter; filter = next)
        !           237:     {
        !           238:       next = filter->next;
        !           239:       filter_free (filter);
        !           240:     }
        !           241: 
        !           242:   master = access->master;
        !           243: 
        !           244:   if (access->type == ACCESS_TYPE_NUMBER)
        !           245:     list = &master->num;
        !           246:   else
        !           247:     list = &master->str;
        !           248: 
        !           249:   if (access->next)
        !           250:     access->next->prev = access->prev;
        !           251:   else
        !           252:     list->tail = access->prev;
        !           253: 
        !           254:   if (access->prev)
        !           255:     access->prev->next = access->next;
        !           256:   else
        !           257:     list->head = access->next;
        !           258: 
        !           259:   if (access->name)
        !           260:     XFREE (MTYPE_ACCESS_LIST_STR, access->name);
        !           261: 
        !           262:   if (access->remark)
        !           263:     XFREE (MTYPE_TMP, access->remark);
        !           264: 
        !           265:   access_list_free (access);
        !           266: }
        !           267: 
        !           268: /* Insert new access list to list of access_list.  Each acceess_list
        !           269:    is sorted by the name. */
        !           270: static struct access_list *
        !           271: access_list_insert (afi_t afi, const char *name)
        !           272: {
        !           273:   unsigned int i;
        !           274:   long number;
        !           275:   struct access_list *access;
        !           276:   struct access_list *point;
        !           277:   struct access_list_list *alist;
        !           278:   struct access_master *master;
        !           279: 
        !           280:   master = access_master_get (afi);
        !           281:   if (master == NULL)
        !           282:     return NULL;
        !           283: 
        !           284:   /* Allocate new access_list and copy given name. */
        !           285:   access = access_list_new ();
        !           286:   access->name = XSTRDUP (MTYPE_ACCESS_LIST_STR, name);
        !           287:   access->master = master;
        !           288: 
        !           289:   /* If name is made by all digit character.  We treat it as
        !           290:      number. */
        !           291:   for (number = 0, i = 0; i < strlen (name); i++)
        !           292:     {
        !           293:       if (isdigit ((int) name[i]))
        !           294:        number = (number * 10) + (name[i] - '0');
        !           295:       else
        !           296:        break;
        !           297:     }
        !           298: 
        !           299:   /* In case of name is all digit character */
        !           300:   if (i == strlen (name))
        !           301:     {
        !           302:       access->type = ACCESS_TYPE_NUMBER;
        !           303: 
        !           304:       /* Set access_list to number list. */
        !           305:       alist = &master->num;
        !           306: 
        !           307:       for (point = alist->head; point; point = point->next)
        !           308:        if (atol (point->name) >= number)
        !           309:          break;
        !           310:     }
        !           311:   else
        !           312:     {
        !           313:       access->type = ACCESS_TYPE_STRING;
        !           314: 
        !           315:       /* Set access_list to string list. */
        !           316:       alist = &master->str;
        !           317:   
        !           318:       /* Set point to insertion point. */
        !           319:       for (point = alist->head; point; point = point->next)
        !           320:        if (strcmp (point->name, name) >= 0)
        !           321:          break;
        !           322:     }
        !           323: 
        !           324:   /* In case of this is the first element of master. */
        !           325:   if (alist->head == NULL)
        !           326:     {
        !           327:       alist->head = alist->tail = access;
        !           328:       return access;
        !           329:     }
        !           330: 
        !           331:   /* In case of insertion is made at the tail of access_list. */
        !           332:   if (point == NULL)
        !           333:     {
        !           334:       access->prev = alist->tail;
        !           335:       alist->tail->next = access;
        !           336:       alist->tail = access;
        !           337:       return access;
        !           338:     }
        !           339: 
        !           340:   /* In case of insertion is made at the head of access_list. */
        !           341:   if (point == alist->head)
        !           342:     {
        !           343:       access->next = alist->head;
        !           344:       alist->head->prev = access;
        !           345:       alist->head = access;
        !           346:       return access;
        !           347:     }
        !           348: 
        !           349:   /* Insertion is made at middle of the access_list. */
        !           350:   access->next = point;
        !           351:   access->prev = point->prev;
        !           352: 
        !           353:   if (point->prev)
        !           354:     point->prev->next = access;
        !           355:   point->prev = access;
        !           356: 
        !           357:   return access;
        !           358: }
        !           359: 
        !           360: /* Lookup access_list from list of access_list by name. */
        !           361: struct access_list *
        !           362: access_list_lookup (afi_t afi, const char *name)
        !           363: {
        !           364:   struct access_list *access;
        !           365:   struct access_master *master;
        !           366: 
        !           367:   if (name == NULL)
        !           368:     return NULL;
        !           369: 
        !           370:   master = access_master_get (afi);
        !           371:   if (master == NULL)
        !           372:     return NULL;
        !           373: 
        !           374:   for (access = master->num.head; access; access = access->next)
        !           375:     if (strcmp (access->name, name) == 0)
        !           376:       return access;
        !           377: 
        !           378:   for (access = master->str.head; access; access = access->next)
        !           379:     if (strcmp (access->name, name) == 0)
        !           380:       return access;
        !           381: 
        !           382:   return NULL;
        !           383: }
        !           384: 
        !           385: /* Get access list from list of access_list.  If there isn't matched
        !           386:    access_list create new one and return it. */
        !           387: static struct access_list *
        !           388: access_list_get (afi_t afi, const char *name)
        !           389: {
        !           390:   struct access_list *access;
        !           391: 
        !           392:   access = access_list_lookup (afi, name);
        !           393:   if (access == NULL)
        !           394:     access = access_list_insert (afi, name);
        !           395:   return access;
        !           396: }
        !           397: 
        !           398: /* Apply access list to object (which should be struct prefix *). */
        !           399: enum filter_type
        !           400: access_list_apply (struct access_list *access, void *object)
        !           401: {
        !           402:   struct filter *filter;
        !           403:   struct prefix *p;
        !           404: 
        !           405:   p = (struct prefix *) object;
        !           406: 
        !           407:   if (access == NULL)
        !           408:     return FILTER_DENY;
        !           409: 
        !           410:   for (filter = access->head; filter; filter = filter->next)
        !           411:     {
        !           412:       if (filter->cisco)
        !           413:        {
        !           414:          if (filter_match_cisco (filter, p))
        !           415:            return filter->type;
        !           416:        }
        !           417:       else
        !           418:        {
        !           419:          if (filter_match_zebra (filter, p))
        !           420:            return filter->type;
        !           421:        }
        !           422:     }
        !           423: 
        !           424:   return FILTER_DENY;
        !           425: }
        !           426: 
        !           427: /* Add hook function. */
        !           428: void
        !           429: access_list_add_hook (void (*func) (struct access_list *access))
        !           430: {
        !           431:   access_master_ipv4.add_hook = func;
        !           432: #ifdef HAVE_IPV6
        !           433:   access_master_ipv6.add_hook = func;
        !           434: #endif /* HAVE_IPV6 */
        !           435: }
        !           436: 
        !           437: /* Delete hook function. */
        !           438: void
        !           439: access_list_delete_hook (void (*func) (struct access_list *access))
        !           440: {
        !           441:   access_master_ipv4.delete_hook = func;
        !           442: #ifdef HAVE_IPV6
        !           443:   access_master_ipv6.delete_hook = func;
        !           444: #endif /* HAVE_IPV6 */
        !           445: }
        !           446: 
        !           447: /* Add new filter to the end of specified access_list. */
        !           448: static void
        !           449: access_list_filter_add (struct access_list *access, struct filter *filter)
        !           450: {
        !           451:   filter->next = NULL;
        !           452:   filter->prev = access->tail;
        !           453: 
        !           454:   if (access->tail)
        !           455:     access->tail->next = filter;
        !           456:   else
        !           457:     access->head = filter;
        !           458:   access->tail = filter;
        !           459: 
        !           460:   /* Run hook function. */
        !           461:   if (access->master->add_hook)
        !           462:     (*access->master->add_hook) (access);
        !           463: }
        !           464: 
        !           465: /* If access_list has no filter then return 1. */
        !           466: static int
        !           467: access_list_empty (struct access_list *access)
        !           468: {
        !           469:   if (access->head == NULL && access->tail == NULL)
        !           470:     return 1;
        !           471:   else
        !           472:     return 0;
        !           473: }
        !           474: 
        !           475: /* Delete filter from specified access_list.  If there is hook
        !           476:    function execute it. */
        !           477: static void
        !           478: access_list_filter_delete (struct access_list *access, struct filter *filter)
        !           479: {
        !           480:   struct access_master *master;
        !           481: 
        !           482:   master = access->master;
        !           483: 
        !           484:   if (filter->next)
        !           485:     filter->next->prev = filter->prev;
        !           486:   else
        !           487:     access->tail = filter->prev;
        !           488: 
        !           489:   if (filter->prev)
        !           490:     filter->prev->next = filter->next;
        !           491:   else
        !           492:     access->head = filter->next;
        !           493: 
        !           494:   filter_free (filter);
        !           495: 
        !           496:   /* If access_list becomes empty delete it from access_master. */
        !           497:   if (access_list_empty (access))
        !           498:     access_list_delete (access);
        !           499: 
        !           500:   /* Run hook function. */
        !           501:   if (master->delete_hook)
        !           502:     (*master->delete_hook) (access);
        !           503: }
        !           504: 
        !           505: /*
        !           506:   deny    Specify packets to reject
        !           507:   permit  Specify packets to forward
        !           508:   dynamic ?
        !           509: */
        !           510: 
        !           511: /*
        !           512:   Hostname or A.B.C.D  Address to match
        !           513:   any                  Any source host
        !           514:   host                 A single host address
        !           515: */
        !           516: 
        !           517: static struct filter *
        !           518: filter_lookup_cisco (struct access_list *access, struct filter *mnew)
        !           519: {
        !           520:   struct filter *mfilter;
        !           521:   struct filter_cisco *filter;
        !           522:   struct filter_cisco *new;
        !           523: 
        !           524:   new = &mnew->u.cfilter;
        !           525: 
        !           526:   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !           527:     {
        !           528:       filter = &mfilter->u.cfilter;
        !           529: 
        !           530:       if (filter->extended)
        !           531:        {
        !           532:          if (mfilter->type == mnew->type
        !           533:              && filter->addr.s_addr == new->addr.s_addr
        !           534:              && filter->addr_mask.s_addr == new->addr_mask.s_addr
        !           535:              && filter->mask.s_addr == new->mask.s_addr
        !           536:              && filter->mask_mask.s_addr == new->mask_mask.s_addr)
        !           537:            return mfilter;
        !           538:        }
        !           539:       else
        !           540:        {
        !           541:          if (mfilter->type == mnew->type
        !           542:              && filter->addr.s_addr == new->addr.s_addr
        !           543:              && filter->addr_mask.s_addr == new->addr_mask.s_addr)
        !           544:            return mfilter;
        !           545:        }
        !           546:     }
        !           547: 
        !           548:   return NULL;
        !           549: }
        !           550: 
        !           551: static struct filter *
        !           552: filter_lookup_zebra (struct access_list *access, struct filter *mnew)
        !           553: {
        !           554:   struct filter *mfilter;
        !           555:   struct filter_zebra *filter;
        !           556:   struct filter_zebra *new;
        !           557: 
        !           558:   new = &mnew->u.zfilter;
        !           559: 
        !           560:   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !           561:     {
        !           562:       filter = &mfilter->u.zfilter;
        !           563: 
        !           564:       if (filter->exact == new->exact
        !           565:          && mfilter->type == mnew->type
        !           566:          && prefix_same (&filter->prefix, &new->prefix))
        !           567:        return mfilter;
        !           568:     }
        !           569:   return NULL;
        !           570: }
        !           571: 
        !           572: static int
        !           573: vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
        !           574: {
        !           575:   struct access_list *access;
        !           576: 
        !           577:   access = access_list_lookup (afi, name);
        !           578:   if (! access)
        !           579:     {
        !           580:       vty_out (vty, "%% access-list %s doesn't exist%s", name,
        !           581:               VTY_NEWLINE);
        !           582:       return CMD_WARNING;
        !           583:     }
        !           584: 
        !           585:   if (access->remark)
        !           586:     {
        !           587:       XFREE (MTYPE_TMP, access->remark);
        !           588:       access->remark = NULL;
        !           589:     }
        !           590: 
        !           591:   if (access->head == NULL && access->tail == NULL && access->remark == NULL)
        !           592:     access_list_delete (access);
        !           593: 
        !           594:   return CMD_SUCCESS;
        !           595: }
        !           596: 
        !           597: static int
        !           598: filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
        !           599:                  const char *addr_str, const char *addr_mask_str,
        !           600:                  const char *mask_str, const char *mask_mask_str,
        !           601:                  int extended, int set)
        !           602: {
        !           603:   int ret;
        !           604:   enum filter_type type;
        !           605:   struct filter *mfilter;
        !           606:   struct filter_cisco *filter;
        !           607:   struct access_list *access;
        !           608:   struct in_addr addr;
        !           609:   struct in_addr addr_mask;
        !           610:   struct in_addr mask;
        !           611:   struct in_addr mask_mask;
        !           612: 
        !           613:   /* Check of filter type. */
        !           614:   if (strncmp (type_str, "p", 1) == 0)
        !           615:     type = FILTER_PERMIT;
        !           616:   else if (strncmp (type_str, "d", 1) == 0)
        !           617:     type = FILTER_DENY;
        !           618:   else
        !           619:     {
        !           620:       vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
        !           621:       return CMD_WARNING;
        !           622:     }
        !           623: 
        !           624:   ret = inet_aton (addr_str, &addr);
        !           625:   if (ret <= 0)
        !           626:     {
        !           627:       vty_out (vty, "%%Inconsistent address and mask%s",
        !           628:               VTY_NEWLINE);
        !           629:       return CMD_WARNING;
        !           630:     }
        !           631: 
        !           632:   ret = inet_aton (addr_mask_str, &addr_mask);
        !           633:   if (ret <= 0)
        !           634:     {
        !           635:       vty_out (vty, "%%Inconsistent address and mask%s",
        !           636:               VTY_NEWLINE);
        !           637:       return CMD_WARNING;
        !           638:     }
        !           639: 
        !           640:   if (extended)
        !           641:     {
        !           642:       ret = inet_aton (mask_str, &mask);
        !           643:       if (ret <= 0)
        !           644:        {
        !           645:          vty_out (vty, "%%Inconsistent address and mask%s",
        !           646:                   VTY_NEWLINE);
        !           647:          return CMD_WARNING;
        !           648:        }
        !           649: 
        !           650:       ret = inet_aton (mask_mask_str, &mask_mask);
        !           651:       if (ret <= 0)
        !           652:        {
        !           653:          vty_out (vty, "%%Inconsistent address and mask%s",
        !           654:                   VTY_NEWLINE);
        !           655:          return CMD_WARNING;
        !           656:        }
        !           657:     }
        !           658: 
        !           659:   mfilter = filter_new();
        !           660:   mfilter->type = type;
        !           661:   mfilter->cisco = 1;
        !           662:   filter = &mfilter->u.cfilter;
        !           663:   filter->extended = extended;
        !           664:   filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
        !           665:   filter->addr_mask.s_addr = addr_mask.s_addr;
        !           666: 
        !           667:   if (extended)
        !           668:     {
        !           669:       filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
        !           670:       filter->mask_mask.s_addr = mask_mask.s_addr;
        !           671:     }
        !           672: 
        !           673:   /* Install new filter to the access_list. */
        !           674:   access = access_list_get (AFI_IP, name_str);
        !           675: 
        !           676:   if (set)
        !           677:     {
        !           678:       if (filter_lookup_cisco (access, mfilter))
        !           679:        filter_free (mfilter);
        !           680:       else
        !           681:        access_list_filter_add (access, mfilter);
        !           682:     }
        !           683:   else
        !           684:     {
        !           685:       struct filter *delete_filter;
        !           686: 
        !           687:       delete_filter = filter_lookup_cisco (access, mfilter);
        !           688:       if (delete_filter)
        !           689:        access_list_filter_delete (access, delete_filter);
        !           690: 
        !           691:       filter_free (mfilter);
        !           692:     }
        !           693: 
        !           694:   return CMD_SUCCESS;
        !           695: }
        !           696: 
        !           697: /* Standard access-list */
        !           698: DEFUN (access_list_standard,
        !           699:        access_list_standard_cmd,
        !           700:        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
        !           701:        "Add an access list entry\n"
        !           702:        "IP standard access list\n"
        !           703:        "IP standard access list (expanded range)\n"
        !           704:        "Specify packets to reject\n"
        !           705:        "Specify packets to forward\n"
        !           706:        "Address to match\n"
        !           707:        "Wildcard bits\n")
        !           708: {
        !           709:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
        !           710:                           NULL, NULL, 0, 1);
        !           711: }
        !           712: 
        !           713: DEFUN (access_list_standard_nomask,
        !           714:        access_list_standard_nomask_cmd,
        !           715:        "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
        !           716:        "Add an access list entry\n"
        !           717:        "IP standard access list\n"
        !           718:        "IP standard access list (expanded range)\n"
        !           719:        "Specify packets to reject\n"
        !           720:        "Specify packets to forward\n"
        !           721:        "Address to match\n")
        !           722: {
        !           723:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
        !           724:                           NULL, NULL, 0, 1);
        !           725: }
        !           726: 
        !           727: DEFUN (access_list_standard_host,
        !           728:        access_list_standard_host_cmd,
        !           729:        "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
        !           730:        "Add an access list entry\n"
        !           731:        "IP standard access list\n"
        !           732:        "IP standard access list (expanded range)\n"
        !           733:        "Specify packets to reject\n"
        !           734:        "Specify packets to forward\n"
        !           735:        "A single host address\n"
        !           736:        "Address to match\n")
        !           737: {
        !           738:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
        !           739:                           NULL, NULL, 0, 1);
        !           740: }
        !           741: 
        !           742: DEFUN (access_list_standard_any,
        !           743:        access_list_standard_any_cmd,
        !           744:        "access-list (<1-99>|<1300-1999>) (deny|permit) any",
        !           745:        "Add an access list entry\n"
        !           746:        "IP standard access list\n"
        !           747:        "IP standard access list (expanded range)\n"
        !           748:        "Specify packets to reject\n"
        !           749:        "Specify packets to forward\n"
        !           750:        "Any source host\n")
        !           751: {
        !           752:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !           753:                           "255.255.255.255", NULL, NULL, 0, 1);
        !           754: }
        !           755: 
        !           756: DEFUN (no_access_list_standard,
        !           757:        no_access_list_standard_cmd,
        !           758:        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
        !           759:        NO_STR
        !           760:        "Add an access list entry\n"
        !           761:        "IP standard access list\n"
        !           762:        "IP standard access list (expanded range)\n"
        !           763:        "Specify packets to reject\n"
        !           764:        "Specify packets to forward\n"
        !           765:        "Address to match\n"
        !           766:        "Wildcard bits\n")
        !           767: {
        !           768:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
        !           769:                           NULL, NULL, 0, 0);
        !           770: }
        !           771: 
        !           772: DEFUN (no_access_list_standard_nomask,
        !           773:        no_access_list_standard_nomask_cmd,
        !           774:        "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
        !           775:        NO_STR
        !           776:        "Add an access list entry\n"
        !           777:        "IP standard access list\n"
        !           778:        "IP standard access list (expanded range)\n"
        !           779:        "Specify packets to reject\n"
        !           780:        "Specify packets to forward\n"
        !           781:        "Address to match\n")
        !           782: {
        !           783:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
        !           784:                           NULL, NULL, 0, 0);
        !           785: }
        !           786: 
        !           787: DEFUN (no_access_list_standard_host,
        !           788:        no_access_list_standard_host_cmd,
        !           789:        "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
        !           790:        NO_STR
        !           791:        "Add an access list entry\n"
        !           792:        "IP standard access list\n"
        !           793:        "IP standard access list (expanded range)\n"
        !           794:        "Specify packets to reject\n"
        !           795:        "Specify packets to forward\n"
        !           796:        "A single host address\n"
        !           797:        "Address to match\n")
        !           798: {
        !           799:   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
        !           800:                           NULL, NULL, 0, 0);
        !           801: }
        !           802: 
        !           803: DEFUN (no_access_list_standard_any,
        !           804:        no_access_list_standard_any_cmd,
        !           805:        "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
        !           806:        NO_STR
        !           807:        "Add an access list entry\n"
        !           808:        "IP standard access list\n"
        !           809:        "IP standard access list (expanded range)\n"
        !           810:        "Specify packets to reject\n"
        !           811:        "Specify packets to forward\n"
        !           812:        "Any source host\n")
        !           813: {
        !           814:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !           815:                           "255.255.255.255", NULL, NULL, 0, 0);
        !           816: }
        !           817: 
        !           818: /* Extended access-list */
        !           819: DEFUN (access_list_extended,
        !           820:        access_list_extended_cmd,
        !           821:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
        !           822:        "Add an access list entry\n"
        !           823:        "IP extended access list\n"
        !           824:        "IP extended access list (expanded range)\n"
        !           825:        "Specify packets to reject\n"
        !           826:        "Specify packets to forward\n"
        !           827:        "Any Internet Protocol\n"
        !           828:        "Source address\n"
        !           829:        "Source wildcard bits\n"
        !           830:        "Destination address\n"
        !           831:        "Destination Wildcard bits\n")
        !           832: {
        !           833:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           834:                           argv[3], argv[4], argv[5], 1 ,1);
        !           835: }
        !           836: 
        !           837: DEFUN (access_list_extended_mask_any,
        !           838:        access_list_extended_mask_any_cmd,
        !           839:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
        !           840:        "Add an access list entry\n"
        !           841:        "IP extended access list\n"
        !           842:        "IP extended access list (expanded range)\n"
        !           843:        "Specify packets to reject\n"
        !           844:        "Specify packets to forward\n"
        !           845:        "Any Internet Protocol\n"
        !           846:        "Source address\n"
        !           847:        "Source wildcard bits\n"
        !           848:        "Any destination host\n")
        !           849: {
        !           850:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           851:                           argv[3], "0.0.0.0",
        !           852:                           "255.255.255.255", 1, 1);
        !           853: }
        !           854: 
        !           855: DEFUN (access_list_extended_any_mask,
        !           856:        access_list_extended_any_mask_cmd,
        !           857:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
        !           858:        "Add an access list entry\n"
        !           859:        "IP extended access list\n"
        !           860:        "IP extended access list (expanded range)\n"
        !           861:        "Specify packets to reject\n"
        !           862:        "Specify packets to forward\n"
        !           863:        "Any Internet Protocol\n"
        !           864:        "Any source host\n"
        !           865:        "Destination address\n"
        !           866:        "Destination Wildcard bits\n")
        !           867: {
        !           868:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !           869:                           "255.255.255.255", argv[2],
        !           870:                           argv[3], 1, 1);
        !           871: }
        !           872: 
        !           873: DEFUN (access_list_extended_any_any,
        !           874:        access_list_extended_any_any_cmd,
        !           875:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
        !           876:        "Add an access list entry\n"
        !           877:        "IP extended access list\n"
        !           878:        "IP extended access list (expanded range)\n"
        !           879:        "Specify packets to reject\n"
        !           880:        "Specify packets to forward\n"
        !           881:        "Any Internet Protocol\n"
        !           882:        "Any source host\n"
        !           883:        "Any destination host\n")
        !           884: {
        !           885:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !           886:                           "255.255.255.255", "0.0.0.0",
        !           887:                           "255.255.255.255", 1, 1);
        !           888: }
        !           889: 
        !           890: DEFUN (access_list_extended_mask_host,
        !           891:        access_list_extended_mask_host_cmd,
        !           892:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
        !           893:        "Add an access list entry\n"
        !           894:        "IP extended access list\n"
        !           895:        "IP extended access list (expanded range)\n"
        !           896:        "Specify packets to reject\n"
        !           897:        "Specify packets to forward\n"
        !           898:        "Any Internet Protocol\n"
        !           899:        "Source address\n"
        !           900:        "Source wildcard bits\n"
        !           901:        "A single destination host\n"
        !           902:        "Destination address\n")
        !           903: {
        !           904:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           905:                           argv[3], argv[4],
        !           906:                           "0.0.0.0", 1, 1);
        !           907: }
        !           908: 
        !           909: DEFUN (access_list_extended_host_mask,
        !           910:        access_list_extended_host_mask_cmd,
        !           911:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
        !           912:        "Add an access list entry\n"
        !           913:        "IP extended access list\n"
        !           914:        "IP extended access list (expanded range)\n"
        !           915:        "Specify packets to reject\n"
        !           916:        "Specify packets to forward\n"
        !           917:        "Any Internet Protocol\n"
        !           918:        "A single source host\n"
        !           919:        "Source address\n"
        !           920:        "Destination address\n"
        !           921:        "Destination Wildcard bits\n")
        !           922: {
        !           923:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           924:                           "0.0.0.0", argv[3],
        !           925:                           argv[4], 1, 1);
        !           926: }
        !           927: 
        !           928: DEFUN (access_list_extended_host_host,
        !           929:        access_list_extended_host_host_cmd,
        !           930:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
        !           931:        "Add an access list entry\n"
        !           932:        "IP extended access list\n"
        !           933:        "IP extended access list (expanded range)\n"
        !           934:        "Specify packets to reject\n"
        !           935:        "Specify packets to forward\n"
        !           936:        "Any Internet Protocol\n"
        !           937:        "A single source host\n"
        !           938:        "Source address\n"
        !           939:        "A single destination host\n"
        !           940:        "Destination address\n")
        !           941: {
        !           942:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           943:                           "0.0.0.0", argv[3],
        !           944:                           "0.0.0.0", 1, 1);
        !           945: }
        !           946: 
        !           947: DEFUN (access_list_extended_any_host,
        !           948:        access_list_extended_any_host_cmd,
        !           949:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
        !           950:        "Add an access list entry\n"
        !           951:        "IP extended access list\n"
        !           952:        "IP extended access list (expanded range)\n"
        !           953:        "Specify packets to reject\n"
        !           954:        "Specify packets to forward\n"
        !           955:        "Any Internet Protocol\n"
        !           956:        "Any source host\n"
        !           957:        "A single destination host\n"
        !           958:        "Destination address\n")
        !           959: {
        !           960:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !           961:                           "255.255.255.255", argv[2],
        !           962:                           "0.0.0.0", 1, 1);
        !           963: }
        !           964: 
        !           965: DEFUN (access_list_extended_host_any,
        !           966:        access_list_extended_host_any_cmd,
        !           967:        "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
        !           968:        "Add an access list entry\n"
        !           969:        "IP extended access list\n"
        !           970:        "IP extended access list (expanded range)\n"
        !           971:        "Specify packets to reject\n"
        !           972:        "Specify packets to forward\n"
        !           973:        "Any Internet Protocol\n"
        !           974:        "A single source host\n"
        !           975:        "Source address\n"
        !           976:        "Any destination host\n")
        !           977: {
        !           978:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           979:                           "0.0.0.0", "0.0.0.0",
        !           980:                           "255.255.255.255", 1, 1);
        !           981: }
        !           982: 
        !           983: DEFUN (no_access_list_extended,
        !           984:        no_access_list_extended_cmd,
        !           985:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
        !           986:        NO_STR
        !           987:        "Add an access list entry\n"
        !           988:        "IP extended access list\n"
        !           989:        "IP extended access list (expanded range)\n"
        !           990:        "Specify packets to reject\n"
        !           991:        "Specify packets to forward\n"
        !           992:        "Any Internet Protocol\n"
        !           993:        "Source address\n"
        !           994:        "Source wildcard bits\n"
        !           995:        "Destination address\n"
        !           996:        "Destination Wildcard bits\n")
        !           997: {
        !           998:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !           999:                           argv[3], argv[4], argv[5], 1, 0);
        !          1000: }
        !          1001: 
        !          1002: DEFUN (no_access_list_extended_mask_any,
        !          1003:        no_access_list_extended_mask_any_cmd,
        !          1004:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
        !          1005:        NO_STR
        !          1006:        "Add an access list entry\n"
        !          1007:        "IP extended access list\n"
        !          1008:        "IP extended access list (expanded range)\n"
        !          1009:        "Specify packets to reject\n"
        !          1010:        "Specify packets to forward\n"
        !          1011:        "Any Internet Protocol\n"
        !          1012:        "Source address\n"
        !          1013:        "Source wildcard bits\n"
        !          1014:        "Any destination host\n")
        !          1015: {
        !          1016:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !          1017:                           argv[3], "0.0.0.0",
        !          1018:                           "255.255.255.255", 1, 0);
        !          1019: }
        !          1020: 
        !          1021: DEFUN (no_access_list_extended_any_mask,
        !          1022:        no_access_list_extended_any_mask_cmd,
        !          1023:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
        !          1024:        NO_STR
        !          1025:        "Add an access list entry\n"
        !          1026:        "IP extended access list\n"
        !          1027:        "IP extended access list (expanded range)\n"
        !          1028:        "Specify packets to reject\n"
        !          1029:        "Specify packets to forward\n"
        !          1030:        "Any Internet Protocol\n"
        !          1031:        "Any source host\n"
        !          1032:        "Destination address\n"
        !          1033:        "Destination Wildcard bits\n")
        !          1034: {
        !          1035:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !          1036:                           "255.255.255.255", argv[2],
        !          1037:                           argv[3], 1, 0);
        !          1038: }
        !          1039: 
        !          1040: DEFUN (no_access_list_extended_any_any,
        !          1041:        no_access_list_extended_any_any_cmd,
        !          1042:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
        !          1043:        NO_STR
        !          1044:        "Add an access list entry\n"
        !          1045:        "IP extended access list\n"
        !          1046:        "IP extended access list (expanded range)\n"
        !          1047:        "Specify packets to reject\n"
        !          1048:        "Specify packets to forward\n"
        !          1049:        "Any Internet Protocol\n"
        !          1050:        "Any source host\n"
        !          1051:        "Any destination host\n")
        !          1052: {
        !          1053:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !          1054:                           "255.255.255.255", "0.0.0.0",
        !          1055:                           "255.255.255.255", 1, 0);
        !          1056: }
        !          1057: 
        !          1058: DEFUN (no_access_list_extended_mask_host,
        !          1059:        no_access_list_extended_mask_host_cmd,
        !          1060:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
        !          1061:        NO_STR
        !          1062:        "Add an access list entry\n"
        !          1063:        "IP extended access list\n"
        !          1064:        "IP extended access list (expanded range)\n"
        !          1065:        "Specify packets to reject\n"
        !          1066:        "Specify packets to forward\n"
        !          1067:        "Any Internet Protocol\n"
        !          1068:        "Source address\n"
        !          1069:        "Source wildcard bits\n"
        !          1070:        "A single destination host\n"
        !          1071:        "Destination address\n")
        !          1072: {
        !          1073:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !          1074:                           argv[3], argv[4],
        !          1075:                           "0.0.0.0", 1, 0);
        !          1076: }
        !          1077: 
        !          1078: DEFUN (no_access_list_extended_host_mask,
        !          1079:        no_access_list_extended_host_mask_cmd,
        !          1080:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
        !          1081:        NO_STR
        !          1082:        "Add an access list entry\n"
        !          1083:        "IP extended access list\n"
        !          1084:        "IP extended access list (expanded range)\n"
        !          1085:        "Specify packets to reject\n"
        !          1086:        "Specify packets to forward\n"
        !          1087:        "Any Internet Protocol\n"
        !          1088:        "A single source host\n"
        !          1089:        "Source address\n"
        !          1090:        "Destination address\n"
        !          1091:        "Destination Wildcard bits\n")
        !          1092: {
        !          1093:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !          1094:                           "0.0.0.0", argv[3],
        !          1095:                           argv[4], 1, 0);
        !          1096: }
        !          1097: 
        !          1098: DEFUN (no_access_list_extended_host_host,
        !          1099:        no_access_list_extended_host_host_cmd,
        !          1100:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
        !          1101:        NO_STR
        !          1102:        "Add an access list entry\n"
        !          1103:        "IP extended access list\n"
        !          1104:        "IP extended access list (expanded range)\n"
        !          1105:        "Specify packets to reject\n"
        !          1106:        "Specify packets to forward\n"
        !          1107:        "Any Internet Protocol\n"
        !          1108:        "A single source host\n"
        !          1109:        "Source address\n"
        !          1110:        "A single destination host\n"
        !          1111:        "Destination address\n")
        !          1112: {
        !          1113:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !          1114:                           "0.0.0.0", argv[3],
        !          1115:                           "0.0.0.0", 1, 0);
        !          1116: }
        !          1117: 
        !          1118: DEFUN (no_access_list_extended_any_host,
        !          1119:        no_access_list_extended_any_host_cmd,
        !          1120:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
        !          1121:        NO_STR
        !          1122:        "Add an access list entry\n"
        !          1123:        "IP extended access list\n"
        !          1124:        "IP extended access list (expanded range)\n"
        !          1125:        "Specify packets to reject\n"
        !          1126:        "Specify packets to forward\n"
        !          1127:        "Any Internet Protocol\n"
        !          1128:        "Any source host\n"
        !          1129:        "A single destination host\n"
        !          1130:        "Destination address\n")
        !          1131: {
        !          1132:   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
        !          1133:                           "255.255.255.255", argv[2],
        !          1134:                           "0.0.0.0", 1, 0);
        !          1135: }
        !          1136: 
        !          1137: DEFUN (no_access_list_extended_host_any,
        !          1138:        no_access_list_extended_host_any_cmd,
        !          1139:        "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
        !          1140:        NO_STR
        !          1141:        "Add an access list entry\n"
        !          1142:        "IP extended access list\n"
        !          1143:        "IP extended access list (expanded range)\n"
        !          1144:        "Specify packets to reject\n"
        !          1145:        "Specify packets to forward\n"
        !          1146:        "Any Internet Protocol\n"
        !          1147:        "A single source host\n"
        !          1148:        "Source address\n"
        !          1149:        "Any destination host\n")
        !          1150: {
        !          1151:   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
        !          1152:                           "0.0.0.0", "0.0.0.0",
        !          1153:                           "255.255.255.255", 1, 0);
        !          1154: }
        !          1155: 
        !          1156: static int
        !          1157: filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
        !          1158:                  afi_t afi, const char *prefix_str, int exact, int set)
        !          1159: {
        !          1160:   int ret;
        !          1161:   enum filter_type type;
        !          1162:   struct filter *mfilter;
        !          1163:   struct filter_zebra *filter;
        !          1164:   struct access_list *access;
        !          1165:   struct prefix p;
        !          1166: 
        !          1167:   /* Check of filter type. */
        !          1168:   if (strncmp (type_str, "p", 1) == 0)
        !          1169:     type = FILTER_PERMIT;
        !          1170:   else if (strncmp (type_str, "d", 1) == 0)
        !          1171:     type = FILTER_DENY;
        !          1172:   else
        !          1173:     {
        !          1174:       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
        !          1175:       return CMD_WARNING;
        !          1176:     }
        !          1177: 
        !          1178:   /* Check string format of prefix and prefixlen. */
        !          1179:   if (afi == AFI_IP)
        !          1180:     {
        !          1181:       ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
        !          1182:       if (ret <= 0)
        !          1183:        {
        !          1184:          vty_out (vty, "IP address prefix/prefixlen is malformed%s",
        !          1185:                   VTY_NEWLINE);
        !          1186:          return CMD_WARNING;
        !          1187:        }
        !          1188:     }
        !          1189: #ifdef HAVE_IPV6
        !          1190:   else if (afi == AFI_IP6)
        !          1191:     {
        !          1192:       ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
        !          1193:       if (ret <= 0)
        !          1194:        {
        !          1195:          vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
        !          1196:                   VTY_NEWLINE);
        !          1197:                   return CMD_WARNING;
        !          1198:        }
        !          1199:     }
        !          1200: #endif /* HAVE_IPV6 */
        !          1201:   else
        !          1202:     return CMD_WARNING;
        !          1203: 
        !          1204:   mfilter = filter_new ();
        !          1205:   mfilter->type = type;
        !          1206:   filter = &mfilter->u.zfilter;
        !          1207:   prefix_copy (&filter->prefix, &p);
        !          1208: 
        !          1209:   /* "exact-match" */
        !          1210:   if (exact)
        !          1211:     filter->exact = 1;
        !          1212: 
        !          1213:   /* Install new filter to the access_list. */
        !          1214:   access = access_list_get (afi, name_str);
        !          1215: 
        !          1216:   if (set)
        !          1217:     {
        !          1218:       if (filter_lookup_zebra (access, mfilter))
        !          1219:        filter_free (mfilter);
        !          1220:       else
        !          1221:        access_list_filter_add (access, mfilter);
        !          1222:     }
        !          1223:   else
        !          1224:     {
        !          1225:       struct filter *delete_filter;
        !          1226: 
        !          1227:       delete_filter = filter_lookup_zebra (access, mfilter);
        !          1228:       if (delete_filter)
        !          1229:         access_list_filter_delete (access, delete_filter);
        !          1230: 
        !          1231:       filter_free (mfilter);
        !          1232:     }
        !          1233: 
        !          1234:   return CMD_SUCCESS;
        !          1235: }
        !          1236: 
        !          1237: /* Zebra access-list */
        !          1238: DEFUN (access_list,
        !          1239:        access_list_cmd,
        !          1240:        "access-list WORD (deny|permit) A.B.C.D/M",
        !          1241:        "Add an access list entry\n"
        !          1242:        "IP zebra access-list name\n"
        !          1243:        "Specify packets to reject\n"
        !          1244:        "Specify packets to forward\n"
        !          1245:        "Prefix to match. e.g. 10.0.0.0/8\n")
        !          1246: {
        !          1247:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
        !          1248: }
        !          1249: 
        !          1250: DEFUN (access_list_exact,
        !          1251:        access_list_exact_cmd,
        !          1252:        "access-list WORD (deny|permit) A.B.C.D/M exact-match",
        !          1253:        "Add an access list entry\n"
        !          1254:        "IP zebra access-list name\n"
        !          1255:        "Specify packets to reject\n"
        !          1256:        "Specify packets to forward\n"
        !          1257:        "Prefix to match. e.g. 10.0.0.0/8\n"
        !          1258:        "Exact match of the prefixes\n")
        !          1259: {
        !          1260:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
        !          1261: }
        !          1262: 
        !          1263: DEFUN (access_list_any,
        !          1264:        access_list_any_cmd,
        !          1265:        "access-list WORD (deny|permit) any",
        !          1266:        "Add an access list entry\n"
        !          1267:        "IP zebra access-list name\n"
        !          1268:        "Specify packets to reject\n"
        !          1269:        "Specify packets to forward\n"
        !          1270:        "Prefix to match. e.g. 10.0.0.0/8\n")
        !          1271: {
        !          1272:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
        !          1273: }
        !          1274: 
        !          1275: DEFUN (no_access_list,
        !          1276:        no_access_list_cmd,
        !          1277:        "no access-list WORD (deny|permit) A.B.C.D/M",
        !          1278:        NO_STR
        !          1279:        "Add an access list entry\n"
        !          1280:        "IP zebra access-list name\n"
        !          1281:        "Specify packets to reject\n"
        !          1282:        "Specify packets to forward\n"
        !          1283:        "Prefix to match. e.g. 10.0.0.0/8\n")
        !          1284: {
        !          1285:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
        !          1286: }
        !          1287: 
        !          1288: DEFUN (no_access_list_exact,
        !          1289:        no_access_list_exact_cmd,
        !          1290:        "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
        !          1291:        NO_STR
        !          1292:        "Add an access list entry\n"
        !          1293:        "IP zebra access-list name\n"
        !          1294:        "Specify packets to reject\n"
        !          1295:        "Specify packets to forward\n"
        !          1296:        "Prefix to match. e.g. 10.0.0.0/8\n"
        !          1297:        "Exact match of the prefixes\n")
        !          1298: {
        !          1299:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
        !          1300: }
        !          1301: 
        !          1302: DEFUN (no_access_list_any,
        !          1303:        no_access_list_any_cmd,
        !          1304:        "no access-list WORD (deny|permit) any",
        !          1305:        NO_STR
        !          1306:        "Add an access list entry\n"
        !          1307:        "IP zebra access-list name\n"
        !          1308:        "Specify packets to reject\n"
        !          1309:        "Specify packets to forward\n"
        !          1310:        "Prefix to match. e.g. 10.0.0.0/8\n")
        !          1311: {
        !          1312:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
        !          1313: }
        !          1314: 
        !          1315: DEFUN (no_access_list_all,
        !          1316:        no_access_list_all_cmd,
        !          1317:        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
        !          1318:        NO_STR
        !          1319:        "Add an access list entry\n"
        !          1320:        "IP standard access list\n"
        !          1321:        "IP extended access list\n"
        !          1322:        "IP standard access list (expanded range)\n"
        !          1323:        "IP extended access list (expanded range)\n"
        !          1324:        "IP zebra access-list name\n")
        !          1325: {
        !          1326:   struct access_list *access;
        !          1327:   struct access_master *master;
        !          1328: 
        !          1329:   /* Looking up access_list. */
        !          1330:   access = access_list_lookup (AFI_IP, argv[0]);
        !          1331:   if (access == NULL)
        !          1332:     {
        !          1333:       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
        !          1334:               VTY_NEWLINE);
        !          1335:       return CMD_WARNING;
        !          1336:     }
        !          1337: 
        !          1338:   master = access->master;
        !          1339: 
        !          1340:   /* Delete all filter from access-list. */
        !          1341:   access_list_delete (access);
        !          1342: 
        !          1343:   /* Run hook function. */
        !          1344:   if (master->delete_hook)
        !          1345:     (*master->delete_hook) (access);
        !          1346:  
        !          1347:   return CMD_SUCCESS;
        !          1348: }
        !          1349: 
        !          1350: DEFUN (access_list_remark,
        !          1351:        access_list_remark_cmd,
        !          1352:        "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
        !          1353:        "Add an access list entry\n"
        !          1354:        "IP standard access list\n"
        !          1355:        "IP extended access list\n"
        !          1356:        "IP standard access list (expanded range)\n"
        !          1357:        "IP extended access list (expanded range)\n"
        !          1358:        "IP zebra access-list\n"
        !          1359:        "Access list entry comment\n"
        !          1360:        "Comment up to 100 characters\n")
        !          1361: {
        !          1362:   struct access_list *access;
        !          1363: 
        !          1364:   access = access_list_get (AFI_IP, argv[0]);
        !          1365: 
        !          1366:   if (access->remark)
        !          1367:     {
        !          1368:       XFREE (MTYPE_TMP, access->remark);
        !          1369:       access->remark = NULL;
        !          1370:     }
        !          1371:   access->remark = argv_concat(argv, argc, 1);
        !          1372: 
        !          1373:   return CMD_SUCCESS;
        !          1374: }
        !          1375: 
        !          1376: DEFUN (no_access_list_remark,
        !          1377:        no_access_list_remark_cmd,
        !          1378:        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
        !          1379:        NO_STR
        !          1380:        "Add an access list entry\n"
        !          1381:        "IP standard access list\n"
        !          1382:        "IP extended access list\n"
        !          1383:        "IP standard access list (expanded range)\n"
        !          1384:        "IP extended access list (expanded range)\n"
        !          1385:        "IP zebra access-list\n"
        !          1386:        "Access list entry comment\n")
        !          1387: {
        !          1388:   return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
        !          1389: }
        !          1390:        
        !          1391: ALIAS (no_access_list_remark,
        !          1392:        no_access_list_remark_arg_cmd,
        !          1393:        "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
        !          1394:        NO_STR
        !          1395:        "Add an access list entry\n"
        !          1396:        "IP standard access list\n"
        !          1397:        "IP extended access list\n"
        !          1398:        "IP standard access list (expanded range)\n"
        !          1399:        "IP extended access list (expanded range)\n"
        !          1400:        "IP zebra access-list\n"
        !          1401:        "Access list entry comment\n"
        !          1402:        "Comment up to 100 characters\n")
        !          1403: 
        !          1404: #ifdef HAVE_IPV6
        !          1405: DEFUN (ipv6_access_list,
        !          1406:        ipv6_access_list_cmd,
        !          1407:        "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
        !          1408:        IPV6_STR
        !          1409:        "Add an access list entry\n"
        !          1410:        "IPv6 zebra access-list\n"
        !          1411:        "Specify packets to reject\n"
        !          1412:        "Specify packets to forward\n"
        !          1413:        "Prefix to match. e.g. 3ffe:506::/32\n")
        !          1414: {
        !          1415:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
        !          1416: }
        !          1417: 
        !          1418: DEFUN (ipv6_access_list_exact,
        !          1419:        ipv6_access_list_exact_cmd,
        !          1420:        "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
        !          1421:        IPV6_STR
        !          1422:        "Add an access list entry\n"
        !          1423:        "IPv6 zebra access-list\n"
        !          1424:        "Specify packets to reject\n"
        !          1425:        "Specify packets to forward\n"
        !          1426:        "Prefix to match. e.g. 3ffe:506::/32\n"
        !          1427:        "Exact match of the prefixes\n")
        !          1428: {
        !          1429:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
        !          1430: }
        !          1431: 
        !          1432: DEFUN (ipv6_access_list_any,
        !          1433:        ipv6_access_list_any_cmd,
        !          1434:        "ipv6 access-list WORD (deny|permit) any",
        !          1435:        IPV6_STR
        !          1436:        "Add an access list entry\n"
        !          1437:        "IPv6 zebra access-list\n"
        !          1438:        "Specify packets to reject\n"
        !          1439:        "Specify packets to forward\n"
        !          1440:        "Any prefixi to match\n")
        !          1441: {
        !          1442:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
        !          1443: }
        !          1444: 
        !          1445: DEFUN (no_ipv6_access_list,
        !          1446:        no_ipv6_access_list_cmd,
        !          1447:        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
        !          1448:        NO_STR
        !          1449:        IPV6_STR
        !          1450:        "Add an access list entry\n"
        !          1451:        "IPv6 zebra access-list\n"
        !          1452:        "Specify packets to reject\n"
        !          1453:        "Specify packets to forward\n"
        !          1454:        "Prefix to match. e.g. 3ffe:506::/32\n")
        !          1455: {
        !          1456:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
        !          1457: }
        !          1458: 
        !          1459: DEFUN (no_ipv6_access_list_exact,
        !          1460:        no_ipv6_access_list_exact_cmd,
        !          1461:        "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
        !          1462:        NO_STR
        !          1463:        IPV6_STR
        !          1464:        "Add an access list entry\n"
        !          1465:        "IPv6 zebra access-list\n"
        !          1466:        "Specify packets to reject\n"
        !          1467:        "Specify packets to forward\n"
        !          1468:        "Prefix to match. e.g. 3ffe:506::/32\n"
        !          1469:        "Exact match of the prefixes\n")
        !          1470: {
        !          1471:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
        !          1472: }
        !          1473: 
        !          1474: DEFUN (no_ipv6_access_list_any,
        !          1475:        no_ipv6_access_list_any_cmd,
        !          1476:        "no ipv6 access-list WORD (deny|permit) any",
        !          1477:        NO_STR
        !          1478:        IPV6_STR
        !          1479:        "Add an access list entry\n"
        !          1480:        "IPv6 zebra access-list\n"
        !          1481:        "Specify packets to reject\n"
        !          1482:        "Specify packets to forward\n"
        !          1483:        "Any prefixi to match\n")
        !          1484: {
        !          1485:   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
        !          1486: }
        !          1487: 
        !          1488: 
        !          1489: DEFUN (no_ipv6_access_list_all,
        !          1490:        no_ipv6_access_list_all_cmd,
        !          1491:        "no ipv6 access-list WORD",
        !          1492:        NO_STR
        !          1493:        IPV6_STR
        !          1494:        "Add an access list entry\n"
        !          1495:        "IPv6 zebra access-list\n")
        !          1496: {
        !          1497:   struct access_list *access;
        !          1498:   struct access_master *master;
        !          1499: 
        !          1500:   /* Looking up access_list. */
        !          1501:   access = access_list_lookup (AFI_IP6, argv[0]);
        !          1502:   if (access == NULL)
        !          1503:     {
        !          1504:       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
        !          1505:               VTY_NEWLINE);
        !          1506:       return CMD_WARNING;
        !          1507:     }
        !          1508: 
        !          1509:   master = access->master;
        !          1510: 
        !          1511:   /* Delete all filter from access-list. */
        !          1512:   access_list_delete (access);
        !          1513: 
        !          1514:   /* Run hook function. */
        !          1515:   if (master->delete_hook)
        !          1516:     (*master->delete_hook) (access);
        !          1517: 
        !          1518:   return CMD_SUCCESS;
        !          1519: }
        !          1520: 
        !          1521: DEFUN (ipv6_access_list_remark,
        !          1522:        ipv6_access_list_remark_cmd,
        !          1523:        "ipv6 access-list WORD remark .LINE",
        !          1524:        IPV6_STR
        !          1525:        "Add an access list entry\n"
        !          1526:        "IPv6 zebra access-list\n"
        !          1527:        "Access list entry comment\n"
        !          1528:        "Comment up to 100 characters\n")
        !          1529: {
        !          1530:   struct access_list *access;
        !          1531: 
        !          1532:   access = access_list_get (AFI_IP6, argv[0]);
        !          1533: 
        !          1534:   if (access->remark)
        !          1535:     {
        !          1536:       XFREE (MTYPE_TMP, access->remark);
        !          1537:       access->remark = NULL;
        !          1538:     }
        !          1539:   access->remark = argv_concat(argv, argc, 1);
        !          1540: 
        !          1541:   return CMD_SUCCESS;
        !          1542: }
        !          1543: 
        !          1544: DEFUN (no_ipv6_access_list_remark,
        !          1545:        no_ipv6_access_list_remark_cmd,
        !          1546:        "no ipv6 access-list WORD remark",
        !          1547:        NO_STR
        !          1548:        IPV6_STR
        !          1549:        "Add an access list entry\n"
        !          1550:        "IPv6 zebra access-list\n"
        !          1551:        "Access list entry comment\n")
        !          1552: {
        !          1553:   return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
        !          1554: }
        !          1555:        
        !          1556: ALIAS (no_ipv6_access_list_remark,
        !          1557:        no_ipv6_access_list_remark_arg_cmd,
        !          1558:        "no ipv6 access-list WORD remark .LINE",
        !          1559:        NO_STR
        !          1560:        IPV6_STR
        !          1561:        "Add an access list entry\n"
        !          1562:        "IPv6 zebra access-list\n"
        !          1563:        "Access list entry comment\n"
        !          1564:        "Comment up to 100 characters\n")
        !          1565: #endif /* HAVE_IPV6 */
        !          1566: 
        !          1567: void config_write_access_zebra (struct vty *, struct filter *);
        !          1568: void config_write_access_cisco (struct vty *, struct filter *);
        !          1569: 
        !          1570: /* show access-list command. */
        !          1571: static int
        !          1572: filter_show (struct vty *vty, const char *name, afi_t afi)
        !          1573: {
        !          1574:   struct access_list *access;
        !          1575:   struct access_master *master;
        !          1576:   struct filter *mfilter;
        !          1577:   struct filter_cisco *filter;
        !          1578:   int write = 0;
        !          1579: 
        !          1580:   master = access_master_get (afi);
        !          1581:   if (master == NULL)
        !          1582:     return 0;
        !          1583: 
        !          1584:   /* Print the name of the protocol */
        !          1585:   if (zlog_default)
        !          1586:       vty_out (vty, "%s:%s",
        !          1587:       zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
        !          1588: 
        !          1589:   for (access = master->num.head; access; access = access->next)
        !          1590:     {
        !          1591:       if (name && strcmp (access->name, name) != 0)
        !          1592:        continue;
        !          1593: 
        !          1594:       write = 1;
        !          1595: 
        !          1596:       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !          1597:        {
        !          1598:          filter = &mfilter->u.cfilter;
        !          1599: 
        !          1600:          if (write)
        !          1601:            {
        !          1602:              vty_out (vty, "%s IP%s access list %s%s",
        !          1603:                       mfilter->cisco ? 
        !          1604:                       (filter->extended ? "Extended" : "Standard") : "Zebra",
        !          1605:                       afi == AFI_IP6 ? "v6" : "",
        !          1606:                       access->name, VTY_NEWLINE);
        !          1607:              write = 0;
        !          1608:            }
        !          1609: 
        !          1610:          vty_out (vty, "    %s%s", filter_type_str (mfilter),
        !          1611:                   mfilter->type == FILTER_DENY ? "  " : "");
        !          1612: 
        !          1613:          if (! mfilter->cisco)
        !          1614:            config_write_access_zebra (vty, mfilter);
        !          1615:          else if (filter->extended)
        !          1616:            config_write_access_cisco (vty, mfilter);
        !          1617:          else
        !          1618:            {
        !          1619:              if (filter->addr_mask.s_addr == 0xffffffff)
        !          1620:                vty_out (vty, " any%s", VTY_NEWLINE);
        !          1621:              else
        !          1622:                {
        !          1623:                  vty_out (vty, " %s", inet_ntoa (filter->addr));
        !          1624:                  if (filter->addr_mask.s_addr != 0)
        !          1625:                    vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
        !          1626:                  vty_out (vty, "%s", VTY_NEWLINE);
        !          1627:                }
        !          1628:            }
        !          1629:        }
        !          1630:     }
        !          1631: 
        !          1632:   for (access = master->str.head; access; access = access->next)
        !          1633:     {
        !          1634:       if (name && strcmp (access->name, name) != 0)
        !          1635:        continue;
        !          1636: 
        !          1637:       write = 1;
        !          1638: 
        !          1639:       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !          1640:        {
        !          1641:          filter = &mfilter->u.cfilter;
        !          1642: 
        !          1643:          if (write)
        !          1644:            {
        !          1645:              vty_out (vty, "%s IP%s access list %s%s",
        !          1646:                       mfilter->cisco ? 
        !          1647:                       (filter->extended ? "Extended" : "Standard") : "Zebra",
        !          1648:                       afi == AFI_IP6 ? "v6" : "",
        !          1649:                       access->name, VTY_NEWLINE);
        !          1650:              write = 0;
        !          1651:            }
        !          1652: 
        !          1653:          vty_out (vty, "    %s%s", filter_type_str (mfilter),
        !          1654:                   mfilter->type == FILTER_DENY ? "  " : "");
        !          1655: 
        !          1656:          if (! mfilter->cisco)
        !          1657:            config_write_access_zebra (vty, mfilter);
        !          1658:          else if (filter->extended)
        !          1659:            config_write_access_cisco (vty, mfilter);
        !          1660:          else
        !          1661:            {
        !          1662:              if (filter->addr_mask.s_addr == 0xffffffff)
        !          1663:                vty_out (vty, " any%s", VTY_NEWLINE);
        !          1664:              else
        !          1665:                {
        !          1666:                  vty_out (vty, " %s", inet_ntoa (filter->addr));
        !          1667:                  if (filter->addr_mask.s_addr != 0)
        !          1668:                    vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
        !          1669:                  vty_out (vty, "%s", VTY_NEWLINE);
        !          1670:                }
        !          1671:            }
        !          1672:        }
        !          1673:     }
        !          1674:   return CMD_SUCCESS;
        !          1675: }
        !          1676: 
        !          1677: DEFUN (show_ip_access_list,
        !          1678:        show_ip_access_list_cmd,
        !          1679:        "show ip access-list",
        !          1680:        SHOW_STR
        !          1681:        IP_STR
        !          1682:        "List IP access lists\n")
        !          1683: {
        !          1684:   return filter_show (vty, NULL, AFI_IP);
        !          1685: }
        !          1686: 
        !          1687: DEFUN (show_ip_access_list_name,
        !          1688:        show_ip_access_list_name_cmd,
        !          1689:        "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
        !          1690:        SHOW_STR
        !          1691:        IP_STR
        !          1692:        "List IP access lists\n"
        !          1693:        "IP standard access list\n"
        !          1694:        "IP extended access list\n"
        !          1695:        "IP standard access list (expanded range)\n"
        !          1696:        "IP extended access list (expanded range)\n"
        !          1697:        "IP zebra access-list\n")
        !          1698: {
        !          1699:   return filter_show (vty, argv[0], AFI_IP);
        !          1700: }
        !          1701: 
        !          1702: #ifdef HAVE_IPV6
        !          1703: DEFUN (show_ipv6_access_list,
        !          1704:        show_ipv6_access_list_cmd,
        !          1705:        "show ipv6 access-list",
        !          1706:        SHOW_STR
        !          1707:        IPV6_STR
        !          1708:        "List IPv6 access lists\n")
        !          1709: {
        !          1710:   return filter_show (vty, NULL, AFI_IP6);
        !          1711: }
        !          1712: 
        !          1713: DEFUN (show_ipv6_access_list_name,
        !          1714:        show_ipv6_access_list_name_cmd,
        !          1715:        "show ipv6 access-list WORD",
        !          1716:        SHOW_STR
        !          1717:        IPV6_STR
        !          1718:        "List IPv6 access lists\n"
        !          1719:        "IPv6 zebra access-list\n")
        !          1720: {
        !          1721:   return filter_show (vty, argv[0], AFI_IP6);
        !          1722: }
        !          1723: #endif /* HAVE_IPV6 */
        !          1724: 
        !          1725: void
        !          1726: config_write_access_cisco (struct vty *vty, struct filter *mfilter)
        !          1727: {
        !          1728:   struct filter_cisco *filter;
        !          1729: 
        !          1730:   filter = &mfilter->u.cfilter;
        !          1731: 
        !          1732:   if (filter->extended)
        !          1733:     {
        !          1734:       vty_out (vty, " ip");
        !          1735:       if (filter->addr_mask.s_addr == 0xffffffff)
        !          1736:        vty_out (vty, " any");
        !          1737:       else if (filter->addr_mask.s_addr == 0)
        !          1738:        vty_out (vty, " host %s", inet_ntoa (filter->addr));
        !          1739:       else
        !          1740:        {
        !          1741:          vty_out (vty, " %s", inet_ntoa (filter->addr));
        !          1742:          vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
        !          1743:         }
        !          1744: 
        !          1745:       if (filter->mask_mask.s_addr == 0xffffffff)
        !          1746:        vty_out (vty, " any");
        !          1747:       else if (filter->mask_mask.s_addr == 0)
        !          1748:        vty_out (vty, " host %s", inet_ntoa (filter->mask));
        !          1749:       else
        !          1750:        {
        !          1751:          vty_out (vty, " %s", inet_ntoa (filter->mask));
        !          1752:          vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
        !          1753:        }
        !          1754:       vty_out (vty, "%s", VTY_NEWLINE);
        !          1755:     }
        !          1756:   else
        !          1757:     {
        !          1758:       if (filter->addr_mask.s_addr == 0xffffffff)
        !          1759:        vty_out (vty, " any%s", VTY_NEWLINE);
        !          1760:       else
        !          1761:        {
        !          1762:          vty_out (vty, " %s", inet_ntoa (filter->addr));
        !          1763:          if (filter->addr_mask.s_addr != 0)
        !          1764:            vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
        !          1765:          vty_out (vty, "%s", VTY_NEWLINE);
        !          1766:        }
        !          1767:     }
        !          1768: }
        !          1769: 
        !          1770: void
        !          1771: config_write_access_zebra (struct vty *vty, struct filter *mfilter)
        !          1772: {
        !          1773:   struct filter_zebra *filter;
        !          1774:   struct prefix *p;
        !          1775:   char buf[BUFSIZ];
        !          1776: 
        !          1777:   filter = &mfilter->u.zfilter;
        !          1778:   p = &filter->prefix;
        !          1779: 
        !          1780:   if (p->prefixlen == 0 && ! filter->exact)
        !          1781:     vty_out (vty, " any");
        !          1782:   else
        !          1783:     vty_out (vty, " %s/%d%s",
        !          1784:             inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
        !          1785:             p->prefixlen,
        !          1786:             filter->exact ? " exact-match" : "");
        !          1787: 
        !          1788:   vty_out (vty, "%s", VTY_NEWLINE);
        !          1789: }
        !          1790: 
        !          1791: static int
        !          1792: config_write_access (struct vty *vty, afi_t afi)
        !          1793: {
        !          1794:   struct access_list *access;
        !          1795:   struct access_master *master;
        !          1796:   struct filter *mfilter;
        !          1797:   int write = 0;
        !          1798: 
        !          1799:   master = access_master_get (afi);
        !          1800:   if (master == NULL)
        !          1801:     return 0;
        !          1802: 
        !          1803:   for (access = master->num.head; access; access = access->next)
        !          1804:     {
        !          1805:       if (access->remark)
        !          1806:        {
        !          1807:          vty_out (vty, "%saccess-list %s remark %s%s",
        !          1808:                   afi == AFI_IP ? "" : "ipv6 ",
        !          1809:                   access->name, access->remark,
        !          1810:                   VTY_NEWLINE);
        !          1811:          write++;
        !          1812:        }
        !          1813: 
        !          1814:       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !          1815:        {
        !          1816:          vty_out (vty, "%saccess-list %s %s",
        !          1817:             afi == AFI_IP ? "" : "ipv6 ",
        !          1818:             access->name,
        !          1819:             filter_type_str (mfilter));
        !          1820: 
        !          1821:          if (mfilter->cisco)
        !          1822:            config_write_access_cisco (vty, mfilter);
        !          1823:          else
        !          1824:            config_write_access_zebra (vty, mfilter);
        !          1825: 
        !          1826:          write++;
        !          1827:        }
        !          1828:     }
        !          1829: 
        !          1830:   for (access = master->str.head; access; access = access->next)
        !          1831:     {
        !          1832:       if (access->remark)
        !          1833:        {
        !          1834:          vty_out (vty, "%saccess-list %s remark %s%s",
        !          1835:                   afi == AFI_IP ? "" : "ipv6 ",
        !          1836:                   access->name, access->remark,
        !          1837:                   VTY_NEWLINE);
        !          1838:          write++;
        !          1839:        }
        !          1840: 
        !          1841:       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
        !          1842:        {
        !          1843:          vty_out (vty, "%saccess-list %s %s",
        !          1844:             afi == AFI_IP ? "" : "ipv6 ",
        !          1845:             access->name,
        !          1846:             filter_type_str (mfilter));
        !          1847: 
        !          1848:          if (mfilter->cisco)
        !          1849:            config_write_access_cisco (vty, mfilter);
        !          1850:          else
        !          1851:            config_write_access_zebra (vty, mfilter);
        !          1852: 
        !          1853:          write++;
        !          1854:        }
        !          1855:     }
        !          1856:   return write;
        !          1857: }
        !          1858: 
        !          1859: /* Access-list node. */
        !          1860: static struct cmd_node access_node =
        !          1861: {
        !          1862:   ACCESS_NODE,
        !          1863:   "",                          /* Access list has no interface. */
        !          1864:   1
        !          1865: };
        !          1866: 
        !          1867: static int
        !          1868: config_write_access_ipv4 (struct vty *vty)
        !          1869: {
        !          1870:   return config_write_access (vty, AFI_IP);
        !          1871: }
        !          1872: 
        !          1873: static void
        !          1874: access_list_reset_ipv4 (void)
        !          1875: {
        !          1876:   struct access_list *access;
        !          1877:   struct access_list *next;
        !          1878:   struct access_master *master;
        !          1879: 
        !          1880:   master = access_master_get (AFI_IP);
        !          1881:   if (master == NULL)
        !          1882:     return;
        !          1883: 
        !          1884:   for (access = master->num.head; access; access = next)
        !          1885:     {
        !          1886:       next = access->next;
        !          1887:       access_list_delete (access);
        !          1888:     }
        !          1889:   for (access = master->str.head; access; access = next)
        !          1890:     {
        !          1891:       next = access->next;
        !          1892:       access_list_delete (access);
        !          1893:     }
        !          1894: 
        !          1895:   assert (master->num.head == NULL);
        !          1896:   assert (master->num.tail == NULL);
        !          1897: 
        !          1898:   assert (master->str.head == NULL);
        !          1899:   assert (master->str.tail == NULL);
        !          1900: }
        !          1901: 
        !          1902: /* Install vty related command. */
        !          1903: static void
        !          1904: access_list_init_ipv4 (void)
        !          1905: {
        !          1906:   install_node (&access_node, config_write_access_ipv4);
        !          1907: 
        !          1908:   install_element (ENABLE_NODE, &show_ip_access_list_cmd);
        !          1909:   install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
        !          1910: 
        !          1911:   /* Zebra access-list */
        !          1912:   install_element (CONFIG_NODE, &access_list_cmd);
        !          1913:   install_element (CONFIG_NODE, &access_list_exact_cmd);
        !          1914:   install_element (CONFIG_NODE, &access_list_any_cmd);
        !          1915:   install_element (CONFIG_NODE, &no_access_list_cmd);
        !          1916:   install_element (CONFIG_NODE, &no_access_list_exact_cmd);
        !          1917:   install_element (CONFIG_NODE, &no_access_list_any_cmd);
        !          1918: 
        !          1919:   /* Standard access-list */
        !          1920:   install_element (CONFIG_NODE, &access_list_standard_cmd);
        !          1921:   install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
        !          1922:   install_element (CONFIG_NODE, &access_list_standard_host_cmd);
        !          1923:   install_element (CONFIG_NODE, &access_list_standard_any_cmd);
        !          1924:   install_element (CONFIG_NODE, &no_access_list_standard_cmd);
        !          1925:   install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
        !          1926:   install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
        !          1927:   install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
        !          1928: 
        !          1929:   /* Extended access-list */
        !          1930:   install_element (CONFIG_NODE, &access_list_extended_cmd);
        !          1931:   install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
        !          1932:   install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
        !          1933:   install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
        !          1934:   install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
        !          1935:   install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
        !          1936:   install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
        !          1937:   install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
        !          1938:   install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
        !          1939:   install_element (CONFIG_NODE, &no_access_list_extended_cmd);
        !          1940:   install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
        !          1941:   install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
        !          1942:   install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
        !          1943:   install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
        !          1944:   install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
        !          1945:   install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
        !          1946:   install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
        !          1947:   install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
        !          1948: 
        !          1949:   install_element (CONFIG_NODE, &access_list_remark_cmd);
        !          1950:   install_element (CONFIG_NODE, &no_access_list_all_cmd);
        !          1951:   install_element (CONFIG_NODE, &no_access_list_remark_cmd);
        !          1952:   install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
        !          1953: }
        !          1954: 
        !          1955: #ifdef HAVE_IPV6
        !          1956: static struct cmd_node access_ipv6_node =
        !          1957: {
        !          1958:   ACCESS_IPV6_NODE,
        !          1959:   "",
        !          1960:   1
        !          1961: };
        !          1962: 
        !          1963: static int
        !          1964: config_write_access_ipv6 (struct vty *vty)
        !          1965: {
        !          1966:   return config_write_access (vty, AFI_IP6);
        !          1967: }
        !          1968: 
        !          1969: static void
        !          1970: access_list_reset_ipv6 (void)
        !          1971: {
        !          1972:   struct access_list *access;
        !          1973:   struct access_list *next;
        !          1974:   struct access_master *master;
        !          1975: 
        !          1976:   master = access_master_get (AFI_IP6);
        !          1977:   if (master == NULL)
        !          1978:     return;
        !          1979: 
        !          1980:   for (access = master->num.head; access; access = next)
        !          1981:     {
        !          1982:       next = access->next;
        !          1983:       access_list_delete (access);
        !          1984:     }
        !          1985:   for (access = master->str.head; access; access = next)
        !          1986:     {
        !          1987:       next = access->next;
        !          1988:       access_list_delete (access);
        !          1989:     }
        !          1990: 
        !          1991:   assert (master->num.head == NULL);
        !          1992:   assert (master->num.tail == NULL);
        !          1993: 
        !          1994:   assert (master->str.head == NULL);
        !          1995:   assert (master->str.tail == NULL);
        !          1996: }
        !          1997: 
        !          1998: static void
        !          1999: access_list_init_ipv6 (void)
        !          2000: {
        !          2001:   install_node (&access_ipv6_node, config_write_access_ipv6);
        !          2002: 
        !          2003:   install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
        !          2004:   install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
        !          2005: 
        !          2006:   install_element (CONFIG_NODE, &ipv6_access_list_cmd);
        !          2007:   install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
        !          2008:   install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
        !          2009:   install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
        !          2010:   install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
        !          2011:   install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
        !          2012: 
        !          2013:   install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
        !          2014:   install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
        !          2015:   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
        !          2016:   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
        !          2017: }
        !          2018: #endif /* HAVE_IPV6 */
        !          2019: 
        !          2020: void
        !          2021: access_list_init ()
        !          2022: {
        !          2023:   access_list_init_ipv4 ();
        !          2024: #ifdef HAVE_IPV6
        !          2025:   access_list_init_ipv6();
        !          2026: #endif /* HAVE_IPV6 */
        !          2027: }
        !          2028: 
        !          2029: void
        !          2030: access_list_reset ()
        !          2031: {
        !          2032:   access_list_reset_ipv4 ();
        !          2033: #ifdef HAVE_IPV6
        !          2034:   access_list_reset_ipv6();
        !          2035: #endif /* HAVE_IPV6 */
        !          2036: }

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