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