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