]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/rfapi_vty.c
Merge pull request #464 from donaldsharp/datacenter
[mirror_frr.git] / bgpd / rfapi / rfapi_vty.c
1 /*
2 *
3 * Copyright 2009-2016, LabN Consulting, L.L.C.
4 *
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22
23 #include <errno.h>
24
25 #include "lib/zebra.h"
26 #include "lib/prefix.h"
27 #include "lib/table.h"
28 #include "lib/vty.h"
29 #include "lib/memory.h"
30 #include "lib/routemap.h"
31 #include "lib/log.h"
32 #include "lib/log_int.h"
33 #include "lib/linklist.h"
34 #include "lib/command.h"
35
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_ecommunity.h"
38 #include "bgpd/bgp_attr.h"
39 #include "bgpd/bgp_route.h"
40 #include "bgpd/bgp_mplsvpn.h"
41
42 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
43 #include "bgpd/rfapi/rfapi.h"
44 #include "bgpd/rfapi/rfapi_backend.h"
45
46 #include "bgpd/bgp_route.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_community.h"
49 #include "bgpd/bgp_vnc_types.h"
50
51 #include "bgpd/rfapi/rfapi_import.h"
52 #include "bgpd/rfapi/rfapi_private.h"
53 #include "bgpd/rfapi/rfapi_monitor.h"
54 #include "bgpd/rfapi/rfapi_rib.h"
55 #include "bgpd/rfapi/rfapi_vty.h"
56 #include "bgpd/rfapi/rfapi_ap.h"
57 #include "bgpd/rfapi/rfapi_encap_tlv.h"
58 #include "bgpd/rfapi/vnc_debug.h"
59
60 #define DEBUG_L2_EXTRA 0
61 #define DEBUG_SHOW_EXTRA 0
62
63 #define VNC_SHOW_STR "VNC information\n"
64
65 /* format related utilies */
66
67
68 #define FMT_MIN 60 /* seconds */
69 #define FMT_HOUR (60 * FMT_MIN)
70 #define FMT_DAY (24 * FMT_HOUR)
71 #define FMT_YEAR (365 * FMT_DAY)
72
73 char *
74 rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len)
75 {
76 int year, day, hour, min;
77
78 if (seconds >= FMT_YEAR)
79 {
80 year = seconds / FMT_YEAR;
81 seconds -= year * FMT_YEAR;
82 }
83 else
84 year = 0;
85
86 if (seconds >= FMT_DAY)
87 {
88 day = seconds / FMT_DAY;
89 seconds -= day * FMT_DAY;
90 }
91 else
92 day = 0;
93
94 if (seconds >= FMT_HOUR)
95 {
96 hour = seconds / FMT_HOUR;
97 seconds -= hour * FMT_HOUR;
98 }
99 else
100 hour = 0;
101
102 if (seconds >= FMT_MIN)
103 {
104 min = seconds / FMT_MIN;
105 seconds -= min * FMT_MIN;
106 }
107 else
108 min = 0;
109
110 if (year > 0)
111 {
112 snprintf (buf, len, "%dy%dd%dh", year, day, hour);
113 }
114 else if (day > 0)
115 {
116 snprintf (buf, len, "%dd%dh%dm", day, hour, min);
117 }
118 else
119 {
120 snprintf (buf, len, "%02d:%02d:%02d", hour, min, seconds);
121 }
122
123 return buf;
124 }
125
126 char *
127 rfapiFormatAge (time_t age, char *buf, size_t len)
128 {
129 time_t now, age_adjusted;
130
131 now = rfapi_time (NULL);
132 age_adjusted = now - age;
133
134 return rfapiFormatSeconds (age_adjusted, buf, len);
135 }
136
137
138 /*
139 * Reimplementation of quagga/lib/prefix.c function, but
140 * for RFAPI-style prefixes
141 */
142 void
143 rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix)
144 {
145 uint8_t *pnt;
146 int index;
147 int offset;
148
149 static uint8_t maskbit[] =
150 { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
151
152 switch (rprefix->prefix.addr_family)
153 {
154 case AF_INET:
155 index = rprefix->length / 8;
156 if (index < 4)
157 {
158 pnt = (uint8_t *) & rprefix->prefix.addr.v4;
159 offset = rprefix->length % 8;
160 pnt[index] &= maskbit[offset];
161 index++;
162 while (index < 4)
163 pnt[index++] = 0;
164 }
165 break;
166
167 case AF_INET6:
168 index = rprefix->length / 8;
169 if (index < 16)
170 {
171 pnt = (uint8_t *) & rprefix->prefix.addr.v6;
172 offset = rprefix->length % 8;
173 pnt[index] &= maskbit[offset];
174 index++;
175 while (index < 16)
176 pnt[index++] = 0;
177 }
178 break;
179
180 default:
181 assert (0);
182 }
183 }
184
185 /*
186 * translate a quagga prefix into a rfapi IP address. The
187 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
188 *
189 * RETURNS:
190 *
191 * 0 Success
192 * <0 Error
193 */
194 int
195 rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr)
196 {
197 memset (raddr, 0, sizeof (struct rfapi_ip_addr));
198 raddr->addr_family = qprefix->family;
199 switch (qprefix->family)
200 {
201 case AF_INET:
202 if (qprefix->prefixlen != 32)
203 return -1;
204 raddr->addr.v4 = qprefix->u.prefix4;
205 break;
206 case AF_INET6:
207 if (qprefix->prefixlen != 128)
208 return -1;
209 raddr->addr.v6 = qprefix->u.prefix6;
210 break;
211 default:
212 return -1;
213 }
214 return 0;
215 }
216
217 /*
218 * Translate Quagga prefix to RFAPI prefix
219 */
220 /* rprefix->cost set to 0 */
221 void
222 rfapiQprefix2Rprefix (struct prefix *qprefix, struct rfapi_ip_prefix *rprefix)
223 {
224 memset (rprefix, 0, sizeof (struct rfapi_ip_prefix));
225 rprefix->length = qprefix->prefixlen;
226 rprefix->prefix.addr_family = qprefix->family;
227 switch (qprefix->family)
228 {
229 case AF_INET:
230 rprefix->prefix.addr.v4 = qprefix->u.prefix4;
231 break;
232 case AF_INET6:
233 rprefix->prefix.addr.v6 = qprefix->u.prefix6;
234 break;
235 default:
236 assert (0);
237 }
238 }
239
240 int
241 rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix)
242 {
243 memset (qprefix, 0, sizeof (struct prefix));
244 qprefix->prefixlen = rprefix->length;
245 qprefix->family = rprefix->prefix.addr_family;
246
247 switch (rprefix->prefix.addr_family)
248 {
249 case AF_INET:
250 qprefix->u.prefix4 = rprefix->prefix.addr.v4;
251 break;
252 case AF_INET6:
253 qprefix->u.prefix6 = rprefix->prefix.addr.v6;
254 break;
255 default:
256 return EAFNOSUPPORT;
257 }
258 return 0;
259 }
260
261 /*
262 * returns 1 if prefixes have same addr family, prefix len, and address
263 * Note that host bits matter in this comparison!
264 *
265 * For paralellism with quagga/lib/prefix.c. if we need a comparison
266 * where host bits are ignored, call that function rfapiRprefixCmp.
267 */
268 int
269 rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2)
270 {
271 if (hp1->prefix.addr_family != hp2->prefix.addr_family)
272 return 0;
273 if (hp1->length != hp2->length)
274 return 0;
275 if (hp1->prefix.addr_family == AF_INET)
276 if (IPV4_ADDR_SAME (&hp1->prefix.addr.v4, &hp2->prefix.addr.v4))
277 return 1;
278 if (hp1->prefix.addr_family == AF_INET6)
279 if (IPV6_ADDR_SAME (&hp1->prefix.addr.v6, &hp2->prefix.addr.v6))
280 return 1;
281 return 0;
282 }
283
284 int
285 rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx)
286 {
287 memset (pfx, 0, sizeof (struct prefix));
288 pfx->family = hia->addr_family;
289
290 switch (hia->addr_family)
291 {
292 case AF_INET:
293 pfx->prefixlen = 32;
294 pfx->u.prefix4 = hia->addr.v4;
295 break;
296 case AF_INET6:
297 pfx->prefixlen = 128;
298 pfx->u.prefix6 = hia->addr.v6;
299 break;
300 default:
301 return EAFNOSUPPORT;
302 }
303 return 0;
304 }
305
306 void
307 rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx)
308 {
309 memset (pfx, 0, sizeof (struct prefix));
310 pfx->family = AF_ETHERNET;
311 pfx->prefixlen = 48;
312 pfx->u.prefix_eth = l2o->macaddr;
313 }
314
315 char *
316 rfapiEthAddr2Str (const struct ethaddr *ea, char *buf, int bufsize)
317 {
318 return prefix_mac2str (ea, buf, bufsize);
319 }
320
321 int
322 rfapiStr2EthAddr (const char *str, struct ethaddr *ea)
323 {
324 unsigned int a[6];
325 int i;
326
327 if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x",
328 a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6)
329 {
330
331 return EINVAL;
332 }
333
334 for (i = 0; i < 6; ++i)
335 ea->octet[i] = a[i] & 0xff;
336
337 return 0;
338 }
339
340 const char *
341 rfapi_ntop (int af, const void *src, char *buf, socklen_t size)
342 {
343 if (af == AF_ETHERNET)
344 {
345 return rfapiEthAddr2Str ((const struct ethaddr *) src, buf, size);
346 }
347
348 return inet_ntop (af, src, buf, size);
349 }
350
351 int
352 rfapiDebugPrintf (void *dummy, const char *format, ...)
353 {
354 va_list args;
355 va_start (args, format);
356 vzlog (LOG_DEBUG, format, args);
357 va_end (args);
358 return 0;
359 }
360
361 static int
362 rfapiStdioPrintf (void *stream, const char *format, ...)
363 {
364 FILE *file = NULL;
365
366 va_list args;
367 va_start (args, format);
368
369 switch ((uintptr_t) stream)
370 {
371 case 1:
372 file = stdout;
373 break;
374 case 2:
375 file = stderr;
376 break;
377 default:
378 assert (0);
379 }
380
381 vfprintf (file, format, args);
382 va_end (args);
383 return 0;
384 }
385
386 /* Fake out for debug logging */
387 static struct vty vty_dummy_zlog;
388 static struct vty vty_dummy_stdio;
389 #define HVTY_NEWLINE ((vty == &vty_dummy_zlog)? "": VTY_NEWLINE)
390
391 static const char *
392 str_vty_newline (struct vty *vty)
393 {
394 if (vty == &vty_dummy_zlog)
395 return "";
396 return VTY_NEWLINE;
397 }
398
399 int
400 rfapiStream2Vty (
401 void *stream, /* input */
402 int (**fp) (void *, const char *, ...), /* output */
403 struct vty **vty, /* output */
404 void **outstream, /* output */
405 const char **vty_newline) /* output */
406 {
407
408 if (!stream)
409 {
410 vty_dummy_zlog.type = VTY_SHELL; /* for VTY_NEWLINE */
411 *vty = &vty_dummy_zlog;
412 *fp = (int (*)(void *, const char *,...)) rfapiDebugPrintf;
413 *outstream = NULL;
414 *vty_newline = str_vty_newline (*vty);
415 return (vzlog_test (LOG_DEBUG));
416 }
417
418 if (((uintptr_t) stream == (uintptr_t) 1) ||
419 ((uintptr_t) stream == (uintptr_t) 2))
420 {
421
422 vty_dummy_stdio.type = VTY_SHELL; /* for VTY_NEWLINE */
423 *vty = &vty_dummy_stdio;
424 *fp = (int (*)(void *, const char *,...)) rfapiStdioPrintf;
425 *outstream = stream;
426 *vty_newline = str_vty_newline (*vty);
427 return 1;
428 }
429
430 if (stream)
431 {
432 *vty = stream; /* VTY_NEWLINE requires vty to be legit */
433 *fp = (int (*)(void *, const char *,...)) vty_out;
434 *outstream = stream;
435 *vty_newline = str_vty_newline (*vty);
436 return 1;
437 }
438
439 return 0;
440 }
441
442 /* called from bgpd/bgp_vty.c'route_vty_out() */
443 void
444 rfapi_vty_out_vncinfo (
445 struct vty *vty,
446 struct prefix *p,
447 struct bgp_info *bi,
448 safi_t safi)
449 {
450 char *s;
451 uint32_t lifetime;
452
453 /*
454 * Print, on an indented line:
455 * UN address [if VPN route and VNC UN addr subtlv]
456 * EC list
457 * VNC lifetime
458 */
459 vty_out (vty, " ");
460
461 if (safi == SAFI_MPLS_VPN)
462 {
463 struct prefix pfx_un;
464
465 if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un))
466 {
467 char buf[BUFSIZ];
468 vty_out (vty, "UN=%s", inet_ntop (pfx_un.family,
469 pfx_un.u.val, buf, BUFSIZ));
470 }
471 }
472
473 if (bi->attr && bi->attr->extra && bi->attr->extra->ecommunity)
474 {
475 s = ecommunity_ecom2str (bi->attr->extra->ecommunity,
476 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
477 vty_out (vty, " EC{%s}", s);
478 XFREE (MTYPE_ECOMMUNITY_STR, s);
479 }
480
481 if (bi->extra != NULL)
482 vty_out (vty, " label=%u", decode_label (bi->extra->tag));
483
484 if (!rfapiGetVncLifetime (bi->attr, &lifetime))
485 {
486 vty_out (vty, " life=%d", lifetime);
487 }
488
489 vty_out (vty, " type=%s, subtype=%d",
490 zebra_route_string (bi->type), bi->sub_type);
491
492 vty_out (vty, "%s", HVTY_NEWLINE);
493 }
494
495 void
496 rfapiPrintAttrPtrs (void *stream, struct attr *attr)
497 {
498 int (*fp) (void *, const char *, ...);
499 struct vty *vty;
500 void *out;
501 const char *vty_newline;
502
503 struct attr_extra *ae;
504 char buf[BUFSIZ];
505
506 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
507 return;
508
509 fp (out, "Attr[%p]:%s", attr, HVTY_NEWLINE);
510 if (!attr)
511 return;
512
513 /* IPv4 Nexthop */
514 inet_ntop (AF_INET, &attr->nexthop, buf, BUFSIZ);
515 fp (out, " nexthop=%s%s", buf, HVTY_NEWLINE);
516
517 fp (out, " aspath=%p, refcnt=%d%s", attr->aspath,
518 (attr->aspath ? attr->aspath->refcnt : 0), HVTY_NEWLINE);
519 fp (out, " community=%p, refcnt=%d%s", attr->community,
520 (attr->community ? attr->community->refcnt : 0), HVTY_NEWLINE);
521
522 if ((ae = attr->extra))
523 {
524 fp (out, " ecommunity=%p, refcnt=%d%s", ae->ecommunity,
525 (ae->ecommunity ? ae->ecommunity->refcnt : 0), HVTY_NEWLINE);
526 fp (out, " cluster=%p, refcnt=%d%s", ae->cluster,
527 (ae->cluster ? ae->cluster->refcnt : 0), HVTY_NEWLINE);
528 fp (out, " transit=%p, refcnt=%d%s", ae->transit,
529 (ae->transit ? ae->transit->refcnt : 0), HVTY_NEWLINE);
530 }
531 }
532
533 /*
534 * Print BI in an Import Table
535 */
536 void
537 rfapiPrintBi (void *stream, struct bgp_info *bi)
538 {
539 char buf[BUFSIZ];
540 char *s;
541
542 int (*fp) (void *, const char *, ...);
543 struct vty *vty;
544 void *out;
545 const char *vty_newline;
546
547 char line[BUFSIZ];
548 char *p = line;
549 int r;
550 int has_macaddr = 0;
551 struct ethaddr macaddr;
552 struct rfapi_l2address_option l2o_buf;
553 uint8_t l2hid=0; /* valid if has_macaddr */
554
555 #define REMAIN (BUFSIZ - (p-line))
556 #define INCP {p += (r > REMAIN)? REMAIN: r;}
557
558 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
559 return;
560
561 if (!bi)
562 return;
563
564 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && bi->extra
565 && bi->extra->vnc.import.timer)
566 {
567 struct thread *t = (struct thread *) bi->extra->vnc.import.timer;
568 r = snprintf (p, REMAIN, " [%4lu] ", thread_timer_remain_second (t));
569 INCP;
570
571 }
572 else
573 {
574 r = snprintf (p, REMAIN, " ");
575 INCP;
576 }
577
578 if (bi->extra)
579 {
580 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
581 if (decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH)
582 {
583 has_macaddr = 1;
584 memcpy (macaddr.octet, bi->extra->vnc.import.rd.val + 2, 6);
585 l2hid = bi->extra->vnc.import.rd.val[1];
586 }
587 }
588
589 /*
590 * Print these items:
591 * type/subtype
592 * nexthop address
593 * lifetime
594 * RFP option sizes (they are opaque values)
595 * extended communities (RTs)
596 */
597 if (bi->attr && bi->attr->extra)
598 {
599 uint32_t lifetime;
600 int printed_1st_gol = 0;
601 struct bgp_attr_encap_subtlv *pEncap;
602 struct prefix pfx_un;
603 int af = BGP_MP_NEXTHOP_FAMILY (bi->attr->extra->mp_nexthop_len);
604
605 /* Nexthop */
606 if (af == AF_INET)
607 {
608 r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET,
609 &bi->attr->extra->mp_nexthop_global_in,
610 buf, BUFSIZ));
611 INCP;
612 }
613 else if (af == AF_INET6)
614 {
615 r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET6,
616 &bi->attr->extra->mp_nexthop_global,
617 buf, BUFSIZ));
618 INCP;
619 }
620 else
621 {
622 r = snprintf (p, REMAIN, "?");
623 INCP;
624 }
625
626 /*
627 * VNC tunnel subtlv, if present, contains UN address
628 */
629 if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un))
630 {
631 r = snprintf (p, REMAIN, " un=%s", inet_ntop (pfx_un.family,
632 pfx_un.u.val, buf,
633 BUFSIZ));
634 INCP;
635
636 }
637
638 /* Lifetime */
639 if (rfapiGetVncLifetime (bi->attr, &lifetime))
640 {
641 r = snprintf (p, REMAIN, " nolife");
642 INCP;
643 }
644 else
645 {
646 if (lifetime == 0xffffffff)
647 r = snprintf (p, REMAIN, " %6s", "infini");
648 else
649 r = snprintf (p, REMAIN, " %6u", lifetime);
650 INCP;
651 }
652
653 /* RFP option lengths */
654 for (pEncap = bi->attr->extra->vnc_subtlvs; pEncap;
655 pEncap = pEncap->next)
656 {
657
658 if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION)
659 {
660 if (printed_1st_gol)
661 {
662 r = snprintf (p, REMAIN, ",");
663 INCP;
664 }
665 else
666 {
667 r = snprintf (p, REMAIN, " "); /* leading space */
668 INCP;
669 }
670 r = snprintf (p, REMAIN, "%d", pEncap->length);
671 INCP;
672 printed_1st_gol = 1;
673 }
674 }
675
676 /* RT list */
677 if (bi->attr->extra->ecommunity)
678 {
679 s = ecommunity_ecom2str (bi->attr->extra->ecommunity,
680 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
681 r = snprintf (p, REMAIN, " %s", s);
682 INCP;
683 XFREE (MTYPE_ECOMMUNITY_STR, s);
684 }
685
686 }
687
688 r = snprintf (p, REMAIN, " bi@%p", bi);
689 INCP;
690
691 r = snprintf (p, REMAIN, " p@%p", bi->peer);
692 INCP;
693
694 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
695 {
696 r = snprintf (p, REMAIN, " HD=yes");
697 INCP;
698 }
699 else
700 {
701 r = snprintf (p, REMAIN, " HD=no");
702 INCP;
703 }
704
705 if (bi->attr)
706 {
707
708 if (bi->attr->extra)
709 {
710 r = snprintf (p, REMAIN, " W=%d", bi->attr->extra->weight);
711 INCP;
712 }
713
714 if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
715 {
716 r = snprintf (p, REMAIN, " LP=%d", bi->attr->local_pref);
717 INCP;
718 }
719 else
720 {
721 r = snprintf (p, REMAIN, " LP=unset");
722 INCP;
723 }
724 }
725
726 r =
727 snprintf (p, REMAIN, " %c:%u", zebra_route_char (bi->type), bi->sub_type);
728 INCP;
729
730 fp (out, "%s%s", line, HVTY_NEWLINE);
731
732 if (has_macaddr)
733 {
734 fp (out, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
735 l2hid,
736 macaddr.octet[0],
737 macaddr.octet[1],
738 macaddr.octet[2],
739 macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], HVTY_NEWLINE);
740 }
741
742 if (!rfapiGetL2o (bi->attr, &l2o_buf))
743 {
744 fp (out,
745 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
746 l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1],
747 l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3],
748 l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], l2o_buf.label,
749 l2o_buf.logical_net_id, l2o_buf.local_nve_id, HVTY_NEWLINE);
750 }
751 if (bi->extra && bi->extra->vnc.import.aux_prefix.family)
752 {
753 char buf[BUFSIZ];
754 const char *sp;
755
756 sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family,
757 &bi->extra->vnc.import.aux_prefix.u.prefix,
758 buf, BUFSIZ);
759 buf[BUFSIZ - 1] = 0;
760 if (sp)
761 {
762 fp (out, " IP: %s%s", sp, HVTY_NEWLINE);
763 }
764 }
765 {
766 struct rfapi_un_option *uo = rfapi_encap_tlv_to_un_option (bi->attr);
767 if (uo)
768 {
769 rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel);
770 rfapi_un_options_free (uo);
771 }
772 }
773 }
774
775 char *
776 rfapiMonitorVpn2Str (struct rfapi_monitor_vpn *m, char *buf, int size)
777 {
778 char buf_pfx[BUFSIZ];
779 char buf_vn[BUFSIZ];
780 char buf_un[BUFSIZ];
781 int rc;
782
783 rfapiRfapiIpAddr2Str (&m->rfd->un_addr, buf_vn, BUFSIZ);
784 rfapiRfapiIpAddr2Str (&m->rfd->vn_addr, buf_un, BUFSIZ);
785
786 rc = snprintf (buf, size,
787 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p",
788 m, m->next, m->rfd, buf_vn, buf_un,
789 inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ),
790 m->p.prefixlen, m->node);
791 buf[size - 1] = 0;
792 if (rc >= size)
793 return NULL;
794 return buf;
795 }
796
797 static void
798 rfapiDebugPrintMonitorVpn (void *stream, struct rfapi_monitor_vpn *m)
799 {
800 char buf[BUFSIZ];
801
802 int (*fp) (void *, const char *, ...);
803 struct vty *vty;
804 void *out;
805 const char *vty_newline;
806
807 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
808 return;
809
810 rfapiMonitorVpn2Str (m, buf, BUFSIZ);
811 fp (out, " Mon %s%s", buf, HVTY_NEWLINE);
812 }
813
814 static void
815 rfapiDebugPrintMonitorEncap (void *stream, struct rfapi_monitor_encap *m)
816 {
817 int (*fp) (void *, const char *, ...);
818 struct vty *vty;
819 void *out = NULL;
820 const char *vty_newline;
821
822 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
823 return;
824
825 fp (out, " Mon m=%p, next=%p, node=%p, bi=%p%s",
826 m, m->next, m->node, m->bi, HVTY_NEWLINE);
827 }
828
829 void
830 rfapiShowItNode (void *stream, struct route_node *rn)
831 {
832 struct bgp_info *bi;
833 char buf[BUFSIZ];
834
835 int (*fp) (void *, const char *, ...);
836 struct vty *vty;
837 void *out;
838 const char *vty_newline;
839
840 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
841 return;
842
843 fp (out, "%s/%d @%p #%d%s",
844 rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
845 rn->p.prefixlen, rn, rn->lock, HVTY_NEWLINE);
846
847 for (bi = rn->info; bi; bi = bi->next)
848 {
849 rfapiPrintBi (stream, bi);
850 }
851
852 /* doesn't show montors */
853 }
854
855 void
856 rfapiShowImportTable (
857 void *stream,
858 const char *label,
859 struct route_table *rt,
860 int isvpn)
861 {
862 struct route_node *rn;
863 char buf[BUFSIZ];
864
865 int (*fp) (void *, const char *, ...);
866 struct vty *vty;
867 void *out;
868 const char *vty_newline;
869
870 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
871 return;
872
873 fp (out, "Import Table [%s]%s", label, HVTY_NEWLINE);
874
875 for (rn = route_top (rt); rn; rn = route_next (rn))
876 {
877 struct bgp_info *bi;
878
879 if (rn->p.family == AF_ETHERNET)
880 {
881 rfapiEthAddr2Str (&rn->p.u.prefix_eth, buf, BUFSIZ);
882 }
883 else
884 {
885 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ);
886 }
887
888 fp (out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, rn->lock - 1, /* account for loop iterator locking */
889 HVTY_NEWLINE);
890
891 for (bi = rn->info; bi; bi = bi->next)
892 {
893 rfapiPrintBi (stream, bi);
894 }
895
896 if (isvpn)
897 {
898 struct rfapi_monitor_vpn *m;
899 for (m = RFAPI_MONITOR_VPN (rn); m; m = m->next)
900 {
901 rfapiDebugPrintMonitorVpn (stream, m);
902 }
903 }
904 else
905 {
906 struct rfapi_monitor_encap *m;
907 for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next)
908 {
909 rfapiDebugPrintMonitorEncap (stream, m);
910 }
911 }
912 }
913 }
914
915 int
916 rfapiShowVncQueries (void *stream, struct prefix *pfx_match)
917 {
918 struct bgp *bgp;
919 struct rfapi *h;
920 struct listnode *node;
921 struct rfapi_descriptor *rfd;
922
923 int (*fp) (void *, const char *, ...);
924 struct vty *vty;
925 void *out;
926 const char *vty_newline;
927
928 int printedheader = 0;
929
930 int nves_total = 0;
931 int nves_with_queries = 0;
932 int nves_displayed = 0;
933
934 int queries_total = 0;
935 int queries_displayed = 0;
936
937 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
938 return CMD_WARNING;
939
940 bgp = bgp_get_default (); /* assume 1 instance for now */
941 if (!bgp)
942 {
943 vty_out (vty, "No BGP instance%s", VTY_NEWLINE);
944 return CMD_WARNING;
945 }
946
947 h = bgp->rfapi;
948 if (!h)
949 {
950 vty_out (vty, "No RFAPI instance%s", VTY_NEWLINE);
951 return CMD_WARNING;
952 }
953
954 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
955 {
956
957 struct route_node *rn;
958 int printedquerier = 0;
959
960
961 ++nves_total;
962
963 if (rfd->mon || (rfd->mon_eth && skiplist_count (rfd->mon_eth)))
964 {
965 ++nves_with_queries;
966 }
967 else
968 {
969 continue;
970 }
971
972 /*
973 * IP Queries
974 */
975 if (rfd->mon)
976 {
977 for (rn = route_top (rfd->mon); rn; rn = route_next (rn))
978 {
979 struct rfapi_monitor_vpn *m;
980 char buf_remain[BUFSIZ];
981 char buf_pfx[BUFSIZ];
982
983 if (!rn->info)
984 continue;
985
986 m = rn->info;
987
988 ++queries_total;
989
990 if (pfx_match && !prefix_match (pfx_match, &rn->p) &&
991 !prefix_match (&rn->p, pfx_match))
992 continue;
993
994 ++queries_displayed;
995
996 if (!printedheader)
997 {
998 ++printedheader;
999 fp (out, "%s", VTY_NEWLINE);
1000 fp (out, "%-15s %-15s %-15s %-10s%s",
1001 "VN Address", "UN Address",
1002 "Target", "Remaining", VTY_NEWLINE);
1003 }
1004
1005 if (!printedquerier)
1006 {
1007 char buf_vn[BUFSIZ];
1008 char buf_un[BUFSIZ];
1009
1010 rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
1011 rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
1012
1013 fp (out, "%-15s %-15s", buf_vn, buf_un);
1014 printedquerier = 1;
1015
1016 ++nves_displayed;
1017 }
1018 else
1019 fp (out, "%-15s %-15s", "", "");
1020 buf_remain[0] = 0;
1021 if (m->timer)
1022 {
1023 rfapiFormatSeconds (thread_timer_remain_second (m->timer),
1024 buf_remain, BUFSIZ);
1025 }
1026 fp (out, " %-15s %-10s%s",
1027 inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ),
1028 buf_remain, VTY_NEWLINE);
1029 }
1030 }
1031
1032 /*
1033 * Ethernet Queries
1034 */
1035 if (rfd->mon_eth && skiplist_count (rfd->mon_eth))
1036 {
1037
1038 int rc;
1039 void *cursor;
1040 struct rfapi_monitor_eth *mon_eth;
1041
1042 for (cursor = NULL,
1043 rc =
1044 skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth,
1045 &cursor); rc == 0;
1046 rc =
1047 skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth,
1048 &cursor))
1049 {
1050
1051 char buf_remain[BUFSIZ];
1052 char buf_pfx[BUFSIZ];
1053 struct prefix pfx_mac;
1054
1055 ++queries_total;
1056
1057 vnc_zlog_debug_verbose ("%s: checking rfd=%p mon_eth=%p", __func__, rfd,
1058 mon_eth);
1059
1060 memset ((void *) &pfx_mac, 0, sizeof (struct prefix));
1061 pfx_mac.family = AF_ETHERNET;
1062 pfx_mac.prefixlen = 48;
1063 pfx_mac.u.prefix_eth = mon_eth->macaddr;
1064
1065 if (pfx_match && !prefix_match (pfx_match, &pfx_mac) &&
1066 !prefix_match (&pfx_mac, pfx_match))
1067 continue;
1068
1069 ++queries_displayed;
1070
1071 if (!printedheader)
1072 {
1073 ++printedheader;
1074 fp (out, "%s", VTY_NEWLINE);
1075 fp (out, "%-15s %-15s %-17s %10s %-10s%s",
1076 "VN Address", "UN Address",
1077 "Target", "LNI", "Remaining", VTY_NEWLINE);
1078 }
1079
1080 if (!printedquerier)
1081 {
1082 char buf_vn[BUFSIZ];
1083 char buf_un[BUFSIZ];
1084
1085 rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
1086 rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
1087
1088 fp (out, "%-15s %-15s", buf_vn, buf_un);
1089 printedquerier = 1;
1090
1091 ++nves_displayed;
1092 }
1093 else
1094 fp (out, "%-15s %-15s", "", "");
1095 buf_remain[0] = 0;
1096 if (mon_eth->timer)
1097 {
1098 rfapiFormatSeconds (thread_timer_remain_second
1099 (mon_eth->timer), buf_remain, BUFSIZ);
1100 }
1101 fp (out, " %-17s %10d %-10s%s",
1102 rfapi_ntop (pfx_mac.family, &pfx_mac.u.prefix, buf_pfx,
1103 BUFSIZ), mon_eth->logical_net_id, buf_remain,
1104 VTY_NEWLINE);
1105 }
1106 }
1107 }
1108
1109 if (queries_total)
1110 {
1111 fp (out, "%s", VTY_NEWLINE);
1112 fp (out, "Displayed %d out of %d total queries%s",
1113 queries_displayed, queries_total, VTY_NEWLINE);
1114 }
1115 return CMD_SUCCESS;
1116 }
1117
1118 static int
1119 rfapiPrintRemoteRegBi (
1120 struct bgp *bgp,
1121 void *stream,
1122 struct route_node *rn,
1123 struct bgp_info *bi)
1124 {
1125 int (*fp) (void *, const char *, ...);
1126 struct vty *vty;
1127 void *out;
1128 const char *vty_newline;
1129 struct prefix pfx_un;
1130 struct prefix pfx_vn;
1131 uint8_t cost;
1132 uint32_t lifetime;
1133 bgp_encap_types tun_type;
1134
1135 char buf_pfx[BUFSIZ];
1136 char buf_ntop[BUFSIZ];
1137 char buf_un[BUFSIZ];
1138 char buf_vn[BUFSIZ];
1139 char buf_lifetime[BUFSIZ];
1140 int nlines = 0;
1141
1142 if (!stream)
1143 return 0; /* for debug log, print into buf & call output once */
1144
1145 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
1146 return 0;
1147
1148 /*
1149 * Prefix
1150 */
1151 buf_pfx[0] = 0;
1152 snprintf (buf_pfx, BUFSIZ, "%s/%d",
1153 rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ),
1154 rn->p.prefixlen);
1155 buf_pfx[BUFSIZ - 1] = 0;
1156 nlines++;
1157
1158 /*
1159 * UN addr
1160 */
1161 buf_un[0] = 0;
1162 if (!rfapiGetUnAddrOfVpnBi (bi, &pfx_un))
1163 {
1164 snprintf (buf_un, BUFSIZ, "%s",
1165 inet_ntop (pfx_un.family, &pfx_un.u.prefix, buf_ntop,
1166 BUFSIZ));
1167 }
1168
1169 rfapiGetTunnelType(bi->attr,&tun_type);
1170 /*
1171 * VN addr
1172 */
1173 buf_vn[0] = 0;
1174 rfapiNexthop2Prefix (bi->attr, &pfx_vn);
1175 if (tun_type == BGP_ENCAP_TYPE_MPLS)
1176 {
1177 /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */
1178 snprintf (buf_un, BUFSIZ, "%s",
1179 inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ));
1180 if (bi->extra)
1181 {
1182 u_int32_t l = decode_label (bi->extra->tag);
1183 snprintf (buf_vn, BUFSIZ, "Label: %d", l);
1184 }
1185 else /* should never happen */
1186 {
1187 snprintf (buf_vn, BUFSIZ, "Label: N/A");
1188 }
1189 }
1190 else
1191 {
1192 snprintf (buf_vn, BUFSIZ, "%s",
1193 inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ));
1194 }
1195 buf_vn[BUFSIZ - 1] = 0;
1196 buf_un[BUFSIZ - 1] = 0;
1197
1198 /*
1199 * Cost is encoded in local_pref as (255-cost)
1200 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1201 * back to cost.
1202 */
1203 if (bi->attr)
1204 {
1205 uint32_t local_pref;
1206 if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1207 local_pref = bi->attr->local_pref;
1208 else
1209 local_pref = 0;
1210 cost = (local_pref > 255) ? 0 : 255 - local_pref;
1211 }
1212 else
1213 {
1214 cost = 0;
1215 }
1216
1217 fp (out, "%-20s ", buf_pfx);
1218 fp (out, "%-15s ", buf_vn);
1219 fp (out, "%-15s ", buf_un);
1220 fp (out, "%-4d ", cost);
1221
1222 /* Lifetime */
1223 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1224 if (rfapiGetVncLifetime (bi->attr, &lifetime) ||
1225 (lifetime == RFAPI_INFINITE_LIFETIME))
1226 {
1227
1228 fp (out, "%-10s ", "infinite");
1229 }
1230 else
1231 {
1232 time_t t_lifetime = lifetime;
1233 rfapiFormatSeconds (t_lifetime, buf_lifetime, BUFSIZ);
1234 fp (out, "%-10s ", buf_lifetime);
1235 }
1236
1237 if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) &&
1238 bi->extra && bi->extra->vnc.import.timer)
1239 {
1240
1241 uint32_t remaining;
1242 time_t age;
1243 char buf_age[BUFSIZ];
1244
1245 struct thread *t = (struct thread *) bi->extra->vnc.import.timer;
1246 remaining = thread_timer_remain_second (t);
1247
1248 #if RFAPI_REGISTRATIONS_REPORT_AGE
1249 /*
1250 * Calculate when the timer started. Doing so here saves
1251 * us a timestamp field in "struct bgp_info".
1252 *
1253 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1254 * original calculation.
1255 */
1256 age = rfapiGetHolddownFromLifetime (lifetime, factor) - remaining;
1257 #else /* report remaining time */
1258 age = remaining;
1259 #endif
1260 rfapiFormatSeconds (age, buf_age, BUFSIZ);
1261
1262 fp (out, "%-10s ", buf_age);
1263
1264 }
1265 else if (RFAPI_LOCAL_BI (bi))
1266 {
1267
1268 char buf_age[BUFSIZ];
1269
1270 if (bi && bi->extra && bi->extra->vnc.import.create_time)
1271 {
1272 rfapiFormatAge (bi->extra->vnc.import.create_time, buf_age, BUFSIZ);
1273 }
1274 else
1275 {
1276 buf_age[0] = '?';
1277 buf_age[1] = 0;
1278 }
1279 fp (out, "%-10s ", buf_age);
1280 }
1281 fp (out, "%s", HVTY_NEWLINE);
1282
1283 if (rn->p.family == AF_ETHERNET)
1284 {
1285 /*
1286 * If there is a corresponding IP address && != VN address,
1287 * print that on the next line
1288 */
1289
1290 if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family)
1291 {
1292 const char *sp;
1293
1294 sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family,
1295 &bi->extra->vnc.import.aux_prefix.u.prefix,
1296 buf_ntop, BUFSIZ);
1297 buf_ntop[BUFSIZ - 1] = 0;
1298
1299 if (sp && strcmp (buf_vn, sp) != 0)
1300 {
1301 fp (out, " IP: %s", sp);
1302 if (nlines == 1)
1303 nlines++;
1304 }
1305 }
1306 }
1307 if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra)
1308 {
1309 u_int32_t l = decode_label (bi->extra->tag);
1310 if (!MPLS_LABEL_IS_NULL (l))
1311 {
1312 fp (out, " Label: %d", l);
1313 if (nlines == 1)
1314 nlines++;
1315 }
1316 }
1317 if (nlines > 1)
1318 fp (out, "%s", HVTY_NEWLINE);
1319
1320 return 1;
1321 }
1322
1323 static int
1324 rfapiShowRemoteRegistrationsIt (
1325 struct bgp *bgp,
1326 void *stream,
1327 struct rfapi_import_table *it,
1328 struct prefix *prefix_only,
1329 int show_expiring, /* either/or */
1330 int show_local,
1331 int show_remote,
1332 int show_imported, /* either/or */
1333 uint32_t *pLni) /* AFI_L2VPN only */
1334 {
1335 afi_t afi;
1336 int printed_rtlist_hdr = 0;
1337
1338 int (*fp) (void *, const char *, ...);
1339 struct vty *vty;
1340 void *out;
1341 const char *vty_newline;
1342 int total = 0;
1343 int printed = 0;
1344
1345 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
1346 return printed;
1347
1348 for (afi = AFI_IP; afi < AFI_MAX; ++afi)
1349 {
1350
1351 struct route_node *rn;
1352
1353 if (!it->imported_vpn[afi])
1354 continue;
1355
1356 for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn))
1357 {
1358
1359 struct bgp_info *bi;
1360 int count_only;
1361
1362 /* allow for wider or more narrow mask from user */
1363 if (prefix_only &&
1364 !prefix_match (prefix_only, &rn->p) &&
1365 !prefix_match (&rn->p, prefix_only))
1366 count_only = 1;
1367 else
1368 count_only = 0;
1369
1370 for (bi = rn->info; bi; bi = bi->next)
1371 {
1372
1373 if (!show_local && RFAPI_LOCAL_BI (bi))
1374 {
1375
1376 /* local route from RFP */
1377 continue;
1378 }
1379
1380 if (!show_remote && !RFAPI_LOCAL_BI (bi))
1381 {
1382
1383 /* remote route */
1384 continue;
1385 }
1386
1387 if (show_expiring && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
1388 continue;
1389
1390 if (!show_expiring && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
1391 continue;
1392
1393 if (bi->type == ZEBRA_ROUTE_BGP_DIRECT ||
1394 bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)
1395 {
1396 if (!show_imported)
1397 continue;
1398 }
1399 else
1400 {
1401 if (show_imported)
1402 continue;
1403 }
1404
1405 total++;
1406 if (count_only == 1)
1407 continue;
1408 if (!printed_rtlist_hdr)
1409 {
1410 const char *agetype = "";
1411 char *s;
1412 const char *type = "";
1413 if (show_imported)
1414 {
1415 type = "Imported";
1416 }
1417 else
1418 {
1419 if (show_expiring)
1420 {
1421 type = "Holddown";
1422 }
1423 else
1424 {
1425 if (RFAPI_LOCAL_BI (bi))
1426 {
1427 type = "Local";
1428 }
1429 else
1430 {
1431 type = "Remote";
1432 }
1433 }
1434 }
1435
1436 s = ecommunity_ecom2str (it->rt_import_list,
1437 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1438
1439 if (pLni)
1440 {
1441 fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1442 HVTY_NEWLINE, type, *pLni, (*pLni & 0xfff), s);
1443 }
1444 else
1445 {
1446 fp (out, "%s[%s] Prefix RT={%s}",
1447 HVTY_NEWLINE, type, s);
1448 }
1449 XFREE (MTYPE_ECOMMUNITY_STR, s);
1450
1451 if (it->rfg && it->rfg->name)
1452 {
1453 fp (out, " %s \"%s\"",
1454 (it->rfg->type == RFAPI_GROUP_CFG_VRF ?
1455 "VRF" : "NVE group"),
1456 it->rfg->name);
1457 }
1458 fp (out, "%s", HVTY_NEWLINE);
1459 if (show_expiring)
1460 {
1461 #if RFAPI_REGISTRATIONS_REPORT_AGE
1462 agetype = "Age";
1463 #else
1464 agetype = "Remaining";
1465 #endif
1466 }
1467 else if (show_local)
1468 {
1469 agetype = "Age";
1470 }
1471
1472 printed_rtlist_hdr = 1;
1473
1474 fp (out, "%-20s %-15s %-15s %4s %-10s %-10s%s",
1475 (pLni ? "L2 Address/IP" : "Prefix"),
1476 "VN Address", "UN Address", "Cost",
1477 "Lifetime", agetype, HVTY_NEWLINE);
1478 }
1479 printed += rfapiPrintRemoteRegBi (bgp, stream, rn, bi);
1480 }
1481 }
1482 }
1483
1484 if (printed > 0)
1485 {
1486
1487 const char *type = "prefixes";
1488
1489 if (show_imported)
1490 {
1491 type = "imported prefixes";
1492 }
1493 else
1494 {
1495 if (show_expiring)
1496 {
1497 type = "prefixes in holddown";
1498 }
1499 else
1500 {
1501 if (show_local && !show_remote)
1502 {
1503 type = "locally registered prefixes";
1504 }
1505 else if (!show_local && show_remote)
1506 {
1507 type = "remotely registered prefixes";
1508 }
1509 }
1510 }
1511
1512 fp (out, "Displayed %d out of %d %s%s",
1513 printed, total, type, HVTY_NEWLINE);
1514 #if DEBUG_SHOW_EXTRA
1515 fp(out, "IT table above: it=%p%s", it, HVTY_NEWLINE);
1516 #endif
1517 }
1518 return printed;
1519 }
1520
1521
1522
1523 /*
1524 * rfapiShowRemoteRegistrations
1525 *
1526 * Similar to rfapiShowImportTable() above. This function
1527 * is mean to produce the "remote" portion of the output
1528 * of "show vnc registrations".
1529 */
1530 int
1531 rfapiShowRemoteRegistrations (
1532 void *stream,
1533 struct prefix *prefix_only,
1534 int show_expiring,
1535 int show_local,
1536 int show_remote,
1537 int show_imported)
1538 {
1539 struct bgp *bgp;
1540 struct rfapi *h;
1541 struct rfapi_import_table *it;
1542 int printed = 0;
1543
1544 bgp = bgp_get_default ();
1545 if (!bgp)
1546 {
1547 return printed;
1548 }
1549
1550 h = bgp->rfapi;
1551 if (!h)
1552 {
1553 return printed;
1554 }
1555
1556 for (it = h->imports; it; it = it->next)
1557 {
1558 printed +=
1559 rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only,
1560 show_expiring, show_local,
1561 show_remote, show_imported, NULL);
1562 }
1563
1564 if (h->import_mac)
1565 {
1566 void *cursor = NULL;
1567 int rc;
1568 uintptr_t lni_as_ptr;
1569 uint32_t lni;
1570 uint32_t *pLni;
1571
1572 for (rc =
1573 skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
1574 &cursor); !rc;
1575 rc =
1576 skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
1577 &cursor))
1578 {
1579 pLni = NULL;
1580 if ((lni_as_ptr & 0xffffffff) == lni_as_ptr)
1581 {
1582 lni = (uint32_t) (lni_as_ptr & 0xffffffff);
1583 pLni = &lni;
1584 }
1585
1586 printed +=
1587 rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only,
1588 show_expiring, show_local,
1589 show_remote, show_imported, pLni);
1590 }
1591 }
1592
1593 return printed;
1594 }
1595
1596 /*------------------------------------------
1597 * rfapiRfapiIpAddr2Str
1598 *
1599 * UI helper: generate string from rfapi_ip_addr
1600 *
1601 * input:
1602 * a IP v4/v6 address
1603 *
1604 * output
1605 * buf put string here
1606 * bufsize max space to write
1607 *
1608 * return value:
1609 * NULL conversion failed
1610 * non-NULL pointer to buf
1611 --------------------------------------------*/
1612 const char *
1613 rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize)
1614 {
1615 const char *rc = NULL;
1616
1617 switch (a->addr_family)
1618 {
1619 case AF_INET:
1620 rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize);
1621 break;
1622 case AF_INET6:
1623 rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize);
1624 break;
1625 }
1626 return rc;
1627 }
1628
1629 void
1630 rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a)
1631 {
1632 char buf[BUFSIZ];
1633 const char *rc = NULL;
1634
1635 int (*fp) (void *, const char *, ...);
1636 struct vty *vty;
1637 void *out = NULL;
1638 const char *vty_newline;
1639
1640 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
1641 return;
1642
1643 rc = rfapiRfapiIpAddr2Str (a, buf, BUFSIZ);
1644
1645 if (rc)
1646 fp (out, "%s", buf);
1647 }
1648
1649 const char *
1650 rfapiRfapiIpPrefix2Str (struct rfapi_ip_prefix *p, char *buf, int bufsize)
1651 {
1652 struct rfapi_ip_addr *a = &p->prefix;
1653 const char *rc = NULL;
1654
1655 switch (a->addr_family)
1656 {
1657 case AF_INET:
1658 rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize);
1659 break;
1660 case AF_INET6:
1661 rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize);
1662 break;
1663 }
1664
1665 if (rc)
1666 {
1667 int alen = strlen (buf);
1668 int remaining = bufsize - alen - 1;
1669 int slen;
1670
1671 if (remaining > 0)
1672 {
1673 slen = snprintf (buf + alen, remaining, "/%u", p->length);
1674 if (slen < remaining) /* see man page for snprintf(3) */
1675 return rc;
1676 }
1677 }
1678
1679 return NULL;
1680 }
1681
1682 void
1683 rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p)
1684 {
1685 char buf[BUFSIZ];
1686 const char *rc;
1687
1688 int (*fp) (void *, const char *, ...);
1689 struct vty *vty;
1690 void *out = NULL;
1691 const char *vty_newline;
1692
1693 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
1694 return;
1695
1696 rc = rfapiRfapiIpPrefix2Str (p, buf, BUFSIZ);
1697
1698 if (rc)
1699 fp (out, "%s:%u", buf, p->cost);
1700 else
1701 fp (out, "?/?:?");
1702 }
1703
1704 void
1705 rfapiPrintRd (struct vty *vty, struct prefix_rd *prd)
1706 {
1707 char buf[BUFSIZ];
1708
1709 buf[0] = 0;
1710 prefix_rd2str (prd, buf, BUFSIZ);
1711 buf[BUFSIZ - 1] = 0;
1712 vty_out (vty, "%s", buf);
1713 }
1714
1715 void
1716 rfapiPrintAdvertisedInfo (
1717 struct vty *vty,
1718 struct rfapi_descriptor *rfd,
1719 safi_t safi,
1720 struct prefix *p)
1721 {
1722 afi_t afi; /* of the VN address */
1723 struct bgp_node *bn;
1724 struct bgp_info *bi;
1725 uint8_t type = ZEBRA_ROUTE_BGP;
1726 struct bgp *bgp;
1727 int printed = 0;
1728 struct prefix_rd prd0;
1729 struct prefix_rd *prd;
1730
1731 /*
1732 * Find the bgp_info in the RIB corresponding to this
1733 * prefix and rfd
1734 */
1735
1736 afi = family2afi (p->family);
1737 assert (afi == AFI_IP || afi == AFI_IP6);
1738
1739 bgp = bgp_get_default (); /* assume 1 instance for now */
1740 assert (bgp);
1741
1742 if (safi == SAFI_ENCAP)
1743 {
1744 memset (&prd0, 0, sizeof (prd0));
1745 prd0.family = AF_UNSPEC;
1746 prd0.prefixlen = 64;
1747 prd = &prd0;
1748 }
1749 else
1750 {
1751 prd = &rfd->rd;
1752 }
1753 bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
1754
1755 vty_out (vty, " bn=%p%s", bn, HVTY_NEWLINE);
1756
1757 for (bi = bn->info; bi; bi = bi->next)
1758 {
1759 if (bi->peer == rfd->peer &&
1760 bi->type == type &&
1761 bi->sub_type == BGP_ROUTE_RFP &&
1762 bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd)
1763 {
1764
1765 rfapiPrintBi (vty, bi);
1766 printed = 1;
1767 }
1768 }
1769
1770 if (!printed)
1771 {
1772 vty_out (vty, " --?--%s", HVTY_NEWLINE);
1773 return;
1774 }
1775
1776 }
1777
1778 void
1779 rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd)
1780 {
1781 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1782 /* RT export list */
1783 /* RT import list */
1784 /* list of advertised prefixes */
1785 /* dump import table */
1786
1787 char *s;
1788 void *cursor;
1789 int rc;
1790 afi_t afi;
1791 struct rfapi_adb *adb;
1792 char buf[BUFSIZ];
1793
1794 vty_out (vty, "%-10p ", rfd);
1795 rfapiPrintRfapiIpAddr (vty, &rfd->un_addr);
1796 vty_out (vty, " ");
1797 rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr);
1798 vty_out (vty, " %p %p ", rfd->response_cb, rfd->cookie);
1799 rfapiPrintRd (vty, &rfd->rd);
1800 vty_out (vty, " %d", rfd->response_lifetime);
1801 vty_out (vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>"));
1802 vty_out (vty, "%s", HVTY_NEWLINE);
1803
1804 vty_out (vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTY_NEWLINE);
1805
1806 /* export RT list */
1807 if (rfd->rt_export_list)
1808 {
1809 s =
1810 ecommunity_ecom2str (rfd->rt_export_list,
1811 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1812 vty_out (vty, " Export %s%s", s, HVTY_NEWLINE);
1813 XFREE (MTYPE_ECOMMUNITY_STR, s);
1814 }
1815 else
1816 {
1817 vty_out (vty, " Export (nil)%s", HVTY_NEWLINE);
1818 }
1819
1820 /* import RT list */
1821 if (rfd->import_table)
1822 {
1823 s = ecommunity_ecom2str (rfd->import_table->rt_import_list,
1824 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1825 vty_out (vty, " Import %s%s", s, HVTY_NEWLINE);
1826 XFREE (MTYPE_ECOMMUNITY_STR, s);
1827 }
1828 else
1829 {
1830 vty_out (vty, " Import (nil)%s", HVTY_NEWLINE);
1831 }
1832
1833 for (afi = AFI_IP; afi < AFI_MAX; ++afi)
1834 {
1835 u_char family;
1836
1837 family = afi2family (afi);
1838 if (!family)
1839 continue;
1840
1841 cursor = NULL;
1842 for (rc =
1843 skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb,
1844 &cursor); rc == 0;
1845 rc =
1846 skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb,
1847 &cursor))
1848 {
1849
1850 /* group like family prefixes together in output */
1851 if (family != adb->u.s.prefix_ip.family)
1852 continue;
1853
1854 prefix2str (&adb->u.s.prefix_ip, buf, BUFSIZ);
1855 buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
1856
1857 vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE);
1858 rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip);
1859 }
1860 }
1861 for (rc =
1862 skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb,
1863 &cursor); rc == 0;
1864 rc =
1865 skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb,
1866 &cursor))
1867 {
1868
1869 prefix2str (&adb->u.s.prefix_eth, buf, BUFSIZ);
1870 buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
1871
1872 vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE);
1873
1874 /* TBD update the following function to print ethernet info */
1875 /* Also need to pass/use rd */
1876 rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip);
1877 }
1878 vty_out (vty, "%s", HVTY_NEWLINE);
1879 }
1880
1881 /*
1882 * test scripts rely on first line for each nve starting in 1st column,
1883 * leading whitespace for additional detail of that nve
1884 */
1885 void
1886 rfapiPrintMatchingDescriptors (struct vty *vty,
1887 struct prefix *vn_prefix,
1888 struct prefix *un_prefix)
1889 {
1890 struct bgp *bgp;
1891 struct rfapi *h;
1892 struct listnode *ln;
1893 struct rfapi_descriptor *rfd;
1894 int printed = 0;
1895
1896 bgp = bgp_get_default (); /* assume 1 instance for now */
1897 if (!bgp)
1898 return;
1899
1900 h = bgp->rfapi;
1901 assert (h);
1902
1903 for (ln = listhead (&h->descriptors); ln; ln = listnextnode (ln))
1904 {
1905 rfd = listgetdata (ln);
1906
1907 struct prefix pfx;
1908
1909 if (vn_prefix)
1910 {
1911 assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx));
1912 if (!prefix_match (vn_prefix, &pfx))
1913 continue;
1914 }
1915
1916 if (un_prefix)
1917 {
1918 assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx));
1919 if (!prefix_match (un_prefix, &pfx))
1920 continue;
1921 }
1922
1923 if (!printed)
1924 {
1925 /* print column header */
1926 vty_out (vty,
1927 "%s %s %s %s %s %s %s %s%s",
1928 "descriptor", "un-addr", "vn-addr", "callback", "cookie",
1929 "RD", "lifetime", "group", HVTY_NEWLINE);
1930 }
1931 rfapiPrintDescriptor (vty, rfd);
1932 printed = 1;
1933 }
1934 }
1935
1936
1937 /*
1938 * Parse an address and put into a struct prefix
1939 */
1940 int
1941 rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p)
1942 {
1943 if (!str2prefix (str, p))
1944 {
1945 vty_out (vty, "Malformed address \"%s\"%s", str, HVTY_NEWLINE);
1946 return CMD_WARNING;
1947 }
1948 switch (p->family)
1949 {
1950 case AF_INET:
1951 if (p->prefixlen != 32)
1952 {
1953 vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE);
1954 return CMD_WARNING;
1955 }
1956 break;
1957 case AF_INET6:
1958 if (p->prefixlen != 128)
1959 {
1960 vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE);
1961 return CMD_WARNING;
1962 }
1963 break;
1964 default:
1965 vty_out (vty, "Invalid address \"%s\"%s", str, HVTY_NEWLINE);
1966 return CMD_WARNING;
1967 }
1968 return 0;
1969 }
1970
1971 int
1972 rfapiCliGetRfapiIpAddr (
1973 struct vty *vty,
1974 const char *str,
1975 struct rfapi_ip_addr *hai)
1976 {
1977 struct prefix pfx;
1978 int rc;
1979
1980 rc = rfapiCliGetPrefixAddr (vty, str, &pfx);
1981 if (rc)
1982 return rc;
1983
1984 hai->addr_family = pfx.family;
1985 if (pfx.family == AF_INET)
1986 hai->addr.v4 = pfx.u.prefix4;
1987 else
1988 hai->addr.v6 = pfx.u.prefix6;
1989
1990 return 0;
1991 }
1992
1993 /*
1994 * Note: this function does not flush vty output, so if it is called
1995 * with a stream pointing to a vty, the user will have to type something
1996 * before the callback output shows up
1997 */
1998 void
1999 rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops)
2000 {
2001 struct rfapi_next_hop_entry *nh;
2002 int count;
2003
2004 int (*fp) (void *, const char *, ...);
2005 struct vty *vty;
2006 void *out;
2007 const char *vty_newline;
2008
2009 #define REMAIN (BUFSIZ - (p-line))
2010 #define INCP {p += (r > REMAIN)? REMAIN: r;}
2011
2012
2013 if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
2014 return;
2015
2016 for (nh = next_hops, count = 1; nh; nh = nh->next, ++count)
2017 {
2018
2019 char line[BUFSIZ];
2020 char *p = line;
2021 int r;
2022
2023 r = snprintf (p, REMAIN, "%3d pfx=", count);
2024 INCP;
2025
2026 if (rfapiRfapiIpPrefix2Str (&nh->prefix, p, REMAIN))
2027 {
2028 /* it fit, so count length */
2029 r = strlen (p);
2030 }
2031 else
2032 {
2033 /* didn't fit */
2034 goto truncate;
2035 }
2036 INCP;
2037
2038 r = snprintf (p, REMAIN, ", un=");
2039 INCP;
2040
2041 if (rfapiRfapiIpAddr2Str (&nh->un_address, p, REMAIN))
2042 {
2043 /* it fit, so count length */
2044 r = strlen (p);
2045 }
2046 else
2047 {
2048 /* didn't fit */
2049 goto truncate;
2050 }
2051 INCP;
2052
2053 r = snprintf (p, REMAIN, ", vn=");
2054 INCP;
2055
2056 if (rfapiRfapiIpAddr2Str (&nh->vn_address, p, REMAIN))
2057 {
2058 /* it fit, so count length */
2059 r = strlen (p);
2060 }
2061 else
2062 {
2063 /* didn't fit */
2064 goto truncate;
2065 }
2066 INCP;
2067
2068 truncate:
2069 line[BUFSIZ - 1] = 0;
2070 fp (out, "%s%s", line, HVTY_NEWLINE);
2071
2072 /*
2073 * options
2074 */
2075 if (nh->vn_options)
2076 {
2077 struct rfapi_vn_option *vo;
2078 char offset[] = " ";
2079
2080 for (vo = nh->vn_options; vo; vo = vo->next)
2081 {
2082 char pbuf[100];
2083
2084 switch (vo->type)
2085 {
2086 case RFAPI_VN_OPTION_TYPE_L2ADDR:
2087 rfapiEthAddr2Str (&vo->v.l2addr.macaddr, pbuf,
2088 sizeof (pbuf));
2089 fp (out, "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
2090 offset, pbuf, (vo->v.l2addr.label & 0x00ffffff),
2091 (vo->v.l2addr.logical_net_id & 0x00ffffff),
2092 vo->v.l2addr.local_nve_id, HVTY_NEWLINE);
2093 break;
2094
2095 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP:
2096 prefix2str (&vo->v.local_nexthop.addr, pbuf, sizeof (pbuf));
2097 fp (out, "%sLNH %s cost=%d%s",
2098 offset, pbuf, vo->v.local_nexthop.cost, HVTY_NEWLINE);
2099 break;
2100
2101 default:
2102 fp (out, "%svn option type %d (unknown)%s",
2103 offset, vo->type, HVTY_NEWLINE);
2104 break;
2105 }
2106 }
2107 }
2108 if (nh->un_options)
2109 {
2110 struct rfapi_un_option *uo;
2111 char offset[] = " ";
2112
2113 for (uo = nh->un_options; uo; uo = uo->next)
2114 {
2115 switch (uo->type)
2116 {
2117 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE:
2118 rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel);
2119 break;
2120 default:
2121 fp (out, "%sUN Option type %d%s",
2122 offset, uo->type, vty_newline);
2123 break;
2124 }
2125
2126 }
2127 }
2128 }
2129 }
2130
2131 /***********************************************************************
2132 * STATIC ROUTES
2133 ***********************************************************************/
2134
2135 /*
2136 * Add another nexthop to the NHL
2137 */
2138 static void
2139 rfapiAddDeleteLocalRfpPrefix (
2140 struct rfapi_ip_addr *un_addr,
2141 struct rfapi_ip_addr *vn_addr,
2142 struct rfapi_ip_prefix *rprefix,
2143 int is_add,
2144 uint32_t lifetime, /* add only */
2145 struct rfapi_vn_option *vn_options,
2146 struct rfapi_next_hop_entry **head,
2147 struct rfapi_next_hop_entry **tail)
2148 {
2149 struct rfapi_next_hop_entry *new;
2150
2151 /*
2152 * construct NHL
2153 */
2154
2155 new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry));
2156 new->prefix = *rprefix;
2157 new->un_address = *un_addr;
2158 new->vn_address = *vn_addr;
2159
2160 new->vn_options = vn_options;
2161 if (is_add)
2162 {
2163 new->lifetime = lifetime;
2164 }
2165 else
2166 {
2167 new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME;
2168 }
2169
2170 if (*tail)
2171 (*tail)->next = new;
2172 *tail = new;
2173 if (!*head)
2174 {
2175 *head = new;
2176 }
2177 }
2178
2179
2180 static int
2181 register_add (
2182 struct vty *vty,
2183 struct cmd_token *carg_prefix,
2184 struct cmd_token *carg_vn,
2185 struct cmd_token *carg_un,
2186 struct cmd_token *carg_cost, /* optional */
2187 struct cmd_token *carg_lifetime, /* optional */
2188 struct cmd_token *carg_macaddr, /* optional */
2189 struct cmd_token *carg_vni, /* mac present=>mandatory Virtual Network ID */
2190 int argc,
2191 struct cmd_token **argv)
2192 {
2193 const char *arg_prefix = carg_prefix->arg;
2194 const char *arg_vn = carg_vn->arg;
2195 const char *arg_un = carg_un->arg;
2196 const char *arg_cost = carg_cost ? carg_cost->arg : NULL;
2197 const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL;
2198 const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL;
2199 const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
2200 struct rfapi_ip_addr vn_address;
2201 struct rfapi_ip_addr un_address;
2202 struct prefix pfx;
2203 struct rfapi_ip_prefix rpfx;
2204 uint32_t cost;
2205 uint32_t lnh_cost;
2206 uint32_t lifetime;
2207 rfapi_handle rfd;
2208 struct rfapi_vn_option optary[10]; /* XXX must be big enough */
2209 struct rfapi_vn_option *opt = NULL;
2210 int opt_next = 0;
2211
2212 int rc = CMD_WARNING;
2213 char *endptr;
2214 struct bgp *bgp;
2215 struct rfapi *h;
2216 struct rfapi_cfg *rfapi_cfg;
2217
2218 const char *arg_lnh = NULL;
2219 const char *arg_lnh_cost = NULL;
2220
2221 bgp = bgp_get_default (); /* assume 1 instance for now */
2222 if (!bgp)
2223 {
2224 if (vty)
2225 vty_out (vty, "BGP not configured%s", VTY_NEWLINE);
2226 return CMD_WARNING;
2227 }
2228
2229 h = bgp->rfapi;
2230 rfapi_cfg = bgp->rfapi_cfg;
2231 if (!h || !rfapi_cfg)
2232 {
2233 if (vty)
2234 vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE);
2235 return CMD_WARNING;
2236 }
2237
2238 for (; argc; --argc, ++argv)
2239 {
2240 if (!strcmp (argv[0]->arg, "local-next-hop"))
2241 {
2242 if (arg_lnh)
2243 {
2244 vty_out (vty, "local-next-hop specified more than once%s",
2245 VTY_NEWLINE);
2246 return CMD_WARNING;
2247 }
2248 if (argc <= 1)
2249 {
2250 vty_out (vty, "Missing parameter for local-next-hop%s",
2251 VTY_NEWLINE);
2252 return CMD_WARNING;
2253 }
2254 ++argv, --argc;
2255 arg_lnh = argv[0]->arg;
2256 }
2257 if (!strcmp (argv[0]->arg, "local-cost"))
2258 {
2259 if (arg_lnh_cost)
2260 {
2261 vty_out (vty, "local-cost specified more than once%s",
2262 VTY_NEWLINE);
2263 return CMD_WARNING;
2264 }
2265 if (argc <= 1)
2266 {
2267 vty_out (vty, "Missing parameter for local-cost%s",
2268 VTY_NEWLINE);
2269 return CMD_WARNING;
2270 }
2271 ++argv, --argc;
2272 arg_lnh_cost = argv[0]->arg;
2273 }
2274 }
2275
2276 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &vn_address)))
2277 goto fail;
2278 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &un_address)))
2279 goto fail;
2280
2281 /* arg_prefix is optional if mac address is given */
2282 if (arg_macaddr && !arg_prefix)
2283 {
2284 /*
2285 * fake up a 0/32 or 0/128 prefix
2286 */
2287 switch (vn_address.addr_family)
2288 {
2289 case AF_INET:
2290 arg_prefix = "0.0.0.0/32";
2291 break;
2292 case AF_INET6:
2293 arg_prefix = "0::0/128";
2294 break;
2295 default:
2296 vty_out (vty, "Internal error, unknown VN address family%s",
2297 VTY_NEWLINE);
2298 return CMD_WARNING;
2299 }
2300
2301 }
2302
2303 if (!str2prefix (arg_prefix, &pfx))
2304 {
2305 vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix,
2306 VTY_NEWLINE);
2307 goto fail;
2308 }
2309 if (pfx.family != AF_INET
2310 && pfx.family != AF_INET6)
2311 {
2312 vty_out (vty, "prefix \"%s\" has invalid address family%s",
2313 arg_prefix, VTY_NEWLINE);
2314 goto fail;
2315 }
2316
2317
2318 memset (optary, 0, sizeof (optary));
2319
2320 if (arg_cost)
2321 {
2322 endptr = NULL;
2323 cost = strtoul (arg_cost, &endptr, 10);
2324 if (*endptr != '\0' || cost > 255)
2325 {
2326 vty_out (vty, "%% Invalid %s value%s", "cost", VTY_NEWLINE);
2327 goto fail;
2328 }
2329 }
2330 else
2331 {
2332 cost = 255;
2333 }
2334
2335 if (arg_lifetime)
2336 {
2337 if (!strcmp (arg_lifetime, "infinite"))
2338 {
2339 lifetime = RFAPI_INFINITE_LIFETIME;
2340 }
2341 else
2342 {
2343 endptr = NULL;
2344 lifetime = strtoul (arg_lifetime, &endptr, 10);
2345 if (*endptr != '\0')
2346 {
2347 vty_out (vty, "%% Invalid %s value%s", "lifetime",
2348 VTY_NEWLINE);
2349 goto fail;
2350 }
2351 }
2352 }
2353 else
2354 {
2355 lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */
2356 }
2357
2358 if (arg_lnh_cost)
2359 {
2360 if (!arg_lnh)
2361 {
2362 vty_out (vty,
2363 "%% %s may only be specified with local-next-hop%s",
2364 "local-cost", VTY_NEWLINE);
2365 goto fail;
2366 }
2367 endptr = NULL;
2368 lnh_cost = strtoul (arg_lnh_cost, &endptr, 10);
2369 if (*endptr != '\0' || lnh_cost > 255)
2370 {
2371 vty_out (vty, "%% Invalid %s value%s", "local-cost",
2372 VTY_NEWLINE);
2373 goto fail;
2374 }
2375 }
2376 else
2377 {
2378 lnh_cost = 255;
2379 }
2380
2381 if (arg_lnh)
2382 {
2383 if (!arg_prefix)
2384 {
2385 vty_out (vty, "%% %s may only be specified with prefix%s",
2386 "local-next-hop", VTY_NEWLINE);
2387 goto fail;
2388 }
2389 if ((rc = rfapiCliGetPrefixAddr (vty, arg_lnh,
2390 &optary[opt_next].v.
2391 local_nexthop.addr)))
2392 {
2393
2394 goto fail;
2395 }
2396
2397 optary[opt_next].v.local_nexthop.cost = lnh_cost;
2398 optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP;
2399
2400 if (opt_next)
2401 {
2402 optary[opt_next - 1].next = optary + opt_next;
2403 }
2404 else
2405 {
2406 opt = optary;
2407 }
2408 ++opt_next;
2409 }
2410
2411 if (arg_vni && !arg_macaddr)
2412 {
2413 vty_out (vty, "%% %s may only be specified with mac address%s",
2414 "virtual-network-identifier", VTY_NEWLINE);
2415 goto fail;
2416 }
2417
2418 if (arg_macaddr)
2419 {
2420 if (!arg_vni)
2421 {
2422 vty_out (vty,
2423 "Missing \"vni\" parameter (mandatory with mac)%s",
2424 VTY_NEWLINE);
2425 return CMD_WARNING;
2426 }
2427 VTY_GET_INTEGER ("Logical Network ID",
2428 optary[opt_next].v.l2addr.logical_net_id,
2429 arg_vni);
2430
2431 if ((rc = rfapiStr2EthAddr (arg_macaddr,
2432 &optary[opt_next].v.l2addr.macaddr)))
2433 {
2434 vty_out (vty, "Invalid %s value%s", "mac address",
2435 VTY_NEWLINE);
2436 goto fail;
2437 }
2438 /* TBD label, NVE ID */
2439
2440 optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
2441
2442 if (opt_next)
2443 {
2444 optary[opt_next - 1].next = optary + opt_next;
2445 }
2446 else
2447 {
2448 opt = optary;
2449 }
2450 ++opt_next;
2451 }
2452
2453 vnc_zlog_debug_verbose
2454 ("%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2455 __func__, arg_vn, arg_un, arg_prefix,
2456 (arg_cost ? arg_cost : "NULL"),
2457 (arg_lifetime ? arg_lifetime : "NULL"),
2458 (arg_lnh ? arg_lnh : "NULL"));
2459
2460 rfapiQprefix2Rprefix (&pfx, &rpfx);
2461
2462 rpfx.cost = cost & 255;
2463
2464 /* look up rf descriptor, call open if it doesn't exist */
2465 rc =
2466 rfapi_find_rfd (bgp, &vn_address, &un_address,
2467 (struct rfapi_descriptor **) &rfd);
2468 if (rc)
2469 {
2470 if (ENOENT == rc)
2471 {
2472 struct rfapi_un_option uo;
2473
2474 /*
2475 * flag descriptor as provisionally opened for static route
2476 * registration so that we can fix up the other parameters
2477 * when the real open comes along
2478 */
2479 memset (&uo, 0, sizeof (uo));
2480 uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL;
2481
2482 rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp), &vn_address, &un_address, &uo, /* flags */
2483 NULL, NULL, /* no userdata */
2484 &rfd);
2485 if (rc)
2486 {
2487 vty_out (vty, "Can't open session for this NVE: %s%s",
2488 rfapi_error_str (rc), VTY_NEWLINE);
2489 rc = CMD_WARNING;
2490 goto fail;
2491 }
2492 }
2493 else
2494 {
2495 vty_out (vty, "Can't find session for this NVE: %s%s",
2496 rfapi_error_str (rc), VTY_NEWLINE);
2497 goto fail;
2498 }
2499 }
2500
2501 rc =
2502 rfapi_register (rfd, &rpfx, lifetime, NULL, opt, RFAPI_REGISTER_ADD);
2503 if (!rc)
2504 {
2505 struct rfapi_next_hop_entry *head = NULL;
2506 struct rfapi_next_hop_entry *tail = NULL;
2507 struct rfapi_vn_option *vn_opt_new;
2508
2509 vnc_zlog_debug_verbose ("%s: rfapi_register succeeded, returning 0", __func__);
2510
2511 if (h->rfp_methods.local_cb)
2512 {
2513 struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfd;
2514 vn_opt_new = rfapi_vn_options_dup (opt);
2515
2516 rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx,
2517 1, lifetime, vn_opt_new, &head,
2518 &tail);
2519 if (head)
2520 {
2521 h->flags |= RFAPI_INCALLBACK;
2522 (*h->rfp_methods.local_cb) (head, r->cookie);
2523 h->flags &= ~RFAPI_INCALLBACK;
2524 }
2525 head = tail = NULL;
2526 }
2527 return 0;
2528 }
2529
2530 vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__);
2531 vty_out (vty, "%s", VTY_NEWLINE);
2532 vty_out (vty, "Registration failed.%s", VTY_NEWLINE);
2533 vty_out (vty,
2534 "Confirm that either the VN or UN address matches a configured NVE group.%s",
2535 VTY_NEWLINE);
2536 return CMD_WARNING;
2537
2538 fail:
2539 vnc_zlog_debug_verbose ("%s: fail, rc=%d", __func__, rc);
2540 return rc;
2541 }
2542
2543 /************************************************************************
2544 * Add prefix With LNH_OPTIONS...
2545 ************************************************************************/
2546 DEFUN (add_vnc_prefix_cost_life_lnh,
2547 add_vnc_prefix_cost_life_lnh_cmd,
2548 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295) LNH_OPTIONS...",
2549 "Add registration\n"
2550 "VNC Information\n"
2551 "Add/modify prefix related information\n"
2552 "IPv4 prefix\n"
2553 "IPv6 prefix\n"
2554 "VN address of NVE\n"
2555 "VN IPv4 interface address\n"
2556 "VN IPv6 interface address\n"
2557 "UN address of NVE\n"
2558 "UN IPv4 interface address\n"
2559 "UN IPv6 interface address\n"
2560 "Administrative cost [default: 255]\n"
2561 "Administrative cost\n"
2562 "Registration lifetime [default: infinite]\n"
2563 "Lifetime value in seconds\n"
2564 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2565 {
2566 /* pfx vn un cost life */
2567 return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11],
2568 /* mac vni */
2569 NULL, NULL, argc - 12, argv + 12);
2570 }
2571
2572 DEFUN (add_vnc_prefix_life_cost_lnh,
2573 add_vnc_prefix_life_cost_lnh_cmd,
2574 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255) LNH_OPTIONS...",
2575 "Add registration\n"
2576 "VNC Information\n"
2577 "Add/modify prefix related information\n"
2578 "IPv4 prefix\n"
2579 "IPv6 prefix\n"
2580 "VN address of NVE\n"
2581 "VN IPv4 interface address\n"
2582 "VN IPv6 interface address\n"
2583 "UN address of NVE\n"
2584 "UN IPv4 interface address\n"
2585 "UN IPv6 interface address\n"
2586 "Registration lifetime [default: infinite]\n"
2587 "Lifetime value in seconds\n"
2588 "Administrative cost [default: 255]\n"
2589 "Administrative cost\n"
2590 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2591 {
2592 /* pfx vn un cost life */
2593 return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9],
2594 /* mac vni */
2595 NULL, NULL, argc - 12, argv + 12);
2596 }
2597
2598 DEFUN (add_vnc_prefix_cost_lnh,
2599 add_vnc_prefix_cost_lnh_cmd,
2600 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) LNH_OPTIONS...",
2601 "Add registration\n"
2602 "VNC Information\n"
2603 "Add/modify prefix related information\n"
2604 "IPv4 prefix\n"
2605 "IPv6 prefix\n"
2606 "VN address of NVE\n"
2607 "VN IPv4 interface address\n"
2608 "VN IPv6 interface address\n"
2609 "UN address of NVE\n"
2610 "UN IPv4 interface address\n"
2611 "UN IPv6 interface address\n"
2612 "Administrative cost [default: 255]\n"
2613 "Administrative cost\n"
2614 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2615 {
2616 /* pfx vn un cost life */
2617 return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL,
2618 /* mac vni */
2619 NULL, NULL, argc - 10, argv + 10);
2620 }
2621
2622 DEFUN (add_vnc_prefix_life_lnh,
2623 add_vnc_prefix_life_lnh_cmd,
2624 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) LNH_OPTIONS...",
2625 "Add registration\n"
2626 "VNC Information\n"
2627 "Add/modify prefix related information\n"
2628 "IPv4 prefix\n"
2629 "IPv6 prefix\n"
2630 "VN address of NVE\n"
2631 "VN IPv4 interface address\n"
2632 "VN IPv6 interface address\n"
2633 "UN address of NVE\n"
2634 "UN IPv4 interface address\n"
2635 "UN IPv6 interface address\n"
2636 "Registration lifetime [default: infinite]\n"
2637 "Lifetime value in seconds\n"
2638 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2639 {
2640 /* pfx vn un cost life */
2641 return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9],
2642 /* mac vni */
2643 NULL, NULL, argc - 10, argv + 10);
2644 }
2645
2646 DEFUN (add_vnc_prefix_lnh,
2647 add_vnc_prefix_lnh_cmd,
2648 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> LNH_OPTIONS...",
2649 "Add registration\n"
2650 "VNC Information\n"
2651 "Add/modify prefix related information\n"
2652 "IPv4 prefix\n"
2653 "IPv6 prefix\n"
2654 "VN address of NVE\n"
2655 "VN IPv4 interface address\n"
2656 "VN IPv6 interface address\n"
2657 "UN address of NVE\n"
2658 "UN IPv4 interface address\n"
2659 "UN IPv6 interface address\n"
2660 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2661 {
2662 /* pfx vn un cost life */
2663 return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL,
2664 /* mac vni */
2665 NULL, NULL, argc - 8, argv + 8);
2666 }
2667
2668 /************************************************************************
2669 * Add prefix Without LNH_OPTIONS...
2670 ************************************************************************/
2671 DEFUN (add_vnc_prefix_cost_life,
2672 add_vnc_prefix_cost_life_cmd,
2673 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
2674 "Add registration\n"
2675 "VNC Information\n"
2676 "Add/modify prefix related information\n"
2677 "IPv4 prefix\n"
2678 "IPv6 prefix\n"
2679 "VN address of NVE\n"
2680 "VN IPv4 interface address\n"
2681 "VN IPv6 interface address\n"
2682 "UN address of NVE\n"
2683 "UN IPv4 interface address\n"
2684 "UN IPv6 interface address\n"
2685 "Administrative cost [default: 255]\n"
2686 "Administrative cost\n"
2687 "Registration lifetime [default: infinite]\n"
2688 "Lifetime value in seconds\n"
2689 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2690 {
2691 /* pfx vn un cost life */
2692 return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11],
2693 /* mac vni */
2694 NULL, NULL, 0, NULL);
2695 }
2696
2697 DEFUN (add_vnc_prefix_life_cost,
2698 add_vnc_prefix_life_cost_cmd,
2699 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255)",
2700 "Add registration\n"
2701 "VNC Information\n"
2702 "Add/modify prefix related information\n"
2703 "IPv4 prefix\n"
2704 "IPv6 prefix\n"
2705 "VN address of NVE\n"
2706 "VN IPv4 interface address\n"
2707 "VN IPv6 interface address\n"
2708 "UN address of NVE\n"
2709 "UN IPv4 interface address\n"
2710 "UN IPv6 interface address\n"
2711 "Registration lifetime [default: infinite]\n"
2712 "Lifetime value in seconds\n"
2713 "Administrative cost [default: 255]\n"
2714 "Administrative cost\n"
2715 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2716 {
2717 /* pfx vn un cost life */
2718 return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9],
2719 /* mac vni */
2720 NULL, NULL, 0, NULL);
2721 }
2722
2723 DEFUN (add_vnc_prefix_cost,
2724 add_vnc_prefix_cost_cmd,
2725 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
2726 "Add registration\n"
2727 "VNC Information\n"
2728 "Add/modify prefix related information\n"
2729 "IPv4 prefix\n"
2730 "IPv6 prefix\n"
2731 "VN address of NVE\n"
2732 "VN IPv4 interface address\n"
2733 "VN IPv6 interface address\n"
2734 "UN address of NVE\n"
2735 "UN IPv4 interface address\n"
2736 "UN IPv6 interface address\n"
2737 "Administrative cost [default: 255]\n"
2738 "Administrative cost\n"
2739 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2740 {
2741 /* pfx vn un cost life */
2742 return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL,
2743 /* mac vni */
2744 NULL, NULL, 0, NULL);
2745 }
2746
2747 DEFUN (add_vnc_prefix_life,
2748 add_vnc_prefix_life_cmd,
2749 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
2750 "Add registration\n"
2751 "VNC Information\n"
2752 "Add/modify prefix related information\n"
2753 "IPv4 prefix\n"
2754 "IPv6 prefix\n"
2755 "VN address of NVE\n"
2756 "VN IPv4 interface address\n"
2757 "VN IPv6 interface address\n"
2758 "UN address of NVE\n"
2759 "UN IPv4 interface address\n"
2760 "UN IPv6 interface address\n"
2761 "Registration lifetime [default: infinite]\n"
2762 "Lifetime value in seconds\n"
2763 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2764 {
2765 /* pfx vn un cost life */
2766 return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9],
2767 /* mac vni */
2768 NULL, NULL, 0, NULL);
2769 }
2770
2771 DEFUN (add_vnc_prefix,
2772 add_vnc_prefix_cmd,
2773 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2774 "Add registration\n"
2775 "VNC Information\n"
2776 "Add/modify prefix related information\n"
2777 "IPv4 prefix\n"
2778 "IPv6 prefix\n"
2779 "VN address of NVE\n"
2780 "VN IPv4 interface address\n"
2781 "VN IPv6 interface address\n"
2782 "UN address of NVE\n"
2783 "UN IPv4 interface address\n"
2784 "UN IPv6 interface address\n"
2785 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2786 {
2787 /* pfx vn un cost life */
2788 return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL,
2789 /* mac vni */
2790 NULL, NULL, 0, NULL);
2791 }
2792
2793 /************************************************************************
2794 * Mac address registrations
2795 ************************************************************************/
2796 DEFUN (add_vnc_mac_vni_prefix_cost_life,
2797 add_vnc_mac_vni_prefix_cost_life_cmd,
2798 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
2799 "Add registration\n"
2800 "VNC Information\n"
2801 "Add/modify mac address information\n"
2802 "MAC address\n"
2803 "Virtual Network Identifier follows\n"
2804 "Virtual Network Identifier\n"
2805 "VN address of NVE\n"
2806 "VN IPv4 interface address\n"
2807 "VN IPv6 interface address\n"
2808 "UN address of NVE\n"
2809 "UN IPv4 interface address\n"
2810 "UN IPv6 interface address\n"
2811 "Add/modify prefix related information\n"
2812 "IPv4 prefix\n"
2813 "IPv6 prefix\n"
2814 "Administrative cost [default: 255]\n"
2815 "Administrative cost\n"
2816 "Registration lifetime [default: infinite]\n"
2817 "Lifetime value in seconds\n")
2818 {
2819 /* pfx vn un cost life */
2820 return register_add (vty, argv[11], argv[7], argv[9], argv[13], argv[15],
2821 /* mac vni */
2822 argv[3], argv[5], 0, NULL);
2823 }
2824
2825
2826 DEFUN (add_vnc_mac_vni_prefix_life,
2827 add_vnc_mac_vni_prefix_life_cmd,
2828 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
2829 "Add registration\n"
2830 "VNC Information\n"
2831 "Add/modify mac address information\n"
2832 "MAC address\n"
2833 "Virtual Network Identifier follows\n"
2834 "Virtual Network Identifier\n"
2835 "VN address of NVE\n"
2836 "VN IPv4 interface address\n"
2837 "VN IPv6 interface address\n"
2838 "UN address of NVE\n"
2839 "UN IPv4 interface address\n"
2840 "UN IPv6 interface address\n"
2841 "Add/modify prefix related information\n"
2842 "IPv4 prefix\n"
2843 "IPv6 prefix\n"
2844 "Registration lifetime [default: infinite]\n"
2845 "Lifetime value in seconds\n")
2846 {
2847 /* pfx vn un cost life */
2848 return register_add (vty, argv[11], argv[7], argv[9], NULL, argv[13],
2849 /* mac vni */
2850 argv[3], argv[5], 0, NULL);
2851 }
2852
2853 DEFUN (add_vnc_mac_vni_prefix_cost,
2854 add_vnc_mac_vni_prefix_cost_cmd,
2855 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
2856 "Add registration\n"
2857 "VNC Information\n"
2858 "Add/modify mac address information\n"
2859 "MAC address\n"
2860 "Virtual Network Identifier follows\n"
2861 "Virtual Network Identifier\n"
2862 "VN address of NVE\n"
2863 "VN IPv4 interface address\n"
2864 "VN IPv6 interface address\n"
2865 "UN address of NVE\n"
2866 "UN IPv4 interface address\n"
2867 "UN IPv6 interface address\n"
2868 "Add/modify prefix related information\n"
2869 "IPv4 prefix\n"
2870 "IPv6 prefix\n"
2871 "Administrative cost [default: 255]\n" "Administrative cost\n")
2872 {
2873 /* pfx vn un cost life */
2874 return register_add (vty, argv[11], argv[7], argv[9], argv[13], NULL,
2875 /* mac vni */
2876 argv[3], argv[5], 0, NULL);
2877 }
2878
2879 DEFUN (add_vnc_mac_vni_prefix,
2880 add_vnc_mac_vni_prefix_cmd,
2881 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
2882 "Add registration\n"
2883 "VNC Information\n"
2884 "Add/modify mac address information\n"
2885 "MAC address\n"
2886 "Virtual Network Identifier follows\n"
2887 "Virtual Network Identifier\n"
2888 "VN address of NVE\n"
2889 "VN IPv4 interface address\n"
2890 "VN IPv6 interface address\n"
2891 "UN address of NVE\n"
2892 "UN IPv4 interface address\n"
2893 "UN IPv6 interface address\n"
2894 "Add/modify prefix related information\n"
2895 "IPv4 prefix\n" "IPv6 prefix\n")
2896 {
2897 /* pfx vn un cost life */
2898 return register_add (vty, argv[11], argv[7], argv[9], NULL, NULL,
2899 /* mac vni */
2900 argv[3], argv[5], 0, NULL);
2901 }
2902
2903 DEFUN (add_vnc_mac_vni_cost_life,
2904 add_vnc_mac_vni_cost_life_cmd,
2905 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
2906 "Add registration\n"
2907 "VNC Information\n"
2908 "Add/modify mac address information\n"
2909 "MAC address\n"
2910 "Virtual Network Identifier follows\n"
2911 "Virtual Network Identifier\n"
2912 "VN address of NVE\n"
2913 "VN IPv4 interface address\n"
2914 "VN IPv6 interface address\n"
2915 "UN address of NVE\n"
2916 "UN IPv4 interface address\n"
2917 "UN IPv6 interface address\n"
2918 "Administrative cost [default: 255]\n"
2919 "Administrative cost\n"
2920 "Registration lifetime [default: infinite]\n"
2921 "Lifetime value in seconds\n")
2922 {
2923 /* pfx vn un cost life */
2924 return register_add (vty, NULL, argv[7], argv[9], argv[11], argv[13],
2925 /* mac vni */
2926 argv[3], argv[5], 0, NULL);
2927 }
2928
2929
2930 DEFUN (add_vnc_mac_vni_cost,
2931 add_vnc_mac_vni_cost_cmd,
2932 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
2933 "Add registration\n"
2934 "VNC Information\n"
2935 "Add/modify mac address information\n"
2936 "MAC address\n"
2937 "Virtual Network Identifier follows\n"
2938 "Virtual Network Identifier\n"
2939 "VN address of NVE\n"
2940 "VN IPv4 interface address\n"
2941 "VN IPv6 interface address\n"
2942 "UN address of NVE\n"
2943 "UN IPv4 interface address\n"
2944 "UN IPv6 interface address\n"
2945 "Administrative cost [default: 255]\n" "Administrative cost\n")
2946 {
2947 /* pfx vn un cost life */
2948 return register_add (vty, NULL, argv[7], argv[9], argv[11], NULL,
2949 /* mac vni */
2950 argv[3], argv[5], 0, NULL);
2951 }
2952
2953
2954 DEFUN (add_vnc_mac_vni_life,
2955 add_vnc_mac_vni_life_cmd,
2956 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
2957 "Add registration\n"
2958 "VNC Information\n"
2959 "Add/modify mac address information\n"
2960 "MAC address\n"
2961 "Virtual Network Identifier follows\n"
2962 "Virtual Network Identifier\n"
2963 "VN address of NVE\n"
2964 "VN IPv4 interface address\n"
2965 "VN IPv6 interface address\n"
2966 "UN address of NVE\n"
2967 "UN IPv4 interface address\n"
2968 "UN IPv6 interface address\n"
2969 "Registration lifetime [default: infinite]\n"
2970 "Lifetime value in seconds\n")
2971 {
2972 /* pfx vn un cost life */
2973 return register_add (vty, NULL, argv[7], argv[9], NULL, argv[11],
2974 /* mac vni */
2975 argv[3], argv[5], 0, NULL);
2976 }
2977
2978
2979 DEFUN (add_vnc_mac_vni,
2980 add_vnc_mac_vni_cmd,
2981 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2982 "Add registration\n"
2983 "VNC Information\n"
2984 "Add/modify mac address information\n"
2985 "MAC address\n"
2986 "Virtual Network Identifier follows\n"
2987 "Virtual Network Identifier\n"
2988 "VN address of NVE\n"
2989 "VN IPv4 interface address\n"
2990 "VN IPv6 interface address\n"
2991 "UN address of NVE\n"
2992 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2993 {
2994 /* pfx vn un cost life */
2995 return register_add (vty, NULL, argv[7], argv[9], NULL, NULL,
2996 /* mac vni */
2997 argv[3], argv[5], 0, NULL);
2998 }
2999
3000 /************************************************************************
3001 * Delete prefix
3002 ************************************************************************/
3003
3004 struct rfapi_local_reg_delete_arg
3005 {
3006 /*
3007 * match parameters
3008 */
3009 struct bgp *bgp;
3010 struct rfapi_ip_addr un_address; /* AF==0: wildcard */
3011 struct rfapi_ip_addr vn_address; /* AF==0: wildcard */
3012 struct prefix prefix; /* AF==0: wildcard */
3013 struct prefix_rd rd; /* plen!=64: wildcard */
3014 struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */
3015
3016 struct rfapi_l2address_option_match l2o;
3017
3018 /*
3019 * result parameters
3020 */
3021 struct vty *vty;
3022 uint32_t reg_count;
3023 uint32_t pfx_count;
3024 uint32_t query_count;
3025
3026 uint32_t failed_pfx_count;
3027
3028 uint32_t nve_count;
3029 struct skiplist *nves;
3030
3031 uint32_t remote_active_nve_count;
3032 uint32_t remote_active_pfx_count;
3033 uint32_t remote_holddown_nve_count;
3034 uint32_t remote_holddown_pfx_count;
3035 };
3036
3037 struct nve_addr
3038 {
3039 struct rfapi_ip_addr vn;
3040 struct rfapi_ip_addr un;
3041 struct rfapi_descriptor *rfd;
3042 struct rfapi_local_reg_delete_arg *cda;
3043 };
3044
3045 static void
3046 nve_addr_free (void *hap)
3047 {
3048 ((struct nve_addr *) hap)->cda->nve_count += 1;
3049 XFREE (MTYPE_RFAPI_NVE_ADDR, hap);
3050 }
3051
3052 static int
3053 nve_addr_cmp (void *k1, void *k2)
3054 {
3055 struct nve_addr *a = (struct nve_addr *) k1;
3056 struct nve_addr *b = (struct nve_addr *) k2;
3057 int ret = 0;
3058
3059 if (!a || !b)
3060 {
3061 return (a - b);
3062 }
3063 if (a->un.addr_family != b->un.addr_family)
3064 {
3065 return (a->un.addr_family - b->un.addr_family);
3066 }
3067 if (a->vn.addr_family != b->vn.addr_family)
3068 {
3069 return (a->vn.addr_family - b->vn.addr_family);
3070 }
3071 if (a->un.addr_family == AF_INET)
3072 {
3073 ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4);
3074 if (ret != 0)
3075 {
3076 return ret;
3077 }
3078 }
3079 else if (a->un.addr_family == AF_INET6)
3080 {
3081 ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6);
3082 if (ret != 0)
3083 {
3084 return ret;
3085 }
3086 }
3087 else
3088 {
3089 assert (0);
3090 }
3091 if (a->vn.addr_family == AF_INET)
3092 {
3093 ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4);
3094 if (ret != 0)
3095 return ret;
3096 }
3097 else if (a->vn.addr_family == AF_INET6)
3098 {
3099 ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6);
3100 if (ret == 0)
3101 {
3102 return ret;
3103 }
3104 }
3105 else
3106 {
3107 assert (0);
3108 }
3109 return 0;
3110 }
3111
3112 static int
3113 parse_deleter_args (
3114 struct vty *vty,
3115 struct bgp *bgp,
3116 const char *arg_prefix,
3117 const char *arg_vn,
3118 const char *arg_un,
3119 const char *arg_l2addr,
3120 const char *arg_vni,
3121 const char *arg_rd,
3122 struct rfapi_nve_group_cfg *arg_rfg,
3123 struct rfapi_local_reg_delete_arg *rcdarg)
3124 {
3125 int rc = CMD_WARNING;
3126
3127 memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg));
3128
3129 rcdarg->vty = vty;
3130 if (bgp == NULL)
3131 bgp = bgp_get_default();
3132 rcdarg->bgp = bgp;
3133 rcdarg->rfg = arg_rfg; /* may be NULL */
3134
3135 if (arg_vn && strcmp (arg_vn, "*"))
3136 {
3137 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address)))
3138 return rc;
3139 }
3140 if (arg_un && strcmp (arg_un, "*"))
3141 {
3142 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address)))
3143 return rc;
3144 }
3145 if (arg_prefix && strcmp (arg_prefix, "*"))
3146 {
3147
3148 if (!str2prefix (arg_prefix, &rcdarg->prefix))
3149 {
3150 vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix, VTY_NEWLINE);
3151 return rc;
3152 }
3153 }
3154
3155 if (arg_l2addr)
3156 {
3157 if (!arg_vni)
3158 {
3159 vty_out (vty, "Missing VNI%s", VTY_NEWLINE);
3160 return rc;
3161 }
3162 if (strcmp (arg_l2addr, "*"))
3163 {
3164 if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr)))
3165 {
3166 vty_out (vty, "Malformed L2 Address \"%s\"%s",
3167 arg_l2addr, VTY_NEWLINE);
3168 return rc;
3169 }
3170 rcdarg->l2o.flags |= RFAPI_L2O_MACADDR;
3171 }
3172 if (strcmp (arg_vni, "*"))
3173 {
3174 VTY_GET_INTEGER ("Logical Network ID",
3175 rcdarg->l2o.o.logical_net_id, arg_vni);
3176 rcdarg->l2o.flags |= RFAPI_L2O_LNI;
3177 }
3178 }
3179 if (arg_rd)
3180 {
3181 if (!str2prefix_rd (arg_rd, &rcdarg->rd))
3182 {
3183 vty_out (vty, "Malformed RD \"%s\"%s",
3184 arg_rd, VTY_NEWLINE);
3185 return rc;
3186 }
3187 }
3188
3189 return CMD_SUCCESS;
3190 }
3191
3192 static int
3193 parse_deleter_tokens (
3194 struct vty *vty,
3195 struct bgp *bgp,
3196 struct cmd_token *carg_prefix,
3197 struct cmd_token *carg_vn,
3198 struct cmd_token *carg_un,
3199 struct cmd_token *carg_l2addr,
3200 struct cmd_token *carg_vni,
3201 struct cmd_token *carg_rd,
3202 struct rfapi_nve_group_cfg *arg_rfg,
3203 struct rfapi_local_reg_delete_arg *rcdarg)
3204 {
3205 const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL;
3206 const char *arg_vn = carg_vn ? carg_vn->arg : NULL;
3207 const char *arg_un = carg_un ? carg_un->arg : NULL;
3208 const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL;
3209 const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
3210 const char *arg_rd = carg_rd ? carg_rd->arg : NULL;
3211 return parse_deleter_args (vty, bgp,arg_prefix, arg_vn, arg_un,
3212 arg_l2addr, arg_vni, arg_rd,
3213 arg_rfg, rcdarg);
3214 }
3215
3216 static void
3217 record_nve_in_cda_list (
3218 struct rfapi_local_reg_delete_arg *cda,
3219 struct rfapi_ip_addr *un_address,
3220 struct rfapi_ip_addr *vn_address,
3221 struct rfapi_descriptor *rfd)
3222 {
3223 struct nve_addr ha;
3224 struct nve_addr *hap;
3225
3226 memset (&ha, 0, sizeof (ha));
3227 ha.un = *un_address;
3228 ha.vn = *vn_address;
3229 ha.rfd = rfd;
3230
3231 if (!cda->nves)
3232 cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
3233
3234 if (skiplist_search (cda->nves, &ha, (void *) &hap))
3235 {
3236 hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
3237 assert (hap);
3238 ha.cda = cda;
3239 * hap = ha;
3240 skiplist_insert (cda->nves, hap, hap);
3241 }
3242 }
3243
3244 static void
3245 clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda)
3246 {
3247 struct rfapi *h;
3248 struct rfapi_descriptor *rfd;
3249 int query_count = 0;
3250 struct listnode *node;
3251 struct bgp *bgp_default = bgp_get_default ();
3252
3253 if (cda->vn_address.addr_family && cda->un_address.addr_family)
3254 {
3255 /*
3256 * Single nve case
3257 */
3258 if (rfapi_find_rfd
3259 (bgp_default, &cda->vn_address, &cda->un_address, &rfd))
3260 return;
3261
3262 rfapiRibClear (rfd);
3263 rfapi_query_done_all (rfd, &query_count);
3264 cda->query_count += query_count;
3265
3266 /*
3267 * Track unique nves seen
3268 */
3269 record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
3270 return;
3271 }
3272
3273 /*
3274 * wildcard case
3275 */
3276
3277 if (!bgp_default)
3278 return; /* ENXIO */
3279
3280 h = bgp_default->rfapi;
3281
3282 if (!h)
3283 return; /* ENXIO */
3284
3285 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
3286 {
3287 /*
3288 * match un, vn addresses of NVEs
3289 */
3290 if (cda->un_address.addr_family &&
3291 rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr))
3292 {
3293 continue;
3294 }
3295 if (cda->vn_address.addr_family &&
3296 rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr))
3297 {
3298 continue;
3299 }
3300
3301 rfapiRibClear (rfd);
3302
3303 rfapi_query_done_all (rfd, &query_count);
3304 cda->query_count += query_count;
3305
3306 /*
3307 * Track unique nves seen
3308 */
3309 record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
3310 }
3311 }
3312
3313 /*
3314 * TBD need to count deleted prefixes and nves?
3315 *
3316 * ENXIO BGP or VNC not configured
3317 */
3318 static int
3319 rfapiDeleteLocalPrefixesByRFD (struct rfapi_local_reg_delete_arg *cda,
3320 struct rfapi_descriptor *rfd)
3321 {
3322 struct rfapi_ip_addr *pUn; /* NULL = wildcard */
3323 struct rfapi_ip_addr *pVn; /* NULL = wildcard */
3324 struct prefix *pPrefix; /* NULL = wildcard */
3325 struct prefix_rd *pPrd; /* NULL = wildcard */
3326
3327 struct rfapi_ip_prefix rprefix;
3328 struct rfapi_next_hop_entry *head = NULL;
3329 struct rfapi_next_hop_entry *tail = NULL;
3330
3331 #if DEBUG_L2_EXTRA
3332 vnc_zlog_debug_verbose ("%s: entry", __func__);
3333 #endif
3334
3335 pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
3336 pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
3337 pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
3338 pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL);
3339
3340 if (pPrefix)
3341 {
3342 rfapiQprefix2Rprefix (pPrefix, &rprefix);
3343 }
3344
3345 do /* to preserve old code structure */
3346 {
3347 struct rfapi *h=cda->bgp->rfapi;;
3348 struct rfapi_adb *adb;
3349 int rc;
3350 int deleted_from_this_nve;
3351 struct nve_addr ha;
3352 struct nve_addr *hap;
3353
3354 #if DEBUG_L2_EXTRA
3355 vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd);
3356 #endif
3357
3358 /*
3359 * match un, vn addresses of NVEs
3360 */
3361 if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr)))
3362 continue;
3363 if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr)))
3364 continue;
3365
3366 #if DEBUG_L2_EXTRA
3367 vnc_zlog_debug_verbose ("%s: un, vn match", __func__);
3368 #endif
3369
3370 /*
3371 * match prefix
3372 */
3373
3374 deleted_from_this_nve = 0;
3375
3376 {
3377 struct skiplist *sl;
3378 struct rfapi_ip_prefix rp;
3379 void *cursor;
3380 struct list *adb_delete_list;
3381
3382 /*
3383 * The advertisements are stored in a skiplist. Withdrawing
3384 * the registration deletes the advertisement from the
3385 * skiplist, which we can't do while iterating over that
3386 * same skiplist using the current skiplist API.
3387 *
3388 * Strategy: iterate over the skiplist and build another
3389 * list containing only the matching ADBs. Then delete
3390 * _everything_ in that second list (which can be done
3391 * using either skiplists or quagga linklists).
3392 */
3393 adb_delete_list = list_new ();
3394
3395 /*
3396 * Advertised IP prefixes (not 0/32 or 0/128)
3397 */
3398 sl = rfd->advertised.ipN_by_prefix;
3399
3400 for (cursor = NULL,
3401 rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
3402 !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
3403 {
3404
3405 if (pPrefix)
3406 {
3407 if (!prefix_same (pPrefix, &adb->u.s.prefix_ip))
3408 {
3409 #if DEBUG_L2_EXTRA
3410 vnc_zlog_debug_verbose ("%s: adb=%p, prefix doesn't match, skipping",
3411 __func__, adb);
3412 #endif
3413 continue;
3414 }
3415 }
3416 if (pPrd)
3417 {
3418 if (memcmp(pPrd->val, adb->u.s.prd.val, 8) != 0)
3419 {
3420 #if DEBUG_L2_EXTRA
3421 vnc_zlog_debug_verbose ("%s: adb=%p, RD doesn't match, skipping",
3422 __func__, adb);
3423 #endif
3424 continue;
3425 }
3426 }
3427 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
3428 {
3429 if (memcmp
3430 (cda->l2o.o.macaddr.octet,
3431 adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN))
3432 {
3433 #if DEBUG_L2_EXTRA
3434 vnc_zlog_debug_verbose ("%s: adb=%p, macaddr doesn't match, skipping",
3435 __func__, adb);
3436 #endif
3437 continue;
3438 }
3439 }
3440
3441 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
3442 {
3443 if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
3444 {
3445 #if DEBUG_L2_EXTRA
3446 vnc_zlog_debug_verbose ("%s: adb=%p, LNI doesn't match, skipping",
3447 __func__, adb);
3448 #endif
3449 continue;
3450 }
3451 }
3452
3453 #if DEBUG_L2_EXTRA
3454 vnc_zlog_debug_verbose ("%s: ipN adding adb %p to delete list", __func__,
3455 adb);
3456 #endif
3457
3458 listnode_add (adb_delete_list, adb);
3459 }
3460
3461 struct listnode *node;
3462
3463 for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
3464 {
3465 int this_advertisement_prefix_count;
3466 struct rfapi_vn_option optary[3];
3467 struct rfapi_vn_option *opt = NULL;
3468 int cur_opt = 0;
3469
3470 this_advertisement_prefix_count = 1;
3471
3472 rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
3473
3474 memset (optary, 0, sizeof (optary));
3475
3476 /* if mac addr present in advert, make l2o vn option */
3477 if (adb->u.s.prefix_eth.family == AF_ETHERNET)
3478 {
3479 if (opt != NULL)
3480 opt->next = &optary[cur_opt];
3481 opt = &optary[cur_opt++];
3482 opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
3483 opt->v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth;
3484 ++this_advertisement_prefix_count;
3485 }
3486 /*
3487 * use saved RD value instead of trying to invert
3488 * complex RD computation in rfapi_register()
3489 */
3490 if (opt != NULL)
3491 opt->next = &optary[cur_opt];
3492 opt = &optary[cur_opt++];
3493 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
3494 opt->v.internal_rd = adb->u.s.prd;
3495
3496 #if DEBUG_L2_EXTRA
3497 vnc_zlog_debug_verbose ("%s: ipN killing reg from adb %p ", __func__, adb);
3498 #endif
3499
3500 rc = rfapi_register (rfd, &rp, 0, NULL,
3501 (cur_opt ? optary : NULL), RFAPI_REGISTER_KILL);
3502 if (!rc)
3503 {
3504 cda->pfx_count += this_advertisement_prefix_count;
3505 cda->reg_count += 1;
3506 deleted_from_this_nve = 1;
3507 }
3508 if (h->rfp_methods.local_cb)
3509 {
3510 rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr,
3511 &rp, 0, 0, NULL, &head, &tail);
3512 }
3513 }
3514 list_delete_all_node (adb_delete_list);
3515
3516 if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix)))
3517 {
3518 void *cursor;
3519
3520 /*
3521 * Caller didn't specify a prefix, or specified (0/32 or 0/128)
3522 */
3523
3524 /*
3525 * Advertised 0/32 and 0/128 (indexed by ethernet address)
3526 */
3527 sl = rfd->advertised.ip0_by_ether;
3528
3529 for (cursor = NULL,
3530 rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
3531 !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
3532 {
3533
3534 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
3535 {
3536 if (memcmp (cda->l2o.o.macaddr.octet,
3537 adb->u.s.prefix_eth.u.prefix_eth.octet,
3538 ETHER_ADDR_LEN))
3539 {
3540
3541 continue;
3542 }
3543 }
3544 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
3545 {
3546 if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
3547 {
3548 continue;
3549 }
3550 }
3551 #if DEBUG_L2_EXTRA
3552 vnc_zlog_debug_verbose ("%s: ip0 adding adb %p to delete list",
3553 __func__, adb);
3554 #endif
3555 listnode_add (adb_delete_list, adb);
3556 }
3557
3558
3559 for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
3560 {
3561
3562 struct rfapi_vn_option vn;
3563
3564 rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
3565
3566 memset (&vn, 0, sizeof (vn));
3567 vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
3568 vn.v.l2addr = adb->l2o;
3569
3570 #if DEBUG_L2_EXTRA
3571 vnc_zlog_debug_verbose ("%s: ip0 killing reg from adb %p ",
3572 __func__, adb);
3573 #endif
3574
3575 rc = rfapi_register (rfd, &rp, 0, NULL, &vn,
3576 RFAPI_REGISTER_KILL);
3577 if (!rc)
3578 {
3579 cda->pfx_count += 1;
3580 cda->reg_count += 1;
3581 deleted_from_this_nve = 1;
3582 }
3583 if (h->rfp_methods.local_cb)
3584 {
3585 struct rfapi_vn_option *vn_opt_new;
3586
3587 vn_opt_new = rfapi_vn_options_dup (&vn);
3588 rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr,
3589 &rfd->vn_addr, &rp, 0, 0,
3590 vn_opt_new, &head, &tail);
3591 }
3592 }
3593 list_delete_all_node (adb_delete_list);
3594 }
3595 list_delete (adb_delete_list);
3596 }
3597
3598
3599 if (head)
3600 { /* should not be set if (NULL == rfapi_cfg->local_cb) */
3601 h->flags |= RFAPI_INCALLBACK;
3602 (*h->rfp_methods.local_cb) (head, rfd->cookie);
3603 h->flags &= ~RFAPI_INCALLBACK;
3604 head = tail = NULL;
3605 }
3606
3607 if (deleted_from_this_nve)
3608 {
3609 /*
3610 * track unique NVEs seen
3611 */
3612 memset (&ha, 0, sizeof (ha));
3613 ha.un = rfd->un_addr;
3614 ha.vn = rfd->vn_addr;
3615
3616 if (!cda->nves)
3617 cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
3618 if (skiplist_search (cda->nves, &ha, (void **) &hap))
3619 {
3620 hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
3621 assert (hap);
3622 ha.cda = cda;
3623 *hap = ha;
3624 skiplist_insert (cda->nves, hap, hap);
3625 }
3626 }
3627 } while (0); /* to preserve old code structure */
3628
3629 return 0;
3630 }
3631
3632 static int
3633 rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
3634 {
3635 int rc = 0;
3636
3637 if (cda->rfg)
3638 {
3639 if (cda->rfg->rfd) /* if not open, nothing to delete */
3640 rc = rfapiDeleteLocalPrefixesByRFD (cda, cda->rfg->rfd);
3641 }
3642 else
3643 {
3644 struct bgp *bgp = cda->bgp;
3645 struct rfapi *h;
3646 struct rfapi_cfg *rfapi_cfg;
3647
3648 struct listnode *node;
3649 struct rfapi_descriptor *rfd;
3650 if (!bgp)
3651 return ENXIO;
3652 h = bgp->rfapi;
3653 rfapi_cfg = bgp->rfapi_cfg;
3654 if (!h || !rfapi_cfg)
3655 return ENXIO;
3656 vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__);
3657 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
3658 {
3659 rc = rfapiDeleteLocalPrefixesByRFD (cda, rfd);
3660 }
3661 }
3662 return rc;
3663 }
3664
3665 /*
3666 * clear_vnc_prefix
3667 *
3668 * Deletes local and remote prefixes that match
3669 */
3670 static void
3671 clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda)
3672 {
3673 struct prefix pfx_un;
3674 struct prefix pfx_vn;
3675
3676 struct prefix *pUN = NULL;
3677 struct prefix *pVN = NULL;
3678 struct prefix *pPrefix = NULL;
3679
3680 struct rfapi_import_table *it = NULL;
3681
3682 /*
3683 * Delete matching remote prefixes in holddown
3684 */
3685 if (cda->vn_address.addr_family)
3686 {
3687 if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn))
3688 pVN = &pfx_vn;
3689 }
3690 if (cda->un_address.addr_family)
3691 {
3692 if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un))
3693 pUN = &pfx_un;
3694 }
3695 if (cda->prefix.family)
3696 {
3697 pPrefix = &cda->prefix;
3698 }
3699 if (cda->rfg)
3700 {
3701 it = cda->rfg->rfapi_import_table;
3702 }
3703 rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, it,
3704 0, 1, &cda->remote_active_pfx_count,
3705 &cda->remote_active_nve_count,
3706 &cda->remote_holddown_pfx_count,
3707 &cda->remote_holddown_nve_count);
3708
3709 /*
3710 * Now do local prefixes
3711 */
3712 rfapiDeleteLocalPrefixes (cda);
3713 }
3714
3715 static void
3716 print_cleared_stats (struct rfapi_local_reg_delete_arg *cda)
3717 {
3718 struct vty *vty = cda->vty; /* for benefit of VTY_NEWLINE */
3719
3720 /* Our special element-deleting function counts nves */
3721 if (cda->nves)
3722 {
3723 skiplist_free (cda->nves);
3724 cda->nves = NULL;
3725 }
3726 if (cda->failed_pfx_count)
3727 vty_out (vty, "Failed to delete %d prefixes%s",
3728 cda->failed_pfx_count, VTY_NEWLINE);
3729
3730 /* left as "prefixes" even in single case for ease of machine parsing */
3731 vty_out (vty,
3732 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs%s",
3733 cda->reg_count, cda->pfx_count, cda->query_count, cda->nve_count,
3734 VTY_NEWLINE);
3735
3736 /*
3737 * We don't currently allow deletion of active remote prefixes from
3738 * the command line
3739 */
3740
3741 vty_out (vty, "[Holddown] Cleared %u prefixes from %u NVEs%s",
3742 cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count,
3743 VTY_NEWLINE);
3744 }
3745
3746 /*
3747 * Caller has already deleted registrations and queries for this/these
3748 * NVEs. Now we just have to close their descriptors.
3749 */
3750 static void
3751 clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda)
3752 {
3753 struct skiplist *sl = cda->nves; /* contains affected NVEs */
3754 struct nve_addr *pKey;
3755 struct nve_addr *pValue;
3756 void *cursor = NULL;
3757 int rc;
3758
3759 if (!sl)
3760 return;
3761
3762 for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor);
3763 !rc;
3764 rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor))
3765 {
3766
3767 if (pValue->rfd)
3768 {
3769 ((struct rfapi_descriptor *) pValue->rfd)->flags |=
3770 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY;
3771 rfapi_close (pValue->rfd);
3772 }
3773 }
3774 }
3775
3776 DEFUN (clear_vnc_nve_all,
3777 clear_vnc_nve_all_cmd,
3778 "clear vnc nve *",
3779 "clear\n"
3780 "VNC Information\n"
3781 "Clear per NVE information\n"
3782 "For all NVEs\n")
3783 {
3784
3785 struct rfapi_local_reg_delete_arg cda;
3786 int rc;
3787
3788 if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
3789 return rc;
3790
3791 cda.vty = vty;
3792
3793 clear_vnc_responses (&cda);
3794 clear_vnc_prefix (&cda);
3795 clear_vnc_nve_closer (&cda);
3796
3797 print_cleared_stats (&cda);
3798
3799 return 0;
3800 }
3801
3802 DEFUN (clear_vnc_nve_vn_un,
3803 clear_vnc_nve_vn_un_cmd,
3804 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3805 "clear\n"
3806 "VNC Information\n"
3807 "Clear prefix registration information\n"
3808 "VN address of NVE\n"
3809 "For all NVEs\n"
3810 "VN IPv4 interface address\n"
3811 "VN IPv6 interface address\n"
3812 "UN address of NVE\n"
3813 "For all UN addresses\n"
3814 "UN IPv4 interface address\n"
3815 "UN IPv6 interface address\n")
3816 {
3817 struct rfapi_local_reg_delete_arg cda;
3818 int rc;
3819
3820 if ((rc =
3821 parse_deleter_tokens (vty, NULL, NULL, argv[4], argv[6], NULL, NULL, NULL, NULL, &cda)))
3822 return rc;
3823
3824 cda.vty = vty;
3825
3826 clear_vnc_responses (&cda);
3827 clear_vnc_prefix (&cda);
3828 clear_vnc_nve_closer (&cda);
3829
3830 print_cleared_stats (&cda);
3831
3832 return 0;
3833 }
3834
3835 DEFUN (clear_vnc_nve_un_vn,
3836 clear_vnc_nve_un_vn_cmd,
3837 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3838 "clear\n"
3839 "VNC Information\n"
3840 "Clear prefix registration information\n"
3841 "UN address of NVE\n"
3842 "For all un NVEs\n"
3843 "UN IPv4 interface address\n"
3844 "UN IPv6 interface address\n"
3845 "VN address of NVE\n"
3846 "For all vn NVEs\n"
3847 "VN IPv4 interface address\n"
3848 "VN IPv6 interface address\n")
3849 {
3850 struct rfapi_local_reg_delete_arg cda;
3851 int rc;
3852
3853 if ((rc =
3854 parse_deleter_tokens (vty, NULL, NULL, argv[6], argv[4], NULL, NULL, NULL, NULL, &cda)))
3855 return rc;
3856
3857 cda.vty = vty;
3858
3859 clear_vnc_responses (&cda);
3860 clear_vnc_prefix (&cda);
3861 clear_vnc_nve_closer (&cda);
3862
3863 print_cleared_stats (&cda);
3864
3865 return 0;
3866 }
3867
3868 DEFUN (clear_vnc_nve_vn,
3869 clear_vnc_nve_vn_cmd,
3870 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3871 "clear\n"
3872 "VNC Information\n"
3873 "Clear prefix registration information\n"
3874 "VN address of NVE\n"
3875 "All addresses\n"
3876 "VN IPv4 interface address\n"
3877 "VN IPv6 interface address\n")
3878 {
3879 struct rfapi_local_reg_delete_arg cda;
3880 int rc;
3881
3882 if ((rc = parse_deleter_tokens (vty, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, NULL, &cda)))
3883 return rc;
3884
3885 cda.vty = vty;
3886
3887 clear_vnc_responses (&cda);
3888 clear_vnc_prefix (&cda);
3889 clear_vnc_nve_closer (&cda);
3890
3891 print_cleared_stats (&cda);
3892 return 0;
3893 }
3894
3895 DEFUN (clear_vnc_nve_un,
3896 clear_vnc_nve_un_cmd,
3897 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3898 "clear\n"
3899 "VNC Information\n"
3900 "Clear prefix registration information\n"
3901 "UN address of NVE\n"
3902 "All un nves\n"
3903 "UN IPv4 interface address\n"
3904 "UN IPv6 interface address\n")
3905 {
3906 struct rfapi_local_reg_delete_arg cda;
3907 int rc;
3908
3909 if ((rc = parse_deleter_tokens (vty, NULL, NULL, NULL, argv[6], NULL, NULL, NULL, NULL, &cda)))
3910 return rc;
3911
3912 cda.vty = vty;
3913
3914 clear_vnc_responses (&cda);
3915 clear_vnc_prefix (&cda);
3916 clear_vnc_nve_closer (&cda);
3917
3918 print_cleared_stats (&cda);
3919 return 0;
3920 }
3921
3922 /*-------------------------------------------------
3923 * Clear VNC Prefix
3924 *-------------------------------------------------*/
3925
3926 /*
3927 * This function is defined in this file (rather than in rfp_registration.c)
3928 * because here we have access to all the task handles.
3929 */
3930 DEFUN (clear_vnc_prefix_vn_un,
3931 clear_vnc_prefix_vn_un_cmd,
3932 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3933 "clear\n"
3934 "VNC Information\n"
3935 "Clear prefix registration information\n"
3936 "All prefixes\n"
3937 "IPv4 prefix\n"
3938 "IPv6 prefix\n"
3939 "VN address of NVE\n"
3940 "All VN addresses\n"
3941 "VN IPv4 interface address\n"
3942 "VN IPv6 interface address\n"
3943 "UN address of NVE\n"
3944 "All UN addresses\n"
3945 "UN IPv4 interface address\n"
3946 "UN IPv6 interface address\n")
3947 {
3948 struct rfapi_local_reg_delete_arg cda;
3949 int rc;
3950
3951 if ((rc =
3952 parse_deleter_tokens (vty, NULL, argv[3], argv[5], argv[7], NULL, NULL, NULL, NULL, &cda)))
3953 return rc;
3954 cda.vty = vty;
3955 clear_vnc_prefix (&cda);
3956 print_cleared_stats (&cda);
3957 return 0;
3958 }
3959
3960 DEFUN (clear_vnc_prefix_un_vn,
3961 clear_vnc_prefix_un_vn_cmd,
3962 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3963 "clear\n"
3964 "VNC Information\n"
3965 "Clear prefix registration information\n"
3966 "All prefixes\n"
3967 "IPv4 prefix\n"
3968 "IPv6 prefix\n"
3969 "UN address of NVE\n"
3970 "All UN addresses\n"
3971 "UN IPv4 interface address\n"
3972 "UN IPv6 interface address\n"
3973 "VN address of NVE\n"
3974 "All VN addresses\n"
3975 "VN IPv4 interface address\n"
3976 "VN IPv6 interface address\n")
3977 {
3978 struct rfapi_local_reg_delete_arg cda;
3979 int rc;
3980
3981 if ((rc =
3982 parse_deleter_tokens (vty, NULL, argv[3], argv[7], argv[5], NULL, NULL, NULL, NULL, &cda)))
3983 return rc;
3984 cda.vty = vty;
3985 clear_vnc_prefix (&cda);
3986 print_cleared_stats (&cda);
3987 return 0;
3988 }
3989
3990 DEFUN (clear_vnc_prefix_un,
3991 clear_vnc_prefix_un_cmd,
3992 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3993 "clear\n"
3994 "VNC Information\n"
3995 "Clear prefix registration information\n"
3996 "All prefixes\n"
3997 "IPv4 prefix\n"
3998 "IPv6 prefix\n"
3999 "UN address of NVE\n"
4000 "All UN addresses\n"
4001 "UN IPv4 interface address\n"
4002 "UN IPv6 interface address\n")
4003 {
4004 struct rfapi_local_reg_delete_arg cda;
4005 int rc;
4006
4007 if ((rc =
4008 parse_deleter_tokens (vty, NULL, argv[3], NULL, argv[5], NULL, NULL, NULL, NULL, &cda)))
4009 return rc;
4010 cda.vty = vty;
4011 clear_vnc_prefix (&cda);
4012 print_cleared_stats (&cda);
4013 return 0;
4014 }
4015
4016 DEFUN (clear_vnc_prefix_vn,
4017 clear_vnc_prefix_vn_cmd,
4018 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
4019 "clear\n"
4020 "VNC Information\n"
4021 "Clear prefix registration information\n"
4022 "All prefixes\n"
4023 "IPv4 prefix\n"
4024 "IPv6 prefix\n"
4025 "UN address of NVE\n"
4026 "All VN addresses\n"
4027 "VN IPv4 interface address\n"
4028 "VN IPv6 interface address\n")
4029 {
4030 struct rfapi_local_reg_delete_arg cda;
4031 int rc;
4032
4033 if ((rc =
4034 parse_deleter_tokens (vty, NULL, argv[3], argv[5], NULL, NULL, NULL, NULL, NULL, &cda)))
4035 return rc;
4036 cda.vty = vty;
4037 clear_vnc_prefix (&cda);
4038 print_cleared_stats (&cda);
4039 return 0;
4040 }
4041
4042 DEFUN (clear_vnc_prefix_all,
4043 clear_vnc_prefix_all_cmd,
4044 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
4045 "clear\n"
4046 "VNC Information\n"
4047 "Clear prefix registration information\n"
4048 "All prefixes\n"
4049 "IPv4 prefix\n"
4050 "IPv6 prefix\n"
4051 "From any NVE\n")
4052 {
4053 struct rfapi_local_reg_delete_arg cda;
4054 int rc;
4055
4056 if ((rc = parse_deleter_tokens (vty, NULL, argv[3], NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
4057 return rc;
4058 cda.vty = vty;
4059 clear_vnc_prefix (&cda);
4060 print_cleared_stats (&cda);
4061 return 0;
4062 }
4063
4064 /*-------------------------------------------------
4065 * Clear VNC MAC
4066 *-------------------------------------------------*/
4067
4068 /*
4069 * This function is defined in this file (rather than in rfp_registration.c)
4070 * because here we have access to all the task handles.
4071 */
4072 DEFUN (clear_vnc_mac_vn_un,
4073 clear_vnc_mac_vn_un_cmd,
4074 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
4075 "clear\n"
4076 "VNC Information\n"
4077 "Clear mac registration information\n"
4078 "All macs\n"
4079 "MAC address\n"
4080 "VNI keyword\n"
4081 "Any virtual network identifier\n"
4082 "Virtual network identifier\n"
4083 "Virtual network identifier\n"
4084 "VN address of NVE\n"
4085 "All VN addresses\n"
4086 "VN IPv4 interface address\n"
4087 "VN IPv6 interface address\n"
4088 "UN address of NVE\n"
4089 "All UN addresses\n"
4090 "UN IPv4 interface address\n"
4091 "UN IPv6 interface address\n")
4092 {
4093 struct rfapi_local_reg_delete_arg cda;
4094 int rc;
4095
4096 /* pfx vn un L2 VNI */
4097 if ((rc =
4098 parse_deleter_tokens (vty, NULL, NULL, argv[7], argv[9], argv[3], argv[5],
4099 NULL, NULL, &cda)))
4100 return rc;
4101 cda.vty = vty;
4102 clear_vnc_prefix (&cda);
4103 print_cleared_stats (&cda);
4104 return 0;
4105 }
4106
4107 DEFUN (clear_vnc_mac_un_vn,
4108 clear_vnc_mac_un_vn_cmd,
4109 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
4110 "clear\n"
4111 "VNC Information\n"
4112 "Clear mac registration information\n"
4113 "All macs\n"
4114 "MAC address\n"
4115 "VNI keyword\n"
4116 "Any virtual network identifier\n"
4117 "Virtual network identifier\n"
4118 "UN address of NVE\n"
4119 "All UN addresses\n"
4120 "UN IPv4 interface address\n"
4121 "UN IPv6 interface address\n"
4122 "VN address of NVE\n"
4123 "All VN addresses\n"
4124 "VN IPv4 interface address\n"
4125 "VN IPv6 interface address\n")
4126 {
4127 struct rfapi_local_reg_delete_arg cda;
4128 int rc;
4129
4130 /* pfx vn un L2 VNI */
4131 if ((rc =
4132 parse_deleter_tokens (vty, NULL, NULL, argv[9], argv[7], argv[3], argv[5],
4133 NULL, NULL, &cda)))
4134 return rc;
4135 cda.vty = vty;
4136 clear_vnc_prefix (&cda);
4137 print_cleared_stats (&cda);
4138 return 0;
4139 }
4140
4141 DEFUN (clear_vnc_mac_un,
4142 clear_vnc_mac_un_cmd,
4143 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
4144 "clear\n"
4145 "VNC Information\n"
4146 "Clear mac registration information\n"
4147 "All macs\n"
4148 "MAC address\n"
4149 "VNI keyword\n"
4150 "Any virtual network identifier\n"
4151 "Virtual network identifier\n"
4152 "UN address of NVE\n"
4153 "All UN addresses\n"
4154 "UN IPv4 interface address\n"
4155 "UN IPv6 interface address\n")
4156 {
4157 struct rfapi_local_reg_delete_arg cda;
4158 int rc;
4159
4160 /* pfx vn un L2 VNI */
4161 if ((rc =
4162 parse_deleter_tokens (vty, NULL, NULL, NULL, argv[7], argv[3], argv[5], NULL, NULL, &cda)))
4163 return rc;
4164 cda.vty = vty;
4165 clear_vnc_prefix (&cda);
4166 print_cleared_stats (&cda);
4167 return 0;
4168 }
4169
4170 DEFUN (clear_vnc_mac_vn,
4171 clear_vnc_mac_vn_cmd,
4172 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
4173 "clear\n"
4174 "VNC Information\n"
4175 "Clear mac registration information\n"
4176 "All macs\n"
4177 "MAC address\n"
4178 "VNI keyword\n"
4179 "Any virtual network identifier\n"
4180 "Virtual network identifier\n"
4181 "UN address of NVE\n"
4182 "All VN addresses\n"
4183 "VN IPv4 interface address\n"
4184 "VN IPv6 interface address\n")
4185 {
4186 struct rfapi_local_reg_delete_arg cda;
4187 int rc;
4188
4189 /* pfx vn un L2 VNI */
4190 if ((rc =
4191 parse_deleter_tokens (vty, NULL, NULL, argv[7], NULL, argv[3], argv[5], NULL, NULL, &cda)))
4192 return rc;
4193 cda.vty = vty;
4194 clear_vnc_prefix (&cda);
4195 print_cleared_stats (&cda);
4196 return 0;
4197 }
4198
4199 DEFUN (clear_vnc_mac_all,
4200 clear_vnc_mac_all_cmd,
4201 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
4202 "clear\n"
4203 "VNC Information\n"
4204 "Clear mac registration information\n"
4205 "All macs\n"
4206 "MAC address\n"
4207 "VNI keyword\n"
4208 "Any virtual network identifier\n"
4209 "Virtual network identifier\n"
4210 "From any NVE\n")
4211 {
4212 struct rfapi_local_reg_delete_arg cda;
4213 int rc;
4214
4215 /* pfx vn un L2 VNI */
4216 if ((rc =
4217 parse_deleter_tokens (vty, NULL, NULL, NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
4218 return rc;
4219 cda.vty = vty;
4220 clear_vnc_prefix (&cda);
4221 print_cleared_stats (&cda);
4222 return 0;
4223 }
4224
4225 /*-------------------------------------------------
4226 * Clear VNC MAC PREFIX
4227 *-------------------------------------------------*/
4228
4229 DEFUN (clear_vnc_mac_vn_un_prefix,
4230 clear_vnc_mac_vn_un_prefix_cmd,
4231 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4232 "clear\n"
4233 "VNC Information\n"
4234 "Clear mac registration information\n"
4235 "All macs\n"
4236 "MAC address\n"
4237 "VNI keyword\n"
4238 "Any virtual network identifier\n"
4239 "Virtual network identifier\n"
4240 "VN address of NVE\n"
4241 "All VN addresses\n"
4242 "VN IPv4 interface address\n"
4243 "VN IPv6 interface address\n"
4244 "UN address of NVE\n"
4245 "All UN addresses\n"
4246 "UN IPv4 interface address\n"
4247 "UN IPv6 interface address\n"
4248 "Clear prefix registration information\n"
4249 "All prefixes\n"
4250 "IPv4 prefix\n"
4251 "IPv6 prefix\n")
4252 {
4253 struct rfapi_local_reg_delete_arg cda;
4254 int rc;
4255
4256 /* pfx vn un L2 VNI */
4257 if ((rc =
4258 parse_deleter_tokens (vty, NULL, argv[11], argv[7], argv[9], argv[3], argv[5],
4259 NULL, NULL, &cda)))
4260 return rc;
4261 cda.vty = vty;
4262 clear_vnc_prefix (&cda);
4263 print_cleared_stats (&cda);
4264 return 0;
4265 }
4266
4267 DEFUN (clear_vnc_mac_un_vn_prefix,
4268 clear_vnc_mac_un_vn_prefix_cmd,
4269 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4270 "clear\n"
4271 "VNC Information\n"
4272 "Clear mac registration information\n"
4273 "All macs\n"
4274 "MAC address\n"
4275 "VNI keyword\n"
4276 "Any virtual network identifier\n"
4277 "Virtual network identifier\n"
4278 "UN address of NVE\n"
4279 "All UN addresses\n"
4280 "UN IPv4 interface address\n"
4281 "UN IPv6 interface address\n"
4282 "VN address of NVE\n"
4283 "All VN addresses\n"
4284 "VN IPv4 interface address\n"
4285 "VN IPv6 interface address\n"
4286 "Clear prefix registration information\n"
4287 "All prefixes\n"
4288 "IPv4 prefix\n"
4289 "IPv6 prefix\n"
4290 "Clear prefix registration information\n"
4291 "All prefixes\n"
4292 "IPv4 prefix\n"
4293 "IPv6 prefix\n")
4294 {
4295 struct rfapi_local_reg_delete_arg cda;
4296 int rc;
4297
4298 /* pfx vn un L2 VNI */
4299 if ((rc =
4300 parse_deleter_tokens (vty, NULL, argv[11], argv[9], argv[7], argv[3], argv[5],
4301 NULL, NULL, &cda)))
4302 return rc;
4303 cda.vty = vty;
4304 clear_vnc_prefix (&cda);
4305 print_cleared_stats (&cda);
4306 return 0;
4307 }
4308
4309 DEFUN (clear_vnc_mac_un_prefix,
4310 clear_vnc_mac_un_prefix_cmd,
4311 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4312 "clear\n"
4313 "VNC Information\n"
4314 "Clear mac registration information\n"
4315 "All macs\n"
4316 "MAC address\n"
4317 "VNI keyword\n"
4318 "Any virtual network identifier\n"
4319 "Virtual network identifier\n"
4320 "UN address of NVE\n"
4321 "All UN addresses\n"
4322 "UN IPv4 interface address\n"
4323 "UN IPv6 interface address\n"
4324 "Clear prefix registration information\n"
4325 "All prefixes\n"
4326 "IPv4 Prefix\n"
4327 "IPv6 Prefix\n")
4328 {
4329 struct rfapi_local_reg_delete_arg cda;
4330 int rc;
4331
4332 /* pfx vn un L2 VNI */
4333 if ((rc =
4334 parse_deleter_tokens (vty, NULL, argv[9], NULL, argv[7], argv[3], argv[5],
4335 NULL, NULL, &cda)))
4336 return rc;
4337 cda.vty = vty;
4338 clear_vnc_prefix (&cda);
4339 print_cleared_stats (&cda);
4340 return 0;
4341 }
4342
4343 DEFUN (clear_vnc_mac_vn_prefix,
4344 clear_vnc_mac_vn_prefix_cmd,
4345 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4346 "clear\n"
4347 "VNC Information\n"
4348 "Clear mac registration information\n"
4349 "All macs\n"
4350 "MAC address\n"
4351 "VNI keyword\n"
4352 "Any virtual network identifier\n"
4353 "Virtual network identifier\n"
4354 "UN address of NVE\n"
4355 "All VN addresses\n"
4356 "VN IPv4 interface address\n"
4357 "VN IPv6 interface address\n"
4358 "Clear prefix registration information\n"
4359 "All prefixes\n"
4360 "IPv4 Prefix\n"
4361 "IPv6 Prefix\n")
4362 {
4363 struct rfapi_local_reg_delete_arg cda;
4364 int rc;
4365
4366 /* pfx vn un L2 VNI */
4367 if ((rc =
4368 parse_deleter_tokens (vty, NULL, argv[9], argv[7], NULL, argv[3], argv[5],
4369 NULL, NULL, &cda)))
4370 return rc;
4371 cda.vty = vty;
4372 clear_vnc_prefix (&cda);
4373 print_cleared_stats (&cda);
4374 return 0;
4375 }
4376
4377 DEFUN (clear_vnc_mac_all_prefix,
4378 clear_vnc_mac_all_prefix_cmd,
4379 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4380 "clear\n"
4381 "VNC Information\n"
4382 "Clear mac registration information\n"
4383 "All macs\n"
4384 "MAC address\n"
4385 "VNI keyword\n"
4386 "Any virtual network identifier\n"
4387 "Virtual network identifier\n"
4388 "UN address of NVE\n"
4389 "All VN addresses\n"
4390 "VN IPv4 interface address\n"
4391 "VN IPv6 interface address\n")
4392 {
4393 struct rfapi_local_reg_delete_arg cda;
4394 int rc;
4395
4396 /* pfx vn un L2 VNI */
4397 if ((rc =
4398 parse_deleter_tokens (vty, NULL, argv[7], NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
4399 return rc;
4400 cda.vty = vty;
4401 clear_vnc_prefix (&cda);
4402 print_cleared_stats (&cda);
4403 return 0;
4404 }
4405
4406 /************************************************************************
4407 * Show commands
4408 ************************************************************************/
4409
4410
4411 /* copied from rfp_vty.c */
4412 static int
4413 check_and_display_is_vnc_running (struct vty *vty)
4414 {
4415 if (!bgp_rfapi_is_vnc_configured (NULL))
4416 return 1; /* is running */
4417
4418 if (vty)
4419 {
4420 vty_out (vty,
4421 "VNC is not configured. (There are no configured BGP VPN SAFI peers.)%s",
4422 VTY_NEWLINE);
4423 }
4424 return 0; /* not running */
4425 }
4426
4427 static int
4428 rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type)
4429 {
4430 struct bgp *bgp_default = bgp_get_default ();
4431 struct rfapi *h;
4432 int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default);
4433
4434 int active_local_routes;
4435 int active_remote_routes;
4436 int holddown_remote_routes;
4437 int imported_remote_routes;
4438
4439 if (!bgp_default)
4440 goto notcfg;
4441
4442 h = bgp_default->rfapi;
4443
4444 if (!h)
4445 goto notcfg;
4446
4447 /* don't show local info if not running RFP */
4448 if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED)
4449 {
4450
4451 switch (show_type)
4452 {
4453
4454 case SHOW_NVE_SUMMARY_ACTIVE_NVES:
4455 vty_out (vty, "%-24s ", "NVEs:");
4456 vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count);
4457 vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors);
4458 vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves);
4459 break;
4460
4461 case SHOW_NVE_SUMMARY_REGISTERED:
4462 /*
4463 * NB: With the introduction of L2 route support, we no
4464 * longer have a one-to-one correspondence between
4465 * locally-originated route advertisements and routes in
4466 * the import tables that have local origin. This
4467 * discrepancy arises because a single advertisement
4468 * may contain both an IP prefix and a MAC address.
4469 * Such an advertisement results in two import table
4470 * entries: one indexed by IP prefix, the other indexed
4471 * by MAC address.
4472 *
4473 * TBD: update computation and display of registration
4474 * statistics to reflect the underlying semantics.
4475 */
4476 if (is_vnc_running)
4477 {
4478 vty_out (vty, "%-24s ", "Registrations:");
4479 vty_out (vty, "%-8s %-8u ", "Active:",
4480 rfapiApCountAll (bgp_default));
4481 vty_out (vty, "%-8s %-8u ", "Failed:",
4482 h->stat.count_registrations_failed);
4483 vty_out (vty, "%-8s %-8u", "Total:",
4484 h->stat.count_registrations);
4485 vty_out (vty, "%s", VTY_NEWLINE);
4486 }
4487 vty_out (vty, "%-24s ", "Prefixes registered:");
4488 vty_out (vty, "%s", VTY_NEWLINE);
4489
4490 rfapiCountAllItRoutes (&active_local_routes,
4491 &active_remote_routes,
4492 &holddown_remote_routes,
4493 &imported_remote_routes);
4494
4495 /* local */
4496 if (is_vnc_running)
4497 {
4498 vty_out (vty, " %-20s ", "Locally:");
4499 vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes);
4500 vty_out (vty, "%s", VTY_NEWLINE);
4501 }
4502
4503
4504 vty_out (vty, " %-20s ", "Remotely:");
4505 vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes);
4506 vty_out (vty, "%s", VTY_NEWLINE);
4507 vty_out (vty, " %-20s ", "In Holddown:");
4508 vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes);
4509 vty_out (vty, "%s", VTY_NEWLINE);
4510 vty_out (vty, " %-20s ", "Imported:");
4511 vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes);
4512 break;
4513
4514 case SHOW_NVE_SUMMARY_QUERIES:
4515 vty_out (vty, "%-24s ", "Queries:");
4516 vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL));
4517 vty_out (vty, "%-8s %-8u ", "Failed:",
4518 h->stat.count_queries_failed);
4519 vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries);
4520 break;
4521
4522 case SHOW_NVE_SUMMARY_RESPONSES:
4523 rfapiRibShowResponsesSummary (vty);
4524
4525 default:
4526 break;
4527 }
4528 vty_out (vty, "%s", VTY_NEWLINE);
4529 }
4530 return 0;
4531
4532 notcfg:
4533 vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
4534 return CMD_WARNING;
4535 }
4536
4537 static int
4538 rfapi_show_nves (
4539 struct vty *vty,
4540 struct prefix *vn_prefix,
4541 struct prefix *un_prefix)
4542 {
4543 //struct hash *rfds;
4544 //struct rfp_rfapi_descriptor_param param;
4545
4546 struct bgp *bgp_default = bgp_get_default ();
4547 struct rfapi *h;
4548 struct listnode *node;
4549 struct rfapi_descriptor *rfd;
4550
4551 int total = 0;
4552 int printed = 0;
4553 int rc;
4554
4555 if (!bgp_default)
4556 goto notcfg;
4557
4558 h = bgp_default->rfapi;
4559
4560 if (!h)
4561 goto notcfg;
4562
4563 rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
4564 if (rc)
4565 return rc;
4566
4567 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
4568 {
4569 struct prefix pfx;
4570 char vn_addr_buf[INET6_ADDRSTRLEN] =
4571 {
4572 0,};
4573 char un_addr_buf[INET6_ADDRSTRLEN] =
4574 {
4575 0,};
4576 char age[10];
4577
4578 ++total;
4579
4580 if (vn_prefix)
4581 {
4582 assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx));
4583 if (!prefix_match (vn_prefix, &pfx))
4584 continue;
4585 }
4586
4587 if (un_prefix)
4588 {
4589 assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx));
4590 if (!prefix_match (un_prefix, &pfx))
4591 continue;
4592 }
4593
4594 rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN);
4595 rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN);
4596
4597 if (!printed)
4598 {
4599 /* print out a header */
4600 vty_out (vty, " "
4601 "Active Next Hops%s", VTY_NEWLINE);
4602 vty_out (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s%s",
4603 "VN Address",
4604 "UN Address",
4605 "Regis", "Resps", "Reach", "Remove", "Age", VTY_NEWLINE);
4606 }
4607
4608 ++printed;
4609
4610 vty_out (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s%s",
4611 vn_addr_buf,
4612 un_addr_buf,
4613 rfapiApCount (rfd),
4614 rfapi_monitor_count (rfd),
4615 rfd->stat_count_nh_reachable,
4616 rfd->stat_count_nh_removal,
4617 rfapiFormatAge (rfd->open_time, age, 10), VTY_NEWLINE);
4618 }
4619
4620 if (printed > 0 || vn_prefix || un_prefix)
4621 vty_out (vty, "Displayed %d out of %d active NVEs%s",
4622 printed, total, VTY_NEWLINE);
4623
4624 return 0;
4625
4626 notcfg:
4627 vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
4628 return CMD_WARNING;
4629 }
4630
4631
4632 DEFUN (vnc_show_summary,
4633 vnc_show_summary_cmd,
4634 "show vnc summary",
4635 SHOW_STR
4636 VNC_SHOW_STR
4637 "Display VNC status summary\n")
4638 {
4639 if (!check_and_display_is_vnc_running (vty))
4640 return CMD_SUCCESS;
4641 bgp_rfapi_show_summary (bgp_get_default (), vty);
4642 vty_out (vty, "%s", VTY_NEWLINE);
4643 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
4644 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4645 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES);
4646 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
4647 return CMD_SUCCESS;
4648 }
4649
4650 DEFUN (vnc_show_nves,
4651 vnc_show_nves_cmd,
4652 "show vnc nves",
4653 SHOW_STR
4654 VNC_SHOW_STR
4655 "List known NVEs\n")
4656 {
4657 rfapi_show_nves (vty, NULL, NULL);
4658 return CMD_SUCCESS;
4659 }
4660
4661 DEFUN (vnc_show_nves_ptct,
4662 vnc_show_nves_ptct_cmd,
4663 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4664 SHOW_STR
4665 VNC_SHOW_STR
4666 "List known NVEs\n"
4667 "VN address of NVE\n"
4668 "UN address of NVE\n"
4669 "IPv4 interface address\n"
4670 "IPv6 interface address\n")
4671 {
4672 struct prefix pfx;
4673
4674 if (!check_and_display_is_vnc_running (vty))
4675 return CMD_SUCCESS;
4676
4677 if (!str2prefix (argv[4]->arg, &pfx))
4678 {
4679 vty_out (vty, "Malformed address \"%s\"%s", argv[4]->arg, VTY_NEWLINE);
4680 return CMD_WARNING;
4681 }
4682 if (pfx.family != AF_INET && pfx.family != AF_INET6)
4683 {
4684 vty_out (vty, "Invalid address \"%s\"%s", argv[4]->arg, VTY_NEWLINE);
4685 return CMD_WARNING;
4686 }
4687
4688 if (argv[3]->arg[0] == 'u')
4689 {
4690 rfapi_show_nves (vty, NULL, &pfx);
4691 }
4692 else
4693 {
4694 rfapi_show_nves (vty, &pfx, NULL);
4695 }
4696
4697 return CMD_SUCCESS;
4698 }
4699
4700 /* adapted from rfp_registration_cache_log() */
4701 static void
4702 rfapi_show_registrations (
4703 struct vty *vty,
4704 struct prefix *restrict_to,
4705 int show_local,
4706 int show_remote,
4707 int show_holddown,
4708 int show_imported)
4709 {
4710 int printed = 0;
4711
4712 if (!vty)
4713 return;
4714
4715 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
4716
4717 if (show_local)
4718 {
4719 /* non-expiring, local */
4720 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0);
4721 }
4722 if (show_remote)
4723 {
4724 /* non-expiring, non-local */
4725 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0);
4726 }
4727 if (show_holddown)
4728 {
4729 /* expiring, including local */
4730 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0);
4731 }
4732 if (show_imported)
4733 {
4734 /* non-expiring, non-local */
4735 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1);
4736 }
4737 if (!printed)
4738 {
4739 vty_out (vty, "%s", VTY_NEWLINE);
4740 }
4741 }
4742
4743 DEFUN (vnc_show_registrations_pfx,
4744 vnc_show_registrations_pfx_cmd,
4745 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4746 SHOW_STR
4747 VNC_SHOW_STR
4748 "List active prefix registrations\n"
4749 "Limit output to a particular IPv4 prefix\n"
4750 "Limit output to a particular IPv6 prefix\n"
4751 "Limit output to a particular IPv6 address\n")
4752 {
4753 struct prefix p;
4754 struct prefix *p_addr = NULL;
4755
4756 if (argc > 3)
4757 {
4758 if (!str2prefix (argv[3]->arg, &p))
4759 {
4760 vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
4761 return CMD_SUCCESS;
4762 }
4763 else
4764 {
4765 p_addr = &p;
4766 }
4767 }
4768
4769 rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1);
4770 return CMD_SUCCESS;
4771 }
4772
4773 DEFUN (vnc_show_registrations_some_pfx,
4774 vnc_show_registrations_some_pfx_cmd,
4775 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4776 SHOW_STR
4777 VNC_SHOW_STR
4778 "List active prefix registrations\n"
4779 "show all registrations\n"
4780 "show only registrations in holddown\n"
4781 "show only imported prefixes\n"
4782 "show only local registrations\n"
4783 "show only remote registrations\n"
4784 "Limit output to a particular prefix or address\n"
4785 "Limit output to a particular prefix or address\n"
4786 "Limit output to a particular prefix or address\n")
4787 {
4788 struct prefix p;
4789 struct prefix *p_addr = NULL;
4790
4791 int show_local = 0;
4792 int show_remote = 0;
4793 int show_holddown = 0;
4794 int show_imported = 0;
4795
4796 if (argc > 4)
4797 {
4798 if (!str2prefix (argv[4]->arg, &p))
4799 {
4800 vty_out (vty, "Invalid prefix: %s%s", argv[4]->arg, VTY_NEWLINE);
4801 return CMD_SUCCESS;
4802 }
4803 else
4804 {
4805 p_addr = &p;
4806 }
4807 }
4808 switch (argv[3]->arg[0])
4809 {
4810 case 'a':
4811 show_local = 1;
4812 show_remote = 1;
4813 show_holddown = 1;
4814 show_imported = 1;
4815 break;
4816
4817 case 'h':
4818 show_holddown = 1;
4819 break;
4820
4821 case 'i':
4822 show_imported = 1;
4823 break;
4824
4825 case 'l':
4826 show_local = 1;
4827 break;
4828
4829 case 'r':
4830 show_remote = 1;
4831 break;
4832 }
4833
4834 rfapi_show_registrations (vty, p_addr,
4835 show_local, show_remote, show_holddown,
4836 show_imported);
4837 return CMD_SUCCESS;
4838 }
4839
4840 DEFUN (vnc_show_responses_pfx,
4841 vnc_show_responses_pfx_cmd,
4842 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4843 SHOW_STR
4844 VNC_SHOW_STR
4845 "List recent query responses\n"
4846 "Limit output to a particular IPv4 prefix\n"
4847 "Limit output to a particular IPv6 prefix\n"
4848 "Limit output to a particular IPv6 address\n" )
4849 {
4850 struct prefix p;
4851 struct prefix *p_addr = NULL;
4852
4853 if (argc > 3)
4854 {
4855 if (!str2prefix (argv[3]->arg, &p))
4856 {
4857 vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
4858 return CMD_SUCCESS;
4859 }
4860 else
4861 {
4862 p_addr = &p;
4863 }
4864 }
4865 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4866
4867 rfapiRibShowResponsesSummary (vty);
4868
4869 rfapiRibShowResponses (vty, p_addr, 0);
4870 rfapiRibShowResponses (vty, p_addr, 1);
4871
4872 return CMD_SUCCESS;
4873 }
4874
4875 DEFUN (vnc_show_responses_some_pfx,
4876 vnc_show_responses_some_pfx_cmd,
4877 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4878 SHOW_STR
4879 VNC_SHOW_STR
4880 "List recent query responses\n"
4881 "show only active query responses\n"
4882 "show only removed query responses\n"
4883 "Limit output to a particular IPv4 prefix\n"
4884 "Limit output to a particular IPv6 prefix\n"
4885 "Limit output to a particular IPV6 address\n")
4886 {
4887 struct prefix p;
4888 struct prefix *p_addr = NULL;
4889
4890 int show_active = 0;
4891 int show_removed = 0;
4892
4893 if (!check_and_display_is_vnc_running (vty))
4894 return CMD_SUCCESS;
4895
4896 if (argc > 4)
4897 {
4898 if (!str2prefix (argv[4]->arg, &p))
4899 {
4900 vty_out (vty, "Invalid prefix: %s%s", argv[4]->arg, VTY_NEWLINE);
4901 return CMD_SUCCESS;
4902 }
4903 else
4904 {
4905 p_addr = &p;
4906 }
4907 }
4908
4909 switch (argv[3]->arg[0])
4910 {
4911 case 'a':
4912 show_active = 1;
4913 break;
4914
4915 case 'r':
4916 show_removed = 1;
4917 break;
4918 }
4919
4920 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4921
4922 rfapiRibShowResponsesSummary (vty);
4923
4924 if (show_active)
4925 rfapiRibShowResponses (vty, p_addr, 0);
4926 if (show_removed)
4927 rfapiRibShowResponses (vty, p_addr, 1);
4928
4929 return CMD_SUCCESS;
4930 }
4931
4932 DEFUN (show_vnc_queries_pfx,
4933 show_vnc_queries_pfx_cmd,
4934 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4935 SHOW_STR
4936 VNC_SHOW_STR
4937 "List active queries\n"
4938 "Limit output to a particular IPv4 prefix or address\n"
4939 "Limit output to a particular IPv6 prefix\n"
4940 "Limit output to a particualr IPV6 address\n")
4941 {
4942 struct prefix pfx;
4943 struct prefix *p = NULL;
4944
4945 if (argc > 3)
4946 {
4947 if (!str2prefix (argv[3]->arg, &pfx))
4948 {
4949 vty_out (vty, "Invalid prefix: %s%s", argv[3]->arg, VTY_NEWLINE);
4950 return CMD_WARNING;
4951 }
4952 p = &pfx;
4953 }
4954
4955 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4956
4957 return rfapiShowVncQueries (vty, p);
4958 }
4959
4960 DEFUN (vnc_clear_counters,
4961 vnc_clear_counters_cmd,
4962 "clear vnc counters",
4963 CLEAR_STR
4964 VNC_SHOW_STR
4965 "Reset VNC counters\n")
4966 {
4967 struct bgp *bgp_default = bgp_get_default ();
4968 struct rfapi *h;
4969 struct listnode *node;
4970 struct rfapi_descriptor *rfd;
4971
4972 if (!bgp_default)
4973 goto notcfg;
4974
4975 h = bgp_default->rfapi;
4976
4977 if (!h)
4978 goto notcfg;
4979
4980 /* per-rfd */
4981 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
4982 {
4983 rfd->stat_count_nh_reachable = 0;
4984 rfd->stat_count_nh_removal = 0;
4985 }
4986
4987 /* global */
4988 memset (&h->stat, 0, sizeof (h->stat));
4989
4990 /*
4991 * 151122 per bug 103, set count_registrations = number active.
4992 * Do same for queries
4993 */
4994 h->stat.count_registrations = rfapiApCountAll (bgp_default);
4995 h->stat.count_queries = rfapi_monitor_count (NULL);
4996
4997 rfapiRibShowResponsesSummaryClear ();
4998
4999 return CMD_SUCCESS;
5000
5001 notcfg:
5002 vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE);
5003 return CMD_WARNING;
5004 }
5005
5006 /************************************************************************
5007 * Add prefix with vrf
5008 *
5009 * add [vrf <vrf-name>] prefix <prefix>
5010 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
5011 ************************************************************************/
5012 static int
5013 vnc_add_vrf_prefix (struct vty *vty,
5014 const char *arg_vrf,
5015 const char *arg_prefix,
5016 const char *arg_rd, /* optional */
5017 const char *arg_label, /* optional */
5018 const char *arg_pref) /* optional */
5019 {
5020 struct bgp *bgp;
5021 struct rfapi_nve_group_cfg *rfg;
5022 struct prefix pfx;
5023 struct rfapi_ip_prefix rpfx;
5024 uint32_t pref = 0;
5025 struct rfapi_vn_option optary[3];
5026 struct rfapi_vn_option *opt = NULL;
5027 int cur_opt = 0;
5028
5029 bgp = bgp_get_default (); /* assume main instance for now */
5030 if (!bgp)
5031 {
5032 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
5033 return CMD_WARNING;
5034 }
5035 if (!bgp->rfapi || !bgp->rfapi_cfg)
5036 {
5037 vty_out (vty, "VRF support not configured%s", VTY_NEWLINE);
5038 return CMD_WARNING;
5039 }
5040
5041 rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
5042 /* arg checks */
5043 if (!rfg)
5044 {
5045 vty_out (vty, "VRF \"%s\" appears not to be configured.%s",
5046 arg_vrf, VTY_NEWLINE);
5047 return CMD_WARNING;
5048 }
5049 if (!rfg->rt_export_list || !rfg->rfapi_import_table)
5050 {
5051 vty_out (vty, "VRF \"%s\" is missing RT import/export RT configuration.%s",
5052 arg_vrf, VTY_NEWLINE);
5053 return CMD_WARNING;
5054 }
5055 if (!rfg->rd.family && !arg_rd)
5056 {
5057 vty_out (vty, "VRF \"%s\" isn't configured with an RD, so RD must be provided.%s",
5058 arg_vrf, VTY_NEWLINE);
5059 return CMD_WARNING;
5060 }
5061 if (rfg->label > MPLS_LABEL_MAX && !arg_label)
5062 {
5063 vty_out (vty, "VRF \"%s\" isn't configured with a default labels, so a label must be provided.%s",
5064 arg_vrf, VTY_NEWLINE);
5065 return CMD_WARNING;
5066 }
5067 if (!str2prefix (arg_prefix, &pfx))
5068 {
5069 vty_out (vty, "Malformed prefix \"%s\"%s",
5070 arg_prefix, VTY_NEWLINE);
5071 return CMD_WARNING;
5072 }
5073 rfapiQprefix2Rprefix (&pfx, &rpfx);
5074 memset (optary, 0, sizeof (optary));
5075 if (arg_rd)
5076 {
5077 if (opt != NULL)
5078 opt->next = &optary[cur_opt];
5079 opt = &optary[cur_opt++];
5080 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
5081 if (!str2prefix_rd (arg_rd, &opt->v.internal_rd))
5082 {
5083 vty_out (vty, "Malformed RD \"%s\"%s",
5084 arg_rd, VTY_NEWLINE);
5085 return CMD_WARNING;
5086 }
5087 }
5088 if (rfg->label <= MPLS_LABEL_MAX || arg_label)
5089 {
5090 struct rfapi_l2address_option *l2o;
5091 if (opt != NULL)
5092 opt->next = &optary[cur_opt];
5093 opt = &optary[cur_opt++];
5094 opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
5095 l2o = &opt->v.l2addr;
5096 if (arg_label)
5097 {
5098 int32_t label;
5099 VTY_GET_INTEGER_RANGE ("Label value", label, arg_label, 0, MPLS_LABEL_MAX);
5100 l2o->label = label;
5101 }
5102 else
5103 l2o->label = rfg->label;
5104 }
5105 if (arg_pref)
5106 {
5107 char *endptr = NULL;
5108 pref = strtoul (arg_pref, &endptr, 10);
5109 if (*endptr != '\0')
5110 {
5111 vty_out (vty, "%% Invalid local-preference value \"%s\"%s", arg_pref, VTY_NEWLINE);
5112 return CMD_WARNING;
5113 }
5114 }
5115 rpfx.cost = 255 - (pref & 255) ;
5116 if (rfg->rfd == NULL) /* need new rfapi_handle */
5117 {
5118 /* based on rfapi_open */
5119 struct rfapi_descriptor *rfd;
5120 rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
5121 rfd->bgp = bgp;
5122 rfg->rfd = rfd;
5123 /* leave most fields empty as will get from (dynamic) config when needed */
5124 rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS;
5125 rfd->cookie = rfg;
5126 if (rfg->vn_prefix.family &&
5127 !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF))
5128 {
5129 rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr);
5130 }
5131 else
5132 {
5133 memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr));
5134 rfd->vn_addr.addr_family = AF_INET;
5135 rfd->vn_addr.addr.v4 = bgp->router_id;
5136 }
5137 rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for lookups */
5138 vnc_zlog_debug_verbose ("%s: Opening RFD for VRF %s",
5139 __func__, rfg->name);
5140 rfapi_init_and_open(bgp, rfd, rfg);
5141 }
5142
5143 if (!rfapi_register (rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL,
5144 (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD))
5145 {
5146 struct rfapi_next_hop_entry *head = NULL;
5147 struct rfapi_next_hop_entry *tail = NULL;
5148 struct rfapi_vn_option *vn_opt_new;
5149
5150 vnc_zlog_debug_verbose ("%s: rfapi_register succeeded", __func__);
5151
5152 if (bgp->rfapi->rfp_methods.local_cb)
5153 {
5154 struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfg->rfd;
5155 vn_opt_new = rfapi_vn_options_dup (opt);
5156
5157 rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx,
5158 1, RFAPI_INFINITE_LIFETIME,
5159 vn_opt_new, &head, &tail);
5160 if (head)
5161 {
5162 bgp->rfapi->flags |= RFAPI_INCALLBACK;
5163 (*bgp->rfapi->rfp_methods.local_cb) (head, r->cookie);
5164 bgp->rfapi->flags &= ~RFAPI_INCALLBACK;
5165 }
5166 head = tail = NULL;
5167 }
5168 vnc_zlog_debug_verbose ("%s completed, count=%d/%d", __func__,
5169 rfg->rfapi_import_table->local_count[AFI_IP],
5170 rfg->rfapi_import_table->local_count[AFI_IP6]);
5171 return CMD_SUCCESS;
5172 }
5173
5174 vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__);
5175 vty_out (vty, "Add failed.%s", VTY_NEWLINE);
5176 return CMD_WARNING;
5177 }
5178
5179 DEFUN (add_vrf_prefix_rd_label_pref,
5180 add_vrf_prefix_rd_label_pref_cmd,
5181 "add vrf NAME prefix <A.B.C.D/M|X:X::X:X/M> [{rd ASN:nn_or_IP-address|label (0-1048575)|preference (0-4294967295)}]",
5182 "Add\n"
5183 "To a VRF\n"
5184 "VRF name\n"
5185 "Add/modify prefix related information\n"
5186 "IPv4 prefix\n"
5187 "IPv6 prefix\n"
5188 "Override configured VRF Route Distinguisher\n"
5189 "<as-number>:<number> or <ip-address>:<number>\n"
5190 "Override configured VRF label\n"
5191 "Label Value <0-1048575>\n"
5192 "Set advertised local preference\n"
5193 "local preference (higher=more preferred)\n")
5194 {
5195 char *arg_vrf = argv[2]->arg;
5196 char *arg_prefix = argv[4]->arg;
5197 char *arg_rd = NULL; /* optional */
5198 char *arg_label = NULL; /* optional */
5199 char *arg_pref = NULL; /* optional */
5200 int pargc = 5;
5201 argc--; /* don't parse argument */
5202 while (pargc < argc)
5203 {
5204 switch (argv[pargc++]->arg[0])
5205 {
5206 case 'r':
5207 arg_rd = argv[pargc]->arg;
5208 break;
5209 case 'l':
5210 arg_label = argv[pargc]->arg;
5211 break;
5212 case 'p':
5213 arg_pref = argv[pargc]->arg;
5214 break;
5215 default:
5216 break;
5217 }
5218 pargc ++;
5219 }
5220
5221 return vnc_add_vrf_prefix (vty, arg_vrf, arg_prefix, arg_rd, arg_label, arg_pref);
5222 }
5223
5224 /************************************************************************
5225 * del prefix with vrf
5226 *
5227 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
5228 ************************************************************************/
5229 static int
5230 rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
5231 {
5232 int count = 0;
5233 afi_t afi = AFI_MAX;
5234 while (afi-- > 0)
5235 {
5236 count += rfg->rfapi_import_table->local_count[afi];
5237 }
5238 return count;
5239 }
5240
5241 static void
5242 clear_vnc_vrf_closer (struct rfapi_nve_group_cfg *rfg)
5243 {
5244 struct rfapi_descriptor *rfd = rfg->rfd;
5245 afi_t afi;
5246
5247 if (rfd == NULL)
5248 return;
5249 /* check if IT is empty */
5250 for (afi = 0;
5251 afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0;
5252 afi++);
5253
5254 if (afi == AFI_MAX)
5255 {
5256 vnc_zlog_debug_verbose ("%s: closing RFD for VRF %s",
5257 __func__, rfg->name);
5258 rfg->rfd = NULL;
5259 rfapi_close(rfd);
5260 }
5261 else
5262 {
5263 vnc_zlog_debug_verbose ("%s: VRF %s afi=%d count=%d",
5264 __func__, rfg->name, afi,
5265 rfg->rfapi_import_table->local_count[afi]);
5266 }
5267 }
5268
5269 static int
5270 vnc_clear_vrf (struct vty *vty,
5271 struct bgp *bgp,
5272 const char *arg_vrf,
5273 const char *arg_prefix, /* NULL = all */
5274 const char *arg_rd) /* optional */
5275 {
5276 struct rfapi_nve_group_cfg *rfg;
5277 struct rfapi_local_reg_delete_arg cda;
5278 int rc;
5279 int start_count;
5280
5281 if (bgp == NULL)
5282 bgp = bgp_get_default (); /* assume main instance for now */
5283 if (!bgp)
5284 {
5285 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
5286 return CMD_WARNING;
5287 }
5288 if (!bgp->rfapi || !bgp->rfapi_cfg)
5289 {
5290 vty_out (vty, "VRF support not configured%s", VTY_NEWLINE);
5291 return CMD_WARNING;
5292 }
5293 rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
5294 /* arg checks */
5295 if (!rfg)
5296 {
5297 vty_out (vty, "VRF \"%s\" appears not to be configured.%s",
5298 arg_vrf, VTY_NEWLINE);
5299 return CMD_WARNING;
5300 }
5301 rc = parse_deleter_args (vty, bgp, arg_prefix, NULL, NULL, NULL, NULL,
5302 arg_rd, rfg, &cda);
5303 if (rc != CMD_SUCCESS) /* parse error */
5304 return rc;
5305
5306 start_count = rfapi_cfg_group_it_count(rfg);
5307 clear_vnc_prefix (&cda);
5308 clear_vnc_vrf_closer (rfg);
5309 vty_out (vty, "Cleared %u out of %d prefixes.%s",
5310 cda.pfx_count, start_count, VTY_NEWLINE);
5311 return CMD_SUCCESS;
5312 }
5313
5314 DEFUN (clear_vrf_prefix_rd,
5315 clear_vrf_prefix_rd_cmd,
5316 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:nn_or_IP-address]",
5317 "Clear stored data\n"
5318 "From a VRF\n"
5319 "VRF name\n"
5320 "Prefix related information\n"
5321 "IPv4 prefix\n"
5322 "IPv6 prefix\n"
5323 "Specific VRF Route Distinguisher\n"
5324 "<as-number>:<number> or <ip-address>:<number>\n")
5325 {
5326 char *arg_vrf = argv[2]->arg;
5327 char *arg_prefix = NULL; /* optional */
5328 char *arg_rd = NULL; /* optional */
5329 int pargc = 3;
5330 argc--; /* don't check parameter */
5331 while (pargc < argc)
5332 {
5333 switch (argv[pargc++]->arg[0])
5334 {
5335 case 'r':
5336 arg_rd = argv[pargc]->arg;
5337 break;
5338 case 'p':
5339 arg_prefix = argv[pargc]->arg;
5340 break;
5341 default:
5342 break;
5343 }
5344 pargc ++;
5345 }
5346 return vnc_clear_vrf (vty, NULL, arg_vrf, arg_prefix, arg_rd);
5347 }
5348
5349 DEFUN (clear_vrf_all,
5350 clear_vrf_all_cmd,
5351 "clear vrf NAME all",
5352 "Clear stored data\n"
5353 "From a VRF\n"
5354 "VRF name\n"
5355 "All prefixes\n")
5356 {
5357 char *arg_vrf = argv[2]->arg;
5358 return vnc_clear_vrf (vty, NULL, arg_vrf, NULL, NULL);
5359 }
5360
5361 void rfapi_vty_init ()
5362 {
5363 install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
5364 install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd);
5365 install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd);
5366 install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd);
5367 install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd);
5368
5369 install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd);
5370 install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd);
5371 install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd);
5372 install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd);
5373 install_element (ENABLE_NODE, &add_vnc_prefix_cmd);
5374
5375 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd);
5376 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd);
5377 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd);
5378 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd);
5379 install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd);
5380 install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd);
5381 install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd);
5382 install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd);
5383
5384 install_element (ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd);
5385
5386 install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd);
5387 install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd);
5388 install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd);
5389 install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd);
5390 install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd);
5391
5392 install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd);
5393 install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd);
5394 install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd);
5395 install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd);
5396 install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd);
5397
5398 install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd);
5399 install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd);
5400 install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd);
5401 install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd);
5402 install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd);
5403
5404 install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd);
5405 install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd);
5406 install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd);
5407 install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd);
5408 install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd);
5409
5410 install_element (ENABLE_NODE, &clear_vrf_prefix_rd_cmd);
5411 install_element (ENABLE_NODE, &clear_vrf_all_cmd);
5412
5413 install_element (ENABLE_NODE, &vnc_clear_counters_cmd);
5414
5415 install_element (VIEW_NODE, &vnc_show_summary_cmd);
5416 install_element (VIEW_NODE, &vnc_show_nves_cmd);
5417 install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd);
5418
5419 install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd);
5420 install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd);
5421 install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd);
5422 install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd);
5423 install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd);
5424 }