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