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