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