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