File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / lib / plist.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 6 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

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

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