filter.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:54k
源码类别:

网络

开发平台:

Unix_Linux

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