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