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