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. */
34struct 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. */
54struct prefix_list_list
55{
56  struct prefix_list *head;
57  struct prefix_list *tail;
58};
59
60/* Master structure of prefix_list. */
61struct 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. */
83static 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. */
94static 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. */
105static struct prefix_master prefix_master_orf =
106{
107  {NULL, NULL},
108  {NULL, NULL},
109  1,
110  NULL,
111  NULL,
112};
113
114static struct prefix_master *
115prefix_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. */
129struct prefix_list *
130prefix_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
153static struct prefix_list *
154prefix_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
162static void
163prefix_list_free (struct prefix_list *plist)
164{
165  XFREE (MTYPE_PREFIX_LIST, plist);
166}
167
168static struct prefix_list_entry *
169prefix_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
177static void
178prefix_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. */
185static struct prefix_list *
186prefix_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
275static struct prefix_list *
276prefix_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. */
288static void
289prefix_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
337static struct prefix_list_entry *
338prefix_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. */
358void
359prefix_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. */
368void
369prefix_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. */
378static int
379prefix_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. */
399static struct prefix_list_entry *
400prefix_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
410static struct prefix_list_entry *
411prefix_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
433static void
434prefix_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
465static void
466prefix_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. */
521static const char *
522prefix_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
535static int
536prefix_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
563enum prefix_list_type
564prefix_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
590static void __attribute__ ((unused))
591prefix_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. */
626static struct prefix_list_entry *
627prefix_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
650static int
651vty_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
658static int
659vty_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
777static int
778vty_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
888static int
889vty_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
912enum display_type
913{
914  normal_display,
915  summary_display,
916  detail_display,
917  sequential_display,
918  longer_display,
919  first_match_display
920};
921
922static void
923vty_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
996static int
997vty_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
1040static int
1041vty_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
1112static int
1113vty_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
1169DEFUN (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
1184DEFUN (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
1200DEFUN (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
1218DEFUN (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
1234DEFUN (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
1252DEFUN (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
1269DEFUN (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
1287DEFUN (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
1307DEFUN (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
1325DEFUN (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
1345DEFUN (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
1357DEFUN (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
1373DEFUN (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
1390DEFUN (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
1409DEFUN (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
1426DEFUN (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
1445DEFUN (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
1463DEFUN (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
1482DEFUN (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
1503DEFUN (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
1522DEFUN (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
1543DEFUN (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
1554DEFUN (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
1566DEFUN (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
1589DEFUN (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
1601ALIAS (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
1611DEFUN (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
1621DEFUN (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
1632DEFUN (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
1645DEFUN (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
1657DEFUN (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
1670DEFUN (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
1683DEFUN (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
1694DEFUN (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
1707DEFUN (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
1718DEFUN (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
1730DEFUN (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
1740DEFUN (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
1751DEFUN (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
1764DEFUN (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
1779DEFUN (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
1795DEFUN (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
1814DEFUN (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
1830DEFUN (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
1848DEFUN (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
1865DEFUN (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
1883DEFUN (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
1903DEFUN (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
1921DEFUN (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
1941DEFUN (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
1953DEFUN (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
1969DEFUN (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
1986DEFUN (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
2005DEFUN (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
2022DEFUN (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
2041DEFUN (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
2059DEFUN (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
2078DEFUN (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
2099DEFUN (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
2118DEFUN (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
2139DEFUN (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
2150DEFUN (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
2162DEFUN (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
2185DEFUN (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
2197ALIAS (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
2207DEFUN (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
2217DEFUN (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
2228DEFUN (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
2241DEFUN (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
2253DEFUN (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
2266DEFUN (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
2279DEFUN (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
2290DEFUN (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
2302DEFUN (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
2313DEFUN (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
2325DEFUN (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
2335DEFUN (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
2346DEFUN (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. */
2360static int
2361config_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
2467struct stream *
2468prefix_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
2493int
2494prefix_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
2544void
2545prefix_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 */
2555int
2556prefix_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
2592static void
2593prefix_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. */
2626static struct cmd_node prefix_node =
2627{
2628  PREFIX_NODE,
2629  "",				/* Prefix list has no interface. */
2630  1
2631};
2632
2633static int
2634config_write_prefix_ipv4 (struct vty *vty)
2635{
2636  return config_write_prefix_afi (AFI_IP, vty);
2637}
2638
2639static void
2640prefix_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
2671static void
2672prefix_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. */
2735static struct cmd_node prefix_ipv6_node =
2736{
2737  PREFIX_IPV6_NODE,
2738  "",				/* Prefix list has no interface. */
2739  1
2740};
2741
2742static int
2743config_write_prefix_ipv6 (struct vty *vty)
2744{
2745  return config_write_prefix_afi (AFI_IP6, vty);
2746}
2747
2748static void
2749prefix_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
2780static void
2781prefix_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
2843void
2844prefix_list_init ()
2845{
2846  prefix_list_init_ipv4 ();
2847#ifdef HAVE_IPV6
2848  prefix_list_init_ipv6 ();
2849#endif /* HAVE_IPV6 */
2850}
2851
2852void
2853prefix_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}
2861