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