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