3 * Copyright 2009-2016, LabN Consulting, L.L.C.
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.
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.
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
24 #include "lib/zebra.h"
25 #include "lib/prefix.h"
26 #include "lib/table.h"
28 #include "lib/memory.h"
29 #include "lib/routemap.h"
31 #include "lib/log_int.h"
32 #include "lib/linklist.h"
33 #include "lib/command.h"
35 #include "bgpd/bgpd.h"
36 #include "bgpd/bgp_ecommunity.h"
37 #include "bgpd/bgp_attr.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_mplsvpn.h"
41 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
42 #include "bgpd/rfapi/rfapi.h"
43 #include "bgpd/rfapi/rfapi_backend.h"
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"
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"
59 #define DEBUG_L2_EXTRA 0
60 #define DEBUG_SHOW_EXTRA 0
62 #define VNC_SHOW_STR "VNC information\n"
64 /* format related utilies */
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)
72 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
74 int year
, day
, hour
, min
;
76 if (seconds
>= FMT_YEAR
) {
77 year
= seconds
/ FMT_YEAR
;
78 seconds
-= year
* FMT_YEAR
;
82 if (seconds
>= FMT_DAY
) {
83 day
= seconds
/ FMT_DAY
;
84 seconds
-= day
* FMT_DAY
;
88 if (seconds
>= FMT_HOUR
) {
89 hour
= seconds
/ FMT_HOUR
;
90 seconds
-= hour
* FMT_HOUR
;
94 if (seconds
>= FMT_MIN
) {
95 min
= seconds
/ FMT_MIN
;
96 seconds
-= min
* FMT_MIN
;
101 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
102 } else if (day
> 0) {
103 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
105 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
111 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
113 time_t now
, age_adjusted
;
115 now
= rfapi_time(NULL
);
116 age_adjusted
= now
- age
;
118 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
123 * Reimplementation of quagga/lib/prefix.c function, but
124 * for RFAPI-style prefixes
126 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
132 static uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
133 0xf8, 0xfc, 0xfe, 0xff};
135 switch (rprefix
->prefix
.addr_family
) {
137 index
= rprefix
->length
/ 8;
139 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
140 offset
= rprefix
->length
% 8;
141 pnt
[index
] &= maskbit
[offset
];
149 index
= rprefix
->length
/ 8;
151 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
152 offset
= rprefix
->length
% 8;
153 pnt
[index
] &= maskbit
[offset
];
166 * translate a quagga prefix into a rfapi IP address. The
167 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
174 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
176 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
177 raddr
->addr_family
= qprefix
->family
;
178 switch (qprefix
->family
) {
180 if (qprefix
->prefixlen
!= 32)
182 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
185 if (qprefix
->prefixlen
!= 128)
187 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
196 * Translate Quagga prefix to RFAPI prefix
198 /* rprefix->cost set to 0 */
199 void rfapiQprefix2Rprefix(struct prefix
*qprefix
,
200 struct rfapi_ip_prefix
*rprefix
)
202 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
203 rprefix
->length
= qprefix
->prefixlen
;
204 rprefix
->prefix
.addr_family
= qprefix
->family
;
205 switch (qprefix
->family
) {
207 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
210 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
217 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
218 struct prefix
*qprefix
)
220 memset(qprefix
, 0, sizeof(struct prefix
));
221 qprefix
->prefixlen
= rprefix
->length
;
222 qprefix
->family
= rprefix
->prefix
.addr_family
;
224 switch (rprefix
->prefix
.addr_family
) {
226 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
229 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
238 * returns 1 if prefixes have same addr family, prefix len, and address
239 * Note that host bits matter in this comparison!
241 * For paralellism with quagga/lib/prefix.c. if we need a comparison
242 * where host bits are ignored, call that function rfapiRprefixCmp.
244 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
246 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
248 if (hp1
->length
!= hp2
->length
)
250 if (hp1
->prefix
.addr_family
== AF_INET
)
251 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
253 if (hp1
->prefix
.addr_family
== AF_INET6
)
254 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
259 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
261 memset(pfx
, 0, sizeof(struct prefix
));
262 pfx
->family
= hia
->addr_family
;
264 switch (hia
->addr_family
) {
267 pfx
->u
.prefix4
= hia
->addr
.v4
;
270 pfx
->prefixlen
= 128;
271 pfx
->u
.prefix6
= hia
->addr
.v6
;
279 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
281 memset(pfx
, 0, sizeof(struct prefix
));
282 pfx
->family
= AF_ETHERNET
;
284 pfx
->u
.prefix_eth
= l2o
->macaddr
;
287 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
289 return prefix_mac2str(ea
, buf
, bufsize
);
292 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
297 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
304 for (i
= 0; i
< 6; ++i
)
305 ea
->octet
[i
] = a
[i
] & 0xff;
310 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
312 if (af
== AF_ETHERNET
) {
313 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
316 return inet_ntop(af
, src
, buf
, size
);
319 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
322 va_start(args
, format
);
323 vzlog(LOG_DEBUG
, format
, args
);
328 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
333 va_start(args
, format
);
335 switch ((uintptr_t)stream
) {
346 vfprintf(file
, format
, args
);
351 /* Fake out for debug logging */
352 static struct vty vty_dummy_zlog
;
353 static struct vty vty_dummy_stdio
;
354 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
356 static const char *str_vty_newline(struct vty
*vty
)
358 if (vty
== &vty_dummy_zlog
)
363 int rfapiStream2Vty(void *stream
, /* input */
364 int (**fp
)(void *, const char *, ...), /* output */
365 struct vty
**vty
, /* output */
366 void **outstream
, /* output */
367 const char **vty_newline
) /* output */
371 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
372 *vty
= &vty_dummy_zlog
;
373 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
375 *vty_newline
= str_vty_newline(*vty
);
376 return (vzlog_test(LOG_DEBUG
));
379 if (((uintptr_t)stream
== (uintptr_t)1)
380 || ((uintptr_t)stream
== (uintptr_t)2)) {
382 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
383 *vty
= &vty_dummy_stdio
;
384 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
386 *vty_newline
= str_vty_newline(*vty
);
391 *vty
= stream
; /* VTYNL requires vty to be legit */
392 *fp
= (int (*)(void *, const char *, ...))vty_out
;
394 *vty_newline
= str_vty_newline(*vty
);
401 /* called from bgpd/bgp_vty.c'route_vty_out() */
402 void rfapi_vty_out_vncinfo(struct vty
*vty
, struct prefix
*p
,
403 struct bgp_info
*bi
, safi_t safi
)
409 * Print, on an indented line:
410 * UN address [if VPN route and VNC UN addr subtlv]
416 if (safi
== SAFI_MPLS_VPN
) {
417 struct prefix pfx_un
;
419 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
421 vty_out(vty
, "UN=%s",
422 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
427 if (bi
->attr
&& bi
->attr
->ecommunity
) {
428 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
429 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
430 vty_out(vty
, " EC{%s}", s
);
431 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
434 if (bi
->extra
!= NULL
)
435 vty_out(vty
, " label=%u", decode_label(&bi
->extra
->label
[0]));
437 if (!rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
438 vty_out(vty
, " life=%d", lifetime
);
441 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bi
->type
),
444 vty_out(vty
, "%s", HVTYNL
);
447 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
449 int (*fp
)(void *, const char *, ...);
452 const char *vty_newline
;
456 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
459 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
464 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
465 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
467 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
468 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
469 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
470 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
472 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
473 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
474 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
475 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
476 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
477 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
481 * Print BI in an Import Table
483 void rfapiPrintBi(void *stream
, struct bgp_info
*bi
)
488 int (*fp
)(void *, const char *, ...);
491 const char *vty_newline
;
497 struct ethaddr macaddr
= {{0}};
498 struct rfapi_l2address_option l2o_buf
;
499 uint8_t l2hid
= 0; /* valid if has_macaddr */
501 #define REMAIN (BUFSIZ - (p-line))
502 #define INCP {p += (r > REMAIN)? REMAIN: r;}
504 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
510 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
511 && bi
->extra
->vnc
.import
.timer
) {
512 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
513 r
= snprintf(p
, REMAIN
, " [%4lu] ",
514 thread_timer_remain_second(t
));
518 r
= snprintf(p
, REMAIN
, " ");
523 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
524 if (decode_rd_type(bi
->extra
->vnc
.import
.rd
.val
)
525 == RD_TYPE_VNC_ETH
) {
527 memcpy(macaddr
.octet
, bi
->extra
->vnc
.import
.rd
.val
+ 2,
529 l2hid
= bi
->extra
->vnc
.import
.rd
.val
[1];
538 * RFP option sizes (they are opaque values)
539 * extended communities (RTs)
543 int printed_1st_gol
= 0;
544 struct bgp_attr_encap_subtlv
*pEncap
;
545 struct prefix pfx_un
;
546 int af
= BGP_MP_NEXTHOP_FAMILY(bi
->attr
->mp_nexthop_len
);
550 r
= snprintf(p
, REMAIN
, "%s",
552 &bi
->attr
->mp_nexthop_global_in
,
555 } else if (af
== AF_INET6
) {
556 r
= snprintf(p
, REMAIN
, "%s",
558 &bi
->attr
->mp_nexthop_global
,
562 r
= snprintf(p
, REMAIN
, "?");
567 * VNC tunnel subtlv, if present, contains UN address
569 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
570 r
= snprintf(p
, REMAIN
, " un=%s",
571 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
577 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
578 r
= snprintf(p
, REMAIN
, " nolife");
581 if (lifetime
== 0xffffffff)
582 r
= snprintf(p
, REMAIN
, " %6s", "infini");
584 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
588 /* RFP option lengths */
589 for (pEncap
= bi
->attr
->vnc_subtlvs
; pEncap
;
590 pEncap
= pEncap
->next
) {
592 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
593 if (printed_1st_gol
) {
594 r
= snprintf(p
, REMAIN
, ",");
597 r
= snprintf(p
, REMAIN
,
598 " "); /* leading space */
601 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
608 if (bi
->attr
->ecommunity
) {
609 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
610 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
611 r
= snprintf(p
, REMAIN
, " %s", s
);
613 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
617 r
= snprintf(p
, REMAIN
, " bi@%p", bi
);
620 r
= snprintf(p
, REMAIN
, " p@%p", bi
->peer
);
623 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
624 r
= snprintf(p
, REMAIN
, " HD=yes");
627 r
= snprintf(p
, REMAIN
, " HD=no");
633 if (bi
->attr
->weight
) {
634 r
= snprintf(p
, REMAIN
, " W=%d", bi
->attr
->weight
);
638 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
639 r
= snprintf(p
, REMAIN
, " LP=%d", bi
->attr
->local_pref
);
642 r
= snprintf(p
, REMAIN
, " LP=unset");
647 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bi
->type
),
651 fp(out
, "%s%s", line
, HVTYNL
);
654 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
655 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
656 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
660 if (!rfapiGetL2o(bi
->attr
, &l2o_buf
)) {
662 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
663 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
664 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
665 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
666 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
669 if (bi
->extra
&& bi
->extra
->vnc
.import
.aux_prefix
.family
) {
673 sp
= rfapi_ntop(bi
->extra
->vnc
.import
.aux_prefix
.family
,
674 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
, buf
,
678 fp(out
, " IP: %s%s", sp
, HVTYNL
);
682 struct rfapi_un_option
*uo
=
683 rfapi_encap_tlv_to_un_option(bi
->attr
);
685 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
686 rfapi_un_options_free(uo
);
691 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
693 char buf_pfx
[BUFSIZ
];
698 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
699 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
701 rc
= snprintf(buf
, size
,
702 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
703 m
->next
, m
->rfd
, buf_vn
, buf_un
,
704 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
705 m
->p
.prefixlen
, m
->node
);
712 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
716 int (*fp
)(void *, const char *, ...);
719 const char *vty_newline
;
721 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
724 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
725 fp(out
, " Mon %s%s", buf
, HVTYNL
);
728 static void rfapiDebugPrintMonitorEncap(void *stream
,
729 struct rfapi_monitor_encap
*m
)
731 int (*fp
)(void *, const char *, ...);
734 const char *vty_newline
;
736 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
739 fp(out
, " Mon m=%p, next=%p, node=%p, bi=%p%s", m
, m
->next
, m
->node
,
743 void rfapiShowItNode(void *stream
, struct route_node
*rn
)
748 int (*fp
)(void *, const char *, ...);
751 const char *vty_newline
;
753 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
756 fp(out
, "%s/%d @%p #%d%s",
757 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
),
758 rn
->p
.prefixlen
, rn
, rn
->lock
, HVTYNL
);
760 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
761 rfapiPrintBi(stream
, bi
);
764 /* doesn't show montors */
767 void rfapiShowImportTable(void *stream
, const char *label
,
768 struct route_table
*rt
, int isvpn
)
770 struct route_node
*rn
;
773 int (*fp
)(void *, const char *, ...);
776 const char *vty_newline
;
778 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
781 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
783 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
786 if (rn
->p
.family
== AF_ETHERNET
) {
787 rfapiEthAddr2Str(&rn
->p
.u
.prefix_eth
, buf
, BUFSIZ
);
789 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
);
792 fp(out
, "%s/%d @%p #%d%s", buf
, rn
->p
.prefixlen
, rn
,
793 rn
->lock
- 1, /* account for loop iterator locking */
796 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
797 rfapiPrintBi(stream
, bi
);
801 struct rfapi_monitor_vpn
*m
;
802 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
803 rfapiDebugPrintMonitorVpn(stream
, m
);
806 struct rfapi_monitor_encap
*m
;
807 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
808 rfapiDebugPrintMonitorEncap(stream
, m
);
814 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
818 struct listnode
*node
;
819 struct rfapi_descriptor
*rfd
;
821 int (*fp
)(void *, const char *, ...);
824 const char *vty_newline
;
826 int printedheader
= 0;
829 int nves_with_queries
= 0;
830 int nves_displayed
= 0;
832 int queries_total
= 0;
833 int queries_displayed
= 0;
835 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
838 bgp
= bgp_get_default(); /* assume 1 instance for now */
840 vty_out(vty
, "No BGP instance\n");
846 vty_out(vty
, "No RFAPI instance\n");
850 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
852 struct route_node
*rn
;
853 int printedquerier
= 0;
859 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
869 for (rn
= route_top(rfd
->mon
); rn
;
870 rn
= route_next(rn
)) {
871 struct rfapi_monitor_vpn
*m
;
872 char buf_remain
[BUFSIZ
];
873 char buf_pfx
[BUFSIZ
];
883 && !prefix_match(pfx_match
, &rn
->p
)
884 && !prefix_match(&rn
->p
, pfx_match
))
889 if (!printedheader
) {
892 fp(out
, "%-15s %-15s %-15s %-10s\n",
893 "VN Address", "UN Address", "Target",
897 if (!printedquerier
) {
901 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
903 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
906 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
911 fp(out
, "%-15s %-15s", "", "");
915 thread_timer_remain_second(
919 fp(out
, " %-15s %-10s\n",
920 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
929 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
933 struct rfapi_monitor_eth
*mon_eth
;
936 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
937 (void **)&mon_eth
, &cursor
);
939 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
940 (void **)&mon_eth
, &cursor
)) {
942 char buf_remain
[BUFSIZ
];
943 char buf_pfx
[BUFSIZ
];
944 struct prefix pfx_mac
;
948 vnc_zlog_debug_verbose(
949 "%s: checking rfd=%p mon_eth=%p",
950 __func__
, rfd
, mon_eth
);
952 memset((void *)&pfx_mac
, 0,
953 sizeof(struct prefix
));
954 pfx_mac
.family
= AF_ETHERNET
;
955 pfx_mac
.prefixlen
= 48;
956 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
959 && !prefix_match(pfx_match
, &pfx_mac
)
960 && !prefix_match(&pfx_mac
, pfx_match
))
965 if (!printedheader
) {
969 "%-15s %-15s %-17s %10s %-10s\n",
970 "VN Address", "UN Address", "Target",
974 if (!printedquerier
) {
978 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
980 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
983 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
988 fp(out
, "%-15s %-15s", "", "");
990 if (mon_eth
->timer
) {
992 thread_timer_remain_second(
996 fp(out
, " %-17s %10d %-10s\n",
997 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
999 mon_eth
->logical_net_id
, buf_remain
);
1004 if (queries_total
) {
1006 fp(out
, "Displayed %d out of %d total queries\n",
1007 queries_displayed
, queries_total
);
1012 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1013 struct route_node
*rn
, struct bgp_info
*bi
)
1015 int (*fp
)(void *, const char *, ...);
1018 const char *vty_newline
;
1019 struct prefix pfx_un
;
1020 struct prefix pfx_vn
;
1023 bgp_encap_types tun_type
;
1025 char buf_pfx
[BUFSIZ
];
1026 char buf_ntop
[BUFSIZ
];
1027 char buf_un
[BUFSIZ
];
1028 char buf_vn
[BUFSIZ
];
1029 char buf_lifetime
[BUFSIZ
];
1033 return 0; /* for debug log, print into buf & call output once */
1035 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1042 snprintf(buf_pfx
, BUFSIZ
, "%s/%d",
1043 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf_ntop
, BUFSIZ
),
1045 buf_pfx
[BUFSIZ
- 1] = 0;
1052 if (!rfapiGetUnAddrOfVpnBi(bi
, &pfx_un
)) {
1053 snprintf(buf_un
, BUFSIZ
, "%s",
1054 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1058 rfapiGetTunnelType(bi
->attr
, &tun_type
);
1063 rfapiNexthop2Prefix(bi
->attr
, &pfx_vn
);
1064 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1065 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1067 snprintf(buf_un
, BUFSIZ
, "%s",
1068 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1071 u_int32_t l
= decode_label(&bi
->extra
->label
[0]);
1072 snprintf(buf_vn
, BUFSIZ
, "Label: %d", l
);
1073 } else /* should never happen */
1075 snprintf(buf_vn
, BUFSIZ
, "Label: N/A");
1078 snprintf(buf_vn
, BUFSIZ
, "%s",
1079 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1082 buf_vn
[BUFSIZ
- 1] = 0;
1083 buf_un
[BUFSIZ
- 1] = 0;
1086 * Cost is encoded in local_pref as (255-cost)
1087 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1091 uint32_t local_pref
;
1092 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1093 local_pref
= bi
->attr
->local_pref
;
1096 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1101 fp(out
, "%-20s ", buf_pfx
);
1102 fp(out
, "%-15s ", buf_vn
);
1103 fp(out
, "%-15s ", buf_un
);
1104 fp(out
, "%-4d ", cost
);
1107 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1108 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)
1109 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1111 fp(out
, "%-10s ", "infinite");
1113 time_t t_lifetime
= lifetime
;
1114 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1115 fp(out
, "%-10s ", buf_lifetime
);
1118 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
1119 && bi
->extra
->vnc
.import
.timer
) {
1123 char buf_age
[BUFSIZ
];
1125 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
1126 remaining
= thread_timer_remain_second(t
);
1128 #if RFAPI_REGISTRATIONS_REPORT_AGE
1130 * Calculate when the timer started. Doing so here saves
1131 * us a timestamp field in "struct bgp_info".
1133 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1134 * original calculation.
1136 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1138 #else /* report remaining time */
1141 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1143 fp(out
, "%-10s ", buf_age
);
1145 } else if (RFAPI_LOCAL_BI(bi
)) {
1147 char buf_age
[BUFSIZ
];
1149 if (bi
->extra
&& bi
->extra
->vnc
.import
.create_time
) {
1150 rfapiFormatAge(bi
->extra
->vnc
.import
.create_time
,
1156 fp(out
, "%-10s ", buf_age
);
1158 fp(out
, "%s", HVTYNL
);
1160 if (rn
->p
.family
== AF_ETHERNET
) {
1162 * If there is a corresponding IP address && != VN address,
1163 * print that on the next line
1167 && bi
->extra
->vnc
.import
.aux_prefix
.family
) {
1171 bi
->extra
->vnc
.import
.aux_prefix
.family
,
1172 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1174 buf_ntop
[BUFSIZ
- 1] = 0;
1176 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1177 fp(out
, " IP: %s", sp
);
1183 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bi
->extra
) {
1184 u_int32_t l
= decode_label(&bi
->extra
->label
[0]);
1185 if (!MPLS_LABEL_IS_NULL(l
)) {
1186 fp(out
, " Label: %d", l
);
1192 fp(out
, "%s", HVTYNL
);
1197 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1198 struct rfapi_import_table
*it
,
1199 struct prefix
*prefix_only
,
1200 int show_expiring
, /* either/or */
1201 int show_local
, int show_remote
,
1202 int show_imported
, /* either/or */
1203 uint32_t *pLni
) /* AFI_L2VPN only */
1206 int printed_rtlist_hdr
= 0;
1208 int (*fp
)(void *, const char *, ...);
1211 const char *vty_newline
;
1215 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1218 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1220 struct route_node
*rn
;
1222 if (!it
->imported_vpn
[afi
])
1225 for (rn
= route_top(it
->imported_vpn
[afi
]); rn
;
1226 rn
= route_next(rn
)) {
1228 struct bgp_info
*bi
;
1231 /* allow for wider or more narrow mask from user */
1232 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1233 && !prefix_match(&rn
->p
, prefix_only
))
1238 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
1240 if (!show_local
&& RFAPI_LOCAL_BI(bi
)) {
1242 /* local route from RFP */
1246 if (!show_remote
&& !RFAPI_LOCAL_BI(bi
)) {
1253 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1257 && CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1260 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1261 || bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1270 if (count_only
== 1)
1272 if (!printed_rtlist_hdr
) {
1273 const char *agetype
= "";
1275 const char *type
= "";
1276 if (show_imported
) {
1279 if (show_expiring
) {
1291 s
= ecommunity_ecom2str(
1293 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1297 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1298 HVTYNL
, type
, *pLni
,
1299 (*pLni
& 0xfff), s
);
1301 fp(out
, "%s[%s] Prefix RT={%s}",
1304 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1306 if (it
->rfg
&& it
->rfg
->name
) {
1307 fp(out
, " %s \"%s\"",
1308 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1313 fp(out
, "%s", HVTYNL
);
1314 if (show_expiring
) {
1315 #if RFAPI_REGISTRATIONS_REPORT_AGE
1318 agetype
= "Remaining";
1320 } else if (show_local
) {
1324 printed_rtlist_hdr
= 1;
1327 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1328 (pLni
? "L2 Address/IP" : "Prefix"),
1329 "VN Address", "UN Address", "Cost",
1330 "Lifetime", agetype
, HVTYNL
);
1332 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1340 const char *type
= "prefixes";
1342 if (show_imported
) {
1343 type
= "imported prefixes";
1345 if (show_expiring
) {
1346 type
= "prefixes in holddown";
1348 if (show_local
&& !show_remote
) {
1349 type
= "locally registered prefixes";
1350 } else if (!show_local
&& show_remote
) {
1351 type
= "remotely registered prefixes";
1356 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1358 #if DEBUG_SHOW_EXTRA
1359 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1367 * rfapiShowRemoteRegistrations
1369 * Similar to rfapiShowImportTable() above. This function
1370 * is mean to produce the "remote" portion of the output
1371 * of "show vnc registrations".
1373 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1374 int show_expiring
, int show_local
,
1375 int show_remote
, int show_imported
)
1379 struct rfapi_import_table
*it
;
1382 bgp
= bgp_get_default();
1392 for (it
= h
->imports
; it
; it
= it
->next
) {
1393 printed
+= rfapiShowRemoteRegistrationsIt(
1394 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1395 show_remote
, show_imported
, NULL
);
1398 if (h
->import_mac
) {
1399 void *cursor
= NULL
;
1401 uintptr_t lni_as_ptr
;
1405 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1406 (void **)&it
, &cursor
);
1408 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1409 (void **)&it
, &cursor
)) {
1411 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1412 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1416 printed
+= rfapiShowRemoteRegistrationsIt(
1417 bgp
, stream
, it
, prefix_only
, show_expiring
,
1418 show_local
, show_remote
, show_imported
, pLni
);
1425 /*------------------------------------------
1426 * rfapiRfapiIpAddr2Str
1428 * UI helper: generate string from rfapi_ip_addr
1431 * a IP v4/v6 address
1434 * buf put string here
1435 * bufsize max space to write
1438 * NULL conversion failed
1439 * non-NULL pointer to buf
1440 --------------------------------------------*/
1441 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1444 const char *rc
= NULL
;
1446 switch (a
->addr_family
) {
1448 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1451 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1457 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1460 const char *rc
= NULL
;
1462 int (*fp
)(void *, const char *, ...);
1465 const char *vty_newline
;
1467 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1470 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1476 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1479 struct rfapi_ip_addr
*a
= &p
->prefix
;
1480 const char *rc
= NULL
;
1482 switch (a
->addr_family
) {
1484 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1487 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1492 int alen
= strlen(buf
);
1493 int remaining
= bufsize
- alen
- 1;
1496 if (remaining
> 0) {
1497 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1499 if (slen
< remaining
) /* see man page for snprintf(3) */
1507 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1512 int (*fp
)(void *, const char *, ...);
1515 const char *vty_newline
;
1517 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1520 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1523 fp(out
, "%s:%u", buf
, p
->cost
);
1528 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1530 char buf
[RD_ADDRSTRLEN
];
1532 prefix_rd2str(prd
, buf
, sizeof(buf
));
1533 vty_out(vty
, "%s", buf
);
1536 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1537 safi_t safi
, struct prefix
*p
)
1539 afi_t afi
; /* of the VN address */
1540 struct bgp_node
*bn
;
1541 struct bgp_info
*bi
;
1542 uint8_t type
= ZEBRA_ROUTE_BGP
;
1545 struct prefix_rd prd0
;
1546 struct prefix_rd
*prd
;
1549 * Find the bgp_info in the RIB corresponding to this
1553 afi
= family2afi(p
->family
);
1554 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1556 bgp
= bgp_get_default(); /* assume 1 instance for now */
1559 if (safi
== SAFI_ENCAP
) {
1560 memset(&prd0
, 0, sizeof(prd0
));
1561 prd0
.family
= AF_UNSPEC
;
1562 prd0
.prefixlen
= 64;
1567 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1569 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1571 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1572 if (bi
->peer
== rfd
->peer
&& bi
->type
== type
1573 && bi
->sub_type
== BGP_ROUTE_RFP
&& bi
->extra
1574 && bi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1576 rfapiPrintBi(vty
, bi
);
1582 vty_out(vty
, " --?--%s", HVTYNL
);
1587 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1589 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1590 /* RT export list */
1591 /* RT import list */
1592 /* list of advertised prefixes */
1593 /* dump import table */
1599 struct rfapi_adb
*adb
;
1600 char buf
[PREFIX_STRLEN
];
1602 vty_out(vty
, "%-10p ", rfd
);
1603 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1605 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1606 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1607 rfapiPrintRd(vty
, &rfd
->rd
);
1608 vty_out(vty
, " %d", rfd
->response_lifetime
);
1609 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1610 vty_out(vty
, "%s", HVTYNL
);
1612 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1614 /* export RT list */
1615 if (rfd
->rt_export_list
) {
1616 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1617 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1618 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1619 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1621 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1624 /* import RT list */
1625 if (rfd
->import_table
) {
1626 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1627 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1628 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1629 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1631 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1634 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1637 family
= afi2family(afi
);
1642 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1643 (void **)&adb
, &cursor
);
1645 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1646 (void **)&adb
, &cursor
)) {
1648 /* group like family prefixes together in output */
1649 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1652 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1654 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1655 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1656 &adb
->u
.s
.prefix_ip
);
1659 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1660 (void **)&adb
, &cursor
);
1661 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1662 (void **)&adb
, &cursor
)) {
1664 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1666 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1668 /* TBD update the following function to print ethernet info */
1669 /* Also need to pass/use rd */
1670 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1671 &adb
->u
.s
.prefix_ip
);
1673 vty_out(vty
, "%s", HVTYNL
);
1677 * test scripts rely on first line for each nve starting in 1st column,
1678 * leading whitespace for additional detail of that nve
1680 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1681 struct prefix
*un_prefix
)
1685 struct listnode
*ln
;
1686 struct rfapi_descriptor
*rfd
;
1689 bgp
= bgp_get_default(); /* assume 1 instance for now */
1696 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1697 rfd
= listgetdata(ln
);
1702 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1703 if (!prefix_match(vn_prefix
, &pfx
))
1708 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1709 if (!prefix_match(un_prefix
, &pfx
))
1714 /* print column header */
1715 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1716 "un-addr", "vn-addr", "callback", "cookie",
1717 "RD", "lifetime", "group", HVTYNL
);
1719 rfapiPrintDescriptor(vty
, rfd
);
1726 * Parse an address and put into a struct prefix
1728 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1730 if (!str2prefix(str
, p
)) {
1731 vty_out(vty
, "Malformed address \"%s\"%s", str
, HVTYNL
);
1734 switch (p
->family
) {
1736 if (p
->prefixlen
!= 32) {
1737 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1743 if (p
->prefixlen
!= 128) {
1744 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1750 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1756 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1757 struct rfapi_ip_addr
*hai
)
1762 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1766 hai
->addr_family
= pfx
.family
;
1767 if (pfx
.family
== AF_INET
)
1768 hai
->addr
.v4
= pfx
.u
.prefix4
;
1770 hai
->addr
.v6
= pfx
.u
.prefix6
;
1776 * Note: this function does not flush vty output, so if it is called
1777 * with a stream pointing to a vty, the user will have to type something
1778 * before the callback output shows up
1780 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1782 struct rfapi_next_hop_entry
*nh
;
1785 int (*fp
)(void *, const char *, ...);
1788 const char *vty_newline
;
1790 #define REMAIN (BUFSIZ - (p-line))
1791 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1793 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1796 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1802 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1805 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1806 /* it fit, so count length */
1814 r
= snprintf(p
, REMAIN
, ", un=");
1817 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1818 /* it fit, so count length */
1826 r
= snprintf(p
, REMAIN
, ", vn=");
1829 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1830 /* it fit, so count length */
1839 line
[BUFSIZ
- 1] = 0;
1840 fp(out
, "%s%s", line
, HVTYNL
);
1845 if (nh
->vn_options
) {
1846 struct rfapi_vn_option
*vo
;
1847 char offset
[] = " ";
1849 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1853 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1854 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1855 pbuf
, sizeof(pbuf
));
1857 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1859 (vo
->v
.l2addr
.label
& 0x00ffffff),
1860 (vo
->v
.l2addr
.logical_net_id
1862 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1865 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1866 prefix2str(&vo
->v
.local_nexthop
.addr
,
1867 pbuf
, sizeof(pbuf
));
1868 fp(out
, "%sLNH %s cost=%d%s", offset
,
1869 pbuf
, vo
->v
.local_nexthop
.cost
,
1875 "%svn option type %d (unknown)%s",
1876 offset
, vo
->type
, HVTYNL
);
1881 if (nh
->un_options
) {
1882 struct rfapi_un_option
*uo
;
1883 char offset
[] = " ";
1885 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1887 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1888 rfapi_print_tunneltype_option(
1889 stream
, 8, &uo
->v
.tunnel
);
1892 fp(out
, "%sUN Option type %d%s", offset
,
1893 uo
->type
, vty_newline
);
1901 /***********************************************************************
1903 ***********************************************************************/
1906 * Add another nexthop to the NHL
1908 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1909 struct rfapi_ip_addr
*vn_addr
,
1910 struct rfapi_ip_prefix
*rprefix
,
1912 uint32_t lifetime
, /* add only */
1913 struct rfapi_vn_option
*vn_options
,
1914 struct rfapi_next_hop_entry
**head
,
1915 struct rfapi_next_hop_entry
**tail
)
1917 struct rfapi_next_hop_entry
*new;
1923 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1924 new->prefix
= *rprefix
;
1925 new->un_address
= *un_addr
;
1926 new->vn_address
= *vn_addr
;
1928 new->vn_options
= vn_options
;
1930 new->lifetime
= lifetime
;
1932 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1936 (*tail
)->next
= new;
1945 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1946 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1947 struct cmd_token
*carg_cost
, /* optional */
1948 struct cmd_token
*carg_lifetime
, /* optional */
1949 struct cmd_token
*carg_macaddr
, /* optional */
1951 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1952 int argc
, struct cmd_token
**argv
)
1954 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1955 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1956 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1957 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1958 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1959 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1960 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1961 struct rfapi_ip_addr vn_address
;
1962 struct rfapi_ip_addr un_address
;
1964 struct rfapi_ip_prefix rpfx
;
1969 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1970 struct rfapi_vn_option
*opt
= NULL
;
1973 int rc
= CMD_WARNING_CONFIG_FAILED
;
1977 struct rfapi_cfg
*rfapi_cfg
;
1979 const char *arg_lnh
= NULL
;
1980 const char *arg_lnh_cost
= NULL
;
1982 bgp
= bgp_get_default(); /* assume 1 instance for now */
1985 vty_out(vty
, "BGP not configured\n");
1986 return CMD_WARNING_CONFIG_FAILED
;
1990 rfapi_cfg
= bgp
->rfapi_cfg
;
1991 if (!h
|| !rfapi_cfg
) {
1993 vty_out(vty
, "RFAPI not configured\n");
1994 return CMD_WARNING_CONFIG_FAILED
;
1997 for (; argc
; --argc
, ++argv
) {
1998 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2001 "local-next-hop specified more than once\n");
2002 return CMD_WARNING_CONFIG_FAILED
;
2006 "Missing parameter for local-next-hop\n");
2007 return CMD_WARNING_CONFIG_FAILED
;
2010 arg_lnh
= argv
[0]->arg
;
2012 if (strmatch(argv
[0]->text
, "local-cost")) {
2015 "local-cost specified more than once\n");
2016 return CMD_WARNING_CONFIG_FAILED
;
2020 "Missing parameter for local-cost\n");
2021 return CMD_WARNING_CONFIG_FAILED
;
2024 arg_lnh_cost
= argv
[0]->arg
;
2028 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2030 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2033 /* arg_prefix is optional if mac address is given */
2034 if (arg_macaddr
&& !arg_prefix
) {
2036 * fake up a 0/32 or 0/128 prefix
2038 switch (vn_address
.addr_family
) {
2040 arg_prefix
= "0.0.0.0/32";
2043 arg_prefix
= "0::0/128";
2047 "Internal error, unknown VN address family\n");
2048 return CMD_WARNING_CONFIG_FAILED
;
2052 if (!str2prefix(arg_prefix
, &pfx
)) {
2053 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2056 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2057 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2063 memset(optary
, 0, sizeof(optary
));
2067 cost
= strtoul(arg_cost
, &endptr
, 10);
2068 if (*endptr
!= '\0' || cost
> 255) {
2069 vty_out(vty
, "%% Invalid %s value\n", "cost");
2077 if (!strcmp(arg_lifetime
, "infinite")) {
2078 lifetime
= RFAPI_INFINITE_LIFETIME
;
2081 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2082 if (*endptr
!= '\0') {
2083 vty_out(vty
, "%% Invalid %s value\n",
2089 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2095 "%% %s may only be specified with local-next-hop\n",
2100 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2101 if (*endptr
!= '\0' || lnh_cost
> 255) {
2102 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2112 "%% %s may only be specified with prefix\n",
2116 if ((rc
= rfapiCliGetPrefixAddr(
2118 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2123 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2124 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2127 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2134 if (arg_vni
&& !arg_macaddr
) {
2135 vty_out(vty
, "%% %s may only be specified with mac address\n",
2136 "virtual-network-identifier");
2143 "Missing \"vni\" parameter (mandatory with mac)\n");
2144 return CMD_WARNING_CONFIG_FAILED
;
2146 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2147 strtoul(arg_vni
, NULL
, 10);
2149 if ((rc
= rfapiStr2EthAddr(
2151 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2152 vty_out(vty
, "Invalid %s value\n", "mac address");
2155 /* TBD label, NVE ID */
2157 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2160 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2167 vnc_zlog_debug_verbose(
2168 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2169 __func__
, arg_vn
, arg_un
, arg_prefix
,
2170 (arg_cost
? arg_cost
: "NULL"),
2171 (arg_lifetime
? arg_lifetime
: "NULL"),
2172 (arg_lnh
? arg_lnh
: "NULL"));
2174 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2176 rpfx
.cost
= cost
& 255;
2178 /* look up rf descriptor, call open if it doesn't exist */
2179 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2180 (struct rfapi_descriptor
**)&rfd
);
2183 struct rfapi_un_option uo
;
2186 * flag descriptor as provisionally opened for static
2188 * registration so that we can fix up the other
2190 * when the real open comes along
2192 memset(&uo
, 0, sizeof(uo
));
2193 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2195 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2196 &vn_address
, &un_address
,
2198 NULL
, NULL
, /* no userdata */
2202 "Can't open session for this NVE: %s\n",
2203 rfapi_error_str(rc
));
2204 rc
= CMD_WARNING_CONFIG_FAILED
;
2208 vty_out(vty
, "Can't find session for this NVE: %s\n",
2209 rfapi_error_str(rc
));
2214 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2215 RFAPI_REGISTER_ADD
);
2217 struct rfapi_next_hop_entry
*head
= NULL
;
2218 struct rfapi_next_hop_entry
*tail
= NULL
;
2219 struct rfapi_vn_option
*vn_opt_new
;
2221 vnc_zlog_debug_verbose(
2222 "%s: rfapi_register succeeded, returning 0", __func__
);
2224 if (h
->rfp_methods
.local_cb
) {
2225 struct rfapi_descriptor
*r
=
2226 (struct rfapi_descriptor
*)rfd
;
2227 vn_opt_new
= rfapi_vn_options_dup(opt
);
2229 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2231 vn_opt_new
, &head
, &tail
);
2233 h
->flags
|= RFAPI_INCALLBACK
;
2234 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2235 h
->flags
&= ~RFAPI_INCALLBACK
;
2242 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2244 vty_out(vty
, "Registration failed.\n");
2246 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2247 return CMD_WARNING_CONFIG_FAILED
;
2250 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2254 /************************************************************************
2255 * Add prefix With LNH_OPTIONS...
2256 ************************************************************************/
2257 DEFUN (add_vnc_prefix_cost_life_lnh
,
2258 add_vnc_prefix_cost_life_lnh_cmd
,
2259 "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...",
2260 "Add registration\n"
2262 "Add/modify prefix related information\n"
2265 "VN address of NVE\n"
2266 "VN IPv4 interface address\n"
2267 "VN IPv6 interface address\n"
2268 "UN address of NVE\n"
2269 "UN IPv4 interface address\n"
2270 "UN IPv6 interface address\n"
2271 "Administrative cost [default: 255]\n"
2272 "Administrative cost\n"
2273 "Registration lifetime [default: infinite]\n"
2274 "Lifetime value in seconds\n"
2275 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2277 /* pfx vn un cost life */
2278 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2280 NULL
, NULL
, argc
- 12, argv
+ 12);
2283 DEFUN (add_vnc_prefix_life_cost_lnh
,
2284 add_vnc_prefix_life_cost_lnh_cmd
,
2285 "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...",
2286 "Add registration\n"
2288 "Add/modify prefix related information\n"
2291 "VN address of NVE\n"
2292 "VN IPv4 interface address\n"
2293 "VN IPv6 interface address\n"
2294 "UN address of NVE\n"
2295 "UN IPv4 interface address\n"
2296 "UN IPv6 interface address\n"
2297 "Registration lifetime [default: infinite]\n"
2298 "Lifetime value in seconds\n"
2299 "Administrative cost [default: 255]\n"
2300 "Administrative cost\n"
2301 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2303 /* pfx vn un cost life */
2304 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2306 NULL
, NULL
, argc
- 12, argv
+ 12);
2309 DEFUN (add_vnc_prefix_cost_lnh
,
2310 add_vnc_prefix_cost_lnh_cmd
,
2311 "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...",
2312 "Add registration\n"
2314 "Add/modify prefix related information\n"
2317 "VN address of NVE\n"
2318 "VN IPv4 interface address\n"
2319 "VN IPv6 interface address\n"
2320 "UN address of NVE\n"
2321 "UN IPv4 interface address\n"
2322 "UN IPv6 interface address\n"
2323 "Administrative cost [default: 255]\n"
2324 "Administrative cost\n"
2325 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2327 /* pfx vn un cost life */
2328 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2330 NULL
, NULL
, argc
- 10, argv
+ 10);
2333 DEFUN (add_vnc_prefix_life_lnh
,
2334 add_vnc_prefix_life_lnh_cmd
,
2335 "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...",
2336 "Add registration\n"
2338 "Add/modify prefix related information\n"
2341 "VN address of NVE\n"
2342 "VN IPv4 interface address\n"
2343 "VN IPv6 interface address\n"
2344 "UN address of NVE\n"
2345 "UN IPv4 interface address\n"
2346 "UN IPv6 interface address\n"
2347 "Registration lifetime [default: infinite]\n"
2348 "Lifetime value in seconds\n"
2349 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2351 /* pfx vn un cost life */
2352 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2354 NULL
, NULL
, argc
- 10, argv
+ 10);
2357 DEFUN (add_vnc_prefix_lnh
,
2358 add_vnc_prefix_lnh_cmd
,
2359 "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...",
2360 "Add registration\n"
2362 "Add/modify prefix related information\n"
2365 "VN address of NVE\n"
2366 "VN IPv4 interface address\n"
2367 "VN IPv6 interface address\n"
2368 "UN address of NVE\n"
2369 "UN IPv4 interface address\n"
2370 "UN IPv6 interface address\n"
2371 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2373 /* pfx vn un cost life */
2374 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2376 NULL
, NULL
, argc
- 8, argv
+ 8);
2379 /************************************************************************
2380 * Add prefix Without LNH_OPTIONS...
2381 ************************************************************************/
2382 DEFUN (add_vnc_prefix_cost_life
,
2383 add_vnc_prefix_cost_life_cmd
,
2384 "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)",
2385 "Add registration\n"
2387 "Add/modify prefix related information\n"
2390 "VN address of NVE\n"
2391 "VN IPv4 interface address\n"
2392 "VN IPv6 interface address\n"
2393 "UN address of NVE\n"
2394 "UN IPv4 interface address\n"
2395 "UN IPv6 interface address\n"
2396 "Administrative cost [default: 255]\n"
2397 "Administrative cost\n"
2398 "Registration lifetime [default: infinite]\n"
2399 "Lifetime value in seconds\n")
2401 /* pfx vn un cost life */
2402 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2404 NULL
, NULL
, 0, NULL
);
2407 DEFUN (add_vnc_prefix_life_cost
,
2408 add_vnc_prefix_life_cost_cmd
,
2409 "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)",
2410 "Add registration\n"
2412 "Add/modify prefix related information\n"
2415 "VN address of NVE\n"
2416 "VN IPv4 interface address\n"
2417 "VN IPv6 interface address\n"
2418 "UN address of NVE\n"
2419 "UN IPv4 interface address\n"
2420 "UN IPv6 interface address\n"
2421 "Registration lifetime [default: infinite]\n"
2422 "Lifetime value in seconds\n"
2423 "Administrative cost [default: 255]\n"
2424 "Administrative cost\n")
2426 /* pfx vn un cost life */
2427 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2429 NULL
, NULL
, 0, NULL
);
2432 DEFUN (add_vnc_prefix_cost
,
2433 add_vnc_prefix_cost_cmd
,
2434 "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)",
2435 "Add registration\n"
2437 "Add/modify prefix related information\n"
2440 "VN address of NVE\n"
2441 "VN IPv4 interface address\n"
2442 "VN IPv6 interface address\n"
2443 "UN address of NVE\n"
2444 "UN IPv4 interface address\n"
2445 "UN IPv6 interface address\n"
2446 "Administrative cost [default: 255]\n"
2447 "Administrative cost\n")
2449 /* pfx vn un cost life */
2450 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2452 NULL
, NULL
, 0, NULL
);
2455 DEFUN (add_vnc_prefix_life
,
2456 add_vnc_prefix_life_cmd
,
2457 "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)",
2458 "Add registration\n"
2460 "Add/modify prefix related information\n"
2463 "VN address of NVE\n"
2464 "VN IPv4 interface address\n"
2465 "VN IPv6 interface address\n"
2466 "UN address of NVE\n"
2467 "UN IPv4 interface address\n"
2468 "UN IPv6 interface address\n"
2469 "Registration lifetime [default: infinite]\n"
2470 "Lifetime value in seconds\n")
2472 /* pfx vn un cost life */
2473 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2475 NULL
, NULL
, 0, NULL
);
2478 DEFUN (add_vnc_prefix
,
2480 "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>",
2481 "Add registration\n"
2483 "Add/modify prefix related information\n"
2486 "VN address of NVE\n"
2487 "VN IPv4 interface address\n"
2488 "VN IPv6 interface address\n"
2489 "UN address of NVE\n"
2490 "UN IPv4 interface address\n"
2491 "UN IPv6 interface address\n")
2493 /* pfx vn un cost life */
2494 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2496 NULL
, NULL
, 0, NULL
);
2499 /************************************************************************
2500 * Mac address registrations
2501 ************************************************************************/
2502 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2503 add_vnc_mac_vni_prefix_cost_life_cmd
,
2504 "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)",
2505 "Add registration\n"
2507 "Add/modify mac address information\n"
2509 "Virtual Network Identifier follows\n"
2510 "Virtual Network Identifier\n"
2511 "VN address of NVE\n"
2512 "VN IPv4 interface address\n"
2513 "VN IPv6 interface address\n"
2514 "UN address of NVE\n"
2515 "UN IPv4 interface address\n"
2516 "UN IPv6 interface address\n"
2517 "Add/modify prefix related information\n"
2520 "Administrative cost [default: 255]\n"
2521 "Administrative cost\n"
2522 "Registration lifetime [default: infinite]\n"
2523 "Lifetime value in seconds\n")
2525 /* pfx vn un cost life */
2526 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2528 argv
[3], argv
[5], 0, NULL
);
2532 DEFUN (add_vnc_mac_vni_prefix_life
,
2533 add_vnc_mac_vni_prefix_life_cmd
,
2534 "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)",
2535 "Add registration\n"
2537 "Add/modify mac address information\n"
2539 "Virtual Network Identifier follows\n"
2540 "Virtual Network Identifier\n"
2541 "VN address of NVE\n"
2542 "VN IPv4 interface address\n"
2543 "VN IPv6 interface address\n"
2544 "UN address of NVE\n"
2545 "UN IPv4 interface address\n"
2546 "UN IPv6 interface address\n"
2547 "Add/modify prefix related information\n"
2550 "Registration lifetime [default: infinite]\n"
2551 "Lifetime value in seconds\n")
2553 /* pfx vn un cost life */
2554 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2556 argv
[3], argv
[5], 0, NULL
);
2559 DEFUN (add_vnc_mac_vni_prefix_cost
,
2560 add_vnc_mac_vni_prefix_cost_cmd
,
2561 "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)",
2562 "Add registration\n"
2564 "Add/modify mac address information\n"
2566 "Virtual Network Identifier follows\n"
2567 "Virtual Network Identifier\n"
2568 "VN address of NVE\n"
2569 "VN IPv4 interface address\n"
2570 "VN IPv6 interface address\n"
2571 "UN address of NVE\n"
2572 "UN IPv4 interface address\n"
2573 "UN IPv6 interface address\n"
2574 "Add/modify prefix related information\n"
2577 "Administrative cost [default: 255]\n" "Administrative cost\n")
2579 /* pfx vn un cost life */
2580 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2582 argv
[3], argv
[5], 0, NULL
);
2585 DEFUN (add_vnc_mac_vni_prefix
,
2586 add_vnc_mac_vni_prefix_cmd
,
2587 "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>",
2588 "Add registration\n"
2590 "Add/modify mac address information\n"
2592 "Virtual Network Identifier follows\n"
2593 "Virtual Network Identifier\n"
2594 "VN address of NVE\n"
2595 "VN IPv4 interface address\n"
2596 "VN IPv6 interface address\n"
2597 "UN address of NVE\n"
2598 "UN IPv4 interface address\n"
2599 "UN IPv6 interface address\n"
2600 "Add/modify prefix related information\n"
2601 "IPv4 prefix\n" "IPv6 prefix\n")
2603 /* pfx vn un cost life */
2604 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2606 argv
[3], argv
[5], 0, NULL
);
2609 DEFUN (add_vnc_mac_vni_cost_life
,
2610 add_vnc_mac_vni_cost_life_cmd
,
2611 "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)",
2612 "Add registration\n"
2614 "Add/modify mac address information\n"
2616 "Virtual Network Identifier follows\n"
2617 "Virtual Network Identifier\n"
2618 "VN address of NVE\n"
2619 "VN IPv4 interface address\n"
2620 "VN IPv6 interface address\n"
2621 "UN address of NVE\n"
2622 "UN IPv4 interface address\n"
2623 "UN IPv6 interface address\n"
2624 "Administrative cost [default: 255]\n"
2625 "Administrative cost\n"
2626 "Registration lifetime [default: infinite]\n"
2627 "Lifetime value in seconds\n")
2629 /* pfx vn un cost life */
2630 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2632 argv
[3], argv
[5], 0, NULL
);
2636 DEFUN (add_vnc_mac_vni_cost
,
2637 add_vnc_mac_vni_cost_cmd
,
2638 "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)",
2639 "Add registration\n"
2641 "Add/modify mac address information\n"
2643 "Virtual Network Identifier follows\n"
2644 "Virtual Network Identifier\n"
2645 "VN address of NVE\n"
2646 "VN IPv4 interface address\n"
2647 "VN IPv6 interface address\n"
2648 "UN address of NVE\n"
2649 "UN IPv4 interface address\n"
2650 "UN IPv6 interface address\n"
2651 "Administrative cost [default: 255]\n" "Administrative cost\n")
2653 /* pfx vn un cost life */
2654 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2656 argv
[3], argv
[5], 0, NULL
);
2660 DEFUN (add_vnc_mac_vni_life
,
2661 add_vnc_mac_vni_life_cmd
,
2662 "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)",
2663 "Add registration\n"
2665 "Add/modify mac address information\n"
2667 "Virtual Network Identifier follows\n"
2668 "Virtual Network Identifier\n"
2669 "VN address of NVE\n"
2670 "VN IPv4 interface address\n"
2671 "VN IPv6 interface address\n"
2672 "UN address of NVE\n"
2673 "UN IPv4 interface address\n"
2674 "UN IPv6 interface address\n"
2675 "Registration lifetime [default: infinite]\n"
2676 "Lifetime value in seconds\n")
2678 /* pfx vn un cost life */
2679 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2681 argv
[3], argv
[5], 0, NULL
);
2685 DEFUN (add_vnc_mac_vni
,
2686 add_vnc_mac_vni_cmd
,
2687 "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>",
2688 "Add registration\n"
2690 "Add/modify mac address information\n"
2692 "Virtual Network Identifier follows\n"
2693 "Virtual Network Identifier\n"
2694 "VN address of NVE\n"
2695 "VN IPv4 interface address\n"
2696 "VN IPv6 interface address\n"
2697 "UN address of NVE\n"
2698 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2700 /* pfx vn un cost life */
2701 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2703 argv
[3], argv
[5], 0, NULL
);
2706 /************************************************************************
2708 ************************************************************************/
2710 struct rfapi_local_reg_delete_arg
{
2715 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2716 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2717 struct prefix prefix
; /* AF==0: wildcard */
2718 struct prefix_rd rd
; /* plen!=64: wildcard */
2719 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2721 struct rfapi_l2address_option_match l2o
;
2729 uint32_t query_count
;
2731 uint32_t failed_pfx_count
;
2734 struct skiplist
*nves
;
2736 uint32_t remote_active_nve_count
;
2737 uint32_t remote_active_pfx_count
;
2738 uint32_t remote_holddown_nve_count
;
2739 uint32_t remote_holddown_pfx_count
;
2743 struct rfapi_ip_addr vn
;
2744 struct rfapi_ip_addr un
;
2745 struct rfapi_descriptor
*rfd
;
2746 struct rfapi_local_reg_delete_arg
*cda
;
2749 static void nve_addr_free(void *hap
)
2751 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2752 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2755 static int nve_addr_cmp(void *k1
, void *k2
)
2757 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2758 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2764 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2765 return (a
->un
.addr_family
- b
->un
.addr_family
);
2767 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2768 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2770 if (a
->un
.addr_family
== AF_INET
) {
2771 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2775 } else if (a
->un
.addr_family
== AF_INET6
) {
2776 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2783 if (a
->vn
.addr_family
== AF_INET
) {
2784 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2787 } else if (a
->vn
.addr_family
== AF_INET6
) {
2788 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2798 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2799 const char *arg_prefix
, const char *arg_vn
,
2800 const char *arg_un
, const char *arg_l2addr
,
2801 const char *arg_vni
, const char *arg_rd
,
2802 struct rfapi_nve_group_cfg
*arg_rfg
,
2803 struct rfapi_local_reg_delete_arg
*rcdarg
)
2805 int rc
= CMD_WARNING
;
2807 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2811 bgp
= bgp_get_default();
2813 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2815 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2816 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2817 &rcdarg
->vn_address
)))
2820 if (arg_un
&& strcmp(arg_un
, "*")) {
2821 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2822 &rcdarg
->un_address
)))
2825 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2827 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2828 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2835 vty_out(vty
, "Missing VNI\n");
2838 if (strcmp(arg_l2addr
, "*")) {
2839 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2840 &rcdarg
->l2o
.o
.macaddr
))) {
2841 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2845 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2847 if (strcmp(arg_vni
, "*")) {
2848 rcdarg
->l2o
.o
.logical_net_id
=
2849 strtoul(arg_vni
, NULL
, 10);
2850 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2854 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2855 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2864 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2865 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2866 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2867 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2868 struct rfapi_nve_group_cfg
*arg_rfg
,
2869 struct rfapi_local_reg_delete_arg
*rcdarg
)
2871 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2872 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2873 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2874 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2875 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2876 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2877 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2878 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2881 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2882 struct rfapi_ip_addr
*un_address
,
2883 struct rfapi_ip_addr
*vn_address
,
2884 struct rfapi_descriptor
*rfd
)
2887 struct nve_addr
*hap
;
2889 memset(&ha
, 0, sizeof(ha
));
2890 ha
.un
= *un_address
;
2891 ha
.vn
= *vn_address
;
2895 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2897 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2898 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2902 skiplist_insert(cda
->nves
, hap
, hap
);
2906 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2909 struct rfapi_descriptor
*rfd
;
2910 int query_count
= 0;
2911 struct listnode
*node
;
2912 struct bgp
*bgp_default
= bgp_get_default();
2914 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2918 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2919 &cda
->un_address
, &rfd
))
2923 rfapi_query_done_all(rfd
, &query_count
);
2924 cda
->query_count
+= query_count
;
2927 * Track unique nves seen
2929 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2940 h
= bgp_default
->rfapi
;
2945 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2947 * match un, vn addresses of NVEs
2949 if (cda
->un_address
.addr_family
2950 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2953 if (cda
->vn_address
.addr_family
2954 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2960 rfapi_query_done_all(rfd
, &query_count
);
2961 cda
->query_count
+= query_count
;
2964 * Track unique nves seen
2966 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2971 * TBD need to count deleted prefixes and nves?
2973 * ENXIO BGP or VNC not configured
2975 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2976 struct rfapi_descriptor
*rfd
)
2978 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2979 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2980 struct prefix
*pPrefix
; /* NULL = wildcard */
2981 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2983 struct rfapi_ip_prefix rprefix
;
2984 struct rfapi_next_hop_entry
*head
= NULL
;
2985 struct rfapi_next_hop_entry
*tail
= NULL
;
2988 vnc_zlog_debug_verbose("%s: entry", __func__
);
2991 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2992 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2993 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2994 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2997 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3000 do /* to preserve old code structure */
3002 struct rfapi
*h
= cda
->bgp
->rfapi
;
3004 struct rfapi_adb
*adb
;
3006 int deleted_from_this_nve
;
3008 struct nve_addr
*hap
;
3011 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3015 * match un, vn addresses of NVEs
3017 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3019 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3023 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3030 deleted_from_this_nve
= 0;
3033 struct skiplist
*sl
;
3034 struct rfapi_ip_prefix rp
;
3036 struct list
*adb_delete_list
;
3039 * The advertisements are stored in a skiplist.
3041 * the registration deletes the advertisement from the
3042 * skiplist, which we can't do while iterating over that
3043 * same skiplist using the current skiplist API.
3045 * Strategy: iterate over the skiplist and build another
3046 * list containing only the matching ADBs. Then delete
3047 * _everything_ in that second list (which can be done
3048 * using either skiplists or quagga linklists).
3050 adb_delete_list
= list_new();
3053 * Advertised IP prefixes (not 0/32 or 0/128)
3055 sl
= rfd
->advertised
.ipN_by_prefix
;
3058 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3060 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3064 if (!prefix_same(pPrefix
,
3065 &adb
->u
.s
.prefix_ip
)) {
3067 vnc_zlog_debug_verbose(
3068 "%s: adb=%p, prefix doesn't match, skipping",
3075 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3079 vnc_zlog_debug_verbose(
3080 "%s: adb=%p, RD doesn't match, skipping",
3086 if (CHECK_FLAG(cda
->l2o
.flags
,
3087 RFAPI_L2O_MACADDR
)) {
3088 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3089 adb
->u
.s
.prefix_eth
.u
3093 vnc_zlog_debug_verbose(
3094 "%s: adb=%p, macaddr doesn't match, skipping",
3101 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3102 if (cda
->l2o
.o
.logical_net_id
3103 != adb
->l2o
.logical_net_id
) {
3105 vnc_zlog_debug_verbose(
3106 "%s: adb=%p, LNI doesn't match, skipping",
3114 vnc_zlog_debug_verbose(
3115 "%s: ipN adding adb %p to delete list",
3119 listnode_add(adb_delete_list
, adb
);
3122 struct listnode
*node
;
3124 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3125 int this_advertisement_prefix_count
;
3126 struct rfapi_vn_option optary
[3];
3127 struct rfapi_vn_option
*opt
= NULL
;
3130 this_advertisement_prefix_count
= 1;
3132 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3134 memset(optary
, 0, sizeof(optary
));
3136 /* if mac addr present in advert, make l2o vn
3138 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3140 opt
->next
= &optary
[cur_opt
];
3141 opt
= &optary
[cur_opt
++];
3142 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3143 opt
->v
.l2addr
.macaddr
=
3144 adb
->u
.s
.prefix_eth
.u
3146 ++this_advertisement_prefix_count
;
3149 * use saved RD value instead of trying to
3151 * complex RD computation in rfapi_register()
3154 opt
->next
= &optary
[cur_opt
];
3155 opt
= &optary
[cur_opt
++];
3156 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3157 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3160 vnc_zlog_debug_verbose(
3161 "%s: ipN killing reg from adb %p ",
3165 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3166 (cur_opt
? optary
: NULL
),
3167 RFAPI_REGISTER_KILL
);
3170 this_advertisement_prefix_count
;
3171 cda
->reg_count
+= 1;
3172 deleted_from_this_nve
= 1;
3174 if (h
->rfp_methods
.local_cb
) {
3175 rfapiAddDeleteLocalRfpPrefix(
3176 &rfd
->un_addr
, &rfd
->vn_addr
,
3177 &rp
, 0, 0, NULL
, &head
, &tail
);
3180 list_delete_all_node(adb_delete_list
);
3182 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3186 * Caller didn't specify a prefix, or specified
3191 * Advertised 0/32 and 0/128 (indexed by
3194 sl
= rfd
->advertised
.ip0_by_ether
;
3197 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3200 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3203 if (CHECK_FLAG(cda
->l2o
.flags
,
3204 RFAPI_L2O_MACADDR
)) {
3205 if (memcmp(cda
->l2o
.o
.macaddr
3207 adb
->u
.s
.prefix_eth
.u
3215 if (CHECK_FLAG(cda
->l2o
.flags
,
3217 if (cda
->l2o
.o
.logical_net_id
3218 != adb
->l2o
.logical_net_id
) {
3223 vnc_zlog_debug_verbose(
3224 "%s: ip0 adding adb %p to delete list",
3227 listnode_add(adb_delete_list
, adb
);
3231 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3234 struct rfapi_vn_option vn
;
3236 rfapiQprefix2Rprefix(
3237 &adb
->u
.s
.prefix_ip
, &rp
);
3239 memset(&vn
, 0, sizeof(vn
));
3240 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3241 vn
.v
.l2addr
= adb
->l2o
;
3244 vnc_zlog_debug_verbose(
3245 "%s: ip0 killing reg from adb %p ",
3249 rc
= rfapi_register(
3250 rfd
, &rp
, 0, NULL
, &vn
,
3251 RFAPI_REGISTER_KILL
);
3253 cda
->pfx_count
+= 1;
3254 cda
->reg_count
+= 1;
3255 deleted_from_this_nve
= 1;
3257 if (h
->rfp_methods
.local_cb
) {
3258 struct rfapi_vn_option
3262 rfapi_vn_options_dup(
3264 rfapiAddDeleteLocalRfpPrefix(
3266 &rfd
->vn_addr
, &rp
, 0,
3267 0, vn_opt_new
, &head
,
3271 list_delete_all_node(adb_delete_list
);
3273 list_delete_and_null(&adb_delete_list
);
3277 if (head
) { /* should not be set if (NULL ==
3278 rfapi_cfg->local_cb) */
3279 h
->flags
|= RFAPI_INCALLBACK
;
3280 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3281 h
->flags
&= ~RFAPI_INCALLBACK
;
3285 if (deleted_from_this_nve
) {
3287 * track unique NVEs seen
3289 memset(&ha
, 0, sizeof(ha
));
3290 ha
.un
= rfd
->un_addr
;
3291 ha
.vn
= rfd
->vn_addr
;
3294 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3296 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3297 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3298 sizeof(struct nve_addr
));
3302 skiplist_insert(cda
->nves
, hap
, hap
);
3305 } while (0); /* to preserve old code structure */
3310 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3315 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3316 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3318 struct bgp
*bgp
= cda
->bgp
;
3320 struct rfapi_cfg
*rfapi_cfg
;
3322 struct listnode
*node
;
3323 struct rfapi_descriptor
*rfd
;
3327 rfapi_cfg
= bgp
->rfapi_cfg
;
3328 if (!h
|| !rfapi_cfg
)
3330 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3332 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3333 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3342 * Deletes local and remote prefixes that match
3344 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3346 struct prefix pfx_un
;
3347 struct prefix pfx_vn
;
3349 struct prefix
*pUN
= NULL
;
3350 struct prefix
*pVN
= NULL
;
3351 struct prefix
*pPrefix
= NULL
;
3353 struct rfapi_import_table
*it
= NULL
;
3356 * Delete matching remote prefixes in holddown
3358 if (cda
->vn_address
.addr_family
) {
3359 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3362 if (cda
->un_address
.addr_family
) {
3363 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3366 if (cda
->prefix
.family
) {
3367 pPrefix
= &cda
->prefix
;
3370 it
= cda
->rfg
->rfapi_import_table
;
3372 rfapiDeleteRemotePrefixes(
3373 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3374 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3375 &cda
->remote_holddown_nve_count
);
3378 * Now do local prefixes
3380 rfapiDeleteLocalPrefixes(cda
);
3383 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3385 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3387 /* Our special element-deleting function counts nves */
3389 skiplist_free(cda
->nves
);
3392 if (cda
->failed_pfx_count
)
3393 vty_out(vty
, "Failed to delete %d prefixes\n",
3394 cda
->failed_pfx_count
);
3396 /* left as "prefixes" even in single case for ease of machine parsing */
3398 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3399 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3403 * We don't currently allow deletion of active remote prefixes from
3407 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3408 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3412 * Caller has already deleted registrations and queries for this/these
3413 * NVEs. Now we just have to close their descriptors.
3415 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3417 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3418 struct nve_addr
*pKey
;
3419 struct nve_addr
*pValue
;
3420 void *cursor
= NULL
;
3426 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3427 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3431 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3432 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3433 rfapi_close(pValue
->rfd
);
3438 DEFUN (clear_vnc_nve_all
,
3439 clear_vnc_nve_all_cmd
,
3443 "Clear per NVE information\n"
3447 struct rfapi_local_reg_delete_arg cda
;
3450 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3456 clear_vnc_responses(&cda
);
3457 clear_vnc_prefix(&cda
);
3458 clear_vnc_nve_closer(&cda
);
3460 print_cleared_stats(&cda
);
3465 DEFUN (clear_vnc_nve_vn_un
,
3466 clear_vnc_nve_vn_un_cmd
,
3467 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3470 "Clear prefix registration information\n"
3471 "VN address of NVE\n"
3473 "VN IPv4 interface address\n"
3474 "VN IPv6 interface address\n"
3475 "UN address of NVE\n"
3476 "For all UN addresses\n"
3477 "UN IPv4 interface address\n"
3478 "UN IPv6 interface address\n")
3480 struct rfapi_local_reg_delete_arg cda
;
3483 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3484 NULL
, NULL
, NULL
, &cda
)))
3489 clear_vnc_responses(&cda
);
3490 clear_vnc_prefix(&cda
);
3491 clear_vnc_nve_closer(&cda
);
3493 print_cleared_stats(&cda
);
3498 DEFUN (clear_vnc_nve_un_vn
,
3499 clear_vnc_nve_un_vn_cmd
,
3500 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3503 "Clear prefix registration information\n"
3504 "UN address of NVE\n"
3506 "UN IPv4 interface address\n"
3507 "UN IPv6 interface address\n"
3508 "VN address of NVE\n"
3510 "VN IPv4 interface address\n"
3511 "VN IPv6 interface address\n")
3513 struct rfapi_local_reg_delete_arg cda
;
3516 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3517 NULL
, NULL
, NULL
, &cda
)))
3522 clear_vnc_responses(&cda
);
3523 clear_vnc_prefix(&cda
);
3524 clear_vnc_nve_closer(&cda
);
3526 print_cleared_stats(&cda
);
3531 DEFUN (clear_vnc_nve_vn
,
3532 clear_vnc_nve_vn_cmd
,
3533 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3536 "Clear prefix registration information\n"
3537 "VN address of NVE\n"
3539 "VN IPv4 interface address\n"
3540 "VN IPv6 interface address\n")
3542 struct rfapi_local_reg_delete_arg cda
;
3545 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3546 NULL
, NULL
, NULL
, &cda
)))
3551 clear_vnc_responses(&cda
);
3552 clear_vnc_prefix(&cda
);
3553 clear_vnc_nve_closer(&cda
);
3555 print_cleared_stats(&cda
);
3559 DEFUN (clear_vnc_nve_un
,
3560 clear_vnc_nve_un_cmd
,
3561 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3564 "Clear prefix registration information\n"
3565 "UN address of NVE\n"
3567 "UN IPv4 interface address\n"
3568 "UN IPv6 interface address\n")
3570 struct rfapi_local_reg_delete_arg cda
;
3573 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3574 NULL
, NULL
, NULL
, &cda
)))
3579 clear_vnc_responses(&cda
);
3580 clear_vnc_prefix(&cda
);
3581 clear_vnc_nve_closer(&cda
);
3583 print_cleared_stats(&cda
);
3587 /*-------------------------------------------------
3589 *-------------------------------------------------*/
3592 * This function is defined in this file (rather than in rfp_registration.c)
3593 * because here we have access to all the task handles.
3595 DEFUN (clear_vnc_prefix_vn_un
,
3596 clear_vnc_prefix_vn_un_cmd
,
3597 "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>",
3600 "Clear prefix registration information\n"
3604 "VN address of NVE\n"
3605 "All VN addresses\n"
3606 "VN IPv4 interface address\n"
3607 "VN IPv6 interface address\n"
3608 "UN address of NVE\n"
3609 "All UN addresses\n"
3610 "UN IPv4 interface address\n"
3611 "UN IPv6 interface address\n")
3613 struct rfapi_local_reg_delete_arg cda
;
3616 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3617 NULL
, NULL
, NULL
, NULL
, &cda
)))
3620 clear_vnc_prefix(&cda
);
3621 print_cleared_stats(&cda
);
3625 DEFUN (clear_vnc_prefix_un_vn
,
3626 clear_vnc_prefix_un_vn_cmd
,
3627 "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>",
3630 "Clear prefix registration information\n"
3634 "UN address of NVE\n"
3635 "All UN addresses\n"
3636 "UN IPv4 interface address\n"
3637 "UN IPv6 interface address\n"
3638 "VN address of NVE\n"
3639 "All VN addresses\n"
3640 "VN IPv4 interface address\n"
3641 "VN IPv6 interface address\n")
3643 struct rfapi_local_reg_delete_arg cda
;
3646 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3647 NULL
, NULL
, NULL
, NULL
, &cda
)))
3650 clear_vnc_prefix(&cda
);
3651 print_cleared_stats(&cda
);
3655 DEFUN (clear_vnc_prefix_un
,
3656 clear_vnc_prefix_un_cmd
,
3657 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3660 "Clear prefix registration information\n"
3664 "UN address of NVE\n"
3665 "All UN addresses\n"
3666 "UN IPv4 interface address\n"
3667 "UN IPv6 interface address\n")
3669 struct rfapi_local_reg_delete_arg cda
;
3672 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3673 NULL
, NULL
, NULL
, &cda
)))
3676 clear_vnc_prefix(&cda
);
3677 print_cleared_stats(&cda
);
3681 DEFUN (clear_vnc_prefix_vn
,
3682 clear_vnc_prefix_vn_cmd
,
3683 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3686 "Clear prefix registration information\n"
3690 "UN address of NVE\n"
3691 "All VN addresses\n"
3692 "VN IPv4 interface address\n"
3693 "VN IPv6 interface address\n")
3695 struct rfapi_local_reg_delete_arg cda
;
3698 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3699 NULL
, NULL
, NULL
, &cda
)))
3702 clear_vnc_prefix(&cda
);
3703 print_cleared_stats(&cda
);
3707 DEFUN (clear_vnc_prefix_all
,
3708 clear_vnc_prefix_all_cmd
,
3709 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3712 "Clear prefix registration information\n"
3718 struct rfapi_local_reg_delete_arg cda
;
3721 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3722 NULL
, NULL
, NULL
, &cda
)))
3725 clear_vnc_prefix(&cda
);
3726 print_cleared_stats(&cda
);
3730 /*-------------------------------------------------
3732 *-------------------------------------------------*/
3735 * This function is defined in this file (rather than in rfp_registration.c)
3736 * because here we have access to all the task handles.
3738 DEFUN (clear_vnc_mac_vn_un
,
3739 clear_vnc_mac_vn_un_cmd
,
3740 "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>",
3743 "Clear mac registration information\n"
3747 "Any virtual network identifier\n"
3748 "Virtual network identifier\n"
3749 "VN address of NVE\n"
3750 "All VN addresses\n"
3751 "VN IPv4 interface address\n"
3752 "VN IPv6 interface address\n"
3753 "UN address of NVE\n"
3754 "All UN addresses\n"
3755 "UN IPv4 interface address\n"
3756 "UN IPv6 interface address\n")
3758 struct rfapi_local_reg_delete_arg cda
;
3761 /* pfx vn un L2 VNI */
3762 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3763 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3766 clear_vnc_prefix(&cda
);
3767 print_cleared_stats(&cda
);
3771 DEFUN (clear_vnc_mac_un_vn
,
3772 clear_vnc_mac_un_vn_cmd
,
3773 "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>",
3776 "Clear mac registration information\n"
3780 "Any virtual network identifier\n"
3781 "Virtual network identifier\n"
3782 "UN address of NVE\n"
3783 "All UN addresses\n"
3784 "UN IPv4 interface address\n"
3785 "UN IPv6 interface address\n"
3786 "VN address of NVE\n"
3787 "All VN addresses\n"
3788 "VN IPv4 interface address\n"
3789 "VN IPv6 interface address\n")
3791 struct rfapi_local_reg_delete_arg cda
;
3794 /* pfx vn un L2 VNI */
3795 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3796 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3799 clear_vnc_prefix(&cda
);
3800 print_cleared_stats(&cda
);
3804 DEFUN (clear_vnc_mac_un
,
3805 clear_vnc_mac_un_cmd
,
3806 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3809 "Clear mac registration information\n"
3813 "Any virtual network identifier\n"
3814 "Virtual network identifier\n"
3815 "UN address of NVE\n"
3816 "All UN addresses\n"
3817 "UN IPv4 interface address\n"
3818 "UN IPv6 interface address\n")
3820 struct rfapi_local_reg_delete_arg cda
;
3823 /* pfx vn un L2 VNI */
3824 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3825 argv
[5], NULL
, NULL
, &cda
)))
3828 clear_vnc_prefix(&cda
);
3829 print_cleared_stats(&cda
);
3833 DEFUN (clear_vnc_mac_vn
,
3834 clear_vnc_mac_vn_cmd
,
3835 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3838 "Clear mac registration information\n"
3842 "Any virtual network identifier\n"
3843 "Virtual network identifier\n"
3844 "UN address of NVE\n"
3845 "All VN addresses\n"
3846 "VN IPv4 interface address\n"
3847 "VN IPv6 interface address\n")
3849 struct rfapi_local_reg_delete_arg cda
;
3852 /* pfx vn un L2 VNI */
3853 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3854 argv
[5], NULL
, NULL
, &cda
)))
3857 clear_vnc_prefix(&cda
);
3858 print_cleared_stats(&cda
);
3862 DEFUN (clear_vnc_mac_all
,
3863 clear_vnc_mac_all_cmd
,
3864 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3867 "Clear mac registration information\n"
3871 "Any virtual network identifier\n"
3872 "Virtual network identifier\n"
3875 struct rfapi_local_reg_delete_arg cda
;
3878 /* pfx vn un L2 VNI */
3879 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3880 argv
[5], NULL
, NULL
, &cda
)))
3883 clear_vnc_prefix(&cda
);
3884 print_cleared_stats(&cda
);
3888 /*-------------------------------------------------
3889 * Clear VNC MAC PREFIX
3890 *-------------------------------------------------*/
3892 DEFUN (clear_vnc_mac_vn_un_prefix
,
3893 clear_vnc_mac_vn_un_prefix_cmd
,
3894 "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>",
3897 "Clear mac registration information\n"
3901 "Any virtual network identifier\n"
3902 "Virtual network identifier\n"
3903 "VN address of NVE\n"
3904 "All VN addresses\n"
3905 "VN IPv4 interface address\n"
3906 "VN IPv6 interface address\n"
3907 "UN address of NVE\n"
3908 "All UN addresses\n"
3909 "UN IPv4 interface address\n"
3910 "UN IPv6 interface address\n"
3911 "Clear prefix registration information\n"
3916 struct rfapi_local_reg_delete_arg cda
;
3919 /* pfx vn un L2 VNI */
3920 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3921 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3924 clear_vnc_prefix(&cda
);
3925 print_cleared_stats(&cda
);
3929 DEFUN (clear_vnc_mac_un_vn_prefix
,
3930 clear_vnc_mac_un_vn_prefix_cmd
,
3931 "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>",
3934 "Clear mac registration information\n"
3938 "Any virtual network identifier\n"
3939 "Virtual network identifier\n"
3940 "UN address of NVE\n"
3941 "All UN addresses\n"
3942 "UN IPv4 interface address\n"
3943 "UN IPv6 interface address\n"
3944 "VN address of NVE\n"
3945 "All VN addresses\n"
3946 "VN IPv4 interface address\n"
3947 "VN IPv6 interface address\n"
3948 "Clear prefix registration information\n"
3952 "Clear prefix registration information\n"
3957 struct rfapi_local_reg_delete_arg cda
;
3960 /* pfx vn un L2 VNI */
3961 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3962 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3965 clear_vnc_prefix(&cda
);
3966 print_cleared_stats(&cda
);
3970 DEFUN (clear_vnc_mac_un_prefix
,
3971 clear_vnc_mac_un_prefix_cmd
,
3972 "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>",
3975 "Clear mac registration information\n"
3979 "Any virtual network identifier\n"
3980 "Virtual network identifier\n"
3981 "UN address of NVE\n"
3982 "All UN addresses\n"
3983 "UN IPv4 interface address\n"
3984 "UN IPv6 interface address\n"
3985 "Clear prefix registration information\n"
3990 struct rfapi_local_reg_delete_arg cda
;
3993 /* pfx vn un L2 VNI */
3994 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3995 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3998 clear_vnc_prefix(&cda
);
3999 print_cleared_stats(&cda
);
4003 DEFUN (clear_vnc_mac_vn_prefix
,
4004 clear_vnc_mac_vn_prefix_cmd
,
4005 "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>",
4008 "Clear mac registration information\n"
4012 "Any virtual network identifier\n"
4013 "Virtual network identifier\n"
4014 "UN address of NVE\n"
4015 "All VN addresses\n"
4016 "VN IPv4 interface address\n"
4017 "VN IPv6 interface address\n"
4018 "Clear prefix registration information\n"
4023 struct rfapi_local_reg_delete_arg cda
;
4026 /* pfx vn un L2 VNI */
4027 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4028 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4031 clear_vnc_prefix(&cda
);
4032 print_cleared_stats(&cda
);
4036 DEFUN (clear_vnc_mac_all_prefix
,
4037 clear_vnc_mac_all_prefix_cmd
,
4038 "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>",
4041 "Clear mac registration information\n"
4045 "Any virtual network identifier\n"
4046 "Virtual network identifier\n"
4047 "UN address of NVE\n"
4048 "All VN addresses\n"
4049 "VN IPv4 interface address\n"
4050 "VN IPv6 interface address\n")
4052 struct rfapi_local_reg_delete_arg cda
;
4055 /* pfx vn un L2 VNI */
4056 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4057 argv
[5], NULL
, NULL
, &cda
)))
4060 clear_vnc_prefix(&cda
);
4061 print_cleared_stats(&cda
);
4065 /************************************************************************
4067 ************************************************************************/
4070 /* copied from rfp_vty.c */
4071 static int check_and_display_is_vnc_running(struct vty
*vty
)
4073 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4074 return 1; /* is running */
4077 vty_out(vty
, "VNC is not configured.\n");
4079 return 0; /* not running */
4082 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4083 show_nve_summary_t show_type
)
4085 struct bgp
*bgp_default
= bgp_get_default();
4087 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4089 int active_local_routes
;
4090 int active_remote_routes
;
4091 int holddown_remote_routes
;
4092 int imported_remote_routes
;
4097 h
= bgp_default
->rfapi
;
4102 /* don't show local info if not running RFP */
4103 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4105 switch (show_type
) {
4107 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4108 vty_out(vty
, "%-24s ", "NVEs:");
4109 vty_out(vty
, "%-8s %-8u ",
4110 "Active:", h
->descriptors
.count
);
4111 vty_out(vty
, "%-8s %-8u ",
4112 "Maximum:", h
->stat
.max_descriptors
);
4113 vty_out(vty
, "%-8s %-8u",
4114 "Unknown:", h
->stat
.count_unknown_nves
);
4117 case SHOW_NVE_SUMMARY_REGISTERED
:
4119 * NB: With the introduction of L2 route support, we no
4120 * longer have a one-to-one correspondence between
4121 * locally-originated route advertisements and routes in
4122 * the import tables that have local origin. This
4123 * discrepancy arises because a single advertisement
4124 * may contain both an IP prefix and a MAC address.
4125 * Such an advertisement results in two import table
4126 * entries: one indexed by IP prefix, the other indexed
4129 * TBD: update computation and display of registration
4130 * statistics to reflect the underlying semantics.
4132 if (is_vnc_running
) {
4133 vty_out(vty
, "%-24s ", "Registrations:");
4134 vty_out(vty
, "%-8s %-8u ", "Active:",
4135 rfapiApCountAll(bgp_default
));
4136 vty_out(vty
, "%-8s %-8u ", "Failed:",
4137 h
->stat
.count_registrations_failed
);
4138 vty_out(vty
, "%-8s %-8u",
4139 "Total:", h
->stat
.count_registrations
);
4142 vty_out(vty
, "%-24s ", "Prefixes registered:");
4145 rfapiCountAllItRoutes(&active_local_routes
,
4146 &active_remote_routes
,
4147 &holddown_remote_routes
,
4148 &imported_remote_routes
);
4151 if (is_vnc_running
) {
4152 vty_out(vty
, " %-20s ", "Locally:");
4153 vty_out(vty
, "%-8s %-8u ",
4154 "Active:", active_local_routes
);
4159 vty_out(vty
, " %-20s ", "Remotely:");
4160 vty_out(vty
, "%-8s %-8u",
4161 "Active:", active_remote_routes
);
4163 vty_out(vty
, " %-20s ", "In Holddown:");
4164 vty_out(vty
, "%-8s %-8u",
4165 "Active:", holddown_remote_routes
);
4167 vty_out(vty
, " %-20s ", "Imported:");
4168 vty_out(vty
, "%-8s %-8u",
4169 "Active:", imported_remote_routes
);
4172 case SHOW_NVE_SUMMARY_QUERIES
:
4173 vty_out(vty
, "%-24s ", "Queries:");
4174 vty_out(vty
, "%-8s %-8u ",
4175 "Active:", rfapi_monitor_count(NULL
));
4176 vty_out(vty
, "%-8s %-8u ",
4177 "Failed:", h
->stat
.count_queries_failed
);
4178 vty_out(vty
, "%-8s %-8u",
4179 "Total:", h
->stat
.count_queries
);
4182 case SHOW_NVE_SUMMARY_RESPONSES
:
4183 rfapiRibShowResponsesSummary(vty
);
4193 vty_out(vty
, "VNC is not configured.\n");
4197 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4198 struct prefix
*un_prefix
)
4200 // struct hash *rfds;
4201 // struct rfp_rfapi_descriptor_param param;
4203 struct bgp
*bgp_default
= bgp_get_default();
4205 struct listnode
*node
;
4206 struct rfapi_descriptor
*rfd
;
4215 h
= bgp_default
->rfapi
;
4220 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4224 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4226 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4229 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4237 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4238 if (!prefix_match(vn_prefix
, &pfx
))
4243 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4244 if (!prefix_match(un_prefix
, &pfx
))
4248 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4250 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4254 /* print out a header */
4256 " Active Next Hops\n");
4257 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4258 "VN Address", "UN Address", "Regis", "Resps",
4259 "Reach", "Remove", "Age");
4264 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4265 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4266 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4267 rfd
->stat_count_nh_removal
,
4268 rfapiFormatAge(rfd
->open_time
, age
, 10));
4271 if (printed
> 0 || vn_prefix
|| un_prefix
)
4272 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4278 vty_out(vty
, "VNC is not configured.\n");
4283 DEFUN (vnc_show_summary
,
4284 vnc_show_summary_cmd
,
4288 "Display VNC status summary\n")
4290 if (!check_and_display_is_vnc_running(vty
))
4292 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4294 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4295 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4296 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4297 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4301 DEFUN (vnc_show_nves
,
4306 "List known NVEs\n")
4308 rfapi_show_nves(vty
, NULL
, NULL
);
4312 DEFUN (vnc_show_nves_ptct
,
4313 vnc_show_nves_ptct_cmd
,
4314 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4318 "VN address of NVE\n"
4319 "UN address of NVE\n"
4320 "IPv4 interface address\n"
4321 "IPv6 interface address\n")
4325 if (!check_and_display_is_vnc_running(vty
))
4328 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4329 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4332 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4333 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4337 if (argv
[3]->arg
[0] == 'u') {
4338 rfapi_show_nves(vty
, NULL
, &pfx
);
4340 rfapi_show_nves(vty
, &pfx
, NULL
);
4346 /* adapted from rfp_registration_cache_log() */
4347 static void rfapi_show_registrations(struct vty
*vty
,
4348 struct prefix
*restrict_to
, int show_local
,
4349 int show_remote
, int show_holddown
,
4357 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4360 /* non-expiring, local */
4361 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4365 /* non-expiring, non-local */
4366 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4369 if (show_holddown
) {
4370 /* expiring, including local */
4371 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4374 if (show_imported
) {
4375 /* non-expiring, non-local */
4376 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4384 DEFUN (vnc_show_registrations_pfx
,
4385 vnc_show_registrations_pfx_cmd
,
4386 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4389 "List active prefix registrations\n"
4390 "Limit output to a particular IPv4 prefix\n"
4391 "Limit output to a particular IPv6 prefix\n"
4392 "Limit output to a particular IPv6 address\n")
4395 struct prefix
*p_addr
= NULL
;
4398 if (!str2prefix(argv
[3]->arg
, &p
)) {
4399 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4406 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4410 DEFUN (vnc_show_registrations_some_pfx
,
4411 vnc_show_registrations_some_pfx_cmd
,
4412 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4415 "List active prefix registrations\n"
4416 "show all registrations\n"
4417 "show only registrations in holddown\n"
4418 "show only imported prefixes\n"
4419 "show only local registrations\n"
4420 "show only remote registrations\n"
4421 "Limit output to a particular prefix or address\n"
4422 "Limit output to a particular prefix or address\n"
4423 "Limit output to a particular prefix or address\n")
4426 struct prefix
*p_addr
= NULL
;
4429 int show_remote
= 0;
4430 int show_holddown
= 0;
4431 int show_imported
= 0;
4434 if (!str2prefix(argv
[4]->arg
, &p
)) {
4435 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4441 switch (argv
[3]->arg
[0]) {
4466 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4467 show_holddown
, show_imported
);
4471 DEFUN (vnc_show_responses_pfx
,
4472 vnc_show_responses_pfx_cmd
,
4473 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4476 "List recent query responses\n"
4477 "Limit output to a particular IPv4 prefix\n"
4478 "Limit output to a particular IPv6 prefix\n"
4479 "Limit output to a particular IPv6 address\n" )
4482 struct prefix
*p_addr
= NULL
;
4485 if (!str2prefix(argv
[3]->arg
, &p
)) {
4486 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4492 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4494 rfapiRibShowResponsesSummary(vty
);
4496 rfapiRibShowResponses(vty
, p_addr
, 0);
4497 rfapiRibShowResponses(vty
, p_addr
, 1);
4502 DEFUN (vnc_show_responses_some_pfx
,
4503 vnc_show_responses_some_pfx_cmd
,
4504 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4507 "List recent query responses\n"
4508 "show only active query responses\n"
4509 "show only removed query responses\n"
4510 "Limit output to a particular IPv4 prefix\n"
4511 "Limit output to a particular IPv6 prefix\n"
4512 "Limit output to a particular IPV6 address\n")
4515 struct prefix
*p_addr
= NULL
;
4517 int show_active
= 0;
4518 int show_removed
= 0;
4520 if (!check_and_display_is_vnc_running(vty
))
4524 if (!str2prefix(argv
[4]->arg
, &p
)) {
4525 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4532 switch (argv
[3]->arg
[0]) {
4542 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4544 rfapiRibShowResponsesSummary(vty
);
4547 rfapiRibShowResponses(vty
, p_addr
, 0);
4549 rfapiRibShowResponses(vty
, p_addr
, 1);
4554 DEFUN (show_vnc_queries_pfx
,
4555 show_vnc_queries_pfx_cmd
,
4556 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4559 "List active queries\n"
4560 "Limit output to a particular IPv4 prefix or address\n"
4561 "Limit output to a particular IPv6 prefix\n"
4562 "Limit output to a particualr IPV6 address\n")
4565 struct prefix
*p
= NULL
;
4568 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4569 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4575 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4577 return rfapiShowVncQueries(vty
, p
);
4580 DEFUN (vnc_clear_counters
,
4581 vnc_clear_counters_cmd
,
4582 "clear vnc counters",
4585 "Reset VNC counters\n")
4587 struct bgp
*bgp_default
= bgp_get_default();
4589 struct listnode
*node
;
4590 struct rfapi_descriptor
*rfd
;
4595 h
= bgp_default
->rfapi
;
4601 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4602 rfd
->stat_count_nh_reachable
= 0;
4603 rfd
->stat_count_nh_removal
= 0;
4607 memset(&h
->stat
, 0, sizeof(h
->stat
));
4610 * 151122 per bug 103, set count_registrations = number active.
4611 * Do same for queries
4613 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4614 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4616 rfapiRibShowResponsesSummaryClear();
4621 vty_out(vty
, "VNC is not configured.\n");
4625 /************************************************************************
4626 * Add prefix with vrf
4628 * add [vrf <vrf-name>] prefix <prefix>
4629 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4630 ************************************************************************/
4631 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4633 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4634 /* based on rfapi_open */
4635 struct rfapi_descriptor
*rfd
;
4637 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4638 sizeof(struct rfapi_descriptor
));
4641 /* leave most fields empty as will get from (dynamic) config
4643 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4645 if (rfg
->vn_prefix
.family
4646 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4647 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4649 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4650 rfd
->vn_addr
.addr_family
= AF_INET
;
4651 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4653 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4655 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4657 rfapi_init_and_open(bgp
, rfd
, rfg
);
4661 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4662 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4663 const char *arg_prefix
,
4664 const char *arg_rd
, /* optional */
4665 const char *arg_label
, /* optional */
4666 const char *arg_pref
) /* optional */
4669 struct rfapi_nve_group_cfg
*rfg
;
4671 struct rfapi_ip_prefix rpfx
;
4673 struct rfapi_vn_option optary
[3];
4674 struct rfapi_vn_option
*opt
= NULL
;
4677 bgp
= bgp_get_default(); /* assume main instance for now */
4679 vty_out(vty
, "No BGP process is configured\n");
4680 return CMD_WARNING_CONFIG_FAILED
;
4682 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4683 vty_out(vty
, "VRF support not configured\n");
4684 return CMD_WARNING_CONFIG_FAILED
;
4687 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4690 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4692 return CMD_WARNING_CONFIG_FAILED
;
4694 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4696 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4698 return CMD_WARNING_CONFIG_FAILED
;
4700 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4702 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4704 return CMD_WARNING_CONFIG_FAILED
;
4706 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4708 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4710 return CMD_WARNING_CONFIG_FAILED
;
4712 if (!str2prefix(arg_prefix
, &pfx
)) {
4713 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4714 return CMD_WARNING_CONFIG_FAILED
;
4716 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4717 memset(optary
, 0, sizeof(optary
));
4720 opt
->next
= &optary
[cur_opt
];
4721 opt
= &optary
[cur_opt
++];
4722 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4723 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4724 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4725 return CMD_WARNING_CONFIG_FAILED
;
4728 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4729 struct rfapi_l2address_option
*l2o
;
4731 opt
->next
= &optary
[cur_opt
];
4732 opt
= &optary
[cur_opt
++];
4733 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4734 l2o
= &opt
->v
.l2addr
;
4737 label
= strtoul(arg_label
, NULL
, 10);
4740 l2o
->label
= rfg
->label
;
4743 char *endptr
= NULL
;
4744 pref
= strtoul(arg_pref
, &endptr
, 10);
4745 if (*endptr
!= '\0') {
4747 "%% Invalid local-preference value \"%s\"\n",
4749 return CMD_WARNING_CONFIG_FAILED
;
4752 rpfx
.cost
= 255 - (pref
& 255);
4753 vnc_add_vrf_opener(bgp
, rfg
);
4755 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4756 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4757 struct rfapi_next_hop_entry
*head
= NULL
;
4758 struct rfapi_next_hop_entry
*tail
= NULL
;
4759 struct rfapi_vn_option
*vn_opt_new
;
4761 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4764 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4765 struct rfapi_descriptor
*r
=
4766 (struct rfapi_descriptor
*)rfg
->rfd
;
4767 vn_opt_new
= rfapi_vn_options_dup(opt
);
4769 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4771 RFAPI_INFINITE_LIFETIME
,
4772 vn_opt_new
, &head
, &tail
);
4774 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4775 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4777 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4781 vnc_zlog_debug_verbose(
4782 "%s completed, count=%d/%d", __func__
,
4783 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4784 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4788 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4789 vty_out(vty
, "Add failed.\n");
4790 return CMD_WARNING_CONFIG_FAILED
;
4793 DEFUN (add_vrf_prefix_rd_label_pref
,
4794 add_vrf_prefix_rd_label_pref_cmd
,
4795 "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)}]",
4799 "Add/modify prefix related information\n"
4802 "Override configured VRF Route Distinguisher\n"
4803 "<as-number>:<number> or <ip-address>:<number>\n"
4804 "Override configured VRF label\n"
4805 "Label Value <0-1048575>\n"
4806 "Set advertised local preference\n"
4807 "local preference (higher=more preferred)\n")
4809 char *arg_vrf
= argv
[2]->arg
;
4810 char *arg_prefix
= argv
[4]->arg
;
4811 char *arg_rd
= NULL
; /* optional */
4812 char *arg_label
= NULL
; /* optional */
4813 char *arg_pref
= NULL
; /* optional */
4815 argc
--; /* don't parse argument */
4816 while (pargc
< argc
) {
4817 switch (argv
[pargc
++]->arg
[0]) {
4819 arg_rd
= argv
[pargc
]->arg
;
4822 arg_label
= argv
[pargc
]->arg
;
4825 arg_pref
= argv
[pargc
]->arg
;
4833 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4837 /************************************************************************
4838 * del prefix with vrf
4840 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4841 ************************************************************************/
4842 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4845 afi_t afi
= AFI_MAX
;
4847 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4852 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4854 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4859 /* check if IT is empty */
4861 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4865 if (afi
== AFI_MAX
) {
4866 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4871 vnc_zlog_debug_verbose(
4872 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4873 rfg
->rfapi_import_table
->local_count
[afi
]);
4877 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4878 const char *arg_prefix
, /* NULL = all */
4879 const char *arg_rd
) /* optional */
4881 struct rfapi_nve_group_cfg
*rfg
;
4882 struct rfapi_local_reg_delete_arg cda
;
4887 bgp
= bgp_get_default(); /* assume main instance for now */
4889 vty_out(vty
, "No BGP process is configured\n");
4892 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4893 vty_out(vty
, "VRF support not configured\n");
4896 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4899 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4903 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4905 if (rc
!= CMD_SUCCESS
) /* parse error */
4908 start_count
= rfapi_cfg_group_it_count(rfg
);
4909 clear_vnc_prefix(&cda
);
4910 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4915 DEFUN (clear_vrf_prefix_rd
,
4916 clear_vrf_prefix_rd_cmd
,
4917 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4918 "Clear stored data\n"
4921 "Prefix related information\n"
4924 "Specific VRF Route Distinguisher\n"
4925 "<as-number>:<number> or <ip-address>:<number>\n")
4927 char *arg_vrf
= argv
[2]->arg
;
4928 char *arg_prefix
= NULL
; /* optional */
4929 char *arg_rd
= NULL
; /* optional */
4931 argc
--; /* don't check parameter */
4932 while (pargc
< argc
) {
4933 switch (argv
[pargc
++]->arg
[0]) {
4935 arg_rd
= argv
[pargc
]->arg
;
4938 arg_prefix
= argv
[pargc
]->arg
;
4945 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4948 DEFUN (clear_vrf_all
,
4950 "clear vrf NAME all",
4951 "Clear stored data\n"
4956 char *arg_vrf
= argv
[2]->arg
;
4957 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4960 void rfapi_vty_init()
4962 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4963 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4966 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4968 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4969 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4983 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4985 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4986 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4989 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5009 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5010 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5012 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5014 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5015 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5016 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5018 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5019 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5022 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);