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

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 */
1.1.1.3 ! misho     113: 
1.1       misho     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: }
1.1.1.3 ! misho     211: 
1.1       misho     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:   /* Run hook function. */
                    497:   if (master->delete_hook)
                    498:     (*master->delete_hook) (access);
1.1.1.3 ! misho     499: 
        !           500:   /* If access_list becomes empty delete it from access_master. */
        !           501:   if (access_list_empty (access))
        !           502:     access_list_delete (access);
1.1       misho     503: }
1.1.1.3 ! misho     504: 
1.1       misho     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:   /* Run hook function. */
                   1341:   if (master->delete_hook)
                   1342:     (*master->delete_hook) (access);
                   1343:  
1.1.1.2   misho    1344:   /* Delete all filter from access-list. */
                   1345:   access_list_delete (access);
                   1346: 
1.1       misho    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:   /* Run hook function. */
                   1512:   if (master->delete_hook)
                   1513:     (*master->delete_hook) (access);
                   1514: 
1.1.1.2   misho    1515:   /* Delete all filter from access-list. */
                   1516:   access_list_delete (access);
                   1517: 
1.1       misho    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>