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