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