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