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