LCOV - code coverage report
Current view: top level - lib - filter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 154 648 23.8 %
Date: 2015-11-19 Functions: 16 83 19.3 %

          Line data    Source code
       1             : /* Route filtering function.
       2             :  * Copyright (C) 1998, 1999 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published
       8             :  * by the Free Software Foundation; either version 2, or (at your
       9             :  * option) any later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with GNU Zebra; see the file COPYING.  If not, write to the
      18             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      19             :  * Boston, MA 02111-1307, USA.
      20             :  */
      21             : 
      22             : #include <zebra.h>
      23             : 
      24             : #include "prefix.h"
      25             : #include "filter.h"
      26             : #include "memory.h"
      27             : #include "command.h"
      28             : #include "sockunion.h"
      29             : #include "buffer.h"
      30             : #include "log.h"
      31             : 
      32             : struct filter_cisco
      33             : {
      34             :   /* Cisco access-list */
      35             :   int extended;
      36             :   struct in_addr addr;
      37             :   struct in_addr addr_mask;
      38             :   struct in_addr mask;
      39             :   struct in_addr mask_mask;
      40             : };
      41             : 
      42             : struct filter_zebra
      43             : {
      44             :   /* If this filter is "exact" match then this flag is set. */
      45             :   int exact;
      46             : 
      47             :   /* Prefix information. */
      48             :   struct prefix prefix;
      49             : };
      50             : 
      51             : /* Filter element of access list */
      52             : struct filter
      53             : {
      54             :   /* For doubly linked list. */
      55             :   struct filter *next;
      56             :   struct filter *prev;
      57             : 
      58             :   /* Filter type information. */
      59             :   enum filter_type type;
      60             : 
      61             :   /* Cisco access-list */
      62             :   int cisco;
      63             : 
      64             :   union
      65             :     {
      66             :       struct filter_cisco cfilter;
      67             :       struct filter_zebra zfilter;
      68             :     } u;
      69             : };
      70             : 
      71             : /* List of access_list. */
      72             : struct access_list_list
      73             : {
      74             :   struct access_list *head;
      75             :   struct access_list *tail;
      76             : };
      77             : 
      78             : /* Master structure of access_list. */
      79             : struct access_master
      80             : {
      81             :   /* List of access_list which name is number. */
      82             :   struct access_list_list num;
      83             : 
      84             :   /* List of access_list which name is string. */
      85             :   struct access_list_list str;
      86             : 
      87             :   /* Hook function which is executed when new access_list is added. */
      88             :   void (*add_hook) (struct access_list *);
      89             : 
      90             :   /* Hook function which is executed when access_list is deleted. */
      91             :   void (*delete_hook) (struct access_list *);
      92             : };
      93             : 
      94             : /* Static structure for IPv4 access_list's master. */
      95             : static struct access_master access_master_ipv4 = 
      96             : { 
      97             :   {NULL, NULL},
      98             :   {NULL, NULL},
      99             :   NULL,
     100             :   NULL,
     101             : };
     102             : 
     103             : #ifdef HAVE_IPV6
     104             : /* Static structure for IPv6 access_list's master. */
     105             : static struct access_master access_master_ipv6 = 
     106             : { 
     107             :   {NULL, NULL},
     108             :   {NULL, NULL},
     109             :   NULL,
     110             :   NULL,
     111             : };
     112             : #endif /* HAVE_IPV6 */
     113             : 
     114             : static struct access_master *
     115          16 : access_master_get (afi_t afi)
     116             : {
     117          16 :   if (afi == AFI_IP)
     118          16 :     return &access_master_ipv4;
     119             : #ifdef HAVE_IPV6
     120           0 :   else if (afi == AFI_IP6)
     121           0 :     return &access_master_ipv6;
     122             : #endif /* HAVE_IPV6 */
     123           0 :   return NULL;
     124             : }
     125             : 
     126             : /* Allocate new filter structure. */
     127             : static struct filter *
     128           4 : filter_new (void)
     129             : {
     130           4 :   return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
     131             :                                     sizeof (struct filter));
     132             : }
     133             : 
     134             : static void
     135           0 : filter_free (struct filter *filter)
     136             : {
     137           0 :   XFREE (MTYPE_ACCESS_FILTER, filter);
     138           0 : }
     139             : 
     140             : /* Return string of filter_type. */
     141             : static const char *
     142           0 : filter_type_str (struct filter *filter)
     143             : {
     144           0 :   switch (filter->type)
     145             :     {
     146             :     case FILTER_PERMIT:
     147           0 :       return "permit";
     148             :       break;
     149             :     case FILTER_DENY:
     150           0 :       return "deny";
     151             :       break;
     152             :     case FILTER_DYNAMIC:
     153           0 :       return "dynamic";
     154             :       break;
     155             :     default:
     156           0 :       return "";
     157             :       break;
     158             :     }
     159             : }
     160             : 
     161             : /* If filter match to the prefix then return 1. */
     162             : static int
     163          14 : 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          14 :   filter = &mfilter->u.cfilter;
     171          14 :   check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
     172             : 
     173          14 :   if (filter->extended)
     174             :     {
     175           0 :       masklen2ip (p->prefixlen, &mask);
     176           0 :       check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
     177             : 
     178           0 :       if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
     179           0 :           && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
     180           0 :         return 1;
     181             :     }
     182          14 :   else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
     183          10 :     return 1;
     184             : 
     185           4 :   return 0;
     186             : }
     187             : 
     188             : /* If filter match to the prefix then return 1. */
     189             : static int
     190           0 : filter_match_zebra (struct filter *mfilter, struct prefix *p)
     191             : {
     192             :   struct filter_zebra *filter;
     193             : 
     194           0 :   filter = &mfilter->u.zfilter;
     195             : 
     196           0 :   if (filter->prefix.family == p->family)
     197             :     {
     198           0 :       if (filter->exact)
     199             :         {
     200           0 :           if (filter->prefix.prefixlen == p->prefixlen)
     201           0 :             return prefix_match (&filter->prefix, p);
     202             :           else
     203           0 :             return 0;
     204             :         }
     205             :       else
     206           0 :         return prefix_match (&filter->prefix, p);
     207             :     }
     208             :   else
     209           0 :     return 0;
     210             : }
     211             : 
     212             : /* Allocate new access list structure. */
     213             : static struct access_list *
     214           2 : access_list_new (void)
     215             : {
     216           2 :   return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
     217             :                                          sizeof (struct access_list));
     218             : }
     219             : 
     220             : /* Free allocated access_list. */
     221             : static void
     222           0 : access_list_free (struct access_list *access)
     223             : {
     224           0 :   XFREE (MTYPE_ACCESS_LIST, access);
     225           0 : }
     226             : 
     227             : /* Delete access_list from access_master and free it. */
     228             : static void
     229           0 : 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           0 :   for (filter = access->head; filter; filter = next)
     237             :     {
     238           0 :       next = filter->next;
     239           0 :       filter_free (filter);
     240             :     }
     241             : 
     242           0 :   master = access->master;
     243             : 
     244           0 :   if (access->type == ACCESS_TYPE_NUMBER)
     245           0 :     list = &master->num;
     246             :   else
     247           0 :     list = &master->str;
     248             : 
     249           0 :   if (access->next)
     250           0 :     access->next->prev = access->prev;
     251             :   else
     252           0 :     list->tail = access->prev;
     253             : 
     254           0 :   if (access->prev)
     255           0 :     access->prev->next = access->next;
     256             :   else
     257           0 :     list->head = access->next;
     258             : 
     259           0 :   if (access->name)
     260           0 :     XFREE (MTYPE_ACCESS_LIST_STR, access->name);
     261             : 
     262           0 :   if (access->remark)
     263           0 :     XFREE (MTYPE_TMP, access->remark);
     264             : 
     265           0 :   access_list_free (access);
     266           0 : }
     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           2 : 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           2 :   master = access_master_get (afi);
     281           2 :   if (master == NULL)
     282           0 :     return NULL;
     283             : 
     284             :   /* Allocate new access_list and copy given name. */
     285           2 :   access = access_list_new ();
     286           2 :   access->name = XSTRDUP (MTYPE_ACCESS_LIST_STR, name);
     287           2 :   access->master = master;
     288             : 
     289             :   /* If name is made by all digit character.  We treat it as
     290             :      number. */
     291           6 :   for (number = 0, i = 0; i < strlen (name); i++)
     292             :     {
     293           4 :       if (isdigit ((int) name[i]))
     294           4 :         number = (number * 10) + (name[i] - '0');
     295             :       else
     296           0 :         break;
     297             :     }
     298             : 
     299             :   /* In case of name is all digit character */
     300           2 :   if (i == strlen (name))
     301             :     {
     302           2 :       access->type = ACCESS_TYPE_NUMBER;
     303             : 
     304             :       /* Set access_list to number list. */
     305           2 :       alist = &master->num;
     306             : 
     307           2 :       for (point = alist->head; point; point = point->next)
     308           0 :         if (atol (point->name) >= number)
     309           0 :           break;
     310             :     }
     311             :   else
     312             :     {
     313           0 :       access->type = ACCESS_TYPE_STRING;
     314             : 
     315             :       /* Set access_list to string list. */
     316           0 :       alist = &master->str;
     317             :   
     318             :       /* Set point to insertion point. */
     319           0 :       for (point = alist->head; point; point = point->next)
     320           0 :         if (strcmp (point->name, name) >= 0)
     321           0 :           break;
     322             :     }
     323             : 
     324             :   /* In case of this is the first element of master. */
     325           2 :   if (alist->head == NULL)
     326             :     {
     327           2 :       alist->head = alist->tail = access;
     328           2 :       return access;
     329             :     }
     330             : 
     331             :   /* In case of insertion is made at the tail of access_list. */
     332           0 :   if (point == NULL)
     333             :     {
     334           0 :       access->prev = alist->tail;
     335           0 :       alist->tail->next = access;
     336           0 :       alist->tail = access;
     337           0 :       return access;
     338             :     }
     339             : 
     340             :   /* In case of insertion is made at the head of access_list. */
     341           0 :   if (point == alist->head)
     342             :     {
     343           0 :       access->next = alist->head;
     344           0 :       alist->head->prev = access;
     345           0 :       alist->head = access;
     346           0 :       return access;
     347             :     }
     348             : 
     349             :   /* Insertion is made at middle of the access_list. */
     350           0 :   access->next = point;
     351           0 :   access->prev = point->prev;
     352             : 
     353           0 :   if (point->prev)
     354           0 :     point->prev->next = access;
     355           0 :   point->prev = access;
     356             : 
     357           0 :   return access;
     358             : }
     359             : 
     360             : /* Lookup access_list from list of access_list by name. */
     361             : struct access_list *
     362          14 : access_list_lookup (afi_t afi, const char *name)
     363             : {
     364             :   struct access_list *access;
     365             :   struct access_master *master;
     366             : 
     367          14 :   if (name == NULL)
     368           0 :     return NULL;
     369             : 
     370          14 :   master = access_master_get (afi);
     371          14 :   if (master == NULL)
     372           0 :     return NULL;
     373             : 
     374          14 :   for (access = master->num.head; access; access = access->next)
     375          12 :     if (strcmp (access->name, name) == 0)
     376          12 :       return access;
     377             : 
     378           2 :   for (access = master->str.head; access; access = access->next)
     379           0 :     if (strcmp (access->name, name) == 0)
     380           0 :       return access;
     381             : 
     382           2 :   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           4 : access_list_get (afi_t afi, const char *name)
     389             : {
     390             :   struct access_list *access;
     391             : 
     392           4 :   access = access_list_lookup (afi, name);
     393           4 :   if (access == NULL)
     394           2 :     access = access_list_insert (afi, name);
     395           4 :   return access;
     396             : }
     397             : 
     398             : /* Apply access list to object (which should be struct prefix *). */
     399             : enum filter_type
     400          10 : access_list_apply (struct access_list *access, void *object)
     401             : {
     402             :   struct filter *filter;
     403             :   struct prefix *p;
     404             : 
     405          10 :   p = (struct prefix *) object;
     406             : 
     407          10 :   if (access == NULL)
     408           0 :     return FILTER_DENY;
     409             : 
     410          14 :   for (filter = access->head; filter; filter = filter->next)
     411             :     {
     412          14 :       if (filter->cisco)
     413             :         {
     414          14 :           if (filter_match_cisco (filter, p))
     415          10 :             return filter->type;
     416             :         }
     417             :       else
     418             :         {
     419           0 :           if (filter_match_zebra (filter, p))
     420           0 :             return filter->type;
     421             :         }
     422             :     }
     423             : 
     424           0 :   return FILTER_DENY;
     425             : }
     426             : 
     427             : /* Add hook function. */
     428             : void
     429           0 : access_list_add_hook (void (*func) (struct access_list *access))
     430             : {
     431           0 :   access_master_ipv4.add_hook = func;
     432             : #ifdef HAVE_IPV6
     433           0 :   access_master_ipv6.add_hook = func;
     434             : #endif /* HAVE_IPV6 */
     435           0 : }
     436             : 
     437             : /* Delete hook function. */
     438             : void
     439           0 : access_list_delete_hook (void (*func) (struct access_list *access))
     440             : {
     441           0 :   access_master_ipv4.delete_hook = func;
     442             : #ifdef HAVE_IPV6
     443           0 :   access_master_ipv6.delete_hook = func;
     444             : #endif /* HAVE_IPV6 */
     445           0 : }
     446             : 
     447             : /* Add new filter to the end of specified access_list. */
     448             : static void
     449           4 : access_list_filter_add (struct access_list *access, struct filter *filter)
     450             : {
     451           4 :   filter->next = NULL;
     452           4 :   filter->prev = access->tail;
     453             : 
     454           4 :   if (access->tail)
     455           2 :     access->tail->next = filter;
     456             :   else
     457           2 :     access->head = filter;
     458           4 :   access->tail = filter;
     459             : 
     460             :   /* Run hook function. */
     461           4 :   if (access->master->add_hook)
     462           0 :     (*access->master->add_hook) (access);
     463           4 : }
     464             : 
     465             : /* If access_list has no filter then return 1. */
     466             : static int
     467           0 : access_list_empty (struct access_list *access)
     468             : {
     469           0 :   if (access->head == NULL && access->tail == NULL)
     470           0 :     return 1;
     471             :   else
     472           0 :     return 0;
     473             : }
     474             : 
     475             : /* Delete filter from specified access_list.  If there is hook
     476             :    function execute it. */
     477             : static void
     478           0 : access_list_filter_delete (struct access_list *access, struct filter *filter)
     479             : {
     480             :   struct access_master *master;
     481             : 
     482           0 :   master = access->master;
     483             : 
     484           0 :   if (filter->next)
     485           0 :     filter->next->prev = filter->prev;
     486             :   else
     487           0 :     access->tail = filter->prev;
     488             : 
     489           0 :   if (filter->prev)
     490           0 :     filter->prev->next = filter->next;
     491             :   else
     492           0 :     access->head = filter->next;
     493             : 
     494           0 :   filter_free (filter);
     495             : 
     496             :   /* If access_list becomes empty delete it from access_master. */
     497           0 :   if (access_list_empty (access))
     498           0 :     access_list_delete (access);
     499             : 
     500             :   /* Run hook function. */
     501           0 :   if (master->delete_hook)
     502           0 :     (*master->delete_hook) (access);
     503           0 : }
     504             : 
     505             : /*
     506             :   deny    Specify packets to reject
     507             :   permit  Specify packets to forward
     508             :   dynamic ?
     509             : */
     510             : 
     511             : /*
     512             :   Hostname or A.B.C.D  Address to match
     513             :   any                  Any source host
     514             :   host                 A single host address
     515             : */
     516             : 
     517             : static struct filter *
     518           4 : 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           4 :   new = &mnew->u.cfilter;
     525             : 
     526           6 :   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
     527             :     {
     528           2 :       filter = &mfilter->u.cfilter;
     529             : 
     530           2 :       if (filter->extended)
     531             :         {
     532           0 :           if (mfilter->type == mnew->type
     533           0 :               && filter->addr.s_addr == new->addr.s_addr
     534           0 :               && filter->addr_mask.s_addr == new->addr_mask.s_addr
     535           0 :               && filter->mask.s_addr == new->mask.s_addr
     536           0 :               && filter->mask_mask.s_addr == new->mask_mask.s_addr)
     537           0 :             return mfilter;
     538             :         }
     539             :       else
     540             :         {
     541           2 :           if (mfilter->type == mnew->type
     542           0 :               && filter->addr.s_addr == new->addr.s_addr
     543           0 :               && filter->addr_mask.s_addr == new->addr_mask.s_addr)
     544           0 :             return mfilter;
     545             :         }
     546             :     }
     547             : 
     548           4 :   return NULL;
     549             : }
     550             : 
     551             : static struct filter *
     552           0 : 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           0 :   new = &mnew->u.zfilter;
     559             : 
     560           0 :   for (mfilter = access->head; mfilter; mfilter = mfilter->next)
     561             :     {
     562           0 :       filter = &mfilter->u.zfilter;
     563             : 
     564           0 :       if (filter->exact == new->exact
     565           0 :           && mfilter->type == mnew->type
     566           0 :           && prefix_same (&filter->prefix, &new->prefix))
     567           0 :         return mfilter;
     568             :     }
     569           0 :   return NULL;
     570             : }
     571             : 
     572             : static int
     573           0 : vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
     574             : {
     575             :   struct access_list *access;
     576             : 
     577           0 :   access = access_list_lookup (afi, name);
     578           0 :   if (! access)
     579             :     {
     580           0 :       vty_out (vty, "%% access-list %s doesn't exist%s", name,
     581           0 :                VTY_NEWLINE);
     582           0 :       return CMD_WARNING;
     583             :     }
     584             : 
     585           0 :   if (access->remark)
     586             :     {
     587           0 :       XFREE (MTYPE_TMP, access->remark);
     588           0 :       access->remark = NULL;
     589             :     }
     590             : 
     591           0 :   if (access->head == NULL && access->tail == NULL && access->remark == NULL)
     592           0 :     access_list_delete (access);
     593             : 
     594           0 :   return CMD_SUCCESS;
     595             : }
     596             : 
     597             : static int
     598           4 : 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           4 :   if (strncmp (type_str, "p", 1) == 0)
     615           2 :     type = FILTER_PERMIT;
     616           2 :   else if (strncmp (type_str, "d", 1) == 0)
     617           2 :     type = FILTER_DENY;
     618             :   else
     619             :     {
     620           0 :       vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
     621           0 :       return CMD_WARNING;
     622             :     }
     623             : 
     624           4 :   ret = inet_aton (addr_str, &addr);
     625           4 :   if (ret <= 0)
     626             :     {
     627           0 :       vty_out (vty, "%%Inconsistent address and mask%s",
     628           0 :                VTY_NEWLINE);
     629           0 :       return CMD_WARNING;
     630             :     }
     631             : 
     632           4 :   ret = inet_aton (addr_mask_str, &addr_mask);
     633           4 :   if (ret <= 0)
     634             :     {
     635           0 :       vty_out (vty, "%%Inconsistent address and mask%s",
     636           0 :                VTY_NEWLINE);
     637           0 :       return CMD_WARNING;
     638             :     }
     639             : 
     640           4 :   if (extended)
     641             :     {
     642           0 :       ret = inet_aton (mask_str, &mask);
     643           0 :       if (ret <= 0)
     644             :         {
     645           0 :           vty_out (vty, "%%Inconsistent address and mask%s",
     646           0 :                    VTY_NEWLINE);
     647           0 :           return CMD_WARNING;
     648             :         }
     649             : 
     650           0 :       ret = inet_aton (mask_mask_str, &mask_mask);
     651           0 :       if (ret <= 0)
     652             :         {
     653           0 :           vty_out (vty, "%%Inconsistent address and mask%s",
     654           0 :                    VTY_NEWLINE);
     655           0 :           return CMD_WARNING;
     656             :         }
     657             :     }
     658             : 
     659           4 :   mfilter = filter_new();
     660           4 :   mfilter->type = type;
     661           4 :   mfilter->cisco = 1;
     662           4 :   filter = &mfilter->u.cfilter;
     663           4 :   filter->extended = extended;
     664           4 :   filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
     665           4 :   filter->addr_mask.s_addr = addr_mask.s_addr;
     666             : 
     667           4 :   if (extended)
     668             :     {
     669           0 :       filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
     670           0 :       filter->mask_mask.s_addr = mask_mask.s_addr;
     671             :     }
     672             : 
     673             :   /* Install new filter to the access_list. */
     674           4 :   access = access_list_get (AFI_IP, name_str);
     675             : 
     676           4 :   if (set)
     677             :     {
     678           4 :       if (filter_lookup_cisco (access, mfilter))
     679           0 :         filter_free (mfilter);
     680             :       else
     681           4 :         access_list_filter_add (access, mfilter);
     682             :     }
     683             :   else
     684             :     {
     685             :       struct filter *delete_filter;
     686             : 
     687           0 :       delete_filter = filter_lookup_cisco (access, mfilter);
     688           0 :       if (delete_filter)
     689           0 :         access_list_filter_delete (access, delete_filter);
     690             : 
     691           0 :       filter_free (mfilter);
     692             :     }
     693             : 
     694           4 :   return CMD_SUCCESS;
     695             : }
     696             : 
     697             : /* Standard access-list */
     698           2 : 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           2 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
     710             :                            NULL, NULL, 0, 1);
     711             : }
     712             : 
     713           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
     724             :                            NULL, NULL, 0, 1);
     725             : }
     726             : 
     727           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
     739             :                            NULL, NULL, 0, 1);
     740             : }
     741             : 
     742           2 : 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           2 :   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           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
     769             :                            NULL, NULL, 0, 0);
     770             : }
     771             : 
     772           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
     784             :                            NULL, NULL, 0, 0);
     785             : }
     786             : 
     787           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
     800             :                            NULL, NULL, 0, 0);
     801             : }
     802             : 
     803           0 : 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           0 :   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           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     834           0 :                            argv[3], argv[4], argv[5], 1 ,1);
     835             : }
     836             : 
     837           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     851           0 :                            argv[3], "0.0.0.0",
     852             :                            "255.255.255.255", 1, 1);
     853             : }
     854             : 
     855           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
     869           0 :                            "255.255.255.255", argv[2],
     870           0 :                            argv[3], 1, 1);
     871             : }
     872             : 
     873           0 : 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           0 :   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           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     905           0 :                            argv[3], argv[4],
     906             :                            "0.0.0.0", 1, 1);
     907             : }
     908             : 
     909           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     924           0 :                            "0.0.0.0", argv[3],
     925           0 :                            argv[4], 1, 1);
     926             : }
     927             : 
     928           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     943           0 :                            "0.0.0.0", argv[3],
     944             :                            "0.0.0.0", 1, 1);
     945             : }
     946             : 
     947           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
     961           0 :                            "255.255.255.255", argv[2],
     962             :                            "0.0.0.0", 1, 1);
     963             : }
     964             : 
     965           0 : 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           0 :   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           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
     999           0 :                            argv[3], argv[4], argv[5], 1, 0);
    1000             : }
    1001             : 
    1002           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
    1017           0 :                            argv[3], "0.0.0.0",
    1018             :                            "255.255.255.255", 1, 0);
    1019             : }
    1020             : 
    1021           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
    1036           0 :                            "255.255.255.255", argv[2],
    1037           0 :                            argv[3], 1, 0);
    1038             : }
    1039             : 
    1040           0 : 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           0 :   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           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
    1074           0 :                            argv[3], argv[4],
    1075             :                            "0.0.0.0", 1, 0);
    1076             : }
    1077             : 
    1078           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
    1094           0 :                            "0.0.0.0", argv[3],
    1095           0 :                            argv[4], 1, 0);
    1096             : }
    1097             : 
    1098           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], argv[2],
    1114           0 :                            "0.0.0.0", argv[3],
    1115             :                            "0.0.0.0", 1, 0);
    1116             : }
    1117             : 
    1118           0 : 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           0 :   return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
    1133           0 :                            "255.255.255.255", argv[2],
    1134             :                            "0.0.0.0", 1, 0);
    1135             : }
    1136             : 
    1137           0 : 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           0 :   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           0 : 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           0 :   if (strncmp (type_str, "p", 1) == 0)
    1169           0 :     type = FILTER_PERMIT;
    1170           0 :   else if (strncmp (type_str, "d", 1) == 0)
    1171           0 :     type = FILTER_DENY;
    1172             :   else
    1173             :     {
    1174           0 :       vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
    1175           0 :       return CMD_WARNING;
    1176             :     }
    1177             : 
    1178             :   /* Check string format of prefix and prefixlen. */
    1179           0 :   if (afi == AFI_IP)
    1180             :     {
    1181           0 :       ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
    1182           0 :       if (ret <= 0)
    1183             :         {
    1184           0 :           vty_out (vty, "IP address prefix/prefixlen is malformed%s",
    1185           0 :                    VTY_NEWLINE);
    1186           0 :           return CMD_WARNING;
    1187             :         }
    1188             :     }
    1189             : #ifdef HAVE_IPV6
    1190           0 :   else if (afi == AFI_IP6)
    1191             :     {
    1192           0 :       ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
    1193           0 :       if (ret <= 0)
    1194             :         {
    1195           0 :           vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
    1196           0 :                    VTY_NEWLINE);
    1197           0 :                    return CMD_WARNING;
    1198             :         }
    1199             :     }
    1200             : #endif /* HAVE_IPV6 */
    1201             :   else
    1202           0 :     return CMD_WARNING;
    1203             : 
    1204           0 :   mfilter = filter_new ();
    1205           0 :   mfilter->type = type;
    1206           0 :   filter = &mfilter->u.zfilter;
    1207           0 :   prefix_copy (&filter->prefix, &p);
    1208             : 
    1209             :   /* "exact-match" */
    1210           0 :   if (exact)
    1211           0 :     filter->exact = 1;
    1212             : 
    1213             :   /* Install new filter to the access_list. */
    1214           0 :   access = access_list_get (afi, name_str);
    1215             : 
    1216           0 :   if (set)
    1217             :     {
    1218           0 :       if (filter_lookup_zebra (access, mfilter))
    1219           0 :         filter_free (mfilter);
    1220             :       else
    1221           0 :         access_list_filter_add (access, mfilter);
    1222             :     }
    1223             :   else
    1224             :     {
    1225             :       struct filter *delete_filter;
    1226             : 
    1227           0 :       delete_filter = filter_lookup_zebra (access, mfilter);
    1228           0 :       if (delete_filter)
    1229           0 :         access_list_filter_delete (access, delete_filter);
    1230             : 
    1231           0 :       filter_free (mfilter);
    1232             :     }
    1233             : 
    1234           0 :   return CMD_SUCCESS;
    1235             : }
    1236             : 
    1237             : /* Zebra access-list */
    1238           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
    1248             : }
    1249             : 
    1250           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
    1261             : }
    1262             : 
    1263           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
    1273             : }
    1274             : 
    1275           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
    1286             : }
    1287             : 
    1288           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
    1300             : }
    1301             : 
    1302           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
    1313             : }
    1314             : 
    1315           0 : 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           0 :   access = access_list_lookup (AFI_IP, argv[0]);
    1331           0 :   if (access == NULL)
    1332             :     {
    1333           0 :       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
    1334           0 :                VTY_NEWLINE);
    1335           0 :       return CMD_WARNING;
    1336             :     }
    1337             : 
    1338           0 :   master = access->master;
    1339             : 
    1340             :   /* Run hook function. */
    1341           0 :   if (master->delete_hook)
    1342           0 :     (*master->delete_hook) (access);
    1343             :  
    1344             :   /* Delete all filter from access-list. */
    1345           0 :   access_list_delete (access);
    1346             : 
    1347           0 :   return CMD_SUCCESS;
    1348             : }
    1349             : 
    1350           0 : 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           0 :   access = access_list_get (AFI_IP, argv[0]);
    1365             : 
    1366           0 :   if (access->remark)
    1367             :     {
    1368           0 :       XFREE (MTYPE_TMP, access->remark);
    1369           0 :       access->remark = NULL;
    1370             :     }
    1371           0 :   access->remark = argv_concat(argv, argc, 1);
    1372             : 
    1373           0 :   return CMD_SUCCESS;
    1374             : }
    1375             : 
    1376           0 : 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           0 :   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           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
    1416             : }
    1417             : 
    1418           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
    1430             : }
    1431             : 
    1432           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
    1443             : }
    1444             : 
    1445           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
    1457             : }
    1458             : 
    1459           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
    1472             : }
    1473             : 
    1474           0 : 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           0 :   return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
    1486             : }
    1487             : 
    1488             : 
    1489           0 : 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           0 :   access = access_list_lookup (AFI_IP6, argv[0]);
    1502           0 :   if (access == NULL)
    1503             :     {
    1504           0 :       vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
    1505           0 :                VTY_NEWLINE);
    1506           0 :       return CMD_WARNING;
    1507             :     }
    1508             : 
    1509           0 :   master = access->master;
    1510             : 
    1511             :   /* Run hook function. */
    1512           0 :   if (master->delete_hook)
    1513           0 :     (*master->delete_hook) (access);
    1514             : 
    1515             :   /* Delete all filter from access-list. */
    1516           0 :   access_list_delete (access);
    1517             : 
    1518           0 :   return CMD_SUCCESS;
    1519             : }
    1520             : 
    1521           0 : 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           0 :   access = access_list_get (AFI_IP6, argv[0]);
    1533             : 
    1534           0 :   if (access->remark)
    1535             :     {
    1536           0 :       XFREE (MTYPE_TMP, access->remark);
    1537           0 :       access->remark = NULL;
    1538             :     }
    1539           0 :   access->remark = argv_concat(argv, argc, 1);
    1540             : 
    1541           0 :   return CMD_SUCCESS;
    1542             : }
    1543             : 
    1544           0 : 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           0 :   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           0 : 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           0 :   int write = 0;
    1579             : 
    1580           0 :   master = access_master_get (afi);
    1581           0 :   if (master == NULL)
    1582           0 :     return 0;
    1583             : 
    1584             :   /* Print the name of the protocol */
    1585           0 :   if (zlog_default)
    1586           0 :       vty_out (vty, "%s:%s",
    1587           0 :       zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
    1588             : 
    1589           0 :   for (access = master->num.head; access; access = access->next)
    1590             :     {
    1591           0 :       if (name && strcmp (access->name, name) != 0)
    1592           0 :         continue;
    1593             : 
    1594           0 :       write = 1;
    1595             : 
    1596           0 :       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
    1597             :         {
    1598           0 :           filter = &mfilter->u.cfilter;
    1599             : 
    1600           0 :           if (write)
    1601             :             {
    1602           0 :               vty_out (vty, "%s IP%s access list %s%s",
    1603           0 :                        mfilter->cisco ? 
    1604           0 :                        (filter->extended ? "Extended" : "Standard") : "Zebra",
    1605             :                        afi == AFI_IP6 ? "v6" : "",
    1606           0 :                        access->name, VTY_NEWLINE);
    1607           0 :               write = 0;
    1608             :             }
    1609             : 
    1610           0 :           vty_out (vty, "    %s%s", filter_type_str (mfilter),
    1611           0 :                    mfilter->type == FILTER_DENY ? "  " : "");
    1612             : 
    1613           0 :           if (! mfilter->cisco)
    1614           0 :             config_write_access_zebra (vty, mfilter);
    1615           0 :           else if (filter->extended)
    1616           0 :             config_write_access_cisco (vty, mfilter);
    1617             :           else
    1618             :             {
    1619           0 :               if (filter->addr_mask.s_addr == 0xffffffff)
    1620           0 :                 vty_out (vty, " any%s", VTY_NEWLINE);
    1621             :               else
    1622             :                 {
    1623           0 :                   vty_out (vty, " %s", inet_ntoa (filter->addr));
    1624           0 :                   if (filter->addr_mask.s_addr != 0)
    1625           0 :                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
    1626           0 :                   vty_out (vty, "%s", VTY_NEWLINE);
    1627             :                 }
    1628             :             }
    1629             :         }
    1630             :     }
    1631             : 
    1632           0 :   for (access = master->str.head; access; access = access->next)
    1633             :     {
    1634           0 :       if (name && strcmp (access->name, name) != 0)
    1635           0 :         continue;
    1636             : 
    1637           0 :       write = 1;
    1638             : 
    1639           0 :       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
    1640             :         {
    1641           0 :           filter = &mfilter->u.cfilter;
    1642             : 
    1643           0 :           if (write)
    1644             :             {
    1645           0 :               vty_out (vty, "%s IP%s access list %s%s",
    1646           0 :                        mfilter->cisco ? 
    1647           0 :                        (filter->extended ? "Extended" : "Standard") : "Zebra",
    1648             :                        afi == AFI_IP6 ? "v6" : "",
    1649           0 :                        access->name, VTY_NEWLINE);
    1650           0 :               write = 0;
    1651             :             }
    1652             : 
    1653           0 :           vty_out (vty, "    %s%s", filter_type_str (mfilter),
    1654           0 :                    mfilter->type == FILTER_DENY ? "  " : "");
    1655             : 
    1656           0 :           if (! mfilter->cisco)
    1657           0 :             config_write_access_zebra (vty, mfilter);
    1658           0 :           else if (filter->extended)
    1659           0 :             config_write_access_cisco (vty, mfilter);
    1660             :           else
    1661             :             {
    1662           0 :               if (filter->addr_mask.s_addr == 0xffffffff)
    1663           0 :                 vty_out (vty, " any%s", VTY_NEWLINE);
    1664             :               else
    1665             :                 {
    1666           0 :                   vty_out (vty, " %s", inet_ntoa (filter->addr));
    1667           0 :                   if (filter->addr_mask.s_addr != 0)
    1668           0 :                     vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
    1669           0 :                   vty_out (vty, "%s", VTY_NEWLINE);
    1670             :                 }
    1671             :             }
    1672             :         }
    1673             :     }
    1674           0 :   return CMD_SUCCESS;
    1675             : }
    1676             : 
    1677           0 : 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           0 :   return filter_show (vty, NULL, AFI_IP);
    1685             : }
    1686             : 
    1687           0 : 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           0 :   return filter_show (vty, argv[0], AFI_IP);
    1700             : }
    1701             : 
    1702             : #ifdef HAVE_IPV6
    1703           0 : 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           0 :   return filter_show (vty, NULL, AFI_IP6);
    1711             : }
    1712             : 
    1713           0 : 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           0 :   return filter_show (vty, argv[0], AFI_IP6);
    1722             : }
    1723             : #endif /* HAVE_IPV6 */
    1724             : 
    1725             : void
    1726           0 : config_write_access_cisco (struct vty *vty, struct filter *mfilter)
    1727             : {
    1728             :   struct filter_cisco *filter;
    1729             : 
    1730           0 :   filter = &mfilter->u.cfilter;
    1731             : 
    1732           0 :   if (filter->extended)
    1733             :     {
    1734           0 :       vty_out (vty, " ip");
    1735           0 :       if (filter->addr_mask.s_addr == 0xffffffff)
    1736           0 :         vty_out (vty, " any");
    1737           0 :       else if (filter->addr_mask.s_addr == 0)
    1738           0 :         vty_out (vty, " host %s", inet_ntoa (filter->addr));
    1739             :       else
    1740             :         {
    1741           0 :           vty_out (vty, " %s", inet_ntoa (filter->addr));
    1742           0 :           vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
    1743             :         }
    1744             : 
    1745           0 :       if (filter->mask_mask.s_addr == 0xffffffff)
    1746           0 :         vty_out (vty, " any");
    1747           0 :       else if (filter->mask_mask.s_addr == 0)
    1748           0 :         vty_out (vty, " host %s", inet_ntoa (filter->mask));
    1749             :       else
    1750             :         {
    1751           0 :           vty_out (vty, " %s", inet_ntoa (filter->mask));
    1752           0 :           vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
    1753             :         }
    1754           0 :       vty_out (vty, "%s", VTY_NEWLINE);
    1755             :     }
    1756             :   else
    1757             :     {
    1758           0 :       if (filter->addr_mask.s_addr == 0xffffffff)
    1759           0 :         vty_out (vty, " any%s", VTY_NEWLINE);
    1760             :       else
    1761             :         {
    1762           0 :           vty_out (vty, " %s", inet_ntoa (filter->addr));
    1763           0 :           if (filter->addr_mask.s_addr != 0)
    1764           0 :             vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
    1765           0 :           vty_out (vty, "%s", VTY_NEWLINE);
    1766             :         }
    1767             :     }
    1768           0 : }
    1769             : 
    1770             : void
    1771           0 : 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           0 :   filter = &mfilter->u.zfilter;
    1778           0 :   p = &filter->prefix;
    1779             : 
    1780           0 :   if (p->prefixlen == 0 && ! filter->exact)
    1781           0 :     vty_out (vty, " any");
    1782             :   else
    1783           0 :     vty_out (vty, " %s/%d%s",
    1784           0 :              inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
    1785           0 :              p->prefixlen,
    1786           0 :              filter->exact ? " exact-match" : "");
    1787             : 
    1788           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    1789           0 : }
    1790             : 
    1791             : static int
    1792           0 : 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           0 :   int write = 0;
    1798             : 
    1799           0 :   master = access_master_get (afi);
    1800           0 :   if (master == NULL)
    1801           0 :     return 0;
    1802             : 
    1803           0 :   for (access = master->num.head; access; access = access->next)
    1804             :     {
    1805           0 :       if (access->remark)
    1806             :         {
    1807           0 :           vty_out (vty, "%saccess-list %s remark %s%s",
    1808             :                    afi == AFI_IP ? "" : "ipv6 ",
    1809             :                    access->name, access->remark,
    1810           0 :                    VTY_NEWLINE);
    1811           0 :           write++;
    1812             :         }
    1813             : 
    1814           0 :       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
    1815             :         {
    1816           0 :           vty_out (vty, "%saccess-list %s %s",
    1817             :              afi == AFI_IP ? "" : "ipv6 ",
    1818             :              access->name,
    1819             :              filter_type_str (mfilter));
    1820             : 
    1821           0 :           if (mfilter->cisco)
    1822           0 :             config_write_access_cisco (vty, mfilter);
    1823             :           else
    1824           0 :             config_write_access_zebra (vty, mfilter);
    1825             : 
    1826           0 :           write++;
    1827             :         }
    1828             :     }
    1829             : 
    1830           0 :   for (access = master->str.head; access; access = access->next)
    1831             :     {
    1832           0 :       if (access->remark)
    1833             :         {
    1834           0 :           vty_out (vty, "%saccess-list %s remark %s%s",
    1835             :                    afi == AFI_IP ? "" : "ipv6 ",
    1836             :                    access->name, access->remark,
    1837           0 :                    VTY_NEWLINE);
    1838           0 :           write++;
    1839             :         }
    1840             : 
    1841           0 :       for (mfilter = access->head; mfilter; mfilter = mfilter->next)
    1842             :         {
    1843           0 :           vty_out (vty, "%saccess-list %s %s",
    1844             :              afi == AFI_IP ? "" : "ipv6 ",
    1845             :              access->name,
    1846             :              filter_type_str (mfilter));
    1847             : 
    1848           0 :           if (mfilter->cisco)
    1849           0 :             config_write_access_cisco (vty, mfilter);
    1850             :           else
    1851           0 :             config_write_access_zebra (vty, mfilter);
    1852             : 
    1853           0 :           write++;
    1854             :         }
    1855             :     }
    1856           0 :   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           0 : config_write_access_ipv4 (struct vty *vty)
    1869             : {
    1870           0 :   return config_write_access (vty, AFI_IP);
    1871             : }
    1872             : 
    1873             : static void
    1874           0 : access_list_reset_ipv4 (void)
    1875             : {
    1876             :   struct access_list *access;
    1877             :   struct access_list *next;
    1878             :   struct access_master *master;
    1879             : 
    1880           0 :   master = access_master_get (AFI_IP);
    1881           0 :   if (master == NULL)
    1882           0 :     return;
    1883             : 
    1884           0 :   for (access = master->num.head; access; access = next)
    1885             :     {
    1886           0 :       next = access->next;
    1887           0 :       access_list_delete (access);
    1888             :     }
    1889           0 :   for (access = master->str.head; access; access = next)
    1890             :     {
    1891           0 :       next = access->next;
    1892           0 :       access_list_delete (access);
    1893             :     }
    1894             : 
    1895           0 :   assert (master->num.head == NULL);
    1896           0 :   assert (master->num.tail == NULL);
    1897             : 
    1898           0 :   assert (master->str.head == NULL);
    1899           0 :   assert (master->str.tail == NULL);
    1900             : }
    1901             : 
    1902             : /* Install vty related command. */
    1903             : static void
    1904          45 : access_list_init_ipv4 (void)
    1905             : {
    1906          45 :   install_node (&access_node, config_write_access_ipv4);
    1907             : 
    1908          45 :   install_element (ENABLE_NODE, &show_ip_access_list_cmd);
    1909          45 :   install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
    1910             : 
    1911             :   /* Zebra access-list */
    1912          45 :   install_element (CONFIG_NODE, &access_list_cmd);
    1913          45 :   install_element (CONFIG_NODE, &access_list_exact_cmd);
    1914          45 :   install_element (CONFIG_NODE, &access_list_any_cmd);
    1915          45 :   install_element (CONFIG_NODE, &no_access_list_cmd);
    1916          45 :   install_element (CONFIG_NODE, &no_access_list_exact_cmd);
    1917          45 :   install_element (CONFIG_NODE, &no_access_list_any_cmd);
    1918             : 
    1919             :   /* Standard access-list */
    1920          45 :   install_element (CONFIG_NODE, &access_list_standard_cmd);
    1921          45 :   install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
    1922          45 :   install_element (CONFIG_NODE, &access_list_standard_host_cmd);
    1923          45 :   install_element (CONFIG_NODE, &access_list_standard_any_cmd);
    1924          45 :   install_element (CONFIG_NODE, &no_access_list_standard_cmd);
    1925          45 :   install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
    1926          45 :   install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
    1927          45 :   install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
    1928             : 
    1929             :   /* Extended access-list */
    1930          45 :   install_element (CONFIG_NODE, &access_list_extended_cmd);
    1931          45 :   install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
    1932          45 :   install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
    1933          45 :   install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
    1934          45 :   install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
    1935          45 :   install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
    1936          45 :   install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
    1937          45 :   install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
    1938          45 :   install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
    1939          45 :   install_element (CONFIG_NODE, &no_access_list_extended_cmd);
    1940          45 :   install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
    1941          45 :   install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
    1942          45 :   install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
    1943          45 :   install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
    1944          45 :   install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
    1945          45 :   install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
    1946          45 :   install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
    1947          45 :   install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
    1948             : 
    1949          45 :   install_element (CONFIG_NODE, &access_list_remark_cmd);
    1950          45 :   install_element (CONFIG_NODE, &no_access_list_all_cmd);
    1951          45 :   install_element (CONFIG_NODE, &no_access_list_remark_cmd);
    1952          45 :   install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
    1953          45 : }
    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           0 : config_write_access_ipv6 (struct vty *vty)
    1965             : {
    1966           0 :   return config_write_access (vty, AFI_IP6);
    1967             : }
    1968             : 
    1969             : static void
    1970           0 : access_list_reset_ipv6 (void)
    1971             : {
    1972             :   struct access_list *access;
    1973             :   struct access_list *next;
    1974             :   struct access_master *master;
    1975             : 
    1976           0 :   master = access_master_get (AFI_IP6);
    1977           0 :   if (master == NULL)
    1978           0 :     return;
    1979             : 
    1980           0 :   for (access = master->num.head; access; access = next)
    1981             :     {
    1982           0 :       next = access->next;
    1983           0 :       access_list_delete (access);
    1984             :     }
    1985           0 :   for (access = master->str.head; access; access = next)
    1986             :     {
    1987           0 :       next = access->next;
    1988           0 :       access_list_delete (access);
    1989             :     }
    1990             : 
    1991           0 :   assert (master->num.head == NULL);
    1992           0 :   assert (master->num.tail == NULL);
    1993             : 
    1994           0 :   assert (master->str.head == NULL);
    1995           0 :   assert (master->str.tail == NULL);
    1996             : }
    1997             : 
    1998             : static void
    1999          45 : access_list_init_ipv6 (void)
    2000             : {
    2001          45 :   install_node (&access_ipv6_node, config_write_access_ipv6);
    2002             : 
    2003          45 :   install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
    2004          45 :   install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
    2005             : 
    2006          45 :   install_element (CONFIG_NODE, &ipv6_access_list_cmd);
    2007          45 :   install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
    2008          45 :   install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
    2009          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
    2010          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
    2011          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
    2012             : 
    2013          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
    2014          45 :   install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
    2015          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
    2016          45 :   install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
    2017          45 : }
    2018             : #endif /* HAVE_IPV6 */
    2019             : 
    2020             : void
    2021          45 : access_list_init ()
    2022             : {
    2023          45 :   access_list_init_ipv4 ();
    2024             : #ifdef HAVE_IPV6
    2025          45 :   access_list_init_ipv6();
    2026             : #endif /* HAVE_IPV6 */
    2027          45 : }
    2028             : 
    2029             : void
    2030           0 : access_list_reset ()
    2031             : {
    2032           0 :   access_list_reset_ipv4 ();
    2033             : #ifdef HAVE_IPV6
    2034           0 :   access_list_reset_ipv6();
    2035             : #endif /* HAVE_IPV6 */
    2036           0 : }

Generated by: LCOV version 1.10