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