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