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