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