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