]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/rfapi_vty.c
Merge branch 'master' of https://github.com/dwalton76/frr into bgpd-ipv4-plus-label...
[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 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2677 {
2678 /* pfx vn un cost life */
2679 return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11],
2680 /* mac vni */
2681 NULL, NULL, 0, NULL);
2682 }
2683
2684 DEFUN (add_vnc_prefix_life_cost,
2685 add_vnc_prefix_life_cost_cmd,
2686 "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)",
2687 "Add registration\n"
2688 "VNC Information\n"
2689 "Add/modify prefix related information\n"
2690 "IPv4 prefix\n"
2691 "IPv6 prefix\n"
2692 "VN address of NVE\n"
2693 "VN IPv4 interface address\n"
2694 "VN IPv6 interface address\n"
2695 "UN address of NVE\n"
2696 "UN IPv4 interface address\n"
2697 "UN IPv6 interface address\n"
2698 "Registration lifetime [default: infinite]\n"
2699 "Lifetime value in seconds\n"
2700 "Administrative cost [default: 255]\n"
2701 "Administrative cost\n"
2702 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2703 {
2704 /* pfx vn un cost life */
2705 return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9],
2706 /* mac vni */
2707 NULL, NULL, 0, NULL);
2708 }
2709
2710 DEFUN (add_vnc_prefix_cost,
2711 add_vnc_prefix_cost_cmd,
2712 "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)",
2713 "Add registration\n"
2714 "VNC Information\n"
2715 "Add/modify prefix related information\n"
2716 "IPv4 prefix\n"
2717 "IPv6 prefix\n"
2718 "VN address of NVE\n"
2719 "VN IPv4 interface address\n"
2720 "VN IPv6 interface address\n"
2721 "UN address of NVE\n"
2722 "UN IPv4 interface address\n"
2723 "UN IPv6 interface address\n"
2724 "Administrative cost [default: 255]\n"
2725 "Administrative cost\n"
2726 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2727 {
2728 /* pfx vn un cost life */
2729 return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL,
2730 /* mac vni */
2731 NULL, NULL, 0, NULL);
2732 }
2733
2734 DEFUN (add_vnc_prefix_life,
2735 add_vnc_prefix_life_cmd,
2736 "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)",
2737 "Add registration\n"
2738 "VNC Information\n"
2739 "Add/modify prefix related information\n"
2740 "IPv4 prefix\n"
2741 "IPv6 prefix\n"
2742 "VN address of NVE\n"
2743 "VN IPv4 interface address\n"
2744 "VN IPv6 interface address\n"
2745 "UN address of NVE\n"
2746 "UN IPv4 interface address\n"
2747 "UN IPv6 interface address\n"
2748 "Registration lifetime [default: infinite]\n"
2749 "Lifetime value in seconds\n"
2750 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2751 {
2752 /* pfx vn un cost life */
2753 return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9],
2754 /* mac vni */
2755 NULL, NULL, 0, NULL);
2756 }
2757
2758 DEFUN (add_vnc_prefix,
2759 add_vnc_prefix_cmd,
2760 "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>",
2761 "Add registration\n"
2762 "VNC Information\n"
2763 "Add/modify prefix related information\n"
2764 "IPv4 prefix\n"
2765 "IPv6 prefix\n"
2766 "VN address of NVE\n"
2767 "VN IPv4 interface address\n"
2768 "VN IPv6 interface address\n"
2769 "UN address of NVE\n"
2770 "UN IPv4 interface address\n"
2771 "UN IPv6 interface address\n"
2772 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2773 {
2774 /* pfx vn un cost life */
2775 return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL,
2776 /* mac vni */
2777 NULL, NULL, 0, NULL);
2778 }
2779
2780 /************************************************************************
2781 * Mac address registrations
2782 ************************************************************************/
2783 DEFUN (add_vnc_mac_vni_prefix_cost_life,
2784 add_vnc_mac_vni_prefix_cost_life_cmd,
2785 "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)",
2786 "Add registration\n"
2787 "VNC Information\n"
2788 "Add/modify mac address information\n"
2789 "MAC address\n"
2790 "Virtual Network Identifier follows\n"
2791 "Virtual Network Identifier\n"
2792 "VN address of NVE\n"
2793 "VN IPv4 interface address\n"
2794 "VN IPv6 interface address\n"
2795 "UN address of NVE\n"
2796 "UN IPv4 interface address\n"
2797 "UN IPv6 interface address\n"
2798 "Add/modify prefix related information\n"
2799 "IPv4 prefix\n"
2800 "IPv6 prefix\n"
2801 "Administrative cost [default: 255]\n"
2802 "Administrative cost\n"
2803 "Registration lifetime [default: infinite]\n"
2804 "Lifetime value in seconds\n")
2805 {
2806 /* pfx vn un cost life */
2807 return register_add (vty, argv[11], argv[7], argv[9], argv[13], argv[15],
2808 /* mac vni */
2809 argv[3], argv[5], 0, NULL);
2810 }
2811
2812
2813 DEFUN (add_vnc_mac_vni_prefix_life,
2814 add_vnc_mac_vni_prefix_life_cmd,
2815 "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)",
2816 "Add registration\n"
2817 "VNC Information\n"
2818 "Add/modify mac address information\n"
2819 "MAC address\n"
2820 "Virtual Network Identifier follows\n"
2821 "Virtual Network Identifier\n"
2822 "VN address of NVE\n"
2823 "VN IPv4 interface address\n"
2824 "VN IPv6 interface address\n"
2825 "UN address of NVE\n"
2826 "UN IPv4 interface address\n"
2827 "UN IPv6 interface address\n"
2828 "Add/modify prefix related information\n"
2829 "IPv4 prefix\n"
2830 "IPv6 prefix\n"
2831 "Registration lifetime [default: infinite]\n"
2832 "Lifetime value in seconds\n")
2833 {
2834 /* pfx vn un cost life */
2835 return register_add (vty, argv[11], argv[7], argv[9], NULL, argv[13],
2836 /* mac vni */
2837 argv[3], argv[5], 0, NULL);
2838 }
2839
2840 DEFUN (add_vnc_mac_vni_prefix_cost,
2841 add_vnc_mac_vni_prefix_cost_cmd,
2842 "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)",
2843 "Add registration\n"
2844 "VNC Information\n"
2845 "Add/modify mac address information\n"
2846 "MAC address\n"
2847 "Virtual Network Identifier follows\n"
2848 "Virtual Network Identifier\n"
2849 "VN address of NVE\n"
2850 "VN IPv4 interface address\n"
2851 "VN IPv6 interface address\n"
2852 "UN address of NVE\n"
2853 "UN IPv4 interface address\n"
2854 "UN IPv6 interface address\n"
2855 "Add/modify prefix related information\n"
2856 "IPv4 prefix\n"
2857 "IPv6 prefix\n"
2858 "Administrative cost [default: 255]\n" "Administrative cost\n")
2859 {
2860 /* pfx vn un cost life */
2861 return register_add (vty, argv[11], argv[7], argv[9], argv[13], NULL,
2862 /* mac vni */
2863 argv[3], argv[5], 0, NULL);
2864 }
2865
2866 DEFUN (add_vnc_mac_vni_prefix,
2867 add_vnc_mac_vni_prefix_cmd,
2868 "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>",
2869 "Add registration\n"
2870 "VNC Information\n"
2871 "Add/modify mac address information\n"
2872 "MAC address\n"
2873 "Virtual Network Identifier follows\n"
2874 "Virtual Network Identifier\n"
2875 "VN address of NVE\n"
2876 "VN IPv4 interface address\n"
2877 "VN IPv6 interface address\n"
2878 "UN address of NVE\n"
2879 "UN IPv4 interface address\n"
2880 "UN IPv6 interface address\n"
2881 "Add/modify prefix related information\n"
2882 "IPv4 prefix\n" "IPv6 prefix\n")
2883 {
2884 /* pfx vn un cost life */
2885 return register_add (vty, argv[11], argv[7], argv[9], NULL, NULL,
2886 /* mac vni */
2887 argv[3], argv[5], 0, NULL);
2888 }
2889
2890 DEFUN (add_vnc_mac_vni_cost_life,
2891 add_vnc_mac_vni_cost_life_cmd,
2892 "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)",
2893 "Add registration\n"
2894 "VNC Information\n"
2895 "Add/modify mac address information\n"
2896 "MAC address\n"
2897 "Virtual Network Identifier follows\n"
2898 "Virtual Network Identifier\n"
2899 "VN address of NVE\n"
2900 "VN IPv4 interface address\n"
2901 "VN IPv6 interface address\n"
2902 "UN address of NVE\n"
2903 "UN IPv4 interface address\n"
2904 "UN IPv6 interface address\n"
2905 "Administrative cost [default: 255]\n"
2906 "Administrative cost\n"
2907 "Registration lifetime [default: infinite]\n"
2908 "Lifetime value in seconds\n")
2909 {
2910 /* pfx vn un cost life */
2911 return register_add (vty, NULL, argv[7], argv[9], argv[11], argv[13],
2912 /* mac vni */
2913 argv[3], argv[5], 0, NULL);
2914 }
2915
2916
2917 DEFUN (add_vnc_mac_vni_cost,
2918 add_vnc_mac_vni_cost_cmd,
2919 "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)",
2920 "Add registration\n"
2921 "VNC Information\n"
2922 "Add/modify mac address information\n"
2923 "MAC address\n"
2924 "Virtual Network Identifier follows\n"
2925 "Virtual Network Identifier\n"
2926 "VN address of NVE\n"
2927 "VN IPv4 interface address\n"
2928 "VN IPv6 interface address\n"
2929 "UN address of NVE\n"
2930 "UN IPv4 interface address\n"
2931 "UN IPv6 interface address\n"
2932 "Administrative cost [default: 255]\n" "Administrative cost\n")
2933 {
2934 /* pfx vn un cost life */
2935 return register_add (vty, NULL, argv[7], argv[9], argv[11], NULL,
2936 /* mac vni */
2937 argv[3], argv[5], 0, NULL);
2938 }
2939
2940
2941 DEFUN (add_vnc_mac_vni_life,
2942 add_vnc_mac_vni_life_cmd,
2943 "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)",
2944 "Add registration\n"
2945 "VNC Information\n"
2946 "Add/modify mac address information\n"
2947 "MAC address\n"
2948 "Virtual Network Identifier follows\n"
2949 "Virtual Network Identifier\n"
2950 "VN address of NVE\n"
2951 "VN IPv4 interface address\n"
2952 "VN IPv6 interface address\n"
2953 "UN address of NVE\n"
2954 "UN IPv4 interface address\n"
2955 "UN IPv6 interface address\n"
2956 "Registration lifetime [default: infinite]\n"
2957 "Lifetime value in seconds\n")
2958 {
2959 /* pfx vn un cost life */
2960 return register_add (vty, NULL, argv[7], argv[9], NULL, argv[11],
2961 /* mac vni */
2962 argv[3], argv[5], 0, NULL);
2963 }
2964
2965
2966 DEFUN (add_vnc_mac_vni,
2967 add_vnc_mac_vni_cmd,
2968 "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>",
2969 "Add registration\n"
2970 "VNC Information\n"
2971 "Add/modify mac address information\n"
2972 "MAC address\n"
2973 "Virtual Network Identifier follows\n"
2974 "Virtual Network Identifier\n"
2975 "VN address of NVE\n"
2976 "VN IPv4 interface address\n"
2977 "VN IPv6 interface address\n"
2978 "UN address of NVE\n"
2979 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2980 {
2981 /* pfx vn un cost life */
2982 return register_add (vty, NULL, argv[7], argv[9], NULL, NULL,
2983 /* mac vni */
2984 argv[3], argv[5], 0, NULL);
2985 }
2986
2987 /************************************************************************
2988 * Delete prefix
2989 ************************************************************************/
2990
2991 struct rfapi_local_reg_delete_arg
2992 {
2993 /*
2994 * match parameters
2995 */
2996 struct bgp *bgp;
2997 struct rfapi_ip_addr un_address; /* AF==0: wildcard */
2998 struct rfapi_ip_addr vn_address; /* AF==0: wildcard */
2999 struct prefix prefix; /* AF==0: wildcard */
3000 struct prefix_rd rd; /* plen!=64: wildcard */
3001 struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */
3002
3003 struct rfapi_l2address_option_match l2o;
3004
3005 /*
3006 * result parameters
3007 */
3008 struct vty *vty;
3009 uint32_t reg_count;
3010 uint32_t pfx_count;
3011 uint32_t query_count;
3012
3013 uint32_t failed_pfx_count;
3014
3015 uint32_t nve_count;
3016 struct skiplist *nves;
3017
3018 uint32_t remote_active_nve_count;
3019 uint32_t remote_active_pfx_count;
3020 uint32_t remote_holddown_nve_count;
3021 uint32_t remote_holddown_pfx_count;
3022 };
3023
3024 struct nve_addr
3025 {
3026 struct rfapi_ip_addr vn;
3027 struct rfapi_ip_addr un;
3028 struct rfapi_descriptor *rfd;
3029 struct rfapi_local_reg_delete_arg *cda;
3030 };
3031
3032 static void
3033 nve_addr_free (void *hap)
3034 {
3035 ((struct nve_addr *) hap)->cda->nve_count += 1;
3036 XFREE (MTYPE_RFAPI_NVE_ADDR, hap);
3037 }
3038
3039 static int
3040 nve_addr_cmp (void *k1, void *k2)
3041 {
3042 struct nve_addr *a = (struct nve_addr *) k1;
3043 struct nve_addr *b = (struct nve_addr *) k2;
3044 int ret = 0;
3045
3046 if (!a || !b)
3047 {
3048 return (a - b);
3049 }
3050 if (a->un.addr_family != b->un.addr_family)
3051 {
3052 return (a->un.addr_family - b->un.addr_family);
3053 }
3054 if (a->vn.addr_family != b->vn.addr_family)
3055 {
3056 return (a->vn.addr_family - b->vn.addr_family);
3057 }
3058 if (a->un.addr_family == AF_INET)
3059 {
3060 ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4);
3061 if (ret != 0)
3062 {
3063 return ret;
3064 }
3065 }
3066 else if (a->un.addr_family == AF_INET6)
3067 {
3068 ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6);
3069 if (ret != 0)
3070 {
3071 return ret;
3072 }
3073 }
3074 else
3075 {
3076 assert (0);
3077 }
3078 if (a->vn.addr_family == AF_INET)
3079 {
3080 ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4);
3081 if (ret != 0)
3082 return ret;
3083 }
3084 else if (a->vn.addr_family == AF_INET6)
3085 {
3086 ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6);
3087 if (ret == 0)
3088 {
3089 return ret;
3090 }
3091 }
3092 else
3093 {
3094 assert (0);
3095 }
3096 return 0;
3097 }
3098
3099 static int
3100 parse_deleter_args (
3101 struct vty *vty,
3102 struct bgp *bgp,
3103 const char *arg_prefix,
3104 const char *arg_vn,
3105 const char *arg_un,
3106 const char *arg_l2addr,
3107 const char *arg_vni,
3108 const char *arg_rd,
3109 struct rfapi_nve_group_cfg *arg_rfg,
3110 struct rfapi_local_reg_delete_arg *rcdarg)
3111 {
3112 int rc = CMD_WARNING;
3113
3114 memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg));
3115
3116 rcdarg->vty = vty;
3117 if (bgp == NULL)
3118 bgp = bgp_get_default();
3119 rcdarg->bgp = bgp;
3120 rcdarg->rfg = arg_rfg; /* may be NULL */
3121
3122 if (arg_vn && strcmp (arg_vn, "*"))
3123 {
3124 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address)))
3125 return rc;
3126 }
3127 if (arg_un && strcmp (arg_un, "*"))
3128 {
3129 if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address)))
3130 return rc;
3131 }
3132 if (arg_prefix && strcmp (arg_prefix, "*"))
3133 {
3134
3135 if (!str2prefix (arg_prefix, &rcdarg->prefix))
3136 {
3137 vty_outln (vty, "Malformed prefix \"%s\"", arg_prefix);
3138 return rc;
3139 }
3140 }
3141
3142 if (arg_l2addr)
3143 {
3144 if (!arg_vni)
3145 {
3146 vty_outln (vty, "Missing VNI");
3147 return rc;
3148 }
3149 if (strcmp (arg_l2addr, "*"))
3150 {
3151 if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr)))
3152 {
3153 vty_outln (vty, "Malformed L2 Address \"%s\"",
3154 arg_l2addr);
3155 return rc;
3156 }
3157 rcdarg->l2o.flags |= RFAPI_L2O_MACADDR;
3158 }
3159 if (strcmp (arg_vni, "*"))
3160 {
3161 rcdarg->l2o.o.logical_net_id = strtoul(arg_vni, NULL, 10);
3162 rcdarg->l2o.flags |= RFAPI_L2O_LNI;
3163 }
3164 }
3165 if (arg_rd)
3166 {
3167 if (!str2prefix_rd (arg_rd, &rcdarg->rd))
3168 {
3169 vty_outln (vty, "Malformed RD \"%s\"",
3170 arg_rd);
3171 return rc;
3172 }
3173 }
3174
3175 return CMD_SUCCESS;
3176 }
3177
3178 static int
3179 parse_deleter_tokens (
3180 struct vty *vty,
3181 struct bgp *bgp,
3182 struct cmd_token *carg_prefix,
3183 struct cmd_token *carg_vn,
3184 struct cmd_token *carg_un,
3185 struct cmd_token *carg_l2addr,
3186 struct cmd_token *carg_vni,
3187 struct cmd_token *carg_rd,
3188 struct rfapi_nve_group_cfg *arg_rfg,
3189 struct rfapi_local_reg_delete_arg *rcdarg)
3190 {
3191 const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL;
3192 const char *arg_vn = carg_vn ? carg_vn->arg : NULL;
3193 const char *arg_un = carg_un ? carg_un->arg : NULL;
3194 const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL;
3195 const char *arg_vni = carg_vni ? carg_vni->arg : NULL;
3196 const char *arg_rd = carg_rd ? carg_rd->arg : NULL;
3197 return parse_deleter_args (vty, bgp,arg_prefix, arg_vn, arg_un,
3198 arg_l2addr, arg_vni, arg_rd,
3199 arg_rfg, rcdarg);
3200 }
3201
3202 static void
3203 record_nve_in_cda_list (
3204 struct rfapi_local_reg_delete_arg *cda,
3205 struct rfapi_ip_addr *un_address,
3206 struct rfapi_ip_addr *vn_address,
3207 struct rfapi_descriptor *rfd)
3208 {
3209 struct nve_addr ha;
3210 struct nve_addr *hap;
3211
3212 memset (&ha, 0, sizeof (ha));
3213 ha.un = *un_address;
3214 ha.vn = *vn_address;
3215 ha.rfd = rfd;
3216
3217 if (!cda->nves)
3218 cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
3219
3220 if (skiplist_search (cda->nves, &ha, (void *) &hap))
3221 {
3222 hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
3223 assert (hap);
3224 ha.cda = cda;
3225 * hap = ha;
3226 skiplist_insert (cda->nves, hap, hap);
3227 }
3228 }
3229
3230 static void
3231 clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda)
3232 {
3233 struct rfapi *h;
3234 struct rfapi_descriptor *rfd;
3235 int query_count = 0;
3236 struct listnode *node;
3237 struct bgp *bgp_default = bgp_get_default ();
3238
3239 if (cda->vn_address.addr_family && cda->un_address.addr_family)
3240 {
3241 /*
3242 * Single nve case
3243 */
3244 if (rfapi_find_rfd
3245 (bgp_default, &cda->vn_address, &cda->un_address, &rfd))
3246 return;
3247
3248 rfapiRibClear (rfd);
3249 rfapi_query_done_all (rfd, &query_count);
3250 cda->query_count += query_count;
3251
3252 /*
3253 * Track unique nves seen
3254 */
3255 record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
3256 return;
3257 }
3258
3259 /*
3260 * wildcard case
3261 */
3262
3263 if (!bgp_default)
3264 return; /* ENXIO */
3265
3266 h = bgp_default->rfapi;
3267
3268 if (!h)
3269 return; /* ENXIO */
3270
3271 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
3272 {
3273 /*
3274 * match un, vn addresses of NVEs
3275 */
3276 if (cda->un_address.addr_family &&
3277 rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr))
3278 {
3279 continue;
3280 }
3281 if (cda->vn_address.addr_family &&
3282 rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr))
3283 {
3284 continue;
3285 }
3286
3287 rfapiRibClear (rfd);
3288
3289 rfapi_query_done_all (rfd, &query_count);
3290 cda->query_count += query_count;
3291
3292 /*
3293 * Track unique nves seen
3294 */
3295 record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd);
3296 }
3297 }
3298
3299 /*
3300 * TBD need to count deleted prefixes and nves?
3301 *
3302 * ENXIO BGP or VNC not configured
3303 */
3304 static int
3305 rfapiDeleteLocalPrefixesByRFD (struct rfapi_local_reg_delete_arg *cda,
3306 struct rfapi_descriptor *rfd)
3307 {
3308 struct rfapi_ip_addr *pUn; /* NULL = wildcard */
3309 struct rfapi_ip_addr *pVn; /* NULL = wildcard */
3310 struct prefix *pPrefix; /* NULL = wildcard */
3311 struct prefix_rd *pPrd; /* NULL = wildcard */
3312
3313 struct rfapi_ip_prefix rprefix;
3314 struct rfapi_next_hop_entry *head = NULL;
3315 struct rfapi_next_hop_entry *tail = NULL;
3316
3317 #if DEBUG_L2_EXTRA
3318 vnc_zlog_debug_verbose ("%s: entry", __func__);
3319 #endif
3320
3321 pUn = (cda->un_address.addr_family ? &cda->un_address : NULL);
3322 pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL);
3323 pPrefix = (cda->prefix.family ? &cda->prefix : NULL);
3324 pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL);
3325
3326 if (pPrefix)
3327 {
3328 rfapiQprefix2Rprefix (pPrefix, &rprefix);
3329 }
3330
3331 do /* to preserve old code structure */
3332 {
3333 struct rfapi *h=cda->bgp->rfapi;;
3334 struct rfapi_adb *adb;
3335 int rc;
3336 int deleted_from_this_nve;
3337 struct nve_addr ha;
3338 struct nve_addr *hap;
3339
3340 #if DEBUG_L2_EXTRA
3341 vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd);
3342 #endif
3343
3344 /*
3345 * match un, vn addresses of NVEs
3346 */
3347 if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr)))
3348 continue;
3349 if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr)))
3350 continue;
3351
3352 #if DEBUG_L2_EXTRA
3353 vnc_zlog_debug_verbose ("%s: un, vn match", __func__);
3354 #endif
3355
3356 /*
3357 * match prefix
3358 */
3359
3360 deleted_from_this_nve = 0;
3361
3362 {
3363 struct skiplist *sl;
3364 struct rfapi_ip_prefix rp;
3365 void *cursor;
3366 struct list *adb_delete_list;
3367
3368 /*
3369 * The advertisements are stored in a skiplist. Withdrawing
3370 * the registration deletes the advertisement from the
3371 * skiplist, which we can't do while iterating over that
3372 * same skiplist using the current skiplist API.
3373 *
3374 * Strategy: iterate over the skiplist and build another
3375 * list containing only the matching ADBs. Then delete
3376 * _everything_ in that second list (which can be done
3377 * using either skiplists or quagga linklists).
3378 */
3379 adb_delete_list = list_new ();
3380
3381 /*
3382 * Advertised IP prefixes (not 0/32 or 0/128)
3383 */
3384 sl = rfd->advertised.ipN_by_prefix;
3385
3386 for (cursor = NULL,
3387 rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
3388 !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
3389 {
3390
3391 if (pPrefix)
3392 {
3393 if (!prefix_same (pPrefix, &adb->u.s.prefix_ip))
3394 {
3395 #if DEBUG_L2_EXTRA
3396 vnc_zlog_debug_verbose ("%s: adb=%p, prefix doesn't match, skipping",
3397 __func__, adb);
3398 #endif
3399 continue;
3400 }
3401 }
3402 if (pPrd)
3403 {
3404 if (memcmp(pPrd->val, adb->u.s.prd.val, 8) != 0)
3405 {
3406 #if DEBUG_L2_EXTRA
3407 vnc_zlog_debug_verbose ("%s: adb=%p, RD doesn't match, skipping",
3408 __func__, adb);
3409 #endif
3410 continue;
3411 }
3412 }
3413 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
3414 {
3415 if (memcmp
3416 (cda->l2o.o.macaddr.octet,
3417 adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN))
3418 {
3419 #if DEBUG_L2_EXTRA
3420 vnc_zlog_debug_verbose ("%s: adb=%p, macaddr doesn't match, skipping",
3421 __func__, adb);
3422 #endif
3423 continue;
3424 }
3425 }
3426
3427 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
3428 {
3429 if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
3430 {
3431 #if DEBUG_L2_EXTRA
3432 vnc_zlog_debug_verbose ("%s: adb=%p, LNI doesn't match, skipping",
3433 __func__, adb);
3434 #endif
3435 continue;
3436 }
3437 }
3438
3439 #if DEBUG_L2_EXTRA
3440 vnc_zlog_debug_verbose ("%s: ipN adding adb %p to delete list", __func__,
3441 adb);
3442 #endif
3443
3444 listnode_add (adb_delete_list, adb);
3445 }
3446
3447 struct listnode *node;
3448
3449 for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
3450 {
3451 int this_advertisement_prefix_count;
3452 struct rfapi_vn_option optary[3];
3453 struct rfapi_vn_option *opt = NULL;
3454 int cur_opt = 0;
3455
3456 this_advertisement_prefix_count = 1;
3457
3458 rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
3459
3460 memset (optary, 0, sizeof (optary));
3461
3462 /* if mac addr present in advert, make l2o vn option */
3463 if (adb->u.s.prefix_eth.family == AF_ETHERNET)
3464 {
3465 if (opt != NULL)
3466 opt->next = &optary[cur_opt];
3467 opt = &optary[cur_opt++];
3468 opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
3469 opt->v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth;
3470 ++this_advertisement_prefix_count;
3471 }
3472 /*
3473 * use saved RD value instead of trying to invert
3474 * complex RD computation in rfapi_register()
3475 */
3476 if (opt != NULL)
3477 opt->next = &optary[cur_opt];
3478 opt = &optary[cur_opt++];
3479 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
3480 opt->v.internal_rd = adb->u.s.prd;
3481
3482 #if DEBUG_L2_EXTRA
3483 vnc_zlog_debug_verbose ("%s: ipN killing reg from adb %p ", __func__, adb);
3484 #endif
3485
3486 rc = rfapi_register (rfd, &rp, 0, NULL,
3487 (cur_opt ? optary : NULL), RFAPI_REGISTER_KILL);
3488 if (!rc)
3489 {
3490 cda->pfx_count += this_advertisement_prefix_count;
3491 cda->reg_count += 1;
3492 deleted_from_this_nve = 1;
3493 }
3494 if (h->rfp_methods.local_cb)
3495 {
3496 rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr,
3497 &rp, 0, 0, NULL, &head, &tail);
3498 }
3499 }
3500 list_delete_all_node (adb_delete_list);
3501
3502 if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix)))
3503 {
3504 void *cursor;
3505
3506 /*
3507 * Caller didn't specify a prefix, or specified (0/32 or 0/128)
3508 */
3509
3510 /*
3511 * Advertised 0/32 and 0/128 (indexed by ethernet address)
3512 */
3513 sl = rfd->advertised.ip0_by_ether;
3514
3515 for (cursor = NULL,
3516 rc = skiplist_next (sl, NULL, (void **) &adb, &cursor);
3517 !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor))
3518 {
3519
3520 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
3521 {
3522 if (memcmp (cda->l2o.o.macaddr.octet,
3523 adb->u.s.prefix_eth.u.prefix_eth.octet,
3524 ETHER_ADDR_LEN))
3525 {
3526
3527 continue;
3528 }
3529 }
3530 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI))
3531 {
3532 if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id)
3533 {
3534 continue;
3535 }
3536 }
3537 #if DEBUG_L2_EXTRA
3538 vnc_zlog_debug_verbose ("%s: ip0 adding adb %p to delete list",
3539 __func__, adb);
3540 #endif
3541 listnode_add (adb_delete_list, adb);
3542 }
3543
3544
3545 for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb))
3546 {
3547
3548 struct rfapi_vn_option vn;
3549
3550 rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
3551
3552 memset (&vn, 0, sizeof (vn));
3553 vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
3554 vn.v.l2addr = adb->l2o;
3555
3556 #if DEBUG_L2_EXTRA
3557 vnc_zlog_debug_verbose ("%s: ip0 killing reg from adb %p ",
3558 __func__, adb);
3559 #endif
3560
3561 rc = rfapi_register (rfd, &rp, 0, NULL, &vn,
3562 RFAPI_REGISTER_KILL);
3563 if (!rc)
3564 {
3565 cda->pfx_count += 1;
3566 cda->reg_count += 1;
3567 deleted_from_this_nve = 1;
3568 }
3569 if (h->rfp_methods.local_cb)
3570 {
3571 struct rfapi_vn_option *vn_opt_new;
3572
3573 vn_opt_new = rfapi_vn_options_dup (&vn);
3574 rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr,
3575 &rfd->vn_addr, &rp, 0, 0,
3576 vn_opt_new, &head, &tail);
3577 }
3578 }
3579 list_delete_all_node (adb_delete_list);
3580 }
3581 list_delete (adb_delete_list);
3582 }
3583
3584
3585 if (head)
3586 { /* should not be set if (NULL == rfapi_cfg->local_cb) */
3587 h->flags |= RFAPI_INCALLBACK;
3588 (*h->rfp_methods.local_cb) (head, rfd->cookie);
3589 h->flags &= ~RFAPI_INCALLBACK;
3590 head = tail = NULL;
3591 }
3592
3593 if (deleted_from_this_nve)
3594 {
3595 /*
3596 * track unique NVEs seen
3597 */
3598 memset (&ha, 0, sizeof (ha));
3599 ha.un = rfd->un_addr;
3600 ha.vn = rfd->vn_addr;
3601
3602 if (!cda->nves)
3603 cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free);
3604 if (skiplist_search (cda->nves, &ha, (void **) &hap))
3605 {
3606 hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr));
3607 assert (hap);
3608 ha.cda = cda;
3609 *hap = ha;
3610 skiplist_insert (cda->nves, hap, hap);
3611 }
3612 }
3613 } while (0); /* to preserve old code structure */
3614
3615 return 0;
3616 }
3617
3618 static int
3619 rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
3620 {
3621 int rc = 0;
3622
3623 if (cda->rfg)
3624 {
3625 if (cda->rfg->rfd) /* if not open, nothing to delete */
3626 rc = rfapiDeleteLocalPrefixesByRFD (cda, cda->rfg->rfd);
3627 }
3628 else
3629 {
3630 struct bgp *bgp = cda->bgp;
3631 struct rfapi *h;
3632 struct rfapi_cfg *rfapi_cfg;
3633
3634 struct listnode *node;
3635 struct rfapi_descriptor *rfd;
3636 if (!bgp)
3637 return ENXIO;
3638 h = bgp->rfapi;
3639 rfapi_cfg = bgp->rfapi_cfg;
3640 if (!h || !rfapi_cfg)
3641 return ENXIO;
3642 vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__);
3643 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
3644 {
3645 rc = rfapiDeleteLocalPrefixesByRFD (cda, rfd);
3646 }
3647 }
3648 return rc;
3649 }
3650
3651 /*
3652 * clear_vnc_prefix
3653 *
3654 * Deletes local and remote prefixes that match
3655 */
3656 static void
3657 clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda)
3658 {
3659 struct prefix pfx_un;
3660 struct prefix pfx_vn;
3661
3662 struct prefix *pUN = NULL;
3663 struct prefix *pVN = NULL;
3664 struct prefix *pPrefix = NULL;
3665
3666 struct rfapi_import_table *it = NULL;
3667
3668 /*
3669 * Delete matching remote prefixes in holddown
3670 */
3671 if (cda->vn_address.addr_family)
3672 {
3673 if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn))
3674 pVN = &pfx_vn;
3675 }
3676 if (cda->un_address.addr_family)
3677 {
3678 if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un))
3679 pUN = &pfx_un;
3680 }
3681 if (cda->prefix.family)
3682 {
3683 pPrefix = &cda->prefix;
3684 }
3685 if (cda->rfg)
3686 {
3687 it = cda->rfg->rfapi_import_table;
3688 }
3689 rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, it,
3690 0, 1, &cda->remote_active_pfx_count,
3691 &cda->remote_active_nve_count,
3692 &cda->remote_holddown_pfx_count,
3693 &cda->remote_holddown_nve_count);
3694
3695 /*
3696 * Now do local prefixes
3697 */
3698 rfapiDeleteLocalPrefixes (cda);
3699 }
3700
3701 static void
3702 print_cleared_stats (struct rfapi_local_reg_delete_arg *cda)
3703 {
3704 struct vty *vty = cda->vty; /* for benefit of VTYNL */
3705
3706 /* Our special element-deleting function counts nves */
3707 if (cda->nves)
3708 {
3709 skiplist_free (cda->nves);
3710 cda->nves = NULL;
3711 }
3712 if (cda->failed_pfx_count)
3713 vty_outln (vty, "Failed to delete %d prefixes",
3714 cda->failed_pfx_count);
3715
3716 /* left as "prefixes" even in single case for ease of machine parsing */
3717 vty_outln (vty,
3718 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs",
3719 cda->reg_count, cda->pfx_count, cda->query_count,cda->nve_count);
3720
3721 /*
3722 * We don't currently allow deletion of active remote prefixes from
3723 * the command line
3724 */
3725
3726 vty_outln (vty, "[Holddown] Cleared %u prefixes from %u NVEs",
3727 cda->remote_holddown_pfx_count,cda->remote_holddown_nve_count);
3728 }
3729
3730 /*
3731 * Caller has already deleted registrations and queries for this/these
3732 * NVEs. Now we just have to close their descriptors.
3733 */
3734 static void
3735 clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda)
3736 {
3737 struct skiplist *sl = cda->nves; /* contains affected NVEs */
3738 struct nve_addr *pKey;
3739 struct nve_addr *pValue;
3740 void *cursor = NULL;
3741 int rc;
3742
3743 if (!sl)
3744 return;
3745
3746 for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor);
3747 !rc;
3748 rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor))
3749 {
3750
3751 if (pValue->rfd)
3752 {
3753 ((struct rfapi_descriptor *) pValue->rfd)->flags |=
3754 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY;
3755 rfapi_close (pValue->rfd);
3756 }
3757 }
3758 }
3759
3760 DEFUN (clear_vnc_nve_all,
3761 clear_vnc_nve_all_cmd,
3762 "clear vnc nve *",
3763 "clear\n"
3764 "VNC Information\n"
3765 "Clear per NVE information\n"
3766 "For all NVEs\n")
3767 {
3768
3769 struct rfapi_local_reg_delete_arg cda;
3770 int rc;
3771
3772 if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
3773 return rc;
3774
3775 cda.vty = vty;
3776
3777 clear_vnc_responses (&cda);
3778 clear_vnc_prefix (&cda);
3779 clear_vnc_nve_closer (&cda);
3780
3781 print_cleared_stats (&cda);
3782
3783 return 0;
3784 }
3785
3786 DEFUN (clear_vnc_nve_vn_un,
3787 clear_vnc_nve_vn_un_cmd,
3788 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3789 "clear\n"
3790 "VNC Information\n"
3791 "Clear prefix registration information\n"
3792 "VN address of NVE\n"
3793 "For all NVEs\n"
3794 "VN IPv4 interface address\n"
3795 "VN IPv6 interface address\n"
3796 "UN address of NVE\n"
3797 "For all UN addresses\n"
3798 "UN IPv4 interface address\n"
3799 "UN IPv6 interface address\n")
3800 {
3801 struct rfapi_local_reg_delete_arg cda;
3802 int rc;
3803
3804 if ((rc =
3805 parse_deleter_tokens (vty, NULL, NULL, argv[4], argv[6], NULL, NULL, NULL, NULL, &cda)))
3806 return rc;
3807
3808 cda.vty = vty;
3809
3810 clear_vnc_responses (&cda);
3811 clear_vnc_prefix (&cda);
3812 clear_vnc_nve_closer (&cda);
3813
3814 print_cleared_stats (&cda);
3815
3816 return 0;
3817 }
3818
3819 DEFUN (clear_vnc_nve_un_vn,
3820 clear_vnc_nve_un_vn_cmd,
3821 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3822 "clear\n"
3823 "VNC Information\n"
3824 "Clear prefix registration information\n"
3825 "UN address of NVE\n"
3826 "For all un NVEs\n"
3827 "UN IPv4 interface address\n"
3828 "UN IPv6 interface address\n"
3829 "VN address of NVE\n"
3830 "For all vn NVEs\n"
3831 "VN IPv4 interface address\n"
3832 "VN IPv6 interface address\n")
3833 {
3834 struct rfapi_local_reg_delete_arg cda;
3835 int rc;
3836
3837 if ((rc =
3838 parse_deleter_tokens (vty, NULL, NULL, argv[6], argv[4], NULL, NULL, NULL, NULL, &cda)))
3839 return rc;
3840
3841 cda.vty = vty;
3842
3843 clear_vnc_responses (&cda);
3844 clear_vnc_prefix (&cda);
3845 clear_vnc_nve_closer (&cda);
3846
3847 print_cleared_stats (&cda);
3848
3849 return 0;
3850 }
3851
3852 DEFUN (clear_vnc_nve_vn,
3853 clear_vnc_nve_vn_cmd,
3854 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3855 "clear\n"
3856 "VNC Information\n"
3857 "Clear prefix registration information\n"
3858 "VN address of NVE\n"
3859 "All addresses\n"
3860 "VN IPv4 interface address\n"
3861 "VN IPv6 interface address\n")
3862 {
3863 struct rfapi_local_reg_delete_arg cda;
3864 int rc;
3865
3866 if ((rc = parse_deleter_tokens (vty, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, NULL, &cda)))
3867 return rc;
3868
3869 cda.vty = vty;
3870
3871 clear_vnc_responses (&cda);
3872 clear_vnc_prefix (&cda);
3873 clear_vnc_nve_closer (&cda);
3874
3875 print_cleared_stats (&cda);
3876 return 0;
3877 }
3878
3879 DEFUN (clear_vnc_nve_un,
3880 clear_vnc_nve_un_cmd,
3881 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3882 "clear\n"
3883 "VNC Information\n"
3884 "Clear prefix registration information\n"
3885 "UN address of NVE\n"
3886 "All un nves\n"
3887 "UN IPv4 interface address\n"
3888 "UN IPv6 interface address\n")
3889 {
3890 struct rfapi_local_reg_delete_arg cda;
3891 int rc;
3892
3893 if ((rc = parse_deleter_tokens (vty, NULL, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, &cda)))
3894 return rc;
3895
3896 cda.vty = vty;
3897
3898 clear_vnc_responses (&cda);
3899 clear_vnc_prefix (&cda);
3900 clear_vnc_nve_closer (&cda);
3901
3902 print_cleared_stats (&cda);
3903 return 0;
3904 }
3905
3906 /*-------------------------------------------------
3907 * Clear VNC Prefix
3908 *-------------------------------------------------*/
3909
3910 /*
3911 * This function is defined in this file (rather than in rfp_registration.c)
3912 * because here we have access to all the task handles.
3913 */
3914 DEFUN (clear_vnc_prefix_vn_un,
3915 clear_vnc_prefix_vn_un_cmd,
3916 "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>",
3917 "clear\n"
3918 "VNC Information\n"
3919 "Clear prefix registration information\n"
3920 "All prefixes\n"
3921 "IPv4 prefix\n"
3922 "IPv6 prefix\n"
3923 "VN address of NVE\n"
3924 "All VN addresses\n"
3925 "VN IPv4 interface address\n"
3926 "VN IPv6 interface address\n"
3927 "UN address of NVE\n"
3928 "All UN addresses\n"
3929 "UN IPv4 interface address\n"
3930 "UN IPv6 interface address\n")
3931 {
3932 struct rfapi_local_reg_delete_arg cda;
3933 int rc;
3934
3935 if ((rc =
3936 parse_deleter_tokens (vty, NULL, argv[3], argv[5], argv[7], NULL, NULL, NULL, NULL, &cda)))
3937 return rc;
3938 cda.vty = vty;
3939 clear_vnc_prefix (&cda);
3940 print_cleared_stats (&cda);
3941 return 0;
3942 }
3943
3944 DEFUN (clear_vnc_prefix_un_vn,
3945 clear_vnc_prefix_un_vn_cmd,
3946 "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>",
3947 "clear\n"
3948 "VNC Information\n"
3949 "Clear prefix registration information\n"
3950 "All prefixes\n"
3951 "IPv4 prefix\n"
3952 "IPv6 prefix\n"
3953 "UN address of NVE\n"
3954 "All UN addresses\n"
3955 "UN IPv4 interface address\n"
3956 "UN IPv6 interface address\n"
3957 "VN address of NVE\n"
3958 "All VN addresses\n"
3959 "VN IPv4 interface address\n"
3960 "VN IPv6 interface address\n")
3961 {
3962 struct rfapi_local_reg_delete_arg cda;
3963 int rc;
3964
3965 if ((rc =
3966 parse_deleter_tokens (vty, NULL, argv[3], argv[7], argv[5], NULL, NULL, NULL, NULL, &cda)))
3967 return rc;
3968 cda.vty = vty;
3969 clear_vnc_prefix (&cda);
3970 print_cleared_stats (&cda);
3971 return 0;
3972 }
3973
3974 DEFUN (clear_vnc_prefix_un,
3975 clear_vnc_prefix_un_cmd,
3976 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3977 "clear\n"
3978 "VNC Information\n"
3979 "Clear prefix registration information\n"
3980 "All prefixes\n"
3981 "IPv4 prefix\n"
3982 "IPv6 prefix\n"
3983 "UN address of NVE\n"
3984 "All UN addresses\n"
3985 "UN IPv4 interface address\n"
3986 "UN IPv6 interface address\n")
3987 {
3988 struct rfapi_local_reg_delete_arg cda;
3989 int rc;
3990
3991 if ((rc =
3992 parse_deleter_tokens (vty, NULL, argv[3], NULL, argv[5], NULL, NULL, NULL, NULL, &cda)))
3993 return rc;
3994 cda.vty = vty;
3995 clear_vnc_prefix (&cda);
3996 print_cleared_stats (&cda);
3997 return 0;
3998 }
3999
4000 DEFUN (clear_vnc_prefix_vn,
4001 clear_vnc_prefix_vn_cmd,
4002 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
4003 "clear\n"
4004 "VNC Information\n"
4005 "Clear prefix registration information\n"
4006 "All prefixes\n"
4007 "IPv4 prefix\n"
4008 "IPv6 prefix\n"
4009 "UN address of NVE\n"
4010 "All VN addresses\n"
4011 "VN IPv4 interface address\n"
4012 "VN IPv6 interface address\n")
4013 {
4014 struct rfapi_local_reg_delete_arg cda;
4015 int rc;
4016
4017 if ((rc =
4018 parse_deleter_tokens (vty, NULL, argv[3], argv[5], NULL, NULL, NULL, NULL, NULL, &cda)))
4019 return rc;
4020 cda.vty = vty;
4021 clear_vnc_prefix (&cda);
4022 print_cleared_stats (&cda);
4023 return 0;
4024 }
4025
4026 DEFUN (clear_vnc_prefix_all,
4027 clear_vnc_prefix_all_cmd,
4028 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
4029 "clear\n"
4030 "VNC Information\n"
4031 "Clear prefix registration information\n"
4032 "All prefixes\n"
4033 "IPv4 prefix\n"
4034 "IPv6 prefix\n"
4035 "From any NVE\n")
4036 {
4037 struct rfapi_local_reg_delete_arg cda;
4038 int rc;
4039
4040 if ((rc = parse_deleter_tokens (vty, NULL, argv[3], NULL, NULL, NULL, NULL, NULL, NULL, &cda)))
4041 return rc;
4042 cda.vty = vty;
4043 clear_vnc_prefix (&cda);
4044 print_cleared_stats (&cda);
4045 return 0;
4046 }
4047
4048 /*-------------------------------------------------
4049 * Clear VNC MAC
4050 *-------------------------------------------------*/
4051
4052 /*
4053 * This function is defined in this file (rather than in rfp_registration.c)
4054 * because here we have access to all the task handles.
4055 */
4056 DEFUN (clear_vnc_mac_vn_un,
4057 clear_vnc_mac_vn_un_cmd,
4058 "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>",
4059 "clear\n"
4060 "VNC Information\n"
4061 "Clear mac registration information\n"
4062 "All macs\n"
4063 "MAC address\n"
4064 "VNI keyword\n"
4065 "Any virtual network identifier\n"
4066 "Virtual network identifier\n"
4067 "Virtual network identifier\n"
4068 "VN address of NVE\n"
4069 "All VN addresses\n"
4070 "VN IPv4 interface address\n"
4071 "VN IPv6 interface address\n"
4072 "UN address of NVE\n"
4073 "All UN addresses\n"
4074 "UN IPv4 interface address\n"
4075 "UN IPv6 interface address\n")
4076 {
4077 struct rfapi_local_reg_delete_arg cda;
4078 int rc;
4079
4080 /* pfx vn un L2 VNI */
4081 if ((rc =
4082 parse_deleter_tokens (vty, NULL, NULL, argv[7], argv[9], argv[3], argv[5],
4083 NULL, NULL, &cda)))
4084 return rc;
4085 cda.vty = vty;
4086 clear_vnc_prefix (&cda);
4087 print_cleared_stats (&cda);
4088 return 0;
4089 }
4090
4091 DEFUN (clear_vnc_mac_un_vn,
4092 clear_vnc_mac_un_vn_cmd,
4093 "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>",
4094 "clear\n"
4095 "VNC Information\n"
4096 "Clear mac registration information\n"
4097 "All macs\n"
4098 "MAC address\n"
4099 "VNI keyword\n"
4100 "Any virtual network identifier\n"
4101 "Virtual network identifier\n"
4102 "UN address of NVE\n"
4103 "All UN addresses\n"
4104 "UN IPv4 interface address\n"
4105 "UN IPv6 interface address\n"
4106 "VN address of NVE\n"
4107 "All VN addresses\n"
4108 "VN IPv4 interface address\n"
4109 "VN IPv6 interface address\n")
4110 {
4111 struct rfapi_local_reg_delete_arg cda;
4112 int rc;
4113
4114 /* pfx vn un L2 VNI */
4115 if ((rc =
4116 parse_deleter_tokens (vty, NULL, NULL, argv[9], argv[7], argv[3], argv[5],
4117 NULL, NULL, &cda)))
4118 return rc;
4119 cda.vty = vty;
4120 clear_vnc_prefix (&cda);
4121 print_cleared_stats (&cda);
4122 return 0;
4123 }
4124
4125 DEFUN (clear_vnc_mac_un,
4126 clear_vnc_mac_un_cmd,
4127 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
4128 "clear\n"
4129 "VNC Information\n"
4130 "Clear mac registration information\n"
4131 "All macs\n"
4132 "MAC address\n"
4133 "VNI keyword\n"
4134 "Any virtual network identifier\n"
4135 "Virtual network identifier\n"
4136 "UN address of NVE\n"
4137 "All UN addresses\n"
4138 "UN IPv4 interface address\n"
4139 "UN IPv6 interface address\n")
4140 {
4141 struct rfapi_local_reg_delete_arg cda;
4142 int rc;
4143
4144 /* pfx vn un L2 VNI */
4145 if ((rc =
4146 parse_deleter_tokens (vty, NULL, NULL, NULL, argv[7], argv[3], argv[5], NULL, NULL, &cda)))
4147 return rc;
4148 cda.vty = vty;
4149 clear_vnc_prefix (&cda);
4150 print_cleared_stats (&cda);
4151 return 0;
4152 }
4153
4154 DEFUN (clear_vnc_mac_vn,
4155 clear_vnc_mac_vn_cmd,
4156 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
4157 "clear\n"
4158 "VNC Information\n"
4159 "Clear mac registration information\n"
4160 "All macs\n"
4161 "MAC address\n"
4162 "VNI keyword\n"
4163 "Any virtual network identifier\n"
4164 "Virtual network identifier\n"
4165 "UN address of NVE\n"
4166 "All VN addresses\n"
4167 "VN IPv4 interface address\n"
4168 "VN IPv6 interface address\n")
4169 {
4170 struct rfapi_local_reg_delete_arg cda;
4171 int rc;
4172
4173 /* pfx vn un L2 VNI */
4174 if ((rc =
4175 parse_deleter_tokens (vty, NULL, NULL, argv[7], NULL, argv[3], argv[5], NULL, NULL, &cda)))
4176 return rc;
4177 cda.vty = vty;
4178 clear_vnc_prefix (&cda);
4179 print_cleared_stats (&cda);
4180 return 0;
4181 }
4182
4183 DEFUN (clear_vnc_mac_all,
4184 clear_vnc_mac_all_cmd,
4185 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
4186 "clear\n"
4187 "VNC Information\n"
4188 "Clear mac registration information\n"
4189 "All macs\n"
4190 "MAC address\n"
4191 "VNI keyword\n"
4192 "Any virtual network identifier\n"
4193 "Virtual network identifier\n"
4194 "From any NVE\n")
4195 {
4196 struct rfapi_local_reg_delete_arg cda;
4197 int rc;
4198
4199 /* pfx vn un L2 VNI */
4200 if ((rc =
4201 parse_deleter_tokens (vty, NULL, NULL, NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
4202 return rc;
4203 cda.vty = vty;
4204 clear_vnc_prefix (&cda);
4205 print_cleared_stats (&cda);
4206 return 0;
4207 }
4208
4209 /*-------------------------------------------------
4210 * Clear VNC MAC PREFIX
4211 *-------------------------------------------------*/
4212
4213 DEFUN (clear_vnc_mac_vn_un_prefix,
4214 clear_vnc_mac_vn_un_prefix_cmd,
4215 "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>",
4216 "clear\n"
4217 "VNC Information\n"
4218 "Clear mac registration information\n"
4219 "All macs\n"
4220 "MAC address\n"
4221 "VNI keyword\n"
4222 "Any virtual network identifier\n"
4223 "Virtual network identifier\n"
4224 "VN address of NVE\n"
4225 "All VN addresses\n"
4226 "VN IPv4 interface address\n"
4227 "VN IPv6 interface address\n"
4228 "UN address of NVE\n"
4229 "All UN addresses\n"
4230 "UN IPv4 interface address\n"
4231 "UN IPv6 interface address\n"
4232 "Clear prefix registration information\n"
4233 "All prefixes\n"
4234 "IPv4 prefix\n"
4235 "IPv6 prefix\n")
4236 {
4237 struct rfapi_local_reg_delete_arg cda;
4238 int rc;
4239
4240 /* pfx vn un L2 VNI */
4241 if ((rc =
4242 parse_deleter_tokens (vty, NULL, argv[11], argv[7], argv[9], argv[3], argv[5],
4243 NULL, NULL, &cda)))
4244 return rc;
4245 cda.vty = vty;
4246 clear_vnc_prefix (&cda);
4247 print_cleared_stats (&cda);
4248 return 0;
4249 }
4250
4251 DEFUN (clear_vnc_mac_un_vn_prefix,
4252 clear_vnc_mac_un_vn_prefix_cmd,
4253 "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>",
4254 "clear\n"
4255 "VNC Information\n"
4256 "Clear mac registration information\n"
4257 "All macs\n"
4258 "MAC address\n"
4259 "VNI keyword\n"
4260 "Any virtual network identifier\n"
4261 "Virtual network identifier\n"
4262 "UN address of NVE\n"
4263 "All UN addresses\n"
4264 "UN IPv4 interface address\n"
4265 "UN IPv6 interface address\n"
4266 "VN address of NVE\n"
4267 "All VN addresses\n"
4268 "VN IPv4 interface address\n"
4269 "VN IPv6 interface address\n"
4270 "Clear prefix registration information\n"
4271 "All prefixes\n"
4272 "IPv4 prefix\n"
4273 "IPv6 prefix\n"
4274 "Clear prefix registration information\n"
4275 "All prefixes\n"
4276 "IPv4 prefix\n"
4277 "IPv6 prefix\n")
4278 {
4279 struct rfapi_local_reg_delete_arg cda;
4280 int rc;
4281
4282 /* pfx vn un L2 VNI */
4283 if ((rc =
4284 parse_deleter_tokens (vty, NULL, argv[11], argv[9], argv[7], argv[3], argv[5],
4285 NULL, NULL, &cda)))
4286 return rc;
4287 cda.vty = vty;
4288 clear_vnc_prefix (&cda);
4289 print_cleared_stats (&cda);
4290 return 0;
4291 }
4292
4293 DEFUN (clear_vnc_mac_un_prefix,
4294 clear_vnc_mac_un_prefix_cmd,
4295 "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>",
4296 "clear\n"
4297 "VNC Information\n"
4298 "Clear mac registration information\n"
4299 "All macs\n"
4300 "MAC address\n"
4301 "VNI keyword\n"
4302 "Any virtual network identifier\n"
4303 "Virtual network identifier\n"
4304 "UN address of NVE\n"
4305 "All UN addresses\n"
4306 "UN IPv4 interface address\n"
4307 "UN IPv6 interface address\n"
4308 "Clear prefix registration information\n"
4309 "All prefixes\n"
4310 "IPv4 Prefix\n"
4311 "IPv6 Prefix\n")
4312 {
4313 struct rfapi_local_reg_delete_arg cda;
4314 int rc;
4315
4316 /* pfx vn un L2 VNI */
4317 if ((rc =
4318 parse_deleter_tokens (vty, NULL, argv[9], NULL, argv[7], argv[3], argv[5],
4319 NULL, NULL, &cda)))
4320 return rc;
4321 cda.vty = vty;
4322 clear_vnc_prefix (&cda);
4323 print_cleared_stats (&cda);
4324 return 0;
4325 }
4326
4327 DEFUN (clear_vnc_mac_vn_prefix,
4328 clear_vnc_mac_vn_prefix_cmd,
4329 "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>",
4330 "clear\n"
4331 "VNC Information\n"
4332 "Clear mac registration information\n"
4333 "All macs\n"
4334 "MAC address\n"
4335 "VNI keyword\n"
4336 "Any virtual network identifier\n"
4337 "Virtual network identifier\n"
4338 "UN address of NVE\n"
4339 "All VN addresses\n"
4340 "VN IPv4 interface address\n"
4341 "VN IPv6 interface address\n"
4342 "Clear prefix registration information\n"
4343 "All prefixes\n"
4344 "IPv4 Prefix\n"
4345 "IPv6 Prefix\n")
4346 {
4347 struct rfapi_local_reg_delete_arg cda;
4348 int rc;
4349
4350 /* pfx vn un L2 VNI */
4351 if ((rc =
4352 parse_deleter_tokens (vty, NULL, argv[9], argv[7], NULL, argv[3], argv[5],
4353 NULL, NULL, &cda)))
4354 return rc;
4355 cda.vty = vty;
4356 clear_vnc_prefix (&cda);
4357 print_cleared_stats (&cda);
4358 return 0;
4359 }
4360
4361 DEFUN (clear_vnc_mac_all_prefix,
4362 clear_vnc_mac_all_prefix_cmd,
4363 "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>",
4364 "clear\n"
4365 "VNC Information\n"
4366 "Clear mac registration information\n"
4367 "All macs\n"
4368 "MAC address\n"
4369 "VNI keyword\n"
4370 "Any virtual network identifier\n"
4371 "Virtual network identifier\n"
4372 "UN address of NVE\n"
4373 "All VN addresses\n"
4374 "VN IPv4 interface address\n"
4375 "VN IPv6 interface address\n")
4376 {
4377 struct rfapi_local_reg_delete_arg cda;
4378 int rc;
4379
4380 /* pfx vn un L2 VNI */
4381 if ((rc =
4382 parse_deleter_tokens (vty, NULL, argv[7], NULL, NULL, argv[3], argv[5], NULL, NULL, &cda)))
4383 return rc;
4384 cda.vty = vty;
4385 clear_vnc_prefix (&cda);
4386 print_cleared_stats (&cda);
4387 return 0;
4388 }
4389
4390 /************************************************************************
4391 * Show commands
4392 ************************************************************************/
4393
4394
4395 /* copied from rfp_vty.c */
4396 static int
4397 check_and_display_is_vnc_running (struct vty *vty)
4398 {
4399 if (!bgp_rfapi_is_vnc_configured (NULL))
4400 return 1; /* is running */
4401
4402 if (vty)
4403 {
4404 vty_outln (vty,
4405 "VNC is not configured. (There are no configured BGP VPN SAFI peers.)");
4406 }
4407 return 0; /* not running */
4408 }
4409
4410 static int
4411 rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type)
4412 {
4413 struct bgp *bgp_default = bgp_get_default ();
4414 struct rfapi *h;
4415 int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default);
4416
4417 int active_local_routes;
4418 int active_remote_routes;
4419 int holddown_remote_routes;
4420 int imported_remote_routes;
4421
4422 if (!bgp_default)
4423 goto notcfg;
4424
4425 h = bgp_default->rfapi;
4426
4427 if (!h)
4428 goto notcfg;
4429
4430 /* don't show local info if not running RFP */
4431 if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED)
4432 {
4433
4434 switch (show_type)
4435 {
4436
4437 case SHOW_NVE_SUMMARY_ACTIVE_NVES:
4438 vty_out (vty, "%-24s ", "NVEs:");
4439 vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count);
4440 vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors);
4441 vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves);
4442 break;
4443
4444 case SHOW_NVE_SUMMARY_REGISTERED:
4445 /*
4446 * NB: With the introduction of L2 route support, we no
4447 * longer have a one-to-one correspondence between
4448 * locally-originated route advertisements and routes in
4449 * the import tables that have local origin. This
4450 * discrepancy arises because a single advertisement
4451 * may contain both an IP prefix and a MAC address.
4452 * Such an advertisement results in two import table
4453 * entries: one indexed by IP prefix, the other indexed
4454 * by MAC address.
4455 *
4456 * TBD: update computation and display of registration
4457 * statistics to reflect the underlying semantics.
4458 */
4459 if (is_vnc_running)
4460 {
4461 vty_out (vty, "%-24s ", "Registrations:");
4462 vty_out (vty, "%-8s %-8u ", "Active:",
4463 rfapiApCountAll (bgp_default));
4464 vty_out (vty, "%-8s %-8u ", "Failed:",
4465 h->stat.count_registrations_failed);
4466 vty_out (vty, "%-8s %-8u", "Total:",
4467 h->stat.count_registrations);
4468 vty_out (vty, VTYNL);
4469 }
4470 vty_out (vty, "%-24s ", "Prefixes registered:");
4471 vty_out (vty, VTYNL);
4472
4473 rfapiCountAllItRoutes (&active_local_routes,
4474 &active_remote_routes,
4475 &holddown_remote_routes,
4476 &imported_remote_routes);
4477
4478 /* local */
4479 if (is_vnc_running)
4480 {
4481 vty_out (vty, " %-20s ", "Locally:");
4482 vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes);
4483 vty_out (vty, VTYNL);
4484 }
4485
4486
4487 vty_out (vty, " %-20s ", "Remotely:");
4488 vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes);
4489 vty_out (vty, VTYNL);
4490 vty_out (vty, " %-20s ", "In Holddown:");
4491 vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes);
4492 vty_out (vty, VTYNL);
4493 vty_out (vty, " %-20s ", "Imported:");
4494 vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes);
4495 break;
4496
4497 case SHOW_NVE_SUMMARY_QUERIES:
4498 vty_out (vty, "%-24s ", "Queries:");
4499 vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL));
4500 vty_out (vty, "%-8s %-8u ", "Failed:",
4501 h->stat.count_queries_failed);
4502 vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries);
4503 break;
4504
4505 case SHOW_NVE_SUMMARY_RESPONSES:
4506 rfapiRibShowResponsesSummary (vty);
4507
4508 default:
4509 break;
4510 }
4511 vty_out (vty, VTYNL);
4512 }
4513 return 0;
4514
4515 notcfg:
4516 vty_outln (vty, "VNC is not configured.");
4517 return CMD_WARNING;
4518 }
4519
4520 static int
4521 rfapi_show_nves (
4522 struct vty *vty,
4523 struct prefix *vn_prefix,
4524 struct prefix *un_prefix)
4525 {
4526 //struct hash *rfds;
4527 //struct rfp_rfapi_descriptor_param param;
4528
4529 struct bgp *bgp_default = bgp_get_default ();
4530 struct rfapi *h;
4531 struct listnode *node;
4532 struct rfapi_descriptor *rfd;
4533
4534 int total = 0;
4535 int printed = 0;
4536 int rc;
4537
4538 if (!bgp_default)
4539 goto notcfg;
4540
4541 h = bgp_default->rfapi;
4542
4543 if (!h)
4544 goto notcfg;
4545
4546 rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
4547 if (rc)
4548 return rc;
4549
4550 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
4551 {
4552 struct prefix pfx;
4553 char vn_addr_buf[INET6_ADDRSTRLEN] =
4554 {
4555 0,};
4556 char un_addr_buf[INET6_ADDRSTRLEN] =
4557 {
4558 0,};
4559 char age[10];
4560
4561 ++total;
4562
4563 if (vn_prefix)
4564 {
4565 assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx));
4566 if (!prefix_match (vn_prefix, &pfx))
4567 continue;
4568 }
4569
4570 if (un_prefix)
4571 {
4572 assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx));
4573 if (!prefix_match (un_prefix, &pfx))
4574 continue;
4575 }
4576
4577 rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN);
4578 rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN);
4579
4580 if (!printed)
4581 {
4582 /* print out a header */
4583 vty_outln (vty,
4584 " " "Active Next Hops");
4585 vty_outln (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s",
4586 "VN Address",
4587 "UN Address",
4588 "Regis", "Resps", "Reach", "Remove", "Age");
4589 }
4590
4591 ++printed;
4592
4593 vty_outln (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s",
4594 vn_addr_buf,
4595 un_addr_buf,
4596 rfapiApCount (rfd),
4597 rfapi_monitor_count (rfd),
4598 rfd->stat_count_nh_reachable,
4599 rfd->stat_count_nh_removal,
4600 rfapiFormatAge(rfd->open_time, age, 10));
4601 }
4602
4603 if (printed > 0 || vn_prefix || un_prefix)
4604 vty_outln (vty, "Displayed %d out of %d active NVEs",
4605 printed, total);
4606
4607 return 0;
4608
4609 notcfg:
4610 vty_outln (vty, "VNC is not configured.");
4611 return CMD_WARNING;
4612 }
4613
4614
4615 DEFUN (vnc_show_summary,
4616 vnc_show_summary_cmd,
4617 "show vnc summary",
4618 SHOW_STR
4619 VNC_SHOW_STR
4620 "Display VNC status summary\n")
4621 {
4622 if (!check_and_display_is_vnc_running (vty))
4623 return CMD_SUCCESS;
4624 bgp_rfapi_show_summary (bgp_get_default (), vty);
4625 vty_out (vty, VTYNL);
4626 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES);
4627 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4628 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES);
4629 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
4630 return CMD_SUCCESS;
4631 }
4632
4633 DEFUN (vnc_show_nves,
4634 vnc_show_nves_cmd,
4635 "show vnc nves",
4636 SHOW_STR
4637 VNC_SHOW_STR
4638 "List known NVEs\n")
4639 {
4640 rfapi_show_nves (vty, NULL, NULL);
4641 return CMD_SUCCESS;
4642 }
4643
4644 DEFUN (vnc_show_nves_ptct,
4645 vnc_show_nves_ptct_cmd,
4646 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4647 SHOW_STR
4648 VNC_SHOW_STR
4649 "List known NVEs\n"
4650 "VN address of NVE\n"
4651 "UN address of NVE\n"
4652 "IPv4 interface address\n"
4653 "IPv6 interface address\n")
4654 {
4655 struct prefix pfx;
4656
4657 if (!check_and_display_is_vnc_running (vty))
4658 return CMD_SUCCESS;
4659
4660 if (!str2prefix (argv[4]->arg, &pfx))
4661 {
4662 vty_outln (vty, "Malformed address \"%s\"", argv[4]->arg);
4663 return CMD_WARNING;
4664 }
4665 if (pfx.family != AF_INET && pfx.family != AF_INET6)
4666 {
4667 vty_outln (vty, "Invalid address \"%s\"", argv[4]->arg);
4668 return CMD_WARNING;
4669 }
4670
4671 if (argv[3]->arg[0] == 'u')
4672 {
4673 rfapi_show_nves (vty, NULL, &pfx);
4674 }
4675 else
4676 {
4677 rfapi_show_nves (vty, &pfx, NULL);
4678 }
4679
4680 return CMD_SUCCESS;
4681 }
4682
4683 /* adapted from rfp_registration_cache_log() */
4684 static void
4685 rfapi_show_registrations (
4686 struct vty *vty,
4687 struct prefix *restrict_to,
4688 int show_local,
4689 int show_remote,
4690 int show_holddown,
4691 int show_imported)
4692 {
4693 int printed = 0;
4694
4695 if (!vty)
4696 return;
4697
4698 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED);
4699
4700 if (show_local)
4701 {
4702 /* non-expiring, local */
4703 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0);
4704 }
4705 if (show_remote)
4706 {
4707 /* non-expiring, non-local */
4708 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0);
4709 }
4710 if (show_holddown)
4711 {
4712 /* expiring, including local */
4713 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0);
4714 }
4715 if (show_imported)
4716 {
4717 /* non-expiring, non-local */
4718 printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1);
4719 }
4720 if (!printed)
4721 {
4722 vty_out (vty, VTYNL);
4723 }
4724 }
4725
4726 DEFUN (vnc_show_registrations_pfx,
4727 vnc_show_registrations_pfx_cmd,
4728 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4729 SHOW_STR
4730 VNC_SHOW_STR
4731 "List active prefix registrations\n"
4732 "Limit output to a particular IPv4 prefix\n"
4733 "Limit output to a particular IPv6 prefix\n"
4734 "Limit output to a particular IPv6 address\n")
4735 {
4736 struct prefix p;
4737 struct prefix *p_addr = NULL;
4738
4739 if (argc > 3)
4740 {
4741 if (!str2prefix (argv[3]->arg, &p))
4742 {
4743 vty_outln (vty, "Invalid prefix: %s", argv[3]->arg);
4744 return CMD_SUCCESS;
4745 }
4746 else
4747 {
4748 p_addr = &p;
4749 }
4750 }
4751
4752 rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1);
4753 return CMD_SUCCESS;
4754 }
4755
4756 DEFUN (vnc_show_registrations_some_pfx,
4757 vnc_show_registrations_some_pfx_cmd,
4758 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4759 SHOW_STR
4760 VNC_SHOW_STR
4761 "List active prefix registrations\n"
4762 "show all registrations\n"
4763 "show only registrations in holddown\n"
4764 "show only imported prefixes\n"
4765 "show only local registrations\n"
4766 "show only remote registrations\n"
4767 "Limit output to a particular prefix or address\n"
4768 "Limit output to a particular prefix or address\n"
4769 "Limit output to a particular prefix or address\n")
4770 {
4771 struct prefix p;
4772 struct prefix *p_addr = NULL;
4773
4774 int show_local = 0;
4775 int show_remote = 0;
4776 int show_holddown = 0;
4777 int show_imported = 0;
4778
4779 if (argc > 4)
4780 {
4781 if (!str2prefix (argv[4]->arg, &p))
4782 {
4783 vty_outln (vty, "Invalid prefix: %s", argv[4]->arg);
4784 return CMD_SUCCESS;
4785 }
4786 else
4787 {
4788 p_addr = &p;
4789 }
4790 }
4791 switch (argv[3]->arg[0])
4792 {
4793 case 'a':
4794 show_local = 1;
4795 show_remote = 1;
4796 show_holddown = 1;
4797 show_imported = 1;
4798 break;
4799
4800 case 'h':
4801 show_holddown = 1;
4802 break;
4803
4804 case 'i':
4805 show_imported = 1;
4806 break;
4807
4808 case 'l':
4809 show_local = 1;
4810 break;
4811
4812 case 'r':
4813 show_remote = 1;
4814 break;
4815 }
4816
4817 rfapi_show_registrations (vty, p_addr,
4818 show_local, show_remote, show_holddown,
4819 show_imported);
4820 return CMD_SUCCESS;
4821 }
4822
4823 DEFUN (vnc_show_responses_pfx,
4824 vnc_show_responses_pfx_cmd,
4825 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4826 SHOW_STR
4827 VNC_SHOW_STR
4828 "List recent query responses\n"
4829 "Limit output to a particular IPv4 prefix\n"
4830 "Limit output to a particular IPv6 prefix\n"
4831 "Limit output to a particular IPv6 address\n" )
4832 {
4833 struct prefix p;
4834 struct prefix *p_addr = NULL;
4835
4836 if (argc > 3)
4837 {
4838 if (!str2prefix (argv[3]->arg, &p))
4839 {
4840 vty_outln (vty, "Invalid prefix: %s", argv[3]->arg);
4841 return CMD_SUCCESS;
4842 }
4843 else
4844 {
4845 p_addr = &p;
4846 }
4847 }
4848 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4849
4850 rfapiRibShowResponsesSummary (vty);
4851
4852 rfapiRibShowResponses (vty, p_addr, 0);
4853 rfapiRibShowResponses (vty, p_addr, 1);
4854
4855 return CMD_SUCCESS;
4856 }
4857
4858 DEFUN (vnc_show_responses_some_pfx,
4859 vnc_show_responses_some_pfx_cmd,
4860 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4861 SHOW_STR
4862 VNC_SHOW_STR
4863 "List recent query responses\n"
4864 "show only active query responses\n"
4865 "show only removed query responses\n"
4866 "Limit output to a particular IPv4 prefix\n"
4867 "Limit output to a particular IPv6 prefix\n"
4868 "Limit output to a particular IPV6 address\n")
4869 {
4870 struct prefix p;
4871 struct prefix *p_addr = NULL;
4872
4873 int show_active = 0;
4874 int show_removed = 0;
4875
4876 if (!check_and_display_is_vnc_running (vty))
4877 return CMD_SUCCESS;
4878
4879 if (argc > 4)
4880 {
4881 if (!str2prefix (argv[4]->arg, &p))
4882 {
4883 vty_outln (vty, "Invalid prefix: %s", argv[4]->arg);
4884 return CMD_SUCCESS;
4885 }
4886 else
4887 {
4888 p_addr = &p;
4889 }
4890 }
4891
4892 switch (argv[3]->arg[0])
4893 {
4894 case 'a':
4895 show_active = 1;
4896 break;
4897
4898 case 'r':
4899 show_removed = 1;
4900 break;
4901 }
4902
4903 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4904
4905 rfapiRibShowResponsesSummary (vty);
4906
4907 if (show_active)
4908 rfapiRibShowResponses (vty, p_addr, 0);
4909 if (show_removed)
4910 rfapiRibShowResponses (vty, p_addr, 1);
4911
4912 return CMD_SUCCESS;
4913 }
4914
4915 DEFUN (show_vnc_queries_pfx,
4916 show_vnc_queries_pfx_cmd,
4917 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4918 SHOW_STR
4919 VNC_SHOW_STR
4920 "List active queries\n"
4921 "Limit output to a particular IPv4 prefix or address\n"
4922 "Limit output to a particular IPv6 prefix\n"
4923 "Limit output to a particualr IPV6 address\n")
4924 {
4925 struct prefix pfx;
4926 struct prefix *p = NULL;
4927
4928 if (argc > 3)
4929 {
4930 if (!str2prefix (argv[3]->arg, &pfx))
4931 {
4932 vty_outln (vty, "Invalid prefix: %s", argv[3]->arg);
4933 return CMD_WARNING;
4934 }
4935 p = &pfx;
4936 }
4937
4938 rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES);
4939
4940 return rfapiShowVncQueries (vty, p);
4941 }
4942
4943 DEFUN (vnc_clear_counters,
4944 vnc_clear_counters_cmd,
4945 "clear vnc counters",
4946 CLEAR_STR
4947 VNC_SHOW_STR
4948 "Reset VNC counters\n")
4949 {
4950 struct bgp *bgp_default = bgp_get_default ();
4951 struct rfapi *h;
4952 struct listnode *node;
4953 struct rfapi_descriptor *rfd;
4954
4955 if (!bgp_default)
4956 goto notcfg;
4957
4958 h = bgp_default->rfapi;
4959
4960 if (!h)
4961 goto notcfg;
4962
4963 /* per-rfd */
4964 for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd))
4965 {
4966 rfd->stat_count_nh_reachable = 0;
4967 rfd->stat_count_nh_removal = 0;
4968 }
4969
4970 /* global */
4971 memset (&h->stat, 0, sizeof (h->stat));
4972
4973 /*
4974 * 151122 per bug 103, set count_registrations = number active.
4975 * Do same for queries
4976 */
4977 h->stat.count_registrations = rfapiApCountAll (bgp_default);
4978 h->stat.count_queries = rfapi_monitor_count (NULL);
4979
4980 rfapiRibShowResponsesSummaryClear ();
4981
4982 return CMD_SUCCESS;
4983
4984 notcfg:
4985 vty_outln (vty, "VNC is not configured.");
4986 return CMD_WARNING;
4987 }
4988
4989 /************************************************************************
4990 * Add prefix with vrf
4991 *
4992 * add [vrf <vrf-name>] prefix <prefix>
4993 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4994 ************************************************************************/
4995 static int
4996 vnc_add_vrf_prefix (struct vty *vty,
4997 const char *arg_vrf,
4998 const char *arg_prefix,
4999 const char *arg_rd, /* optional */
5000 const char *arg_label, /* optional */
5001 const char *arg_pref) /* optional */
5002 {
5003 struct bgp *bgp;
5004 struct rfapi_nve_group_cfg *rfg;
5005 struct prefix pfx;
5006 struct rfapi_ip_prefix rpfx;
5007 uint32_t pref = 0;
5008 struct rfapi_vn_option optary[3];
5009 struct rfapi_vn_option *opt = NULL;
5010 int cur_opt = 0;
5011
5012 bgp = bgp_get_default (); /* assume main instance for now */
5013 if (!bgp)
5014 {
5015 vty_outln (vty, "No BGP process is configured");
5016 return CMD_WARNING;
5017 }
5018 if (!bgp->rfapi || !bgp->rfapi_cfg)
5019 {
5020 vty_outln (vty, "VRF support not configured");
5021 return CMD_WARNING;
5022 }
5023
5024 rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
5025 /* arg checks */
5026 if (!rfg)
5027 {
5028 vty_outln (vty, "VRF \"%s\" appears not to be configured.",
5029 arg_vrf);
5030 return CMD_WARNING;
5031 }
5032 if (!rfg->rt_export_list || !rfg->rfapi_import_table)
5033 {
5034 vty_outln (vty, "VRF \"%s\" is missing RT import/export RT configuration.",
5035 arg_vrf);
5036 return CMD_WARNING;
5037 }
5038 if (!rfg->rd.family && !arg_rd)
5039 {
5040 vty_outln (vty, "VRF \"%s\" isn't configured with an RD, so RD must be provided.",
5041 arg_vrf);
5042 return CMD_WARNING;
5043 }
5044 if (rfg->label > MPLS_LABEL_MAX && !arg_label)
5045 {
5046 vty_outln (vty, "VRF \"%s\" isn't configured with a default labels, so a label must be provided.",
5047 arg_vrf);
5048 return CMD_WARNING;
5049 }
5050 if (!str2prefix (arg_prefix, &pfx))
5051 {
5052 vty_outln (vty, "Malformed prefix \"%s\"",
5053 arg_prefix);
5054 return CMD_WARNING;
5055 }
5056 rfapiQprefix2Rprefix (&pfx, &rpfx);
5057 memset (optary, 0, sizeof (optary));
5058 if (arg_rd)
5059 {
5060 if (opt != NULL)
5061 opt->next = &optary[cur_opt];
5062 opt = &optary[cur_opt++];
5063 opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
5064 if (!str2prefix_rd (arg_rd, &opt->v.internal_rd))
5065 {
5066 vty_outln (vty, "Malformed RD \"%s\"",
5067 arg_rd);
5068 return CMD_WARNING;
5069 }
5070 }
5071 if (rfg->label <= MPLS_LABEL_MAX || arg_label)
5072 {
5073 struct rfapi_l2address_option *l2o;
5074 if (opt != NULL)
5075 opt->next = &optary[cur_opt];
5076 opt = &optary[cur_opt++];
5077 opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR;
5078 l2o = &opt->v.l2addr;
5079 if (arg_label)
5080 {
5081 int32_t label;
5082 label = strtoul(arg_label, NULL, 10);
5083 l2o->label = label;
5084 }
5085 else
5086 l2o->label = rfg->label;
5087 }
5088 if (arg_pref)
5089 {
5090 char *endptr = NULL;
5091 pref = strtoul (arg_pref, &endptr, 10);
5092 if (*endptr != '\0')
5093 {
5094 vty_outln (vty, "%% Invalid local-preference value \"%s\"",
5095 arg_pref);
5096 return CMD_WARNING;
5097 }
5098 }
5099 rpfx.cost = 255 - (pref & 255) ;
5100 if (rfg->rfd == NULL) /* need new rfapi_handle */
5101 {
5102 /* based on rfapi_open */
5103 struct rfapi_descriptor *rfd;
5104 rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
5105 rfd->bgp = bgp;
5106 rfg->rfd = rfd;
5107 /* leave most fields empty as will get from (dynamic) config when needed */
5108 rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS;
5109 rfd->cookie = rfg;
5110 if (rfg->vn_prefix.family &&
5111 !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF))
5112 {
5113 rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr);
5114 }
5115 else
5116 {
5117 memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr));
5118 rfd->vn_addr.addr_family = AF_INET;
5119 rfd->vn_addr.addr.v4 = bgp->router_id;
5120 }
5121 rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for lookups */
5122 vnc_zlog_debug_verbose ("%s: Opening RFD for VRF %s",
5123 __func__, rfg->name);
5124 rfapi_init_and_open(bgp, rfd, rfg);
5125 }
5126
5127 if (!rfapi_register (rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL,
5128 (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD))
5129 {
5130 struct rfapi_next_hop_entry *head = NULL;
5131 struct rfapi_next_hop_entry *tail = NULL;
5132 struct rfapi_vn_option *vn_opt_new;
5133
5134 vnc_zlog_debug_verbose ("%s: rfapi_register succeeded", __func__);
5135
5136 if (bgp->rfapi->rfp_methods.local_cb)
5137 {
5138 struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfg->rfd;
5139 vn_opt_new = rfapi_vn_options_dup (opt);
5140
5141 rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx,
5142 1, RFAPI_INFINITE_LIFETIME,
5143 vn_opt_new, &head, &tail);
5144 if (head)
5145 {
5146 bgp->rfapi->flags |= RFAPI_INCALLBACK;
5147 (*bgp->rfapi->rfp_methods.local_cb) (head, r->cookie);
5148 bgp->rfapi->flags &= ~RFAPI_INCALLBACK;
5149 }
5150 head = tail = NULL;
5151 }
5152 vnc_zlog_debug_verbose ("%s completed, count=%d/%d", __func__,
5153 rfg->rfapi_import_table->local_count[AFI_IP],
5154 rfg->rfapi_import_table->local_count[AFI_IP6]);
5155 return CMD_SUCCESS;
5156 }
5157
5158 vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__);
5159 vty_outln (vty, "Add failed.");
5160 return CMD_WARNING;
5161 }
5162
5163 DEFUN (add_vrf_prefix_rd_label_pref,
5164 add_vrf_prefix_rd_label_pref_cmd,
5165 "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)}]",
5166 "Add\n"
5167 "To a VRF\n"
5168 "VRF name\n"
5169 "Add/modify prefix related information\n"
5170 "IPv4 prefix\n"
5171 "IPv6 prefix\n"
5172 "Override configured VRF Route Distinguisher\n"
5173 "<as-number>:<number> or <ip-address>:<number>\n"
5174 "Override configured VRF label\n"
5175 "Label Value <0-1048575>\n"
5176 "Set advertised local preference\n"
5177 "local preference (higher=more preferred)\n")
5178 {
5179 char *arg_vrf = argv[2]->arg;
5180 char *arg_prefix = argv[4]->arg;
5181 char *arg_rd = NULL; /* optional */
5182 char *arg_label = NULL; /* optional */
5183 char *arg_pref = NULL; /* optional */
5184 int pargc = 5;
5185 argc--; /* don't parse argument */
5186 while (pargc < argc)
5187 {
5188 switch (argv[pargc++]->arg[0])
5189 {
5190 case 'r':
5191 arg_rd = argv[pargc]->arg;
5192 break;
5193 case 'l':
5194 arg_label = argv[pargc]->arg;
5195 break;
5196 case 'p':
5197 arg_pref = argv[pargc]->arg;
5198 break;
5199 default:
5200 break;
5201 }
5202 pargc ++;
5203 }
5204
5205 return vnc_add_vrf_prefix (vty, arg_vrf, arg_prefix, arg_rd, arg_label, arg_pref);
5206 }
5207
5208 /************************************************************************
5209 * del prefix with vrf
5210 *
5211 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
5212 ************************************************************************/
5213 static int
5214 rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)
5215 {
5216 int count = 0;
5217 afi_t afi = AFI_MAX;
5218 while (afi-- > 0)
5219 {
5220 count += rfg->rfapi_import_table->local_count[afi];
5221 }
5222 return count;
5223 }
5224
5225 static void
5226 clear_vnc_vrf_closer (struct rfapi_nve_group_cfg *rfg)
5227 {
5228 struct rfapi_descriptor *rfd = rfg->rfd;
5229 afi_t afi;
5230
5231 if (rfd == NULL)
5232 return;
5233 /* check if IT is empty */
5234 for (afi = 0;
5235 afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0;
5236 afi++);
5237
5238 if (afi == AFI_MAX)
5239 {
5240 vnc_zlog_debug_verbose ("%s: closing RFD for VRF %s",
5241 __func__, rfg->name);
5242 rfg->rfd = NULL;
5243 rfapi_close(rfd);
5244 }
5245 else
5246 {
5247 vnc_zlog_debug_verbose ("%s: VRF %s afi=%d count=%d",
5248 __func__, rfg->name, afi,
5249 rfg->rfapi_import_table->local_count[afi]);
5250 }
5251 }
5252
5253 static int
5254 vnc_clear_vrf (struct vty *vty,
5255 struct bgp *bgp,
5256 const char *arg_vrf,
5257 const char *arg_prefix, /* NULL = all */
5258 const char *arg_rd) /* optional */
5259 {
5260 struct rfapi_nve_group_cfg *rfg;
5261 struct rfapi_local_reg_delete_arg cda;
5262 int rc;
5263 int start_count;
5264
5265 if (bgp == NULL)
5266 bgp = bgp_get_default (); /* assume main instance for now */
5267 if (!bgp)
5268 {
5269 vty_outln (vty, "No BGP process is configured");
5270 return CMD_WARNING;
5271 }
5272 if (!bgp->rfapi || !bgp->rfapi_cfg)
5273 {
5274 vty_outln (vty, "VRF support not configured");
5275 return CMD_WARNING;
5276 }
5277 rfg = bgp_rfapi_cfg_match_byname (bgp, arg_vrf, RFAPI_GROUP_CFG_VRF);
5278 /* arg checks */
5279 if (!rfg)
5280 {
5281 vty_outln (vty, "VRF \"%s\" appears not to be configured.",
5282 arg_vrf);
5283 return CMD_WARNING;
5284 }
5285 rc = parse_deleter_args (vty, bgp, arg_prefix, NULL, NULL, NULL, NULL,
5286 arg_rd, rfg, &cda);
5287 if (rc != CMD_SUCCESS) /* parse error */
5288 return rc;
5289
5290 start_count = rfapi_cfg_group_it_count(rfg);
5291 clear_vnc_prefix (&cda);
5292 clear_vnc_vrf_closer (rfg);
5293 vty_outln (vty, "Cleared %u out of %d prefixes.",
5294 cda.pfx_count, start_count);
5295 return CMD_SUCCESS;
5296 }
5297
5298 DEFUN (clear_vrf_prefix_rd,
5299 clear_vrf_prefix_rd_cmd,
5300 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:nn_or_IP-address]",
5301 "Clear stored data\n"
5302 "From a VRF\n"
5303 "VRF name\n"
5304 "Prefix related information\n"
5305 "IPv4 prefix\n"
5306 "IPv6 prefix\n"
5307 "Specific VRF Route Distinguisher\n"
5308 "<as-number>:<number> or <ip-address>:<number>\n")
5309 {
5310 char *arg_vrf = argv[2]->arg;
5311 char *arg_prefix = NULL; /* optional */
5312 char *arg_rd = NULL; /* optional */
5313 int pargc = 3;
5314 argc--; /* don't check parameter */
5315 while (pargc < argc)
5316 {
5317 switch (argv[pargc++]->arg[0])
5318 {
5319 case 'r':
5320 arg_rd = argv[pargc]->arg;
5321 break;
5322 case 'p':
5323 arg_prefix = argv[pargc]->arg;
5324 break;
5325 default:
5326 break;
5327 }
5328 pargc ++;
5329 }
5330 return vnc_clear_vrf (vty, NULL, arg_vrf, arg_prefix, arg_rd);
5331 }
5332
5333 DEFUN (clear_vrf_all,
5334 clear_vrf_all_cmd,
5335 "clear vrf NAME all",
5336 "Clear stored data\n"
5337 "From a VRF\n"
5338 "VRF name\n"
5339 "All prefixes\n")
5340 {
5341 char *arg_vrf = argv[2]->arg;
5342 return vnc_clear_vrf (vty, NULL, arg_vrf, NULL, NULL);
5343 }
5344
5345 void rfapi_vty_init ()
5346 {
5347 install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
5348 install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd);
5349 install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd);
5350 install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd);
5351 install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd);
5352
5353 install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd);
5354 install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd);
5355 install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd);
5356 install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd);
5357 install_element (ENABLE_NODE, &add_vnc_prefix_cmd);
5358
5359 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd);
5360 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd);
5361 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd);
5362 install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd);
5363 install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd);
5364 install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd);
5365 install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd);
5366 install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd);
5367
5368 install_element (ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd);
5369
5370 install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd);
5371 install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd);
5372 install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd);
5373 install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd);
5374 install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd);
5375
5376 install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd);
5377 install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd);
5378 install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd);
5379 install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd);
5380 install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd);
5381
5382 install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd);
5383 install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd);
5384 install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd);
5385 install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd);
5386 install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd);
5387
5388 install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd);
5389 install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd);
5390 install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd);
5391 install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd);
5392 install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd);
5393
5394 install_element (ENABLE_NODE, &clear_vrf_prefix_rd_cmd);
5395 install_element (ENABLE_NODE, &clear_vrf_all_cmd);
5396
5397 install_element (ENABLE_NODE, &vnc_clear_counters_cmd);
5398
5399 install_element (VIEW_NODE, &vnc_show_summary_cmd);
5400 install_element (VIEW_NODE, &vnc_show_nves_cmd);
5401 install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd);
5402
5403 install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd);
5404 install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd);
5405 install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd);
5406 install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd);
5407 install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd);
5408 }