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