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

网络

开发平台:

Unix_Linux

  1. /* Prefix list functions.
  2.  * Copyright (C) 1999 Kunihiro Ishiguro
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  6.  * GNU Zebra is free software; you can redistribute it and/or modify
  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 "command.h"
  24. #include "memory.h"
  25. #include "plist.h"
  26. #include "sockunion.h"
  27. #include "buffer.h"
  28. /* Each prefix-list's entry. */
  29. struct prefix_list_entry
  30. {
  31.   int seq;
  32.   int le;
  33.   int ge;
  34.   enum prefix_list_type type;
  35.   int any;
  36.   struct prefix prefix;
  37.   unsigned long refcnt;
  38.   unsigned long hitcnt;
  39.   struct prefix_list_entry *next;
  40.   struct prefix_list_entry *prev;
  41. };
  42. /* List of struct prefix_list. */
  43. struct prefix_list_list
  44. {
  45.   struct prefix_list *head;
  46.   struct prefix_list *tail;
  47. };
  48. /* Master structure of prefix_list. */
  49. struct prefix_master
  50. {
  51.   /* List of prefix_list which name is number. */
  52.   struct prefix_list_list num;
  53.   /* List of prefix_list which name is string. */
  54.   struct prefix_list_list str;
  55.   /* Whether sequential number is used. */
  56.   int seqnum;
  57.   /* The latest update. */
  58.   struct prefix_list *recent;
  59.   /* Hook function which is executed when new prefix_list is added. */
  60.   void (*add_hook) ();
  61.   /* Hook function which is executed when prefix_list is deleted. */
  62.   void (*delete_hook) ();
  63. };
  64. /* Static structure of IPv4 prefix_list's master. */
  65. static struct prefix_master prefix_master_ipv4 = 
  66.   {NULL, NULL},
  67.   {NULL, NULL},
  68.   1,
  69.   NULL,
  70.   NULL,
  71. };
  72. #ifdef HAVE_IPV6
  73. /* Static structure of IPv6 prefix-list's master. */
  74. static struct prefix_master prefix_master_ipv6 = 
  75.   {NULL, NULL},
  76.   {NULL, NULL},
  77.   1,
  78.   NULL,
  79.   NULL,
  80. };
  81. #endif /* HAVE_IPV6*/
  82. /* Static structure of BGP ORF prefix_list's master. */
  83. static struct prefix_master prefix_master_orf = 
  84.   {NULL, NULL},
  85.   {NULL, NULL},
  86.   1,
  87.   NULL,
  88.   NULL,
  89. };
  90. struct prefix_master *
  91. prefix_master_get (afi_t afi)
  92. {
  93.   if (afi == AFI_IP)
  94.     return &prefix_master_ipv4;
  95. #ifdef HAVE_IPV6
  96.   else if (afi == AFI_IP6)
  97.     return &prefix_master_ipv6;
  98. #endif /* HAVE_IPV6 */
  99.   else if (afi == AFI_ORF_PREFIX)
  100.     return &prefix_master_orf;
  101.   return NULL;
  102. }
  103. /* Lookup prefix_list from list of prefix_list by name. */
  104. struct prefix_list *
  105. prefix_list_lookup (afi_t afi, char *name)
  106. {
  107.   struct prefix_list *plist;
  108.   struct prefix_master *master;
  109.   if (name == NULL)
  110.     return NULL;
  111.   master = prefix_master_get (afi);
  112.   if (master == NULL)
  113.     return NULL;
  114.   for (plist = master->num.head; plist; plist = plist->next)
  115.     if (strcmp (plist->name, name) == 0)
  116.       return plist;
  117.   for (plist = master->str.head; plist; plist = plist->next)
  118.     if (strcmp (plist->name, name) == 0)
  119.       return plist;
  120.   return NULL;
  121. }
  122. struct prefix_list *
  123. prefix_list_new ()
  124. {
  125.   struct prefix_list *new;
  126.   new = XCALLOC (MTYPE_PREFIX_LIST, sizeof (struct prefix_list));
  127.   return new;
  128. }
  129. void
  130. prefix_list_free (struct prefix_list *plist)
  131. {
  132.   XFREE (MTYPE_PREFIX_LIST, plist);
  133. }
  134. struct prefix_list_entry *
  135. prefix_list_entry_new ()
  136. {
  137.   struct prefix_list_entry *new;
  138.   new = XCALLOC (MTYPE_PREFIX_LIST_ENTRY, sizeof (struct prefix_list_entry));
  139.   return new;
  140. }
  141. void
  142. prefix_list_entry_free (struct prefix_list_entry *pentry)
  143. {
  144.   XFREE (MTYPE_PREFIX_LIST_ENTRY, pentry);
  145. }
  146. /* Insert new prefix list to list of prefix_list.  Each prefix_list
  147.    is sorted by the name. */
  148. struct prefix_list *
  149. prefix_list_insert (afi_t afi, char *name)
  150. {
  151.   int i;
  152.   long number;
  153.   struct prefix_list *plist;
  154.   struct prefix_list *point;
  155.   struct prefix_list_list *list;
  156.   struct prefix_master *master;
  157.   master = prefix_master_get (afi);
  158.   if (master == NULL)
  159.     return NULL;
  160.   /* Allocate new prefix_list and copy given name. */
  161.   plist = prefix_list_new ();
  162.   plist->name = XSTRDUP (MTYPE_PREFIX_LIST_STR, name);
  163.   plist->master = master;
  164.   /* If name is made by all digit character.  We treat it as
  165.      number. */
  166.   for (number = 0, i = 0; i < strlen (name); i++)
  167.     {
  168.       if (isdigit ((int) name[i]))
  169. number = (number * 10) + (name[i] - '0');
  170.       else
  171. break;
  172.     }
  173.   /* In case of name is all digit character */
  174.   if (i == strlen (name))
  175.     {
  176.       plist->type = PREFIX_TYPE_NUMBER;
  177.       /* Set prefix_list to number list. */
  178.       list = &master->num;
  179.       for (point = list->head; point; point = point->next)
  180. if (atol (point->name) >= number)
  181.   break;
  182.     }
  183.   else
  184.     {
  185.       plist->type = PREFIX_TYPE_STRING;
  186.       /* Set prefix_list to string list. */
  187.       list = &master->str;
  188.   
  189.       /* Set point to insertion point. */
  190.       for (point = list->head; point; point = point->next)
  191. if (strcmp (point->name, name) >= 0)
  192.   break;
  193.     }
  194.   /* In case of this is the first element of master. */
  195.   if (list->head == NULL)
  196.     {
  197.       list->head = list->tail = plist;
  198.       return plist;
  199.     }
  200.   /* In case of insertion is made at the tail of access_list. */
  201.   if (point == NULL)
  202.     {
  203.       plist->prev = list->tail;
  204.       list->tail->next = plist;
  205.       list->tail = plist;
  206.       return plist;
  207.     }
  208.   /* In case of insertion is made at the head of access_list. */
  209.   if (point == list->head)
  210.     {
  211.       plist->next = list->head;
  212.       list->head->prev = plist;
  213.       list->head = plist;
  214.       return plist;
  215.     }
  216.   /* Insertion is made at middle of the access_list. */
  217.   plist->next = point;
  218.   plist->prev = point->prev;
  219.   if (point->prev)
  220.     point->prev->next = plist;
  221.   point->prev = plist;
  222.   return plist;
  223. }
  224. struct prefix_list *
  225. prefix_list_get (afi_t afi, char *name)
  226. {
  227.   struct prefix_list *plist;
  228.   plist = prefix_list_lookup (afi, name);
  229.   if (plist == NULL)
  230.     plist = prefix_list_insert (afi, name);
  231.   return plist;
  232. }
  233. /* Delete prefix-list from prefix_list_master and free it. */
  234. void
  235. prefix_list_delete (struct prefix_list *plist)
  236. {
  237.   struct prefix_list_list *list;
  238.   struct prefix_master *master;
  239.   struct prefix_list_entry *pentry;
  240.   struct prefix_list_entry *next;
  241.   /* If prefix-list contain prefix_list_entry free all of it. */
  242.   for (pentry = plist->head; pentry; pentry = next)
  243.     {
  244.       next = pentry->next;
  245.       prefix_list_entry_free (pentry);
  246.       plist->count--;
  247.     }
  248.   master = plist->master;
  249.   if (plist->type == PREFIX_TYPE_NUMBER)
  250.     list = &master->num;
  251.   else
  252.     list = &master->str;
  253.   if (plist->next)
  254.     plist->next->prev = plist->prev;
  255.   else
  256.     list->tail = plist->prev;
  257.   if (plist->prev)
  258.     plist->prev->next = plist->next;
  259.   else
  260.     list->head = plist->next;
  261.   if (plist->desc)
  262.     XFREE (MTYPE_TMP, plist->desc);
  263.   /* Make sure master's recent changed prefix-list information is
  264.      cleared. */
  265.   master->recent = NULL;
  266.   if (plist->name)
  267.     XFREE (MTYPE_PREFIX_LIST_STR, plist->name);
  268.   prefix_list_free (plist);
  269.   if (master->delete_hook)
  270.     (*master->delete_hook) ();
  271. }
  272. struct prefix_list_entry *
  273. prefix_list_entry_make (struct prefix *prefix, enum prefix_list_type type,
  274. int seq, int le, int ge, int any)
  275. {
  276.   struct prefix_list_entry *pentry;
  277.   pentry = prefix_list_entry_new ();
  278.   if (any)
  279.     pentry->any = 1;
  280.   prefix_copy (&pentry->prefix, prefix);
  281.   pentry->type = type;
  282.   pentry->seq = seq;
  283.   pentry->le = le;
  284.   pentry->ge = ge;
  285.   return pentry;
  286. }
  287. /* Add hook function. */
  288. void
  289. prefix_list_add_hook (void (*func) (struct prefix_list *plist))
  290. {
  291.   prefix_master_ipv4.add_hook = func;
  292. #ifdef HAVE_IPV6
  293.   prefix_master_ipv6.add_hook = func;
  294. #endif /* HAVE_IPV6 */
  295. }
  296. /* Delete hook function. */
  297. void
  298. prefix_list_delete_hook (void (*func) (struct prefix_list *plist))
  299. {
  300.   prefix_master_ipv4.delete_hook = func;
  301. #ifdef HAVE_IPV6
  302.   prefix_master_ipv6.delete_hook = func;
  303. #endif /* HAVE_IPVt6 */
  304. }
  305. /* Calculate new sequential number. */
  306. int
  307. prefix_new_seq_get (struct prefix_list *plist)
  308. {
  309.   int maxseq;
  310.   int newseq;
  311.   struct prefix_list_entry *pentry;
  312.   maxseq = newseq = 0;
  313.   for (pentry = plist->head; pentry; pentry = pentry->next)
  314.     {
  315.       if (maxseq < pentry->seq)
  316. maxseq = pentry->seq;
  317.     }
  318.   newseq = ((maxseq / 5) * 5) + 5;
  319.   
  320.   return newseq;
  321. }
  322. /* Return prefix list entry which has same seq number. */
  323. struct prefix_list_entry *
  324. prefix_seq_check (struct prefix_list *plist, int seq)
  325. {
  326.   struct prefix_list_entry *pentry;
  327.   for (pentry = plist->head; pentry; pentry = pentry->next)
  328.     if (pentry->seq == seq)
  329.       return pentry;
  330.   return NULL;
  331. }
  332. struct prefix_list_entry *
  333. prefix_list_entry_lookup (struct prefix_list *plist, struct prefix *prefix,
  334.   enum prefix_list_type type, int seq, int le, int ge)
  335. {
  336.   struct prefix_list_entry *pentry;
  337.   for (pentry = plist->head; pentry; pentry = pentry->next)
  338.     if (prefix_same (&pentry->prefix, prefix) && pentry->type == type)
  339.       {
  340. if (seq >= 0 && pentry->seq != seq)
  341.   continue;
  342. if (pentry->le != le)
  343.   continue;
  344. if (pentry->ge != ge)
  345.   continue;
  346. return pentry;
  347.       }
  348.   return NULL;
  349. }
  350. void
  351. prefix_list_entry_delete (struct prefix_list *plist, 
  352.   struct prefix_list_entry *pentry,
  353.   int update_list)
  354. {
  355.   if (plist == NULL || pentry == NULL)
  356.     return;
  357.   if (pentry->prev)
  358.     pentry->prev->next = pentry->next;
  359.   else
  360.     plist->head = pentry->next;
  361.   if (pentry->next)
  362.     pentry->next->prev = pentry->prev;
  363.   else
  364.     plist->tail = pentry->prev;
  365.   prefix_list_entry_free (pentry);
  366.   plist->count--;
  367.   if (update_list)
  368.     {
  369.       if (plist->master->delete_hook)
  370. (*plist->master->delete_hook) (plist);
  371.       if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL)
  372. prefix_list_delete (plist);
  373.       else
  374. plist->master->recent = plist;
  375.     }
  376. }
  377. void
  378. prefix_list_entry_add (struct prefix_list *plist,
  379.        struct prefix_list_entry *pentry)
  380. {
  381.   struct prefix_list_entry *replace;
  382.   struct prefix_list_entry *point;
  383.   /* Automatic asignment of seq no. */
  384.   if (pentry->seq == -1)
  385.     pentry->seq = prefix_new_seq_get (plist);
  386.   /* Is there any same seq prefix list entry? */
  387.   replace = prefix_seq_check (plist, pentry->seq);
  388.   if (replace)
  389.     prefix_list_entry_delete (plist, replace, 0);
  390.   /* Check insert point. */
  391.   for (point = plist->head; point; point = point->next)
  392.     if (point->seq >= pentry->seq)
  393.       break;
  394.   /* In case of this is the first element of the list. */
  395.   pentry->next = point;
  396.   if (point)
  397.     {
  398.       if (point->prev)
  399. point->prev->next = pentry;
  400.       else
  401. plist->head = pentry;
  402.       pentry->prev = point->prev;
  403.       point->prev = pentry;
  404.     }
  405.   else
  406.     {
  407.       if (plist->tail)
  408. plist->tail->next = pentry;
  409.       else
  410. plist->head = pentry;
  411.       pentry->prev = plist->tail;
  412.       plist->tail = pentry;
  413.     }
  414.   /* Increment count. */
  415.   plist->count++;
  416.   /* Run hook function. */
  417.   if (plist->master->add_hook)
  418.     (*plist->master->add_hook) (plist);
  419.   plist->master->recent = plist;
  420. }
  421. /* Return string of prefix_list_type. */
  422. static char *
  423. prefix_list_type_str (struct prefix_list_entry *pentry)
  424. {
  425.   switch (pentry->type)
  426.     {
  427.     case PREFIX_PERMIT:
  428.       return "permit";
  429.       break;
  430.     case PREFIX_DENY:
  431.       return "deny";
  432.       break;
  433.     default:
  434.       return "";
  435.       break;
  436.     }
  437. }
  438. int
  439. prefix_list_entry_match (struct prefix_list_entry *pentry, struct prefix *p)
  440. {
  441.   int ret;
  442.   ret = prefix_match (&pentry->prefix, p);
  443.   if (! ret)
  444.     return 0;
  445.   
  446.   /* In case of le nor ge is specified, exact match is performed. */
  447.   if (! pentry->le && ! pentry->ge)
  448.     {
  449.       if (pentry->prefix.prefixlen != p->prefixlen)
  450. return 0;
  451.     }
  452.   else
  453.     {  
  454.       if (pentry->le)
  455. if (p->prefixlen > pentry->le)
  456.   return 0;
  457.       if (pentry->ge)
  458. if (p->prefixlen < pentry->ge)
  459.   return 0;
  460.     }
  461.   return 1;
  462. }
  463. enum prefix_list_type
  464. prefix_list_apply (struct prefix_list *plist, void *object)
  465. {
  466.   struct prefix_list_entry *pentry;
  467.   struct prefix *p;
  468.   p = (struct prefix *) object;
  469.   if (plist == NULL)
  470.     return PREFIX_DENY;
  471.   if (plist->count == 0)
  472.     return PREFIX_PERMIT;
  473.   for (pentry = plist->head; pentry; pentry = pentry->next)
  474.     {
  475.       pentry->refcnt++;
  476.       if (prefix_list_entry_match (pentry, p))
  477. {
  478.   pentry->hitcnt++;
  479.   return pentry->type;
  480. }
  481.     }
  482.   return PREFIX_DENY;
  483. }
  484. void
  485. prefix_list_print (struct prefix_list *plist)
  486. {
  487.   struct prefix_list_entry *pentry;
  488.   if (plist == NULL)
  489.     return;
  490.   printf ("ip prefix-list %s: %d entriesn", plist->name, plist->count);
  491.   for (pentry = plist->head; pentry; pentry = pentry->next)
  492.     {
  493.       if (pentry->any)
  494. printf ("any %sn", prefix_list_type_str (pentry));
  495.       else
  496. {
  497.   struct prefix *p;
  498.   char buf[BUFSIZ];
  499.   
  500.   p = &pentry->prefix;
  501.   
  502.   printf ("  seq %d %s %s/%d", 
  503.   pentry->seq,
  504.   prefix_list_type_str (pentry),
  505.   inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  506.   p->prefixlen);
  507.   if (pentry->ge)
  508.     printf (" ge %d", pentry->ge);
  509.   if (pentry->le)
  510.     printf (" le %d", pentry->le);
  511.   printf ("n");
  512. }
  513.     }
  514. }
  515. /* Retrun 1 when plist already include pentry policy. */
  516. struct prefix_list_entry *
  517. prefix_entry_dup_check (struct prefix_list *plist,
  518. struct prefix_list_entry *new)
  519. {
  520.   struct prefix_list_entry *pentry;
  521.   int seq = 0;
  522.   if (new->seq == -1)
  523.     seq = prefix_new_seq_get (plist);
  524.   else
  525.     seq = new->seq;
  526.   for (pentry = plist->head; pentry; pentry = pentry->next)
  527.     {
  528.       if (prefix_same (&pentry->prefix, &new->prefix)
  529.   && pentry->type == new->type
  530.   && pentry->le == new->le
  531.   && pentry->ge == new->ge
  532.   && pentry->seq != seq)
  533. return pentry;
  534.     }
  535.   return NULL;
  536. }
  537. int
  538. vty_invalid_prefix_range (struct vty *vty, char *prefix)
  539. {
  540.   vty_out (vty, "%% Invalid prefix range for %s, make sure: len < ge-value <= le-value%s",
  541.            prefix, VTY_NEWLINE);
  542.   return CMD_WARNING;
  543. }
  544. int
  545. vty_prefix_list_install (struct vty *vty, afi_t afi,
  546.  char *name, char *seq, char *typestr,
  547.  char *prefix, char *ge, char *le)
  548. {
  549.   int ret;
  550.   enum prefix_list_type type;
  551.   struct prefix_list *plist;
  552.   struct prefix_list_entry *pentry;
  553.   struct prefix_list_entry *dup;
  554.   struct prefix p;
  555.   int any = 0;
  556.   int seqnum = -1;
  557.   int lenum = 0;
  558.   int genum = 0;
  559.   /* Sequential number. */
  560.   if (seq)
  561.     seqnum = atoi (seq);
  562.   /* ge and le number */
  563.   if (ge)
  564.     genum = atoi (ge);
  565.   if (le)
  566.     lenum = atoi (le);
  567.   /* Check filter type. */
  568.   if (strncmp ("permit", typestr, 1) == 0)
  569.     type = PREFIX_PERMIT;
  570.   else if (strncmp ("deny", typestr, 1) == 0)
  571.     type = PREFIX_DENY;
  572.   else
  573.     {
  574.       vty_out (vty, "%% prefix type must be permit or deny%s", VTY_NEWLINE);
  575.       return CMD_WARNING;
  576.     }
  577.   /* "any" is special token for matching any IPv4 addresses.  */
  578.   if (afi == AFI_IP)
  579.     {
  580.       if (strncmp ("any", prefix, strlen (prefix)) == 0)
  581. {
  582.   ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p);
  583.   genum = 0;
  584.   lenum = IPV4_MAX_BITLEN;
  585.   any = 1;
  586. }
  587.       else
  588. ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p);
  589.       if (ret <= 0)
  590. {
  591.   vty_out (vty, "%% Malformed IPv4 prefix%s", VTY_NEWLINE);
  592.   return CMD_WARNING;
  593. }
  594.     }
  595. #ifdef HAVE_IPV6
  596.   else if (afi == AFI_IP6)
  597.     {
  598.       if (strncmp ("any", prefix, strlen (prefix)) == 0)
  599. {
  600.   ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p);
  601.   genum = 0;
  602.   lenum = IPV6_MAX_BITLEN;
  603.   any = 1;
  604. }
  605.       else
  606. ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p);
  607.       if (ret <= 0)
  608. {
  609.   vty_out (vty, "%% Malformed IPv6 prefix%s", VTY_NEWLINE);
  610.   return CMD_WARNING;
  611. }
  612.     }
  613. #endif /* HAVE_IPV6 */
  614.   /* ge and le check. */
  615.   if (genum && genum <= p.prefixlen)
  616.     return vty_invalid_prefix_range (vty, prefix);
  617.   if (lenum && lenum <= p.prefixlen)
  618.     return vty_invalid_prefix_range (vty, prefix);
  619.   if (lenum && genum > lenum)
  620.     return vty_invalid_prefix_range (vty, prefix);
  621.   if (genum && lenum == (afi == AFI_IP ? 32 : 128))
  622.     lenum = 0;
  623.   /* Get prefix_list with name. */
  624.   plist = prefix_list_get (afi, name);
  625.   /* Make prefix entry. */
  626.   pentry = prefix_list_entry_make (&p, type, seqnum, lenum, genum, any);
  627.     
  628.   /* Check same policy. */
  629.   dup = prefix_entry_dup_check (plist, pentry);
  630.   if (dup)
  631.     {
  632.       prefix_list_entry_free (pentry);
  633.       vty_out (vty, "%% Insertion failed - prefix-list entry exists:%s",
  634.        VTY_NEWLINE);
  635.       vty_out (vty, "   seq %d %s %s", dup->seq, typestr, prefix);
  636.       if (! any && genum)
  637. vty_out (vty, " ge %d", genum);
  638.       if (! any && lenum)
  639. vty_out (vty, " le %d", lenum);
  640.       vty_out (vty, "%s", VTY_NEWLINE);
  641.       return CMD_WARNING;
  642.     }
  643.   /* Install new filter to the access_list. */
  644.   prefix_list_entry_add (plist, pentry);
  645.   return CMD_SUCCESS;
  646. }
  647. int
  648. vty_prefix_list_uninstall (struct vty *vty, afi_t afi,
  649.    char *name, char *seq, char *typestr,
  650.    char *prefix, char *ge, char *le)
  651. {
  652.   int ret;
  653.   enum prefix_list_type type;
  654.   struct prefix_list *plist;
  655.   struct prefix_list_entry *pentry;
  656.   struct prefix p;
  657.   int seqnum = -1;
  658.   int lenum = 0;
  659.   int genum = 0;
  660.   /* Check prefix list name. */
  661.   plist = prefix_list_lookup (afi, name);
  662.   if (! plist)
  663.     {
  664.       vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  665.       return CMD_WARNING;
  666.     }
  667.   /* Only prefix-list name specified, delete the entire prefix-list. */
  668.   if (seq == NULL && typestr == NULL && prefix == NULL && 
  669.       ge == NULL && le == NULL)
  670.     {
  671.       prefix_list_delete (plist);
  672.       return CMD_SUCCESS;
  673.     }
  674.   /* Check sequence number. */
  675.   if (seq)
  676.     seqnum = atoi (seq);
  677.   /* ge and le number */
  678.   if (ge)
  679.     genum = atoi (ge);
  680.   if (le)
  681.     lenum = atoi (le);
  682.   /* Check of filter type. */
  683.   if (strncmp ("permit", typestr, 1) == 0)
  684.     type = PREFIX_PERMIT;
  685.   else if (strncmp ("deny", typestr, 1) == 0)
  686.     type = PREFIX_DENY;
  687.   else
  688.     {
  689.       vty_out (vty, "%% prefix type must be permit or deny%s", VTY_NEWLINE);
  690.       return CMD_WARNING;
  691.     }
  692.   /* "any" is special token for matching any IPv4 addresses.  */
  693.   if (afi == AFI_IP)
  694.     {
  695.       if (strncmp ("any", prefix, strlen (prefix)) == 0)
  696. {
  697.   ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p);
  698.   genum = 0;
  699.   lenum = IPV4_MAX_BITLEN;
  700. }
  701.       else
  702. ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p);
  703.       if (ret <= 0)
  704. {
  705.   vty_out (vty, "%% Malformed IPv4 prefix%s", VTY_NEWLINE);
  706.   return CMD_WARNING;
  707. }
  708.     }
  709. #ifdef HAVE_IPV6
  710.   else if (afi == AFI_IP6)
  711.     {
  712.       if (strncmp ("any", prefix, strlen (prefix)) == 0)
  713. {
  714.   ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p);
  715.   genum = 0;
  716.   lenum = IPV6_MAX_BITLEN;
  717. }
  718.       else
  719. ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p);
  720.       if (ret <= 0)
  721. {
  722.   vty_out (vty, "%% Malformed IPv6 prefix%s", VTY_NEWLINE);
  723.   return CMD_WARNING;
  724. }
  725.     }
  726. #endif /* HAVE_IPV6 */
  727.   /* Lookup prefix entry. */
  728.   pentry = prefix_list_entry_lookup(plist, &p, type, seqnum, lenum, genum);
  729.   if (pentry == NULL)
  730.     {
  731.       vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  732.       return CMD_WARNING;
  733.     }
  734.   /* Install new filter to the access_list. */
  735.   prefix_list_entry_delete (plist, pentry, 1);
  736.   return CMD_SUCCESS;
  737. }
  738. int
  739. vty_prefix_list_desc_unset (struct vty *vty, afi_t afi, char *name)
  740. {
  741.   struct prefix_list *plist;
  742.   plist = prefix_list_lookup (afi, name);
  743.   if (! plist)
  744.     {
  745.       vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  746.       return CMD_WARNING;
  747.     }
  748.   if (plist->desc)
  749.     {
  750.       XFREE (MTYPE_TMP, plist->desc);
  751.       plist->desc = NULL;
  752.     }
  753.   if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL)
  754.     prefix_list_delete (plist);
  755.   return CMD_SUCCESS;
  756. }
  757. enum display_type
  758. {
  759.   normal_display,
  760.   summary_display,
  761.   detail_display,
  762.   sequential_display,
  763.   longer_display,
  764.   first_match_display
  765. };
  766. void
  767. vty_show_prefix_entry (struct vty *vty, afi_t afi, struct prefix_list *plist,
  768.        struct prefix_master *master, enum display_type dtype,
  769.        int seqnum)
  770. {
  771.   struct prefix_list_entry *pentry;
  772.   if (dtype == normal_display)
  773.     {
  774.       vty_out (vty, "ip%s prefix-list %s: %d entries%s",
  775.        afi == AFI_IP ? "" : "v6",
  776.        plist->name, plist->count, VTY_NEWLINE);
  777.       if (plist->desc)
  778. vty_out (vty, "   Description: %s%s", plist->desc, VTY_NEWLINE);
  779.     }
  780.   else if (dtype == summary_display || dtype == detail_display)
  781.     {
  782.       vty_out (vty, "ip%s prefix-list %s:%s",
  783.        afi == AFI_IP ? "" : "v6", plist->name, VTY_NEWLINE);
  784.       if (plist->desc)
  785. vty_out (vty, "   Description: %s%s", plist->desc, VTY_NEWLINE);
  786.       vty_out (vty, "   count: %d, range entries: %d, sequences: %d - %d%s",
  787.        plist->count, plist->rangecount, 
  788.        plist->head ? plist->head->seq : 0, 
  789.        plist->tail ? plist->tail->seq : 0,
  790.        VTY_NEWLINE);
  791.     }
  792.   if (dtype != summary_display)
  793.     {
  794.       for (pentry = plist->head; pentry; pentry = pentry->next)
  795. {
  796.   if (dtype == sequential_display && pentry->seq != seqnum)
  797.     continue;
  798.     
  799.   vty_out (vty, "   ");
  800.   if (master->seqnum)
  801.     vty_out (vty, "seq %d ", pentry->seq);
  802.   vty_out (vty, "%s ", prefix_list_type_str (pentry));
  803.   if (pentry->any)
  804.     vty_out (vty, "any");
  805.   else
  806.     {
  807.       struct prefix *p = &pentry->prefix;
  808.       char buf[BUFSIZ];
  809.       vty_out (vty, "%s/%d",
  810.        inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  811.        p->prefixlen);
  812.       if (pentry->ge)
  813. vty_out (vty, " ge %d", pentry->ge);
  814.       if (pentry->le)
  815. vty_out (vty, " le %d", pentry->le);
  816.     }
  817.   if (dtype == detail_display || dtype == sequential_display)
  818.     vty_out (vty, " (hit count: %ld, refcount: %ld)", 
  819.      pentry->hitcnt, pentry->refcnt);
  820.   
  821.   vty_out (vty, "%s", VTY_NEWLINE);
  822. }
  823.     }
  824. }
  825. int
  826. vty_show_prefix_list (struct vty *vty, afi_t afi, char *name,
  827.       char *seq, enum display_type dtype)
  828. {
  829.   struct prefix_list *plist;
  830.   struct prefix_master *master;
  831.   int seqnum = 0;
  832.   master = prefix_master_get (afi);
  833.   if (master == NULL)
  834.     return CMD_WARNING;
  835.   if (seq)
  836.     seqnum = atoi (seq);
  837.   if (name)
  838.     {
  839.       plist = prefix_list_lookup (afi, name);
  840.       if (! plist)
  841. {
  842.   vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  843.   return CMD_WARNING;
  844. }
  845.       vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
  846.     }
  847.   else
  848.     {
  849.       if (dtype == detail_display || dtype == summary_display)
  850. {
  851.   if (master->recent)
  852.     vty_out (vty, "Prefix-list with the last deletion/insertion: %s%s",
  853.      master->recent->name, VTY_NEWLINE);
  854. }
  855.       for (plist = master->num.head; plist; plist = plist->next)
  856. vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
  857.       for (plist = master->str.head; plist; plist = plist->next)
  858. vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
  859.     }
  860.   return CMD_SUCCESS;
  861. }
  862. int
  863. vty_show_prefix_list_prefix (struct vty *vty, afi_t afi, char *name, 
  864.      char *prefix, enum display_type type)
  865. {
  866.   struct prefix_list *plist;
  867.   struct prefix_list_entry *pentry;
  868.   struct prefix p;
  869.   int ret;
  870.   int match;
  871.   plist = prefix_list_lookup (afi, name);
  872.   if (! plist)
  873.     {
  874.       vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  875.       return CMD_WARNING;
  876.     }
  877.   ret = str2prefix (prefix, &p);
  878.   if (ret <= 0)
  879.     {
  880.       vty_out (vty, "%% prefix is malformed%s", VTY_NEWLINE);
  881.       return CMD_WARNING;
  882.     }
  883.   for (pentry = plist->head; pentry; pentry = pentry->next)
  884.     {
  885.       match = 0;
  886.       if (type == normal_display || type == first_match_display)
  887. if (prefix_same (&p, &pentry->prefix))
  888.   match = 1;
  889.       if (type == longer_display)
  890. if (prefix_match (&p, &pentry->prefix))
  891.   match = 1;
  892.       if (match)
  893. {
  894.   vty_out (vty, "   seq %d %s ", 
  895.    pentry->seq,
  896.    prefix_list_type_str (pentry));
  897.   if (pentry->any)
  898.     vty_out (vty, "any");
  899.   else
  900.     {
  901.       struct prefix *p = &pentry->prefix;
  902.       char buf[BUFSIZ];
  903.       
  904.       vty_out (vty, "%s/%d",
  905.        inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  906.        p->prefixlen);
  907.       if (pentry->ge)
  908. vty_out (vty, " ge %d", pentry->ge);
  909.       if (pentry->le)
  910. vty_out (vty, " le %d", pentry->le);
  911.     }
  912.   
  913.   if (type == normal_display || type == first_match_display)
  914.     vty_out (vty, " (hit count: %ld, refcount: %ld)", 
  915.      pentry->hitcnt, pentry->refcnt);
  916.   vty_out (vty, "%s", VTY_NEWLINE);
  917.   if (type == first_match_display)
  918.     return CMD_SUCCESS;
  919. }
  920.     }
  921.   return CMD_SUCCESS;
  922. }
  923. int
  924. vty_clear_prefix_list (struct vty *vty, afi_t afi, char *name, char *prefix)
  925. {
  926.   struct prefix_master *master;
  927.   struct prefix_list *plist;
  928.   struct prefix_list_entry *pentry;
  929.   int ret;
  930.   struct prefix p;
  931.   master = prefix_master_get (afi);
  932.   if (master == NULL)
  933.     return CMD_WARNING;
  934.   if (name == NULL && prefix == NULL)
  935.     {
  936.       for (plist = master->num.head; plist; plist = plist->next)
  937. for (pentry = plist->head; pentry; pentry = pentry->next)
  938.   pentry->hitcnt = 0;
  939.       for (plist = master->str.head; plist; plist = plist->next)
  940. for (pentry = plist->head; pentry; pentry = pentry->next)
  941.   pentry->hitcnt = 0;
  942.     }
  943.   else
  944.     {
  945.       plist = prefix_list_lookup (afi, name);
  946.       if (! plist)
  947. {
  948.   vty_out (vty, "%% Can't find specified prefix-list%s", VTY_NEWLINE);
  949.   return CMD_WARNING;
  950. }
  951.       if (prefix)
  952. {
  953.   ret = str2prefix (prefix, &p);
  954.   if (ret <= 0)
  955.     {
  956.       vty_out (vty, "%% prefix is malformed%s", VTY_NEWLINE);
  957.       return CMD_WARNING;
  958.     }
  959. }
  960.       for (pentry = plist->head; pentry; pentry = pentry->next)
  961. {
  962.   if (prefix)
  963.     {
  964.       if (prefix_match (&pentry->prefix, &p))
  965. pentry->hitcnt = 0;
  966.     }
  967.   else
  968.     pentry->hitcnt = 0;
  969. }
  970.     }
  971.   return CMD_SUCCESS;
  972. }
  973. DEFUN (ip_prefix_list,
  974.        ip_prefix_list_cmd,
  975.        "ip prefix-list WORD (deny|permit) (A.B.C.D/M|any)",
  976.        IP_STR
  977.        PREFIX_LIST_STR
  978.        "Name of a prefix listn"
  979.        "Specify packets to rejectn"
  980.        "Specify packets to forwardn"
  981.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  982.        "Any prefix match. Same as "0.0.0.0/0 le 32"n")
  983. {
  984.   return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, 
  985.   argv[1], argv[2], NULL, NULL);
  986. }
  987. DEFUN (ip_prefix_list_ge,
  988.        ip_prefix_list_ge_cmd,
  989.        "ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32>",
  990.        IP_STR
  991.        PREFIX_LIST_STR
  992.        "Name of a prefix listn"
  993.        "Specify packets to rejectn"
  994.        "Specify packets to forwardn"
  995.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  996.        "Minimum prefix length to be matchedn"
  997.        "Minimum prefix lengthn")
  998. {
  999.   return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1], 
  1000.  argv[2], argv[3], NULL);
  1001. }
  1002. DEFUN (ip_prefix_list_ge_le,
  1003.        ip_prefix_list_ge_le_cmd,
  1004.        "ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
  1005.        IP_STR
  1006.        PREFIX_LIST_STR
  1007.        "Name of a prefix listn"
  1008.        "Specify packets to rejectn"
  1009.        "Specify packets to forwardn"
  1010.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1011.        "Minimum prefix length to be matchedn"
  1012.        "Minimum prefix lengthn"
  1013.        "Maximum prefix length to be matchedn"
  1014.        "Maximum prefix lengthn")
  1015. {
  1016.   return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1], 
  1017.   argv[2], argv[3], argv[4]);
  1018. }
  1019. DEFUN (ip_prefix_list_le,
  1020.        ip_prefix_list_le_cmd,
  1021.        "ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32>",
  1022.        IP_STR
  1023.        PREFIX_LIST_STR
  1024.        "Name of a prefix listn"
  1025.        "Specify packets to rejectn"
  1026.        "Specify packets to forwardn"
  1027.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1028.        "Maximum prefix length to be matchedn"
  1029.        "Maximum prefix lengthn")
  1030. {
  1031.   return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
  1032.   argv[2], NULL, argv[3]);
  1033. }
  1034. DEFUN (ip_prefix_list_le_ge,
  1035.        ip_prefix_list_le_ge_cmd,
  1036.        "ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
  1037.        IP_STR
  1038.        PREFIX_LIST_STR
  1039.        "Name of a prefix listn"
  1040.        "Specify packets to rejectn"
  1041.        "Specify packets to forwardn"
  1042.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1043.        "Maximum prefix length to be matchedn"
  1044.        "Maximum prefix lengthn"
  1045.        "Minimum prefix length to be matchedn"
  1046.        "Minimum prefix lengthn")
  1047. {
  1048.   return vty_prefix_list_install (vty, AFI_IP, argv[0], NULL, argv[1],
  1049.   argv[2], argv[4], argv[3]);
  1050. }
  1051. DEFUN (ip_prefix_list_seq,
  1052.        ip_prefix_list_seq_cmd,
  1053.        "ip prefix-list WORD seq <1-4294967295> (deny|permit) (A.B.C.D/M|any)",
  1054.        IP_STR
  1055.        PREFIX_LIST_STR
  1056.        "Name of a prefix listn"
  1057.        "sequence number of an entryn"
  1058.        "Sequence numbern"
  1059.        "Specify packets to rejectn"
  1060.        "Specify packets to forwardn"
  1061.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1062.        "Any prefix match. Same as "0.0.0.0/0 le 32"n")
  1063. {
  1064.   return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
  1065.   argv[3], NULL, NULL);
  1066. }
  1067. DEFUN (ip_prefix_list_seq_ge,
  1068.        ip_prefix_list_seq_ge_cmd,
  1069.        "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32>",
  1070.        IP_STR
  1071.        PREFIX_LIST_STR
  1072.        "Name of a prefix listn"
  1073.        "sequence number of an entryn"
  1074.        "Sequence numbern"
  1075.        "Specify packets to rejectn"
  1076.        "Specify packets to forwardn"
  1077.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1078.        "Minimum prefix length to be matchedn"
  1079.        "Minimum prefix lengthn")
  1080. {
  1081.   return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
  1082.   argv[3], argv[4], NULL);
  1083. }
  1084. DEFUN (ip_prefix_list_seq_ge_le,
  1085.        ip_prefix_list_seq_ge_le_cmd,
  1086.        "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
  1087.        IP_STR
  1088.        PREFIX_LIST_STR
  1089.        "Name of a prefix listn"
  1090.        "sequence number of an entryn"
  1091.        "Sequence numbern"
  1092.        "Specify packets to rejectn"
  1093.        "Specify packets to forwardn"
  1094.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1095.        "Minimum prefix length to be matchedn"
  1096.        "Minimum prefix lengthn"
  1097.        "Maximum prefix length to be matchedn"
  1098.        "Maximum prefix lengthn")
  1099. {
  1100.   return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
  1101.   argv[3], argv[4], argv[5]);
  1102. }
  1103. DEFUN (ip_prefix_list_seq_le,
  1104.        ip_prefix_list_seq_le_cmd,
  1105.        "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32>",
  1106.        IP_STR
  1107.        PREFIX_LIST_STR
  1108.        "Name of a prefix listn"
  1109.        "sequence number of an entryn"
  1110.        "Sequence numbern"
  1111.        "Specify packets to rejectn"
  1112.        "Specify packets to forwardn"
  1113.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1114.        "Maximum prefix length to be matchedn"
  1115.        "Maximum prefix lengthn")
  1116. {
  1117.   return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
  1118.   argv[3], NULL, argv[4]);
  1119. }
  1120. DEFUN (ip_prefix_list_seq_le_ge,
  1121.        ip_prefix_list_seq_le_ge_cmd,
  1122.        "ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
  1123.        IP_STR
  1124.        PREFIX_LIST_STR
  1125.        "Name of a prefix listn"
  1126.        "sequence number of an entryn"
  1127.        "Sequence numbern"
  1128.        "Specify packets to rejectn"
  1129.        "Specify packets to forwardn"
  1130.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1131.        "Maximum prefix length to be matchedn"
  1132.        "Maximum prefix lengthn"
  1133.        "Minimum prefix length to be matchedn"
  1134.        "Minimum prefix lengthn")
  1135. {
  1136.   return vty_prefix_list_install (vty, AFI_IP, argv[0], argv[1], argv[2],
  1137.   argv[3], argv[5], argv[4]);
  1138. }
  1139. DEFUN (no_ip_prefix_list,
  1140.        no_ip_prefix_list_cmd,
  1141.        "no ip prefix-list WORD",
  1142.        NO_STR
  1143.        IP_STR
  1144.        PREFIX_LIST_STR
  1145.        "Name of a prefix listn")
  1146. {
  1147.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, NULL,
  1148.     NULL, NULL, NULL);
  1149. }
  1150. DEFUN (no_ip_prefix_list_prefix,
  1151.        no_ip_prefix_list_prefix_cmd,
  1152.        "no ip prefix-list WORD (deny|permit) (A.B.C.D/M|any)",
  1153.        NO_STR
  1154.        IP_STR
  1155.        PREFIX_LIST_STR
  1156.        "Name of a prefix listn"
  1157.        "Specify packets to rejectn"
  1158.        "Specify packets to forwardn"
  1159.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1160.        "Any prefix match.  Same as "0.0.0.0/0 le 32"n")
  1161. {
  1162.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
  1163.     argv[2], NULL, NULL);
  1164. }
  1165. DEFUN (no_ip_prefix_list_ge,
  1166.        no_ip_prefix_list_ge_cmd,
  1167.        "no ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32>",
  1168.        NO_STR
  1169.        IP_STR
  1170.        PREFIX_LIST_STR
  1171.        "Name of a prefix listn"
  1172.        "Specify packets to rejectn"
  1173.        "Specify packets to forwardn"
  1174.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1175.        "Minimum prefix length to be matchedn"
  1176.        "Minimum prefix lengthn")
  1177. {
  1178.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
  1179.     argv[2], argv[3], NULL);
  1180. }
  1181. DEFUN (no_ip_prefix_list_ge_le,
  1182.        no_ip_prefix_list_ge_le_cmd,
  1183.        "no ip prefix-list WORD (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
  1184.        NO_STR
  1185.        IP_STR
  1186.        PREFIX_LIST_STR
  1187.        "Name of a prefix listn"
  1188.        "Specify packets to rejectn"
  1189.        "Specify packets to forwardn"
  1190.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1191.        "Minimum prefix length to be matchedn"
  1192.        "Minimum prefix lengthn"
  1193.        "Maximum prefix length to be matchedn"
  1194.        "Maximum prefix lengthn")
  1195. {
  1196.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
  1197.     argv[2], argv[3], argv[4]);
  1198. }
  1199. DEFUN (no_ip_prefix_list_le,
  1200.        no_ip_prefix_list_le_cmd,
  1201.        "no ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32>",
  1202.        NO_STR
  1203.        IP_STR
  1204.        PREFIX_LIST_STR
  1205.        "Name of a prefix listn"
  1206.        "Specify packets to rejectn"
  1207.        "Specify packets to forwardn"
  1208.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1209.        "Maximum prefix length to be matchedn"
  1210.        "Maximum prefix lengthn")
  1211. {
  1212.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
  1213.     argv[2], NULL, argv[3]);
  1214. }
  1215. DEFUN (no_ip_prefix_list_le_ge,
  1216.        no_ip_prefix_list_le_ge_cmd,
  1217.        "no ip prefix-list WORD (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
  1218.        NO_STR
  1219.        IP_STR
  1220.        PREFIX_LIST_STR
  1221.        "Name of a prefix listn"
  1222.        "Specify packets to rejectn"
  1223.        "Specify packets to forwardn"
  1224.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1225.        "Maximum prefix length to be matchedn"
  1226.        "Maximum prefix lengthn"
  1227.        "Minimum prefix length to be matchedn"
  1228.        "Minimum prefix lengthn")
  1229. {
  1230.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], NULL, argv[1],
  1231.     argv[2], argv[4], argv[3]);
  1232. }
  1233. DEFUN (no_ip_prefix_list_seq,
  1234.        no_ip_prefix_list_seq_cmd,
  1235.        "no ip prefix-list WORD seq <1-4294967295> (deny|permit) (A.B.C.D/M|any)",
  1236.        NO_STR
  1237.        IP_STR
  1238.        PREFIX_LIST_STR
  1239.        "Name of a prefix listn"
  1240.        "sequence number of an entryn"
  1241.        "Sequence numbern"
  1242.        "Specify packets to rejectn"
  1243.        "Specify packets to forwardn"
  1244.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1245.        "Any prefix match.  Same as "0.0.0.0/0 le 32"n")
  1246. {
  1247.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
  1248.     argv[3], NULL, NULL);
  1249. }
  1250. DEFUN (no_ip_prefix_list_seq_ge,
  1251.        no_ip_prefix_list_seq_ge_cmd,
  1252.        "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32>",
  1253.        NO_STR
  1254.        IP_STR
  1255.        PREFIX_LIST_STR
  1256.        "Name of a prefix listn"
  1257.        "sequence number of an entryn"
  1258.        "Sequence numbern"
  1259.        "Specify packets to rejectn"
  1260.        "Specify packets to forwardn"
  1261.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1262.        "Minimum prefix length to be matchedn"
  1263.        "Minimum prefix lengthn")
  1264. {
  1265.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
  1266.     argv[3], argv[4], NULL);
  1267. }
  1268. DEFUN (no_ip_prefix_list_seq_ge_le,
  1269.        no_ip_prefix_list_seq_ge_le_cmd,
  1270.        "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M ge <0-32> le <0-32>",
  1271.        NO_STR
  1272.        IP_STR
  1273.        PREFIX_LIST_STR
  1274.        "Name of a prefix listn"
  1275.        "sequence number of an entryn"
  1276.        "Sequence numbern"
  1277.        "Specify packets to rejectn"
  1278.        "Specify packets to forwardn"
  1279.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1280.        "Minimum prefix length to be matchedn"
  1281.        "Minimum prefix lengthn"
  1282.        "Maximum prefix length to be matchedn"
  1283.        "Maximum prefix lengthn")
  1284. {
  1285.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
  1286.     argv[3], argv[4], argv[5]);
  1287. }
  1288. DEFUN (no_ip_prefix_list_seq_le,
  1289.        no_ip_prefix_list_seq_le_cmd,
  1290.        "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32>",
  1291.        NO_STR
  1292.        IP_STR
  1293.        PREFIX_LIST_STR
  1294.        "Name of a prefix listn"
  1295.        "sequence number of an entryn"
  1296.        "Sequence numbern"
  1297.        "Specify packets to rejectn"
  1298.        "Specify packets to forwardn"
  1299.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1300.        "Maximum prefix length to be matchedn"
  1301.        "Maximum prefix lengthn")
  1302. {
  1303.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
  1304.     argv[3], NULL, argv[4]);
  1305. }
  1306. DEFUN (no_ip_prefix_list_seq_le_ge,
  1307.        no_ip_prefix_list_seq_le_ge_cmd,
  1308.        "no ip prefix-list WORD seq <1-4294967295> (deny|permit) A.B.C.D/M le <0-32> ge <0-32>",
  1309.        NO_STR
  1310.        IP_STR
  1311.        PREFIX_LIST_STR
  1312.        "Name of a prefix listn"
  1313.        "sequence number of an entryn"
  1314.        "Sequence numbern"
  1315.        "Specify packets to rejectn"
  1316.        "Specify packets to forwardn"
  1317.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1318.        "Maximum prefix length to be matchedn"
  1319.        "Maximum prefix lengthn"
  1320.        "Minimum prefix length to be matchedn"
  1321.        "Minimum prefix lengthn")
  1322. {
  1323.   return vty_prefix_list_uninstall (vty, AFI_IP, argv[0], argv[1], argv[2],
  1324.     argv[3], argv[5], argv[4]);
  1325. }
  1326. DEFUN (ip_prefix_list_sequence_number,
  1327.        ip_prefix_list_sequence_number_cmd,
  1328.        "ip prefix-list sequence-number",
  1329.        IP_STR
  1330.        PREFIX_LIST_STR
  1331.        "Include/exclude sequence numbers in NVGENn")
  1332. {
  1333.   prefix_master_ipv4.seqnum = 1;
  1334.   return CMD_SUCCESS;
  1335. }
  1336. DEFUN (no_ip_prefix_list_sequence_number,
  1337.        no_ip_prefix_list_sequence_number_cmd,
  1338.        "no ip prefix-list sequence-number",
  1339.        NO_STR
  1340.        IP_STR
  1341.        PREFIX_LIST_STR
  1342.        "Include/exclude sequence numbers in NVGENn")
  1343. {
  1344.   prefix_master_ipv4.seqnum = 0;
  1345.   return CMD_SUCCESS;
  1346. }
  1347. DEFUN (ip_prefix_list_description,
  1348.        ip_prefix_list_description_cmd,
  1349.        "ip prefix-list WORD description .LINE",
  1350.        IP_STR
  1351.        PREFIX_LIST_STR
  1352.        "Name of a prefix listn"
  1353.        "Prefix-list specific descriptionn"
  1354.        "Up to 80 characters describing this prefix-listn")
  1355. {
  1356.   struct prefix_list *plist;
  1357.   struct buffer *b;
  1358.   int i;
  1359.   plist = prefix_list_get (AFI_IP, argv[0]);
  1360.   
  1361.   if (plist->desc)
  1362.     {
  1363.       XFREE (MTYPE_TMP, plist->desc);
  1364.       plist->desc = NULL;
  1365.     }
  1366.   /* Below is description get codes. */
  1367.   b = buffer_new (1024);
  1368.   for (i = 1; i < argc; i++)
  1369.     {
  1370.       buffer_putstr (b, (u_char *)argv[i]);
  1371.       buffer_putc (b, ' ');
  1372.     }
  1373.   buffer_putc (b, '');
  1374.   plist->desc = buffer_getstr (b);
  1375.   buffer_free (b);
  1376.   return CMD_SUCCESS;
  1377. }       
  1378. DEFUN (no_ip_prefix_list_description,
  1379.        no_ip_prefix_list_description_cmd,
  1380.        "no ip prefix-list WORD description",
  1381.        NO_STR
  1382.        IP_STR
  1383.        PREFIX_LIST_STR
  1384.        "Name of a prefix listn"
  1385.        "Prefix-list specific descriptionn")
  1386. {
  1387.   return vty_prefix_list_desc_unset (vty, AFI_IP, argv[0]);
  1388. }
  1389. ALIAS (no_ip_prefix_list_description,
  1390.        no_ip_prefix_list_description_arg_cmd,
  1391.        "no ip prefix-list WORD description .LINE",
  1392.        NO_STR
  1393.        IP_STR
  1394.        PREFIX_LIST_STR
  1395.        "Name of a prefix listn"
  1396.        "Prefix-list specific descriptionn"
  1397.        "Up to 80 characters describing this prefix-listn");
  1398. DEFUN (show_ip_prefix_list,
  1399.        show_ip_prefix_list_cmd,
  1400.        "show ip prefix-list",
  1401.        SHOW_STR
  1402.        IP_STR
  1403.        PREFIX_LIST_STR)
  1404. {
  1405.   return vty_show_prefix_list (vty, AFI_IP, NULL, NULL, normal_display);
  1406. }
  1407. DEFUN (show_ip_prefix_list_name,
  1408.        show_ip_prefix_list_name_cmd,
  1409.        "show ip prefix-list WORD",
  1410.        SHOW_STR
  1411.        IP_STR
  1412.        PREFIX_LIST_STR
  1413.        "Name of a prefix listn")
  1414. {
  1415.   return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, normal_display);
  1416. }
  1417. DEFUN (show_ip_prefix_list_name_seq,
  1418.        show_ip_prefix_list_name_seq_cmd,
  1419.        "show ip prefix-list WORD seq <1-4294967295>",
  1420.        SHOW_STR
  1421.        IP_STR
  1422.        PREFIX_LIST_STR
  1423.        "Name of a prefix listn"
  1424.        "sequence number of an entryn"
  1425.        "Sequence numbern")
  1426. {
  1427.   return vty_show_prefix_list (vty, AFI_IP, argv[0], argv[1], sequential_display);
  1428. }
  1429. DEFUN (show_ip_prefix_list_prefix,
  1430.        show_ip_prefix_list_prefix_cmd,
  1431.        "show ip prefix-list WORD A.B.C.D/M",
  1432.        SHOW_STR
  1433.        IP_STR
  1434.        PREFIX_LIST_STR
  1435.        "Name of a prefix listn"
  1436.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1437. {
  1438.   return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], normal_display);
  1439. }
  1440. DEFUN (show_ip_prefix_list_prefix_longer,
  1441.        show_ip_prefix_list_prefix_longer_cmd,
  1442.        "show ip prefix-list WORD A.B.C.D/M longer",
  1443.        SHOW_STR
  1444.        IP_STR
  1445.        PREFIX_LIST_STR
  1446.        "Name of a prefix listn"
  1447.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1448.        "Lookup longer prefixn")
  1449. {
  1450.   return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], longer_display);
  1451. }
  1452. DEFUN (show_ip_prefix_list_prefix_first_match,
  1453.        show_ip_prefix_list_prefix_first_match_cmd,
  1454.        "show ip prefix-list WORD A.B.C.D/M first-match",
  1455.        SHOW_STR
  1456.        IP_STR
  1457.        PREFIX_LIST_STR
  1458.        "Name of a prefix listn"
  1459.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n"
  1460.        "First matched prefixn")
  1461. {
  1462.   return vty_show_prefix_list_prefix (vty, AFI_IP, argv[0], argv[1], first_match_display);
  1463. }
  1464. DEFUN (show_ip_prefix_list_summary,
  1465.        show_ip_prefix_list_summary_cmd,
  1466.        "show ip prefix-list summary",
  1467.        SHOW_STR
  1468.        IP_STR
  1469.        PREFIX_LIST_STR
  1470.        "Summary of prefix listsn")
  1471. {
  1472.   return vty_show_prefix_list (vty, AFI_IP, NULL, NULL, summary_display);
  1473. }
  1474. DEFUN (show_ip_prefix_list_summary_name,
  1475.        show_ip_prefix_list_summary_name_cmd,
  1476.        "show ip prefix-list summary WORD",
  1477.        SHOW_STR
  1478.        IP_STR
  1479.        PREFIX_LIST_STR
  1480.        "Summary of prefix listsn"
  1481.        "Name of a prefix listn")
  1482. {
  1483.   return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, summary_display);
  1484. }
  1485. DEFUN (show_ip_prefix_list_detail,
  1486.        show_ip_prefix_list_detail_cmd,
  1487.        "show ip prefix-list detail",
  1488.        SHOW_STR
  1489.        IP_STR
  1490.        PREFIX_LIST_STR
  1491.        "Detail of prefix listsn")
  1492. {
  1493.   return vty_show_prefix_list (vty, AFI_IP, NULL, NULL, detail_display);
  1494. }
  1495. DEFUN (show_ip_prefix_list_detail_name,
  1496.        show_ip_prefix_list_detail_name_cmd,
  1497.        "show ip prefix-list detail WORD",
  1498.        SHOW_STR
  1499.        IP_STR
  1500.        PREFIX_LIST_STR
  1501.        "Detail of prefix listsn"
  1502.        "Name of a prefix listn")
  1503. {
  1504.   return vty_show_prefix_list (vty, AFI_IP, argv[0], NULL, detail_display);
  1505. }
  1506. DEFUN (clear_ip_prefix_list,
  1507.        clear_ip_prefix_list_cmd,
  1508.        "clear ip prefix-list",
  1509.        CLEAR_STR
  1510.        IP_STR
  1511.        PREFIX_LIST_STR)
  1512. {
  1513.   return vty_clear_prefix_list (vty, AFI_IP, NULL, NULL);
  1514. }
  1515. DEFUN (clear_ip_prefix_list_name,
  1516.        clear_ip_prefix_list_name_cmd,
  1517.        "clear ip prefix-list WORD",
  1518.        CLEAR_STR
  1519.        IP_STR
  1520.        PREFIX_LIST_STR
  1521.        "Name of a prefix listn")
  1522. {
  1523.   return vty_clear_prefix_list (vty, AFI_IP, argv[0], NULL);
  1524. }
  1525. DEFUN (clear_ip_prefix_list_name_prefix,
  1526.        clear_ip_prefix_list_name_prefix_cmd,
  1527.        "clear ip prefix-list WORD A.B.C.D/M",
  1528.        CLEAR_STR
  1529.        IP_STR
  1530.        PREFIX_LIST_STR
  1531.        "Name of a prefix listn"
  1532.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1533. {
  1534.   return vty_clear_prefix_list (vty, AFI_IP, argv[0], argv[1]);
  1535. }
  1536. #ifdef HAVE_IPV6
  1537. DEFUN (ipv6_prefix_list,
  1538.        ipv6_prefix_list_cmd,
  1539.        "ipv6 prefix-list WORD (deny|permit) (X:X::X:X/M|any)",
  1540.        IPV6_STR
  1541.        PREFIX_LIST_STR
  1542.        "Name of a prefix listn"
  1543.        "Specify packets to rejectn"
  1544.        "Specify packets to forwardn"
  1545.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1546.        "Any prefix match.  Same as "::0/0 le 128"n")
  1547. {
  1548.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, 
  1549.   argv[1], argv[2], NULL, NULL);
  1550. }
  1551. DEFUN (ipv6_prefix_list_ge,
  1552.        ipv6_prefix_list_ge_cmd,
  1553.        "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128>",
  1554.        IPV6_STR
  1555.        PREFIX_LIST_STR
  1556.        "Name of a prefix listn"
  1557.        "Specify packets to rejectn"
  1558.        "Specify packets to forwardn"
  1559.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1560.        "Minimum prefix length to be matchedn"
  1561.        "Minimum prefix lengthn")
  1562. {
  1563.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1], 
  1564.  argv[2], argv[3], NULL);
  1565. }
  1566. DEFUN (ipv6_prefix_list_ge_le,
  1567.        ipv6_prefix_list_ge_le_cmd,
  1568.        "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
  1569.        IPV6_STR
  1570.        PREFIX_LIST_STR
  1571.        "Name of a prefix listn"
  1572.        "Specify packets to rejectn"
  1573.        "Specify packets to forwardn"
  1574.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1575.        "Minimum prefix length to be matchedn"
  1576.        "Minimum prefix lengthn"
  1577.        "Maximum prefix length to be matchedn"
  1578.        "Maximum prefix lengthn")
  1579. {
  1580.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1], 
  1581.   argv[2], argv[3], argv[4]);
  1582. }
  1583. DEFUN (ipv6_prefix_list_le,
  1584.        ipv6_prefix_list_le_cmd,
  1585.        "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128>",
  1586.        IPV6_STR
  1587.        PREFIX_LIST_STR
  1588.        "Name of a prefix listn"
  1589.        "Specify packets to rejectn"
  1590.        "Specify packets to forwardn"
  1591.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1592.        "Maximum prefix length to be matchedn"
  1593.        "Maximum prefix lengthn")
  1594. {
  1595.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
  1596.   argv[2], NULL, argv[3]);
  1597. }
  1598. DEFUN (ipv6_prefix_list_le_ge,
  1599.        ipv6_prefix_list_le_ge_cmd,
  1600.        "ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
  1601.        IPV6_STR
  1602.        PREFIX_LIST_STR
  1603.        "Name of a prefix listn"
  1604.        "Specify packets to rejectn"
  1605.        "Specify packets to forwardn"
  1606.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1607.        "Maximum prefix length to be matchedn"
  1608.        "Maximum prefix lengthn"
  1609.        "Minimum prefix length to be matchedn"
  1610.        "Minimum prefix lengthn")
  1611. {
  1612.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], NULL, argv[1],
  1613.   argv[2], argv[4], argv[3]);
  1614. }
  1615. DEFUN (ipv6_prefix_list_seq,
  1616.        ipv6_prefix_list_seq_cmd,
  1617.        "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) (X:X::X:X/M|any)",
  1618.        IPV6_STR
  1619.        PREFIX_LIST_STR
  1620.        "Name of a prefix listn"
  1621.        "sequence number of an entryn"
  1622.        "Sequence numbern"
  1623.        "Specify packets to rejectn"
  1624.        "Specify packets to forwardn"
  1625.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1626.        "Any prefix match.  Same as "::0/0 le 128"n")
  1627. {
  1628.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1629.   argv[3], NULL, NULL);
  1630. }
  1631. DEFUN (ipv6_prefix_list_seq_ge,
  1632.        ipv6_prefix_list_seq_ge_cmd,
  1633.        "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128>",
  1634.        IPV6_STR
  1635.        PREFIX_LIST_STR
  1636.        "Name of a prefix listn"
  1637.        "sequence number of an entryn"
  1638.        "Sequence numbern"
  1639.        "Specify packets to rejectn"
  1640.        "Specify packets to forwardn"
  1641.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1642.        "Minimum prefix length to be matchedn"
  1643.        "Minimum prefix lengthn")
  1644. {
  1645.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1646.   argv[3], argv[4], NULL);
  1647. }
  1648. DEFUN (ipv6_prefix_list_seq_ge_le,
  1649.        ipv6_prefix_list_seq_ge_le_cmd,
  1650.        "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
  1651.        IPV6_STR
  1652.        PREFIX_LIST_STR
  1653.        "Name of a prefix listn"
  1654.        "sequence number of an entryn"
  1655.        "Sequence numbern"
  1656.        "Specify packets to rejectn"
  1657.        "Specify packets to forwardn"
  1658.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1659.        "Minimum prefix length to be matchedn"
  1660.        "Minimum prefix lengthn"
  1661.        "Maximum prefix length to be matchedn"
  1662.        "Maximum prefix lengthn")
  1663. {
  1664.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1665.   argv[3], argv[4], argv[5]);
  1666. }
  1667. DEFUN (ipv6_prefix_list_seq_le,
  1668.        ipv6_prefix_list_seq_le_cmd,
  1669.        "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128>",
  1670.        IPV6_STR
  1671.        PREFIX_LIST_STR
  1672.        "Name of a prefix listn"
  1673.        "sequence number of an entryn"
  1674.        "Sequence numbern"
  1675.        "Specify packets to rejectn"
  1676.        "Specify packets to forwardn"
  1677.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1678.        "Maximum prefix length to be matchedn"
  1679.        "Maximum prefix lengthn")
  1680. {
  1681.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1682.   argv[3], NULL, argv[4]);
  1683. }
  1684. DEFUN (ipv6_prefix_list_seq_le_ge,
  1685.        ipv6_prefix_list_seq_le_ge_cmd,
  1686.        "ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
  1687.        IPV6_STR
  1688.        PREFIX_LIST_STR
  1689.        "Name of a prefix listn"
  1690.        "sequence number of an entryn"
  1691.        "Sequence numbern"
  1692.        "Specify packets to rejectn"
  1693.        "Specify packets to forwardn"
  1694.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1695.        "Maximum prefix length to be matchedn"
  1696.        "Maximum prefix lengthn"
  1697.        "Minimum prefix length to be matchedn"
  1698.        "Minimum prefix lengthn")
  1699. {
  1700.   return vty_prefix_list_install (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1701.   argv[3], argv[5], argv[4]);
  1702. }
  1703. DEFUN (no_ipv6_prefix_list,
  1704.        no_ipv6_prefix_list_cmd,
  1705.        "no ipv6 prefix-list WORD",
  1706.        NO_STR
  1707.        IPV6_STR
  1708.        PREFIX_LIST_STR
  1709.        "Name of a prefix listn")
  1710. {
  1711.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, NULL,
  1712.     NULL, NULL, NULL);
  1713. }
  1714. DEFUN (no_ipv6_prefix_list_prefix,
  1715.        no_ipv6_prefix_list_prefix_cmd,
  1716.        "no ipv6 prefix-list WORD (deny|permit) (X:X::X:X/M|any)",
  1717.        NO_STR
  1718.        IPV6_STR
  1719.        PREFIX_LIST_STR
  1720.        "Name of a prefix listn"
  1721.        "Specify packets to rejectn"
  1722.        "Specify packets to forwardn"
  1723.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1724.        "Any prefix match.  Same as "::0/0 le 128"n")
  1725. {
  1726.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
  1727.     argv[2], NULL, NULL);
  1728. }
  1729. DEFUN (no_ipv6_prefix_list_ge,
  1730.        no_ipv6_prefix_list_ge_cmd,
  1731.        "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128>",
  1732.        NO_STR
  1733.        IPV6_STR
  1734.        PREFIX_LIST_STR
  1735.        "Name of a prefix listn"
  1736.        "Specify packets to rejectn"
  1737.        "Specify packets to forwardn"
  1738.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1739.        "Minimum prefix length to be matchedn"
  1740.        "Minimum prefix lengthn")
  1741. {
  1742.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
  1743.     argv[2], argv[3], NULL);
  1744. }
  1745. DEFUN (no_ipv6_prefix_list_ge_le,
  1746.        no_ipv6_prefix_list_ge_le_cmd,
  1747.        "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
  1748.        NO_STR
  1749.        IPV6_STR
  1750.        PREFIX_LIST_STR
  1751.        "Name of a prefix listn"
  1752.        "Specify packets to rejectn"
  1753.        "Specify packets to forwardn"
  1754.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1755.        "Minimum prefix length to be matchedn"
  1756.        "Minimum prefix lengthn"
  1757.        "Maximum prefix length to be matchedn"
  1758.        "Maximum prefix lengthn")
  1759. {
  1760.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
  1761.     argv[2], argv[3], argv[4]);
  1762. }
  1763. DEFUN (no_ipv6_prefix_list_le,
  1764.        no_ipv6_prefix_list_le_cmd,
  1765.        "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128>",
  1766.        NO_STR
  1767.        IPV6_STR
  1768.        PREFIX_LIST_STR
  1769.        "Name of a prefix listn"
  1770.        "Specify packets to rejectn"
  1771.        "Specify packets to forwardn"
  1772.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1773.        "Maximum prefix length to be matchedn"
  1774.        "Maximum prefix lengthn")
  1775. {
  1776.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
  1777.     argv[2], NULL, argv[3]);
  1778. }
  1779. DEFUN (no_ipv6_prefix_list_le_ge,
  1780.        no_ipv6_prefix_list_le_ge_cmd,
  1781.        "no ipv6 prefix-list WORD (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
  1782.        NO_STR
  1783.        IPV6_STR
  1784.        PREFIX_LIST_STR
  1785.        "Name of a prefix listn"
  1786.        "Specify packets to rejectn"
  1787.        "Specify packets to forwardn"
  1788.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1789.        "Maximum prefix length to be matchedn"
  1790.        "Maximum prefix lengthn"
  1791.        "Minimum prefix length to be matchedn"
  1792.        "Minimum prefix lengthn")
  1793. {
  1794.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], NULL, argv[1],
  1795.     argv[2], argv[4], argv[3]);
  1796. }
  1797. DEFUN (no_ipv6_prefix_list_seq,
  1798.        no_ipv6_prefix_list_seq_cmd,
  1799.        "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) (X:X::X:X/M|any)",
  1800.        NO_STR
  1801.        IPV6_STR
  1802.        PREFIX_LIST_STR
  1803.        "Name of a prefix listn"
  1804.        "sequence number of an entryn"
  1805.        "Sequence numbern"
  1806.        "Specify packets to rejectn"
  1807.        "Specify packets to forwardn"
  1808.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1809.        "Any prefix match.  Same as "::0/0 le 128"n")
  1810. {
  1811.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1812.     argv[3], NULL, NULL);
  1813. }
  1814. DEFUN (no_ipv6_prefix_list_seq_ge,
  1815.        no_ipv6_prefix_list_seq_ge_cmd,
  1816.        "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128>",
  1817.        NO_STR
  1818.        IPV6_STR
  1819.        PREFIX_LIST_STR
  1820.        "Name of a prefix listn"
  1821.        "sequence number of an entryn"
  1822.        "Sequence numbern"
  1823.        "Specify packets to rejectn"
  1824.        "Specify packets to forwardn"
  1825.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1826.        "Minimum prefix length to be matchedn"
  1827.        "Minimum prefix lengthn")
  1828. {
  1829.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1830.     argv[3], argv[4], NULL);
  1831. }
  1832. DEFUN (no_ipv6_prefix_list_seq_ge_le,
  1833.        no_ipv6_prefix_list_seq_ge_le_cmd,
  1834.        "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M ge <0-128> le <0-128>",
  1835.        NO_STR
  1836.        IPV6_STR
  1837.        PREFIX_LIST_STR
  1838.        "Name of a prefix listn"
  1839.        "sequence number of an entryn"
  1840.        "Sequence numbern"
  1841.        "Specify packets to rejectn"
  1842.        "Specify packets to forwardn"
  1843.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1844.        "Minimum prefix length to be matchedn"
  1845.        "Minimum prefix lengthn"
  1846.        "Maximum prefix length to be matchedn"
  1847.        "Maximum prefix lengthn")
  1848. {
  1849.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1850.     argv[3], argv[4], argv[5]);
  1851. }
  1852. DEFUN (no_ipv6_prefix_list_seq_le,
  1853.        no_ipv6_prefix_list_seq_le_cmd,
  1854.        "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128>",
  1855.        NO_STR
  1856.        IPV6_STR
  1857.        PREFIX_LIST_STR
  1858.        "Name of a prefix listn"
  1859.        "sequence number of an entryn"
  1860.        "Sequence numbern"
  1861.        "Specify packets to rejectn"
  1862.        "Specify packets to forwardn"
  1863.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1864.        "Maximum prefix length to be matchedn"
  1865.        "Maximum prefix lengthn")
  1866. {
  1867.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1868.     argv[3], NULL, argv[4]);
  1869. }
  1870. DEFUN (no_ipv6_prefix_list_seq_le_ge,
  1871.        no_ipv6_prefix_list_seq_le_ge_cmd,
  1872.        "no ipv6 prefix-list WORD seq <1-4294967295> (deny|permit) X:X::X:X/M le <0-128> ge <0-128>",
  1873.        NO_STR
  1874.        IPV6_STR
  1875.        PREFIX_LIST_STR
  1876.        "Name of a prefix listn"
  1877.        "sequence number of an entryn"
  1878.        "Sequence numbern"
  1879.        "Specify packets to rejectn"
  1880.        "Specify packets to forwardn"
  1881.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  1882.        "Maximum prefix length to be matchedn"
  1883.        "Maximum prefix lengthn"
  1884.        "Minimum prefix length to be matchedn"
  1885.        "Minimum prefix lengthn")
  1886. {
  1887.   return vty_prefix_list_uninstall (vty, AFI_IP6, argv[0], argv[1], argv[2],
  1888.     argv[3], argv[5], argv[4]);
  1889. }
  1890. DEFUN (ipv6_prefix_list_sequence_number,
  1891.        ipv6_prefix_list_sequence_number_cmd,
  1892.        "ipv6 prefix-list sequence-number",
  1893.        IPV6_STR
  1894.        PREFIX_LIST_STR
  1895.        "Include/exclude sequence numbers in NVGENn")
  1896. {
  1897.   prefix_master_ipv6.seqnum = 1;
  1898.   return CMD_SUCCESS;
  1899. }
  1900. DEFUN (no_ipv6_prefix_list_sequence_number,
  1901.        no_ipv6_prefix_list_sequence_number_cmd,
  1902.        "no ipv6 prefix-list sequence-number",
  1903.        NO_STR
  1904.        IPV6_STR
  1905.        PREFIX_LIST_STR
  1906.        "Include/exclude sequence numbers in NVGENn")
  1907. {
  1908.   prefix_master_ipv6.seqnum = 0;
  1909.   return CMD_SUCCESS;
  1910. }
  1911. DEFUN (ipv6_prefix_list_description,
  1912.        ipv6_prefix_list_description_cmd,
  1913.        "ipv6 prefix-list WORD description .LINE",
  1914.        IPV6_STR
  1915.        PREFIX_LIST_STR
  1916.        "Name of a prefix listn"
  1917.        "Prefix-list specific descriptionn"
  1918.        "Up to 80 characters describing this prefix-listn")
  1919. {
  1920.   struct prefix_list *plist;
  1921.   struct buffer *b;
  1922.   int i;
  1923.   plist = prefix_list_get (AFI_IP6, argv[0]);
  1924.   
  1925.   if (plist->desc)
  1926.     {
  1927.       XFREE (MTYPE_TMP, plist->desc);
  1928.       plist->desc = NULL;
  1929.     }
  1930.   /* Below is description get codes. */
  1931.   b = buffer_new (1024);
  1932.   for (i = 1; i < argc; i++)
  1933.     {
  1934.       buffer_putstr (b, (u_char *)argv[i]);
  1935.       buffer_putc (b, ' ');
  1936.     }
  1937.   buffer_putc (b, '');
  1938.   plist->desc = buffer_getstr (b);
  1939.   buffer_free (b);
  1940.   return CMD_SUCCESS;
  1941. }       
  1942. DEFUN (no_ipv6_prefix_list_description,
  1943.        no_ipv6_prefix_list_description_cmd,
  1944.        "no ipv6 prefix-list WORD description",
  1945.        NO_STR
  1946.        IPV6_STR
  1947.        PREFIX_LIST_STR
  1948.        "Name of a prefix listn"
  1949.        "Prefix-list specific descriptionn")
  1950. {
  1951.   return vty_prefix_list_desc_unset (vty, AFI_IP6, argv[0]);
  1952. }
  1953. ALIAS (no_ipv6_prefix_list_description,
  1954.        no_ipv6_prefix_list_description_arg_cmd,
  1955.        "no ipv6 prefix-list WORD description .LINE",
  1956.        NO_STR
  1957.        IPV6_STR
  1958.        PREFIX_LIST_STR
  1959.        "Name of a prefix listn"
  1960.        "Prefix-list specific descriptionn"
  1961.        "Up to 80 characters describing this prefix-listn");
  1962. DEFUN (show_ipv6_prefix_list,
  1963.        show_ipv6_prefix_list_cmd,
  1964.        "show ipv6 prefix-list",
  1965.        SHOW_STR
  1966.        IPV6_STR
  1967.        PREFIX_LIST_STR)
  1968. {
  1969.   return vty_show_prefix_list (vty, AFI_IP6, NULL, NULL, normal_display);
  1970. }
  1971. DEFUN (show_ipv6_prefix_list_name,
  1972.        show_ipv6_prefix_list_name_cmd,
  1973.        "show ipv6 prefix-list WORD",
  1974.        SHOW_STR
  1975.        IPV6_STR
  1976.        PREFIX_LIST_STR
  1977.        "Name of a prefix listn")
  1978. {
  1979.   return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, normal_display);
  1980. }
  1981. DEFUN (show_ipv6_prefix_list_name_seq,
  1982.        show_ipv6_prefix_list_name_seq_cmd,
  1983.        "show ipv6 prefix-list WORD seq <1-4294967295>",
  1984.        SHOW_STR
  1985.        IPV6_STR
  1986.        PREFIX_LIST_STR
  1987.        "Name of a prefix listn"
  1988.        "sequence number of an entryn"
  1989.        "Sequence numbern")
  1990. {
  1991.   return vty_show_prefix_list (vty, AFI_IP6, argv[0], argv[1], sequential_display);
  1992. }
  1993. DEFUN (show_ipv6_prefix_list_prefix,
  1994.        show_ipv6_prefix_list_prefix_cmd,
  1995.        "show ipv6 prefix-list WORD X:X::X:X/M",
  1996.        SHOW_STR
  1997.        IPV6_STR
  1998.        PREFIX_LIST_STR
  1999.        "Name of a prefix listn"
  2000.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n")
  2001. {
  2002.   return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], normal_display);
  2003. }
  2004. DEFUN (show_ipv6_prefix_list_prefix_longer,
  2005.        show_ipv6_prefix_list_prefix_longer_cmd,
  2006.        "show ipv6 prefix-list WORD X:X::X:X/M longer",
  2007.        SHOW_STR
  2008.        IPV6_STR
  2009.        PREFIX_LIST_STR
  2010.        "Name of a prefix listn"
  2011.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  2012.        "Lookup longer prefixn")
  2013. {
  2014.   return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], longer_display);
  2015. }
  2016. DEFUN (show_ipv6_prefix_list_prefix_first_match,
  2017.        show_ipv6_prefix_list_prefix_first_match_cmd,
  2018.        "show ipv6 prefix-list WORD X:X::X:X/M first-match",
  2019.        SHOW_STR
  2020.        IPV6_STR
  2021.        PREFIX_LIST_STR
  2022.        "Name of a prefix listn"
  2023.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n"
  2024.        "First matched prefixn")
  2025. {
  2026.   return vty_show_prefix_list_prefix (vty, AFI_IP6, argv[0], argv[1], first_match_display);
  2027. }
  2028. DEFUN (show_ipv6_prefix_list_summary,
  2029.        show_ipv6_prefix_list_summary_cmd,
  2030.        "show ipv6 prefix-list summary",
  2031.        SHOW_STR
  2032.        IPV6_STR
  2033.        PREFIX_LIST_STR
  2034.        "Summary of prefix listsn")
  2035. {
  2036.   return vty_show_prefix_list (vty, AFI_IP6, NULL, NULL, summary_display);
  2037. }
  2038. DEFUN (show_ipv6_prefix_list_summary_name,
  2039.        show_ipv6_prefix_list_summary_name_cmd,
  2040.        "show ipv6 prefix-list summary WORD",
  2041.        SHOW_STR
  2042.        IPV6_STR
  2043.        PREFIX_LIST_STR
  2044.        "Summary of prefix listsn"
  2045.        "Name of a prefix listn")
  2046. {
  2047.   return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, summary_display);
  2048. }
  2049. DEFUN (show_ipv6_prefix_list_detail,
  2050.        show_ipv6_prefix_list_detail_cmd,
  2051.        "show ipv6 prefix-list detail",
  2052.        SHOW_STR
  2053.        IPV6_STR
  2054.        PREFIX_LIST_STR
  2055.        "Detail of prefix listsn")
  2056. {
  2057.   return vty_show_prefix_list (vty, AFI_IP6, NULL, NULL, detail_display);
  2058. }
  2059. DEFUN (show_ipv6_prefix_list_detail_name,
  2060.        show_ipv6_prefix_list_detail_name_cmd,
  2061.        "show ipv6 prefix-list detail WORD",
  2062.        SHOW_STR
  2063.        IPV6_STR
  2064.        PREFIX_LIST_STR
  2065.        "Detail of prefix listsn"
  2066.        "Name of a prefix listn")
  2067. {
  2068.   return vty_show_prefix_list (vty, AFI_IP6, argv[0], NULL, detail_display);
  2069. }
  2070. DEFUN (clear_ipv6_prefix_list,
  2071.        clear_ipv6_prefix_list_cmd,
  2072.        "clear ipv6 prefix-list",
  2073.        CLEAR_STR
  2074.        IPV6_STR
  2075.        PREFIX_LIST_STR)
  2076. {
  2077.   return vty_clear_prefix_list (vty, AFI_IP6, NULL, NULL);
  2078. }
  2079. DEFUN (clear_ipv6_prefix_list_name,
  2080.        clear_ipv6_prefix_list_name_cmd,
  2081.        "clear ipv6 prefix-list WORD",
  2082.        CLEAR_STR
  2083.        IPV6_STR
  2084.        PREFIX_LIST_STR
  2085.        "Name of a prefix listn")
  2086. {
  2087.   return vty_clear_prefix_list (vty, AFI_IP6, argv[0], NULL);
  2088. }
  2089. DEFUN (clear_ipv6_prefix_list_name_prefix,
  2090.        clear_ipv6_prefix_list_name_prefix_cmd,
  2091.        "clear ipv6 prefix-list WORD X:X::X:X/M",
  2092.        CLEAR_STR
  2093.        IPV6_STR
  2094.        PREFIX_LIST_STR
  2095.        "Name of a prefix listn"
  2096.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n")
  2097. {
  2098.   return vty_clear_prefix_list (vty, AFI_IP6, argv[0], argv[1]);
  2099. }
  2100. #endif /* HAVE_IPV6 */
  2101. /* Configuration write function. */
  2102. int
  2103. config_write_prefix_afi (afi_t afi, struct vty *vty)
  2104. {
  2105.   struct prefix_list *plist;
  2106.   struct prefix_list_entry *pentry;
  2107.   struct prefix_master *master;
  2108.   int write = 0;
  2109.   master = prefix_master_get (afi);
  2110.   if (master == NULL)
  2111.     return 0;
  2112.   if (! master->seqnum)
  2113.     {
  2114.       vty_out (vty, "no ip%s prefix-list sequence-number%s", 
  2115.        afi == AFI_IP ? "" : "v6", VTY_NEWLINE);
  2116.       vty_out (vty, "!%s", VTY_NEWLINE);
  2117.     }
  2118.   for (plist = master->num.head; plist; plist = plist->next)
  2119.     {
  2120.       if (plist->desc)
  2121. {
  2122.   vty_out (vty, "ip%s prefix-list %s description %s%s",
  2123.    afi == AFI_IP ? "" : "v6",
  2124.    plist->name, plist->desc, VTY_NEWLINE);
  2125.   write++;
  2126. }
  2127.       for (pentry = plist->head; pentry; pentry = pentry->next)
  2128. {
  2129.   vty_out (vty, "ip%s prefix-list %s ",
  2130.    afi == AFI_IP ? "" : "v6",
  2131.    plist->name);
  2132.   if (master->seqnum)
  2133.     vty_out (vty, "seq %d ", pentry->seq);
  2134.   vty_out (vty, "%s ", prefix_list_type_str (pentry));
  2135.   if (pentry->any)
  2136.     vty_out (vty, "any");
  2137.   else
  2138.     {
  2139.       struct prefix *p = &pentry->prefix;
  2140.       char buf[BUFSIZ];
  2141.       vty_out (vty, "%s/%d",
  2142.        inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  2143.        p->prefixlen);
  2144.       if (pentry->ge)
  2145. vty_out (vty, " ge %d", pentry->ge);
  2146.       if (pentry->le)
  2147. vty_out (vty, " le %d", pentry->le);
  2148.     }
  2149.   vty_out (vty, "%s", VTY_NEWLINE);
  2150.   write++;
  2151. }
  2152.       /* vty_out (vty, "!%s", VTY_NEWLINE); */
  2153.     }
  2154.   for (plist = master->str.head; plist; plist = plist->next)
  2155.     {
  2156.       if (plist->desc)
  2157. {
  2158.   vty_out (vty, "ip%s prefix-list %s description %s%s",
  2159.    afi == AFI_IP ? "" : "v6",
  2160.    plist->name, plist->desc, VTY_NEWLINE);
  2161.   write++;
  2162. }
  2163.       for (pentry = plist->head; pentry; pentry = pentry->next)
  2164. {
  2165.   vty_out (vty, "ip%s prefix-list %s ",
  2166.    afi == AFI_IP ? "" : "v6",
  2167.    plist->name);
  2168.   if (master->seqnum)
  2169.     vty_out (vty, "seq %d ", pentry->seq);
  2170.   vty_out (vty, "%s", prefix_list_type_str (pentry));
  2171.   if (pentry->any)
  2172.     vty_out (vty, " any");
  2173.   else
  2174.     {
  2175.       struct prefix *p = &pentry->prefix;
  2176.       char buf[BUFSIZ];
  2177.       vty_out (vty, " %s/%d",
  2178.        inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  2179.        p->prefixlen);
  2180.       if (pentry->ge)
  2181. vty_out (vty, " ge %d", pentry->ge);
  2182.       if (pentry->le)
  2183. vty_out (vty, " le %d", pentry->le);
  2184.     }
  2185.   vty_out (vty, "%s", VTY_NEWLINE);
  2186.   write++;
  2187. }
  2188.     }
  2189.   
  2190.   return write;
  2191. }
  2192. int stream_putc (struct stream *, u_char);
  2193. int stream_putl (struct stream *, u_int32_t);
  2194. int stream_put_prefix (struct stream *, struct prefix *);
  2195. struct stream *
  2196. prefix_bgp_orf_entry (struct stream *s, struct prefix_list *plist,
  2197.       u_char init_flag, u_char permit_flag, u_char deny_flag)
  2198. {
  2199.   struct prefix_list_entry *pentry;
  2200.   if (! plist)
  2201.     return s;
  2202.   for (pentry = plist->head; pentry; pentry = pentry->next)
  2203.     {
  2204.       u_char flag = init_flag;
  2205.       struct prefix *p = &pentry->prefix;
  2206.       flag |= (pentry->type == PREFIX_PERMIT ?
  2207.                permit_flag : deny_flag);
  2208.       stream_putc (s, flag);
  2209.       stream_putl (s, (u_int32_t)pentry->seq);
  2210.       stream_putc (s, (u_char)pentry->ge);
  2211.       stream_putc (s, (u_char)pentry->le);
  2212.       stream_put_prefix (s, p);
  2213.     }
  2214.   return s;
  2215. }
  2216. int
  2217. prefix_bgp_orf_set (char *name, afi_t afi, struct orf_prefix *orfp,
  2218.     int permit, int set)
  2219. {
  2220.   struct prefix_list *plist;
  2221.   struct prefix_list_entry *pentry;
  2222.   /* ge and le value check */ 
  2223.   if (orfp->ge && orfp->ge <= orfp->p.prefixlen)
  2224.     return CMD_WARNING;
  2225.   if (orfp->le && orfp->le <= orfp->p.prefixlen)
  2226.     return CMD_WARNING;
  2227.   if (orfp->le && orfp->ge > orfp->le)
  2228.     return CMD_WARNING;
  2229.   if (orfp->ge && orfp->le == (afi == AFI_IP ? 32 : 128))
  2230.     orfp->le = 0;
  2231.   plist = prefix_list_get (AFI_ORF_PREFIX, name);
  2232.   if (! plist)
  2233.     return CMD_WARNING;
  2234.   if (set)
  2235.     {
  2236.       pentry = prefix_list_entry_make (&orfp->p,
  2237.        (permit ? PREFIX_PERMIT : PREFIX_DENY),
  2238.        orfp->seq, orfp->le, orfp->ge, 0);
  2239.       if (prefix_entry_dup_check (plist, pentry))
  2240. {
  2241.   prefix_list_entry_free (pentry);
  2242.   return CMD_WARNING;
  2243. }
  2244.       prefix_list_entry_add (plist, pentry);
  2245.     }
  2246.   else
  2247.     {
  2248.       pentry = prefix_list_entry_lookup (plist, &orfp->p,
  2249.  (permit ? PREFIX_PERMIT : PREFIX_DENY),
  2250.  orfp->seq, orfp->le, orfp->ge);
  2251.       if (! pentry)
  2252. return CMD_WARNING;
  2253.       prefix_list_entry_delete (plist, pentry, 1);
  2254.     }
  2255.   return CMD_SUCCESS;
  2256. }
  2257. void
  2258. prefix_bgp_orf_remove_all (char *name)
  2259. {
  2260.   struct prefix_list *plist;
  2261.   plist = prefix_list_lookup (AFI_ORF_PREFIX, name);
  2262.   if (plist)
  2263.     prefix_list_delete (plist);
  2264. }
  2265. /* return prefix count */
  2266. int
  2267. prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name)
  2268. {
  2269.   struct prefix_list *plist;
  2270.   struct prefix_list_entry *pentry;
  2271.   plist = prefix_list_lookup (AFI_ORF_PREFIX, name);
  2272.   if (! plist)
  2273.     return 0;
  2274.   if (! vty)
  2275.     return plist->count;
  2276.   vty_out (vty, "ip%s prefix-list %s: %d entries%s",
  2277.    afi == AFI_IP ? "" : "v6",
  2278.    plist->name, plist->count, VTY_NEWLINE);
  2279.   for (pentry = plist->head; pentry; pentry = pentry->next)
  2280.     {
  2281.       struct prefix *p = &pentry->prefix;
  2282.       char buf[BUFSIZ];
  2283.       vty_out (vty, "   seq %d %s %s/%d", pentry->seq,
  2284.        prefix_list_type_str (pentry),
  2285.        inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  2286.        p->prefixlen);
  2287.       if (pentry->ge)
  2288. vty_out (vty, " ge %d", pentry->ge);
  2289.       if (pentry->le)
  2290. vty_out (vty, " le %d", pentry->le);
  2291.       vty_out (vty, "%s", VTY_NEWLINE);
  2292.     }
  2293.   return plist->count;
  2294. }
  2295. void
  2296. prefix_list_reset_orf ()
  2297. {
  2298.   struct prefix_list *plist;
  2299.   struct prefix_list *next;
  2300.   struct prefix_master *master;
  2301.   master = prefix_master_get (AFI_ORF_PREFIX);
  2302.   if (master == NULL)
  2303.     return;
  2304.   for (plist = master->num.head; plist; plist = next)
  2305.     {
  2306.       next = plist->next;
  2307.       prefix_list_delete (plist);
  2308.     }
  2309.   for (plist = master->str.head; plist; plist = next)
  2310.     {
  2311.       next = plist->next;
  2312.       prefix_list_delete (plist);
  2313.     }
  2314.   assert (master->num.head == NULL);
  2315.   assert (master->num.tail == NULL);
  2316.   assert (master->str.head == NULL);
  2317.   assert (master->str.tail == NULL);
  2318.   master->seqnum = 1;
  2319.   master->recent = NULL;
  2320. }
  2321. /* Prefix-list node. */
  2322. struct cmd_node prefix_node =
  2323. {
  2324.   PREFIX_NODE,
  2325.   "", /* Prefix list has no interface. */
  2326.   1
  2327. };
  2328. int
  2329. config_write_prefix_ipv4 (struct vty *vty)
  2330. {
  2331.   return config_write_prefix_afi (AFI_IP, vty);
  2332. }
  2333. void
  2334. prefix_list_reset_ipv4 ()
  2335. {
  2336.   struct prefix_list *plist;
  2337.   struct prefix_list *next;
  2338.   struct prefix_master *master;
  2339.   master = prefix_master_get (AFI_IP);
  2340.   if (master == NULL)
  2341.     return;
  2342.   for (plist = master->num.head; plist; plist = next)
  2343.     {
  2344.       next = plist->next;
  2345.       prefix_list_delete (plist);
  2346.     }
  2347.   for (plist = master->str.head; plist; plist = next)
  2348.     {
  2349.       next = plist->next;
  2350.       prefix_list_delete (plist);
  2351.     }
  2352.   assert (master->num.head == NULL);
  2353.   assert (master->num.tail == NULL);
  2354.   assert (master->str.head == NULL);
  2355.   assert (master->str.tail == NULL);
  2356.   master->seqnum = 1;
  2357.   master->recent = NULL;
  2358. }
  2359. void
  2360. prefix_list_init_ipv4 ()
  2361. {
  2362.   install_node (&prefix_node, config_write_prefix_ipv4);
  2363.   install_element (CONFIG_NODE, &ip_prefix_list_cmd);
  2364.   install_element (CONFIG_NODE, &ip_prefix_list_ge_cmd);
  2365.   install_element (CONFIG_NODE, &ip_prefix_list_ge_le_cmd);
  2366.   install_element (CONFIG_NODE, &ip_prefix_list_le_cmd);
  2367.   install_element (CONFIG_NODE, &ip_prefix_list_le_ge_cmd);
  2368.   install_element (CONFIG_NODE, &ip_prefix_list_seq_cmd);
  2369.   install_element (CONFIG_NODE, &ip_prefix_list_seq_ge_cmd);
  2370.   install_element (CONFIG_NODE, &ip_prefix_list_seq_ge_le_cmd);
  2371.   install_element (CONFIG_NODE, &ip_prefix_list_seq_le_cmd);
  2372.   install_element (CONFIG_NODE, &ip_prefix_list_seq_le_ge_cmd);
  2373.   install_element (CONFIG_NODE, &no_ip_prefix_list_cmd);
  2374.   install_element (CONFIG_NODE, &no_ip_prefix_list_prefix_cmd);
  2375.   install_element (CONFIG_NODE, &no_ip_prefix_list_ge_cmd);
  2376.   install_element (CONFIG_NODE, &no_ip_prefix_list_ge_le_cmd);
  2377.   install_element (CONFIG_NODE, &no_ip_prefix_list_le_cmd);
  2378.   install_element (CONFIG_NODE, &no_ip_prefix_list_le_ge_cmd);
  2379.   install_element (CONFIG_NODE, &no_ip_prefix_list_seq_cmd);
  2380.   install_element (CONFIG_NODE, &no_ip_prefix_list_seq_ge_cmd);
  2381.   install_element (CONFIG_NODE, &no_ip_prefix_list_seq_ge_le_cmd);
  2382.   install_element (CONFIG_NODE, &no_ip_prefix_list_seq_le_cmd);
  2383.   install_element (CONFIG_NODE, &no_ip_prefix_list_seq_le_ge_cmd);
  2384.   install_element (CONFIG_NODE, &ip_prefix_list_description_cmd);
  2385.   install_element (CONFIG_NODE, &no_ip_prefix_list_description_cmd);
  2386.   install_element (CONFIG_NODE, &no_ip_prefix_list_description_arg_cmd);
  2387.   install_element (CONFIG_NODE, &ip_prefix_list_sequence_number_cmd);
  2388.   install_element (CONFIG_NODE, &no_ip_prefix_list_sequence_number_cmd);
  2389.   install_element (VIEW_NODE, &show_ip_prefix_list_cmd);
  2390.   install_element (VIEW_NODE, &show_ip_prefix_list_name_cmd);
  2391.   install_element (VIEW_NODE, &show_ip_prefix_list_name_seq_cmd);
  2392.   install_element (VIEW_NODE, &show_ip_prefix_list_prefix_cmd);
  2393.   install_element (VIEW_NODE, &show_ip_prefix_list_prefix_longer_cmd);
  2394.   install_element (VIEW_NODE, &show_ip_prefix_list_prefix_first_match_cmd);
  2395.   install_element (VIEW_NODE, &show_ip_prefix_list_summary_cmd);
  2396.   install_element (VIEW_NODE, &show_ip_prefix_list_summary_name_cmd);
  2397.   install_element (VIEW_NODE, &show_ip_prefix_list_detail_cmd);
  2398.   install_element (VIEW_NODE, &show_ip_prefix_list_detail_name_cmd);
  2399.   install_element (ENABLE_NODE, &show_ip_prefix_list_cmd);
  2400.   install_element (ENABLE_NODE, &show_ip_prefix_list_name_cmd);
  2401.   install_element (ENABLE_NODE, &show_ip_prefix_list_name_seq_cmd);
  2402.   install_element (ENABLE_NODE, &show_ip_prefix_list_prefix_cmd);
  2403.   install_element (ENABLE_NODE, &show_ip_prefix_list_prefix_longer_cmd);
  2404.   install_element (ENABLE_NODE, &show_ip_prefix_list_prefix_first_match_cmd);
  2405.   install_element (ENABLE_NODE, &show_ip_prefix_list_summary_cmd);
  2406.   install_element (ENABLE_NODE, &show_ip_prefix_list_summary_name_cmd);
  2407.   install_element (ENABLE_NODE, &show_ip_prefix_list_detail_cmd);
  2408.   install_element (ENABLE_NODE, &show_ip_prefix_list_detail_name_cmd);
  2409.   install_element (ENABLE_NODE, &clear_ip_prefix_list_cmd);
  2410.   install_element (ENABLE_NODE, &clear_ip_prefix_list_name_cmd);
  2411.   install_element (ENABLE_NODE, &clear_ip_prefix_list_name_prefix_cmd);
  2412. }
  2413. #ifdef HAVE_IPV6
  2414. /* Prefix-list node. */
  2415. struct cmd_node prefix_ipv6_node =
  2416. {
  2417.   PREFIX_IPV6_NODE,
  2418.   "", /* Prefix list has no interface. */
  2419.   1
  2420. };
  2421. int
  2422. config_write_prefix_ipv6 (struct vty *vty)
  2423. {
  2424.   return config_write_prefix_afi (AFI_IP6, vty);
  2425. }
  2426. void
  2427. prefix_list_reset_ipv6 ()
  2428. {
  2429.   struct prefix_list *plist;
  2430.   struct prefix_list *next;
  2431.   struct prefix_master *master;
  2432.   master = prefix_master_get (AFI_IP6);
  2433.   if (master == NULL)
  2434.     return;
  2435.   for (plist = master->num.head; plist; plist = next)
  2436.     {
  2437.       next = plist->next;
  2438.       prefix_list_delete (plist);
  2439.     }
  2440.   for (plist = master->str.head; plist; plist = next)
  2441.     {
  2442.       next = plist->next;
  2443.       prefix_list_delete (plist);
  2444.     }
  2445.   assert (master->num.head == NULL);
  2446.   assert (master->num.tail == NULL);
  2447.   assert (master->str.head == NULL);
  2448.   assert (master->str.tail == NULL);
  2449.   master->seqnum = 1;
  2450.   master->recent = NULL;
  2451. }
  2452. void
  2453. prefix_list_init_ipv6 ()
  2454. {
  2455.   install_node (&prefix_ipv6_node, config_write_prefix_ipv6);
  2456.   install_element (CONFIG_NODE, &ipv6_prefix_list_cmd);
  2457.   install_element (CONFIG_NODE, &ipv6_prefix_list_ge_cmd);
  2458.   install_element (CONFIG_NODE, &ipv6_prefix_list_ge_le_cmd);
  2459.   install_element (CONFIG_NODE, &ipv6_prefix_list_le_cmd);
  2460.   install_element (CONFIG_NODE, &ipv6_prefix_list_le_ge_cmd);
  2461.   install_element (CONFIG_NODE, &ipv6_prefix_list_seq_cmd);
  2462.   install_element (CONFIG_NODE, &ipv6_prefix_list_seq_ge_cmd);
  2463.   install_element (CONFIG_NODE, &ipv6_prefix_list_seq_ge_le_cmd);
  2464.   install_element (CONFIG_NODE, &ipv6_prefix_list_seq_le_cmd);
  2465.   install_element (CONFIG_NODE, &ipv6_prefix_list_seq_le_ge_cmd);
  2466.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_cmd);
  2467.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_prefix_cmd);
  2468.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_ge_cmd);
  2469.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_ge_le_cmd);
  2470.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_le_cmd);
  2471.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_le_ge_cmd);
  2472.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_seq_cmd);
  2473.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_seq_ge_cmd);
  2474.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_seq_ge_le_cmd);
  2475.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_seq_le_cmd);
  2476.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_seq_le_ge_cmd);
  2477.   install_element (CONFIG_NODE, &ipv6_prefix_list_description_cmd);
  2478.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_cmd);
  2479.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_arg_cmd);
  2480.   install_element (CONFIG_NODE, &ipv6_prefix_list_sequence_number_cmd);
  2481.   install_element (CONFIG_NODE, &no_ipv6_prefix_list_sequence_number_cmd);
  2482.   install_element (VIEW_NODE, &show_ipv6_prefix_list_cmd);
  2483.   install_element (VIEW_NODE, &show_ipv6_prefix_list_name_cmd);
  2484.   install_element (VIEW_NODE, &show_ipv6_prefix_list_name_seq_cmd);
  2485.   install_element (VIEW_NODE, &show_ipv6_prefix_list_prefix_cmd);
  2486.   install_element (VIEW_NODE, &show_ipv6_prefix_list_prefix_longer_cmd);
  2487.   install_element (VIEW_NODE, &show_ipv6_prefix_list_prefix_first_match_cmd);
  2488.   install_element (VIEW_NODE, &show_ipv6_prefix_list_summary_cmd);
  2489.   install_element (VIEW_NODE, &show_ipv6_prefix_list_summary_name_cmd);
  2490.   install_element (VIEW_NODE, &show_ipv6_prefix_list_detail_cmd);
  2491.   install_element (VIEW_NODE, &show_ipv6_prefix_list_detail_name_cmd);
  2492.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_cmd);
  2493.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_name_cmd);
  2494.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_name_seq_cmd);
  2495.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_prefix_cmd);
  2496.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_prefix_longer_cmd);
  2497.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_prefix_first_match_cmd);
  2498.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_summary_cmd);
  2499.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_summary_name_cmd);
  2500.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_detail_cmd);
  2501.   install_element (ENABLE_NODE, &show_ipv6_prefix_list_detail_name_cmd);
  2502.   install_element (ENABLE_NODE, &clear_ipv6_prefix_list_cmd);
  2503.   install_element (ENABLE_NODE, &clear_ipv6_prefix_list_name_cmd);
  2504.   install_element (ENABLE_NODE, &clear_ipv6_prefix_list_name_prefix_cmd);
  2505. }
  2506. #endif /* HAVE_IPV6 */
  2507. void
  2508. prefix_list_init ()
  2509. {
  2510.   prefix_list_init_ipv4 ();
  2511. #ifdef HAVE_IPV6
  2512.   prefix_list_init_ipv6 ();
  2513. #endif /* HAVE_IPV6 */
  2514. }
  2515. void
  2516. prefix_list_reset ()
  2517. {
  2518.   prefix_list_reset_ipv4 ();
  2519. #ifdef HAVE_IPV6
  2520.   prefix_list_reset_ipv6 ();
  2521. #endif /* HAVE_IPV6 */
  2522.   prefix_list_reset_orf ();
  2523. }