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