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