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