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