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
));
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
;
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
);
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
&& 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
);
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
)
1533 prefix_rd2str(prd
, buf
, BUFSIZ
);
1534 buf
[BUFSIZ
- 1] = 0;
1535 vty_out(vty
, "%s", buf
);
1538 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1539 safi_t safi
, struct prefix
*p
)
1541 afi_t afi
; /* of the VN address */
1542 struct bgp_node
*bn
;
1543 struct bgp_info
*bi
;
1544 uint8_t type
= ZEBRA_ROUTE_BGP
;
1547 struct prefix_rd prd0
;
1548 struct prefix_rd
*prd
;
1551 * Find the bgp_info in the RIB corresponding to this
1555 afi
= family2afi(p
->family
);
1556 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1558 bgp
= bgp_get_default(); /* assume 1 instance for now */
1561 if (safi
== SAFI_ENCAP
) {
1562 memset(&prd0
, 0, sizeof(prd0
));
1563 prd0
.family
= AF_UNSPEC
;
1564 prd0
.prefixlen
= 64;
1569 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1571 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1573 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1574 if (bi
->peer
== rfd
->peer
&& bi
->type
== type
1575 && bi
->sub_type
== BGP_ROUTE_RFP
&& bi
->extra
1576 && bi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1578 rfapiPrintBi(vty
, bi
);
1584 vty_out(vty
, " --?--%s", HVTYNL
);
1589 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1591 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1592 /* RT export list */
1593 /* RT import list */
1594 /* list of advertised prefixes */
1595 /* dump import table */
1601 struct rfapi_adb
*adb
;
1604 vty_out(vty
, "%-10p ", rfd
);
1605 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1607 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1608 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1609 rfapiPrintRd(vty
, &rfd
->rd
);
1610 vty_out(vty
, " %d", rfd
->response_lifetime
);
1611 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1612 vty_out(vty
, "%s", HVTYNL
);
1614 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1616 /* export RT list */
1617 if (rfd
->rt_export_list
) {
1618 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1619 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1620 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1621 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1623 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1626 /* import RT list */
1627 if (rfd
->import_table
) {
1628 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1629 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1630 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1631 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1633 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1636 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1639 family
= afi2family(afi
);
1644 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1645 (void **)&adb
, &cursor
);
1647 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1648 (void **)&adb
, &cursor
)) {
1650 /* group like family prefixes together in output */
1651 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1654 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, BUFSIZ
);
1655 buf
[BUFSIZ
- 1] = 0; /* guarantee NUL-terminated */
1657 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1658 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1659 &adb
->u
.s
.prefix_ip
);
1662 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1663 (void **)&adb
, &cursor
);
1664 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1665 (void **)&adb
, &cursor
)) {
1667 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, BUFSIZ
);
1668 buf
[BUFSIZ
- 1] = 0; /* guarantee NUL-terminated */
1670 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1672 /* TBD update the following function to print ethernet info */
1673 /* Also need to pass/use rd */
1674 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1675 &adb
->u
.s
.prefix_ip
);
1677 vty_out(vty
, "%s", HVTYNL
);
1681 * test scripts rely on first line for each nve starting in 1st column,
1682 * leading whitespace for additional detail of that nve
1684 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1685 struct prefix
*un_prefix
)
1689 struct listnode
*ln
;
1690 struct rfapi_descriptor
*rfd
;
1693 bgp
= bgp_get_default(); /* assume 1 instance for now */
1700 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1701 rfd
= listgetdata(ln
);
1706 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1707 if (!prefix_match(vn_prefix
, &pfx
))
1712 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1713 if (!prefix_match(un_prefix
, &pfx
))
1718 /* print column header */
1719 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1720 "un-addr", "vn-addr", "callback", "cookie",
1721 "RD", "lifetime", "group", HVTYNL
);
1723 rfapiPrintDescriptor(vty
, rfd
);
1730 * Parse an address and put into a struct prefix
1732 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1734 if (!str2prefix(str
, p
)) {
1735 vty_out(vty
, "Malformed address \"%s\"%s", str
, HVTYNL
);
1738 switch (p
->family
) {
1740 if (p
->prefixlen
!= 32) {
1741 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1747 if (p
->prefixlen
!= 128) {
1748 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1754 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1760 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1761 struct rfapi_ip_addr
*hai
)
1766 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1770 hai
->addr_family
= pfx
.family
;
1771 if (pfx
.family
== AF_INET
)
1772 hai
->addr
.v4
= pfx
.u
.prefix4
;
1774 hai
->addr
.v6
= pfx
.u
.prefix6
;
1780 * Note: this function does not flush vty output, so if it is called
1781 * with a stream pointing to a vty, the user will have to type something
1782 * before the callback output shows up
1784 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1786 struct rfapi_next_hop_entry
*nh
;
1789 int (*fp
)(void *, const char *, ...);
1792 const char *vty_newline
;
1794 #define REMAIN (BUFSIZ - (p-line))
1795 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1797 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1800 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1806 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1809 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1810 /* it fit, so count length */
1818 r
= snprintf(p
, REMAIN
, ", un=");
1821 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1822 /* it fit, so count length */
1830 r
= snprintf(p
, REMAIN
, ", vn=");
1833 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1834 /* it fit, so count length */
1843 line
[BUFSIZ
- 1] = 0;
1844 fp(out
, "%s%s", line
, HVTYNL
);
1849 if (nh
->vn_options
) {
1850 struct rfapi_vn_option
*vo
;
1851 char offset
[] = " ";
1853 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1857 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1858 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1859 pbuf
, sizeof(pbuf
));
1861 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1863 (vo
->v
.l2addr
.label
& 0x00ffffff),
1864 (vo
->v
.l2addr
.logical_net_id
1866 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1869 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1870 prefix2str(&vo
->v
.local_nexthop
.addr
,
1871 pbuf
, sizeof(pbuf
));
1872 fp(out
, "%sLNH %s cost=%d%s", offset
,
1873 pbuf
, vo
->v
.local_nexthop
.cost
,
1879 "%svn option type %d (unknown)%s",
1880 offset
, vo
->type
, HVTYNL
);
1885 if (nh
->un_options
) {
1886 struct rfapi_un_option
*uo
;
1887 char offset
[] = " ";
1889 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1891 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1892 rfapi_print_tunneltype_option(
1893 stream
, 8, &uo
->v
.tunnel
);
1896 fp(out
, "%sUN Option type %d%s", offset
,
1897 uo
->type
, vty_newline
);
1905 /***********************************************************************
1907 ***********************************************************************/
1910 * Add another nexthop to the NHL
1912 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1913 struct rfapi_ip_addr
*vn_addr
,
1914 struct rfapi_ip_prefix
*rprefix
,
1916 uint32_t lifetime
, /* add only */
1917 struct rfapi_vn_option
*vn_options
,
1918 struct rfapi_next_hop_entry
**head
,
1919 struct rfapi_next_hop_entry
**tail
)
1921 struct rfapi_next_hop_entry
*new;
1927 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1928 new->prefix
= *rprefix
;
1929 new->un_address
= *un_addr
;
1930 new->vn_address
= *vn_addr
;
1932 new->vn_options
= vn_options
;
1934 new->lifetime
= lifetime
;
1936 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1940 (*tail
)->next
= new;
1949 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1950 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1951 struct cmd_token
*carg_cost
, /* optional */
1952 struct cmd_token
*carg_lifetime
, /* optional */
1953 struct cmd_token
*carg_macaddr
, /* optional */
1955 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1956 int argc
, struct cmd_token
**argv
)
1958 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1959 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1960 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1961 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1962 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1963 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1964 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1965 struct rfapi_ip_addr vn_address
;
1966 struct rfapi_ip_addr un_address
;
1968 struct rfapi_ip_prefix rpfx
;
1973 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1974 struct rfapi_vn_option
*opt
= NULL
;
1977 int rc
= CMD_WARNING_CONFIG_FAILED
;
1981 struct rfapi_cfg
*rfapi_cfg
;
1983 const char *arg_lnh
= NULL
;
1984 const char *arg_lnh_cost
= NULL
;
1986 bgp
= bgp_get_default(); /* assume 1 instance for now */
1989 vty_out(vty
, "BGP not configured\n");
1990 return CMD_WARNING_CONFIG_FAILED
;
1994 rfapi_cfg
= bgp
->rfapi_cfg
;
1995 if (!h
|| !rfapi_cfg
) {
1997 vty_out(vty
, "RFAPI not configured\n");
1998 return CMD_WARNING_CONFIG_FAILED
;
2001 for (; argc
; --argc
, ++argv
) {
2002 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2005 "local-next-hop specified more than once\n");
2006 return CMD_WARNING_CONFIG_FAILED
;
2010 "Missing parameter for local-next-hop\n");
2011 return CMD_WARNING_CONFIG_FAILED
;
2014 arg_lnh
= argv
[0]->arg
;
2016 if (strmatch(argv
[0]->text
, "local-cost")) {
2019 "local-cost specified more than once\n");
2020 return CMD_WARNING_CONFIG_FAILED
;
2024 "Missing parameter for local-cost\n");
2025 return CMD_WARNING_CONFIG_FAILED
;
2028 arg_lnh_cost
= argv
[0]->arg
;
2032 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2034 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2037 /* arg_prefix is optional if mac address is given */
2038 if (arg_macaddr
&& !arg_prefix
) {
2040 * fake up a 0/32 or 0/128 prefix
2042 switch (vn_address
.addr_family
) {
2044 arg_prefix
= "0.0.0.0/32";
2047 arg_prefix
= "0::0/128";
2051 "Internal error, unknown VN address family\n");
2052 return CMD_WARNING_CONFIG_FAILED
;
2056 if (!str2prefix(arg_prefix
, &pfx
)) {
2057 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2060 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2061 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2067 memset(optary
, 0, sizeof(optary
));
2071 cost
= strtoul(arg_cost
, &endptr
, 10);
2072 if (*endptr
!= '\0' || cost
> 255) {
2073 vty_out(vty
, "%% Invalid %s value\n", "cost");
2081 if (!strcmp(arg_lifetime
, "infinite")) {
2082 lifetime
= RFAPI_INFINITE_LIFETIME
;
2085 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2086 if (*endptr
!= '\0') {
2087 vty_out(vty
, "%% Invalid %s value\n",
2093 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2099 "%% %s may only be specified with local-next-hop\n",
2104 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2105 if (*endptr
!= '\0' || lnh_cost
> 255) {
2106 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2116 "%% %s may only be specified with prefix\n",
2120 if ((rc
= rfapiCliGetPrefixAddr(
2122 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2127 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2128 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2131 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2138 if (arg_vni
&& !arg_macaddr
) {
2139 vty_out(vty
, "%% %s may only be specified with mac address\n",
2140 "virtual-network-identifier");
2147 "Missing \"vni\" parameter (mandatory with mac)\n");
2148 return CMD_WARNING_CONFIG_FAILED
;
2150 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2151 strtoul(arg_vni
, NULL
, 10);
2153 if ((rc
= rfapiStr2EthAddr(
2155 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2156 vty_out(vty
, "Invalid %s value\n", "mac address");
2159 /* TBD label, NVE ID */
2161 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2164 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2171 vnc_zlog_debug_verbose(
2172 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2173 __func__
, arg_vn
, arg_un
, arg_prefix
,
2174 (arg_cost
? arg_cost
: "NULL"),
2175 (arg_lifetime
? arg_lifetime
: "NULL"),
2176 (arg_lnh
? arg_lnh
: "NULL"));
2178 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2180 rpfx
.cost
= cost
& 255;
2182 /* look up rf descriptor, call open if it doesn't exist */
2183 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2184 (struct rfapi_descriptor
**)&rfd
);
2187 struct rfapi_un_option uo
;
2190 * flag descriptor as provisionally opened for static
2192 * registration so that we can fix up the other
2194 * when the real open comes along
2196 memset(&uo
, 0, sizeof(uo
));
2197 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2199 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2200 &vn_address
, &un_address
,
2202 NULL
, NULL
, /* no userdata */
2206 "Can't open session for this NVE: %s\n",
2207 rfapi_error_str(rc
));
2208 rc
= CMD_WARNING_CONFIG_FAILED
;
2212 vty_out(vty
, "Can't find session for this NVE: %s\n",
2213 rfapi_error_str(rc
));
2218 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2219 RFAPI_REGISTER_ADD
);
2221 struct rfapi_next_hop_entry
*head
= NULL
;
2222 struct rfapi_next_hop_entry
*tail
= NULL
;
2223 struct rfapi_vn_option
*vn_opt_new
;
2225 vnc_zlog_debug_verbose(
2226 "%s: rfapi_register succeeded, returning 0", __func__
);
2228 if (h
->rfp_methods
.local_cb
) {
2229 struct rfapi_descriptor
*r
=
2230 (struct rfapi_descriptor
*)rfd
;
2231 vn_opt_new
= rfapi_vn_options_dup(opt
);
2233 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2235 vn_opt_new
, &head
, &tail
);
2237 h
->flags
|= RFAPI_INCALLBACK
;
2238 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2239 h
->flags
&= ~RFAPI_INCALLBACK
;
2246 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2248 vty_out(vty
, "Registration failed.\n");
2250 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2251 return CMD_WARNING_CONFIG_FAILED
;
2254 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2258 /************************************************************************
2259 * Add prefix With LNH_OPTIONS...
2260 ************************************************************************/
2261 DEFUN (add_vnc_prefix_cost_life_lnh
,
2262 add_vnc_prefix_cost_life_lnh_cmd
,
2263 "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...",
2264 "Add registration\n"
2266 "Add/modify prefix related information\n"
2269 "VN address of NVE\n"
2270 "VN IPv4 interface address\n"
2271 "VN IPv6 interface address\n"
2272 "UN address of NVE\n"
2273 "UN IPv4 interface address\n"
2274 "UN IPv6 interface address\n"
2275 "Administrative cost [default: 255]\n"
2276 "Administrative cost\n"
2277 "Registration lifetime [default: infinite]\n"
2278 "Lifetime value in seconds\n"
2279 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2281 /* pfx vn un cost life */
2282 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2284 NULL
, NULL
, argc
- 12, argv
+ 12);
2287 DEFUN (add_vnc_prefix_life_cost_lnh
,
2288 add_vnc_prefix_life_cost_lnh_cmd
,
2289 "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...",
2290 "Add registration\n"
2292 "Add/modify prefix related information\n"
2295 "VN address of NVE\n"
2296 "VN IPv4 interface address\n"
2297 "VN IPv6 interface address\n"
2298 "UN address of NVE\n"
2299 "UN IPv4 interface address\n"
2300 "UN IPv6 interface address\n"
2301 "Registration lifetime [default: infinite]\n"
2302 "Lifetime value in seconds\n"
2303 "Administrative cost [default: 255]\n"
2304 "Administrative cost\n"
2305 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2307 /* pfx vn un cost life */
2308 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2310 NULL
, NULL
, argc
- 12, argv
+ 12);
2313 DEFUN (add_vnc_prefix_cost_lnh
,
2314 add_vnc_prefix_cost_lnh_cmd
,
2315 "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...",
2316 "Add registration\n"
2318 "Add/modify prefix related information\n"
2321 "VN address of NVE\n"
2322 "VN IPv4 interface address\n"
2323 "VN IPv6 interface address\n"
2324 "UN address of NVE\n"
2325 "UN IPv4 interface address\n"
2326 "UN IPv6 interface address\n"
2327 "Administrative cost [default: 255]\n"
2328 "Administrative cost\n"
2329 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2331 /* pfx vn un cost life */
2332 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2334 NULL
, NULL
, argc
- 10, argv
+ 10);
2337 DEFUN (add_vnc_prefix_life_lnh
,
2338 add_vnc_prefix_life_lnh_cmd
,
2339 "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...",
2340 "Add registration\n"
2342 "Add/modify prefix related information\n"
2345 "VN address of NVE\n"
2346 "VN IPv4 interface address\n"
2347 "VN IPv6 interface address\n"
2348 "UN address of NVE\n"
2349 "UN IPv4 interface address\n"
2350 "UN IPv6 interface address\n"
2351 "Registration lifetime [default: infinite]\n"
2352 "Lifetime value in seconds\n"
2353 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2355 /* pfx vn un cost life */
2356 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2358 NULL
, NULL
, argc
- 10, argv
+ 10);
2361 DEFUN (add_vnc_prefix_lnh
,
2362 add_vnc_prefix_lnh_cmd
,
2363 "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...",
2364 "Add registration\n"
2366 "Add/modify prefix related information\n"
2369 "VN address of NVE\n"
2370 "VN IPv4 interface address\n"
2371 "VN IPv6 interface address\n"
2372 "UN address of NVE\n"
2373 "UN IPv4 interface address\n"
2374 "UN IPv6 interface address\n"
2375 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2377 /* pfx vn un cost life */
2378 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2380 NULL
, NULL
, argc
- 8, argv
+ 8);
2383 /************************************************************************
2384 * Add prefix Without LNH_OPTIONS...
2385 ************************************************************************/
2386 DEFUN (add_vnc_prefix_cost_life
,
2387 add_vnc_prefix_cost_life_cmd
,
2388 "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)",
2389 "Add registration\n"
2391 "Add/modify prefix related information\n"
2394 "VN address of NVE\n"
2395 "VN IPv4 interface address\n"
2396 "VN IPv6 interface address\n"
2397 "UN address of NVE\n"
2398 "UN IPv4 interface address\n"
2399 "UN IPv6 interface address\n"
2400 "Administrative cost [default: 255]\n"
2401 "Administrative cost\n"
2402 "Registration lifetime [default: infinite]\n"
2403 "Lifetime value in seconds\n")
2405 /* pfx vn un cost life */
2406 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2408 NULL
, NULL
, 0, NULL
);
2411 DEFUN (add_vnc_prefix_life_cost
,
2412 add_vnc_prefix_life_cost_cmd
,
2413 "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)",
2414 "Add registration\n"
2416 "Add/modify prefix related information\n"
2419 "VN address of NVE\n"
2420 "VN IPv4 interface address\n"
2421 "VN IPv6 interface address\n"
2422 "UN address of NVE\n"
2423 "UN IPv4 interface address\n"
2424 "UN IPv6 interface address\n"
2425 "Registration lifetime [default: infinite]\n"
2426 "Lifetime value in seconds\n"
2427 "Administrative cost [default: 255]\n"
2428 "Administrative cost\n")
2430 /* pfx vn un cost life */
2431 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2433 NULL
, NULL
, 0, NULL
);
2436 DEFUN (add_vnc_prefix_cost
,
2437 add_vnc_prefix_cost_cmd
,
2438 "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)",
2439 "Add registration\n"
2441 "Add/modify prefix related information\n"
2444 "VN address of NVE\n"
2445 "VN IPv4 interface address\n"
2446 "VN IPv6 interface address\n"
2447 "UN address of NVE\n"
2448 "UN IPv4 interface address\n"
2449 "UN IPv6 interface address\n"
2450 "Administrative cost [default: 255]\n"
2451 "Administrative cost\n")
2453 /* pfx vn un cost life */
2454 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2456 NULL
, NULL
, 0, NULL
);
2459 DEFUN (add_vnc_prefix_life
,
2460 add_vnc_prefix_life_cmd
,
2461 "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)",
2462 "Add registration\n"
2464 "Add/modify prefix related information\n"
2467 "VN address of NVE\n"
2468 "VN IPv4 interface address\n"
2469 "VN IPv6 interface address\n"
2470 "UN address of NVE\n"
2471 "UN IPv4 interface address\n"
2472 "UN IPv6 interface address\n"
2473 "Registration lifetime [default: infinite]\n"
2474 "Lifetime value in seconds\n")
2476 /* pfx vn un cost life */
2477 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2479 NULL
, NULL
, 0, NULL
);
2482 DEFUN (add_vnc_prefix
,
2484 "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>",
2485 "Add registration\n"
2487 "Add/modify prefix related information\n"
2490 "VN address of NVE\n"
2491 "VN IPv4 interface address\n"
2492 "VN IPv6 interface address\n"
2493 "UN address of NVE\n"
2494 "UN IPv4 interface address\n"
2495 "UN IPv6 interface address\n")
2497 /* pfx vn un cost life */
2498 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2500 NULL
, NULL
, 0, NULL
);
2503 /************************************************************************
2504 * Mac address registrations
2505 ************************************************************************/
2506 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2507 add_vnc_mac_vni_prefix_cost_life_cmd
,
2508 "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)",
2509 "Add registration\n"
2511 "Add/modify mac address information\n"
2513 "Virtual Network Identifier follows\n"
2514 "Virtual Network Identifier\n"
2515 "VN address of NVE\n"
2516 "VN IPv4 interface address\n"
2517 "VN IPv6 interface address\n"
2518 "UN address of NVE\n"
2519 "UN IPv4 interface address\n"
2520 "UN IPv6 interface address\n"
2521 "Add/modify prefix related information\n"
2524 "Administrative cost [default: 255]\n"
2525 "Administrative cost\n"
2526 "Registration lifetime [default: infinite]\n"
2527 "Lifetime value in seconds\n")
2529 /* pfx vn un cost life */
2530 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2532 argv
[3], argv
[5], 0, NULL
);
2536 DEFUN (add_vnc_mac_vni_prefix_life
,
2537 add_vnc_mac_vni_prefix_life_cmd
,
2538 "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)",
2539 "Add registration\n"
2541 "Add/modify mac address information\n"
2543 "Virtual Network Identifier follows\n"
2544 "Virtual Network Identifier\n"
2545 "VN address of NVE\n"
2546 "VN IPv4 interface address\n"
2547 "VN IPv6 interface address\n"
2548 "UN address of NVE\n"
2549 "UN IPv4 interface address\n"
2550 "UN IPv6 interface address\n"
2551 "Add/modify prefix related information\n"
2554 "Registration lifetime [default: infinite]\n"
2555 "Lifetime value in seconds\n")
2557 /* pfx vn un cost life */
2558 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2560 argv
[3], argv
[5], 0, NULL
);
2563 DEFUN (add_vnc_mac_vni_prefix_cost
,
2564 add_vnc_mac_vni_prefix_cost_cmd
,
2565 "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)",
2566 "Add registration\n"
2568 "Add/modify mac address information\n"
2570 "Virtual Network Identifier follows\n"
2571 "Virtual Network Identifier\n"
2572 "VN address of NVE\n"
2573 "VN IPv4 interface address\n"
2574 "VN IPv6 interface address\n"
2575 "UN address of NVE\n"
2576 "UN IPv4 interface address\n"
2577 "UN IPv6 interface address\n"
2578 "Add/modify prefix related information\n"
2581 "Administrative cost [default: 255]\n" "Administrative cost\n")
2583 /* pfx vn un cost life */
2584 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2586 argv
[3], argv
[5], 0, NULL
);
2589 DEFUN (add_vnc_mac_vni_prefix
,
2590 add_vnc_mac_vni_prefix_cmd
,
2591 "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>",
2592 "Add registration\n"
2594 "Add/modify mac address information\n"
2596 "Virtual Network Identifier follows\n"
2597 "Virtual Network Identifier\n"
2598 "VN address of NVE\n"
2599 "VN IPv4 interface address\n"
2600 "VN IPv6 interface address\n"
2601 "UN address of NVE\n"
2602 "UN IPv4 interface address\n"
2603 "UN IPv6 interface address\n"
2604 "Add/modify prefix related information\n"
2605 "IPv4 prefix\n" "IPv6 prefix\n")
2607 /* pfx vn un cost life */
2608 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2610 argv
[3], argv
[5], 0, NULL
);
2613 DEFUN (add_vnc_mac_vni_cost_life
,
2614 add_vnc_mac_vni_cost_life_cmd
,
2615 "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)",
2616 "Add registration\n"
2618 "Add/modify mac address information\n"
2620 "Virtual Network Identifier follows\n"
2621 "Virtual Network Identifier\n"
2622 "VN address of NVE\n"
2623 "VN IPv4 interface address\n"
2624 "VN IPv6 interface address\n"
2625 "UN address of NVE\n"
2626 "UN IPv4 interface address\n"
2627 "UN IPv6 interface address\n"
2628 "Administrative cost [default: 255]\n"
2629 "Administrative cost\n"
2630 "Registration lifetime [default: infinite]\n"
2631 "Lifetime value in seconds\n")
2633 /* pfx vn un cost life */
2634 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2636 argv
[3], argv
[5], 0, NULL
);
2640 DEFUN (add_vnc_mac_vni_cost
,
2641 add_vnc_mac_vni_cost_cmd
,
2642 "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)",
2643 "Add registration\n"
2645 "Add/modify mac address information\n"
2647 "Virtual Network Identifier follows\n"
2648 "Virtual Network Identifier\n"
2649 "VN address of NVE\n"
2650 "VN IPv4 interface address\n"
2651 "VN IPv6 interface address\n"
2652 "UN address of NVE\n"
2653 "UN IPv4 interface address\n"
2654 "UN IPv6 interface address\n"
2655 "Administrative cost [default: 255]\n" "Administrative cost\n")
2657 /* pfx vn un cost life */
2658 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2660 argv
[3], argv
[5], 0, NULL
);
2664 DEFUN (add_vnc_mac_vni_life
,
2665 add_vnc_mac_vni_life_cmd
,
2666 "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)",
2667 "Add registration\n"
2669 "Add/modify mac address information\n"
2671 "Virtual Network Identifier follows\n"
2672 "Virtual Network Identifier\n"
2673 "VN address of NVE\n"
2674 "VN IPv4 interface address\n"
2675 "VN IPv6 interface address\n"
2676 "UN address of NVE\n"
2677 "UN IPv4 interface address\n"
2678 "UN IPv6 interface address\n"
2679 "Registration lifetime [default: infinite]\n"
2680 "Lifetime value in seconds\n")
2682 /* pfx vn un cost life */
2683 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2685 argv
[3], argv
[5], 0, NULL
);
2689 DEFUN (add_vnc_mac_vni
,
2690 add_vnc_mac_vni_cmd
,
2691 "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>",
2692 "Add registration\n"
2694 "Add/modify mac address information\n"
2696 "Virtual Network Identifier follows\n"
2697 "Virtual Network Identifier\n"
2698 "VN address of NVE\n"
2699 "VN IPv4 interface address\n"
2700 "VN IPv6 interface address\n"
2701 "UN address of NVE\n"
2702 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2704 /* pfx vn un cost life */
2705 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2707 argv
[3], argv
[5], 0, NULL
);
2710 /************************************************************************
2712 ************************************************************************/
2714 struct rfapi_local_reg_delete_arg
{
2719 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2720 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2721 struct prefix prefix
; /* AF==0: wildcard */
2722 struct prefix_rd rd
; /* plen!=64: wildcard */
2723 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2725 struct rfapi_l2address_option_match l2o
;
2733 uint32_t query_count
;
2735 uint32_t failed_pfx_count
;
2738 struct skiplist
*nves
;
2740 uint32_t remote_active_nve_count
;
2741 uint32_t remote_active_pfx_count
;
2742 uint32_t remote_holddown_nve_count
;
2743 uint32_t remote_holddown_pfx_count
;
2747 struct rfapi_ip_addr vn
;
2748 struct rfapi_ip_addr un
;
2749 struct rfapi_descriptor
*rfd
;
2750 struct rfapi_local_reg_delete_arg
*cda
;
2753 static void nve_addr_free(void *hap
)
2755 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2756 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2759 static int nve_addr_cmp(void *k1
, void *k2
)
2761 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2762 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2768 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2769 return (a
->un
.addr_family
- b
->un
.addr_family
);
2771 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2772 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2774 if (a
->un
.addr_family
== AF_INET
) {
2775 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2779 } else if (a
->un
.addr_family
== AF_INET6
) {
2780 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2787 if (a
->vn
.addr_family
== AF_INET
) {
2788 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2791 } else if (a
->vn
.addr_family
== AF_INET6
) {
2792 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2802 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2803 const char *arg_prefix
, const char *arg_vn
,
2804 const char *arg_un
, const char *arg_l2addr
,
2805 const char *arg_vni
, const char *arg_rd
,
2806 struct rfapi_nve_group_cfg
*arg_rfg
,
2807 struct rfapi_local_reg_delete_arg
*rcdarg
)
2809 int rc
= CMD_WARNING
;
2811 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2815 bgp
= bgp_get_default();
2817 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2819 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2820 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2821 &rcdarg
->vn_address
)))
2824 if (arg_un
&& strcmp(arg_un
, "*")) {
2825 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2826 &rcdarg
->un_address
)))
2829 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2831 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2832 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2839 vty_out(vty
, "Missing VNI\n");
2842 if (strcmp(arg_l2addr
, "*")) {
2843 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2844 &rcdarg
->l2o
.o
.macaddr
))) {
2845 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2849 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2851 if (strcmp(arg_vni
, "*")) {
2852 rcdarg
->l2o
.o
.logical_net_id
=
2853 strtoul(arg_vni
, NULL
, 10);
2854 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2858 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2859 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2868 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2869 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2870 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2871 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2872 struct rfapi_nve_group_cfg
*arg_rfg
,
2873 struct rfapi_local_reg_delete_arg
*rcdarg
)
2875 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2876 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2877 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2878 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2879 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2880 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2881 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2882 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2885 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2886 struct rfapi_ip_addr
*un_address
,
2887 struct rfapi_ip_addr
*vn_address
,
2888 struct rfapi_descriptor
*rfd
)
2891 struct nve_addr
*hap
;
2893 memset(&ha
, 0, sizeof(ha
));
2894 ha
.un
= *un_address
;
2895 ha
.vn
= *vn_address
;
2899 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2901 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2902 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2906 skiplist_insert(cda
->nves
, hap
, hap
);
2910 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2913 struct rfapi_descriptor
*rfd
;
2914 int query_count
= 0;
2915 struct listnode
*node
;
2916 struct bgp
*bgp_default
= bgp_get_default();
2918 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2922 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2923 &cda
->un_address
, &rfd
))
2927 rfapi_query_done_all(rfd
, &query_count
);
2928 cda
->query_count
+= query_count
;
2931 * Track unique nves seen
2933 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2944 h
= bgp_default
->rfapi
;
2949 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2951 * match un, vn addresses of NVEs
2953 if (cda
->un_address
.addr_family
2954 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2957 if (cda
->vn_address
.addr_family
2958 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2964 rfapi_query_done_all(rfd
, &query_count
);
2965 cda
->query_count
+= query_count
;
2968 * Track unique nves seen
2970 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2975 * TBD need to count deleted prefixes and nves?
2977 * ENXIO BGP or VNC not configured
2979 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2980 struct rfapi_descriptor
*rfd
)
2982 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2983 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2984 struct prefix
*pPrefix
; /* NULL = wildcard */
2985 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2987 struct rfapi_ip_prefix rprefix
;
2988 struct rfapi_next_hop_entry
*head
= NULL
;
2989 struct rfapi_next_hop_entry
*tail
= NULL
;
2992 vnc_zlog_debug_verbose("%s: entry", __func__
);
2995 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2996 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2997 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2998 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
3001 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3004 do /* to preserve old code structure */
3006 struct rfapi
*h
= cda
->bgp
->rfapi
;
3008 struct rfapi_adb
*adb
;
3010 int deleted_from_this_nve
;
3012 struct nve_addr
*hap
;
3015 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3019 * match un, vn addresses of NVEs
3021 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3023 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3027 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3034 deleted_from_this_nve
= 0;
3037 struct skiplist
*sl
;
3038 struct rfapi_ip_prefix rp
;
3040 struct list
*adb_delete_list
;
3043 * The advertisements are stored in a skiplist.
3045 * the registration deletes the advertisement from the
3046 * skiplist, which we can't do while iterating over that
3047 * same skiplist using the current skiplist API.
3049 * Strategy: iterate over the skiplist and build another
3050 * list containing only the matching ADBs. Then delete
3051 * _everything_ in that second list (which can be done
3052 * using either skiplists or quagga linklists).
3054 adb_delete_list
= list_new();
3057 * Advertised IP prefixes (not 0/32 or 0/128)
3059 sl
= rfd
->advertised
.ipN_by_prefix
;
3062 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3064 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3068 if (!prefix_same(pPrefix
,
3069 &adb
->u
.s
.prefix_ip
)) {
3071 vnc_zlog_debug_verbose(
3072 "%s: adb=%p, prefix doesn't match, skipping",
3079 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3083 vnc_zlog_debug_verbose(
3084 "%s: adb=%p, RD doesn't match, skipping",
3090 if (CHECK_FLAG(cda
->l2o
.flags
,
3091 RFAPI_L2O_MACADDR
)) {
3092 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3093 adb
->u
.s
.prefix_eth
.u
3097 vnc_zlog_debug_verbose(
3098 "%s: adb=%p, macaddr doesn't match, skipping",
3105 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3106 if (cda
->l2o
.o
.logical_net_id
3107 != adb
->l2o
.logical_net_id
) {
3109 vnc_zlog_debug_verbose(
3110 "%s: adb=%p, LNI doesn't match, skipping",
3118 vnc_zlog_debug_verbose(
3119 "%s: ipN adding adb %p to delete list",
3123 listnode_add(adb_delete_list
, adb
);
3126 struct listnode
*node
;
3128 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3129 int this_advertisement_prefix_count
;
3130 struct rfapi_vn_option optary
[3];
3131 struct rfapi_vn_option
*opt
= NULL
;
3134 this_advertisement_prefix_count
= 1;
3136 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3138 memset(optary
, 0, sizeof(optary
));
3140 /* if mac addr present in advert, make l2o vn
3142 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3144 opt
->next
= &optary
[cur_opt
];
3145 opt
= &optary
[cur_opt
++];
3146 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3147 opt
->v
.l2addr
.macaddr
=
3148 adb
->u
.s
.prefix_eth
.u
3150 ++this_advertisement_prefix_count
;
3153 * use saved RD value instead of trying to
3155 * complex RD computation in rfapi_register()
3158 opt
->next
= &optary
[cur_opt
];
3159 opt
= &optary
[cur_opt
++];
3160 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3161 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3164 vnc_zlog_debug_verbose(
3165 "%s: ipN killing reg from adb %p ",
3169 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3170 (cur_opt
? optary
: NULL
),
3171 RFAPI_REGISTER_KILL
);
3174 this_advertisement_prefix_count
;
3175 cda
->reg_count
+= 1;
3176 deleted_from_this_nve
= 1;
3178 if (h
->rfp_methods
.local_cb
) {
3179 rfapiAddDeleteLocalRfpPrefix(
3180 &rfd
->un_addr
, &rfd
->vn_addr
,
3181 &rp
, 0, 0, NULL
, &head
, &tail
);
3184 list_delete_all_node(adb_delete_list
);
3186 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3190 * Caller didn't specify a prefix, or specified
3195 * Advertised 0/32 and 0/128 (indexed by
3198 sl
= rfd
->advertised
.ip0_by_ether
;
3201 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3204 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3207 if (CHECK_FLAG(cda
->l2o
.flags
,
3208 RFAPI_L2O_MACADDR
)) {
3209 if (memcmp(cda
->l2o
.o
.macaddr
3211 adb
->u
.s
.prefix_eth
.u
3219 if (CHECK_FLAG(cda
->l2o
.flags
,
3221 if (cda
->l2o
.o
.logical_net_id
3222 != adb
->l2o
.logical_net_id
) {
3227 vnc_zlog_debug_verbose(
3228 "%s: ip0 adding adb %p to delete list",
3231 listnode_add(adb_delete_list
, adb
);
3235 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3238 struct rfapi_vn_option vn
;
3240 rfapiQprefix2Rprefix(
3241 &adb
->u
.s
.prefix_ip
, &rp
);
3243 memset(&vn
, 0, sizeof(vn
));
3244 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3245 vn
.v
.l2addr
= adb
->l2o
;
3248 vnc_zlog_debug_verbose(
3249 "%s: ip0 killing reg from adb %p ",
3253 rc
= rfapi_register(
3254 rfd
, &rp
, 0, NULL
, &vn
,
3255 RFAPI_REGISTER_KILL
);
3257 cda
->pfx_count
+= 1;
3258 cda
->reg_count
+= 1;
3259 deleted_from_this_nve
= 1;
3261 if (h
->rfp_methods
.local_cb
) {
3262 struct rfapi_vn_option
3266 rfapi_vn_options_dup(
3268 rfapiAddDeleteLocalRfpPrefix(
3270 &rfd
->vn_addr
, &rp
, 0,
3271 0, vn_opt_new
, &head
,
3275 list_delete_all_node(adb_delete_list
);
3277 list_delete(adb_delete_list
);
3281 if (head
) { /* should not be set if (NULL ==
3282 rfapi_cfg->local_cb) */
3283 h
->flags
|= RFAPI_INCALLBACK
;
3284 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3285 h
->flags
&= ~RFAPI_INCALLBACK
;
3289 if (deleted_from_this_nve
) {
3291 * track unique NVEs seen
3293 memset(&ha
, 0, sizeof(ha
));
3294 ha
.un
= rfd
->un_addr
;
3295 ha
.vn
= rfd
->vn_addr
;
3298 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3300 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3301 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3302 sizeof(struct nve_addr
));
3306 skiplist_insert(cda
->nves
, hap
, hap
);
3309 } while (0); /* to preserve old code structure */
3314 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3319 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3320 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3322 struct bgp
*bgp
= cda
->bgp
;
3324 struct rfapi_cfg
*rfapi_cfg
;
3326 struct listnode
*node
;
3327 struct rfapi_descriptor
*rfd
;
3331 rfapi_cfg
= bgp
->rfapi_cfg
;
3332 if (!h
|| !rfapi_cfg
)
3334 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3336 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3337 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3346 * Deletes local and remote prefixes that match
3348 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3350 struct prefix pfx_un
;
3351 struct prefix pfx_vn
;
3353 struct prefix
*pUN
= NULL
;
3354 struct prefix
*pVN
= NULL
;
3355 struct prefix
*pPrefix
= NULL
;
3357 struct rfapi_import_table
*it
= NULL
;
3360 * Delete matching remote prefixes in holddown
3362 if (cda
->vn_address
.addr_family
) {
3363 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3366 if (cda
->un_address
.addr_family
) {
3367 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3370 if (cda
->prefix
.family
) {
3371 pPrefix
= &cda
->prefix
;
3374 it
= cda
->rfg
->rfapi_import_table
;
3376 rfapiDeleteRemotePrefixes(
3377 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3378 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3379 &cda
->remote_holddown_nve_count
);
3382 * Now do local prefixes
3384 rfapiDeleteLocalPrefixes(cda
);
3387 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3389 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3391 /* Our special element-deleting function counts nves */
3393 skiplist_free(cda
->nves
);
3396 if (cda
->failed_pfx_count
)
3397 vty_out(vty
, "Failed to delete %d prefixes\n",
3398 cda
->failed_pfx_count
);
3400 /* left as "prefixes" even in single case for ease of machine parsing */
3402 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3403 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3407 * We don't currently allow deletion of active remote prefixes from
3411 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3412 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3416 * Caller has already deleted registrations and queries for this/these
3417 * NVEs. Now we just have to close their descriptors.
3419 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3421 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3422 struct nve_addr
*pKey
;
3423 struct nve_addr
*pValue
;
3424 void *cursor
= NULL
;
3430 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3431 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3435 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3436 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3437 rfapi_close(pValue
->rfd
);
3442 DEFUN (clear_vnc_nve_all
,
3443 clear_vnc_nve_all_cmd
,
3447 "Clear per NVE information\n"
3451 struct rfapi_local_reg_delete_arg cda
;
3454 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3460 clear_vnc_responses(&cda
);
3461 clear_vnc_prefix(&cda
);
3462 clear_vnc_nve_closer(&cda
);
3464 print_cleared_stats(&cda
);
3469 DEFUN (clear_vnc_nve_vn_un
,
3470 clear_vnc_nve_vn_un_cmd
,
3471 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3474 "Clear prefix registration information\n"
3475 "VN address of NVE\n"
3477 "VN IPv4 interface address\n"
3478 "VN IPv6 interface address\n"
3479 "UN address of NVE\n"
3480 "For all UN addresses\n"
3481 "UN IPv4 interface address\n"
3482 "UN IPv6 interface address\n")
3484 struct rfapi_local_reg_delete_arg cda
;
3487 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3488 NULL
, NULL
, NULL
, &cda
)))
3493 clear_vnc_responses(&cda
);
3494 clear_vnc_prefix(&cda
);
3495 clear_vnc_nve_closer(&cda
);
3497 print_cleared_stats(&cda
);
3502 DEFUN (clear_vnc_nve_un_vn
,
3503 clear_vnc_nve_un_vn_cmd
,
3504 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3507 "Clear prefix registration information\n"
3508 "UN address of NVE\n"
3510 "UN IPv4 interface address\n"
3511 "UN IPv6 interface address\n"
3512 "VN address of NVE\n"
3514 "VN IPv4 interface address\n"
3515 "VN IPv6 interface address\n")
3517 struct rfapi_local_reg_delete_arg cda
;
3520 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3521 NULL
, NULL
, NULL
, &cda
)))
3526 clear_vnc_responses(&cda
);
3527 clear_vnc_prefix(&cda
);
3528 clear_vnc_nve_closer(&cda
);
3530 print_cleared_stats(&cda
);
3535 DEFUN (clear_vnc_nve_vn
,
3536 clear_vnc_nve_vn_cmd
,
3537 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3540 "Clear prefix registration information\n"
3541 "VN address of NVE\n"
3543 "VN IPv4 interface address\n"
3544 "VN IPv6 interface address\n")
3546 struct rfapi_local_reg_delete_arg cda
;
3549 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3550 NULL
, NULL
, NULL
, &cda
)))
3555 clear_vnc_responses(&cda
);
3556 clear_vnc_prefix(&cda
);
3557 clear_vnc_nve_closer(&cda
);
3559 print_cleared_stats(&cda
);
3563 DEFUN (clear_vnc_nve_un
,
3564 clear_vnc_nve_un_cmd
,
3565 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3568 "Clear prefix registration information\n"
3569 "UN address of NVE\n"
3571 "UN IPv4 interface address\n"
3572 "UN IPv6 interface address\n")
3574 struct rfapi_local_reg_delete_arg cda
;
3577 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3578 NULL
, NULL
, NULL
, &cda
)))
3583 clear_vnc_responses(&cda
);
3584 clear_vnc_prefix(&cda
);
3585 clear_vnc_nve_closer(&cda
);
3587 print_cleared_stats(&cda
);
3591 /*-------------------------------------------------
3593 *-------------------------------------------------*/
3596 * This function is defined in this file (rather than in rfp_registration.c)
3597 * because here we have access to all the task handles.
3599 DEFUN (clear_vnc_prefix_vn_un
,
3600 clear_vnc_prefix_vn_un_cmd
,
3601 "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>",
3604 "Clear prefix registration information\n"
3608 "VN address of NVE\n"
3609 "All VN addresses\n"
3610 "VN IPv4 interface address\n"
3611 "VN IPv6 interface address\n"
3612 "UN address of NVE\n"
3613 "All UN addresses\n"
3614 "UN IPv4 interface address\n"
3615 "UN IPv6 interface address\n")
3617 struct rfapi_local_reg_delete_arg cda
;
3620 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3621 NULL
, NULL
, NULL
, NULL
, &cda
)))
3624 clear_vnc_prefix(&cda
);
3625 print_cleared_stats(&cda
);
3629 DEFUN (clear_vnc_prefix_un_vn
,
3630 clear_vnc_prefix_un_vn_cmd
,
3631 "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>",
3634 "Clear prefix registration information\n"
3638 "UN address of NVE\n"
3639 "All UN addresses\n"
3640 "UN IPv4 interface address\n"
3641 "UN IPv6 interface address\n"
3642 "VN address of NVE\n"
3643 "All VN addresses\n"
3644 "VN IPv4 interface address\n"
3645 "VN IPv6 interface address\n")
3647 struct rfapi_local_reg_delete_arg cda
;
3650 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3651 NULL
, NULL
, NULL
, NULL
, &cda
)))
3654 clear_vnc_prefix(&cda
);
3655 print_cleared_stats(&cda
);
3659 DEFUN (clear_vnc_prefix_un
,
3660 clear_vnc_prefix_un_cmd
,
3661 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3664 "Clear prefix registration information\n"
3668 "UN address of NVE\n"
3669 "All UN addresses\n"
3670 "UN IPv4 interface address\n"
3671 "UN IPv6 interface address\n")
3673 struct rfapi_local_reg_delete_arg cda
;
3676 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3677 NULL
, NULL
, NULL
, &cda
)))
3680 clear_vnc_prefix(&cda
);
3681 print_cleared_stats(&cda
);
3685 DEFUN (clear_vnc_prefix_vn
,
3686 clear_vnc_prefix_vn_cmd
,
3687 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3690 "Clear prefix registration information\n"
3694 "UN address of NVE\n"
3695 "All VN addresses\n"
3696 "VN IPv4 interface address\n"
3697 "VN IPv6 interface address\n")
3699 struct rfapi_local_reg_delete_arg cda
;
3702 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3703 NULL
, NULL
, NULL
, &cda
)))
3706 clear_vnc_prefix(&cda
);
3707 print_cleared_stats(&cda
);
3711 DEFUN (clear_vnc_prefix_all
,
3712 clear_vnc_prefix_all_cmd
,
3713 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3716 "Clear prefix registration information\n"
3722 struct rfapi_local_reg_delete_arg cda
;
3725 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3726 NULL
, NULL
, NULL
, &cda
)))
3729 clear_vnc_prefix(&cda
);
3730 print_cleared_stats(&cda
);
3734 /*-------------------------------------------------
3736 *-------------------------------------------------*/
3739 * This function is defined in this file (rather than in rfp_registration.c)
3740 * because here we have access to all the task handles.
3742 DEFUN (clear_vnc_mac_vn_un
,
3743 clear_vnc_mac_vn_un_cmd
,
3744 "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>",
3747 "Clear mac registration information\n"
3751 "Any virtual network identifier\n"
3752 "Virtual network identifier\n"
3753 "VN address of NVE\n"
3754 "All VN addresses\n"
3755 "VN IPv4 interface address\n"
3756 "VN IPv6 interface address\n"
3757 "UN address of NVE\n"
3758 "All UN addresses\n"
3759 "UN IPv4 interface address\n"
3760 "UN IPv6 interface address\n")
3762 struct rfapi_local_reg_delete_arg cda
;
3765 /* pfx vn un L2 VNI */
3766 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3767 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3770 clear_vnc_prefix(&cda
);
3771 print_cleared_stats(&cda
);
3775 DEFUN (clear_vnc_mac_un_vn
,
3776 clear_vnc_mac_un_vn_cmd
,
3777 "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>",
3780 "Clear mac registration information\n"
3784 "Any virtual network identifier\n"
3785 "Virtual network identifier\n"
3786 "UN address of NVE\n"
3787 "All UN addresses\n"
3788 "UN IPv4 interface address\n"
3789 "UN IPv6 interface address\n"
3790 "VN address of NVE\n"
3791 "All VN addresses\n"
3792 "VN IPv4 interface address\n"
3793 "VN IPv6 interface address\n")
3795 struct rfapi_local_reg_delete_arg cda
;
3798 /* pfx vn un L2 VNI */
3799 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3800 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3803 clear_vnc_prefix(&cda
);
3804 print_cleared_stats(&cda
);
3808 DEFUN (clear_vnc_mac_un
,
3809 clear_vnc_mac_un_cmd
,
3810 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3813 "Clear mac registration information\n"
3817 "Any virtual network identifier\n"
3818 "Virtual network identifier\n"
3819 "UN address of NVE\n"
3820 "All UN addresses\n"
3821 "UN IPv4 interface address\n"
3822 "UN IPv6 interface address\n")
3824 struct rfapi_local_reg_delete_arg cda
;
3827 /* pfx vn un L2 VNI */
3828 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3829 argv
[5], NULL
, NULL
, &cda
)))
3832 clear_vnc_prefix(&cda
);
3833 print_cleared_stats(&cda
);
3837 DEFUN (clear_vnc_mac_vn
,
3838 clear_vnc_mac_vn_cmd
,
3839 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3842 "Clear mac registration information\n"
3846 "Any virtual network identifier\n"
3847 "Virtual network identifier\n"
3848 "UN address of NVE\n"
3849 "All VN addresses\n"
3850 "VN IPv4 interface address\n"
3851 "VN IPv6 interface address\n")
3853 struct rfapi_local_reg_delete_arg cda
;
3856 /* pfx vn un L2 VNI */
3857 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3858 argv
[5], NULL
, NULL
, &cda
)))
3861 clear_vnc_prefix(&cda
);
3862 print_cleared_stats(&cda
);
3866 DEFUN (clear_vnc_mac_all
,
3867 clear_vnc_mac_all_cmd
,
3868 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3871 "Clear mac registration information\n"
3875 "Any virtual network identifier\n"
3876 "Virtual network identifier\n"
3879 struct rfapi_local_reg_delete_arg cda
;
3882 /* pfx vn un L2 VNI */
3883 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3884 argv
[5], NULL
, NULL
, &cda
)))
3887 clear_vnc_prefix(&cda
);
3888 print_cleared_stats(&cda
);
3892 /*-------------------------------------------------
3893 * Clear VNC MAC PREFIX
3894 *-------------------------------------------------*/
3896 DEFUN (clear_vnc_mac_vn_un_prefix
,
3897 clear_vnc_mac_vn_un_prefix_cmd
,
3898 "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>",
3901 "Clear mac registration information\n"
3905 "Any virtual network identifier\n"
3906 "Virtual network identifier\n"
3907 "VN address of NVE\n"
3908 "All VN addresses\n"
3909 "VN IPv4 interface address\n"
3910 "VN IPv6 interface address\n"
3911 "UN address of NVE\n"
3912 "All UN addresses\n"
3913 "UN IPv4 interface address\n"
3914 "UN IPv6 interface address\n"
3915 "Clear prefix registration information\n"
3920 struct rfapi_local_reg_delete_arg cda
;
3923 /* pfx vn un L2 VNI */
3924 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3925 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3928 clear_vnc_prefix(&cda
);
3929 print_cleared_stats(&cda
);
3933 DEFUN (clear_vnc_mac_un_vn_prefix
,
3934 clear_vnc_mac_un_vn_prefix_cmd
,
3935 "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>",
3938 "Clear mac registration information\n"
3942 "Any virtual network identifier\n"
3943 "Virtual network identifier\n"
3944 "UN address of NVE\n"
3945 "All UN addresses\n"
3946 "UN IPv4 interface address\n"
3947 "UN IPv6 interface address\n"
3948 "VN address of NVE\n"
3949 "All VN addresses\n"
3950 "VN IPv4 interface address\n"
3951 "VN IPv6 interface address\n"
3952 "Clear prefix registration information\n"
3956 "Clear prefix registration information\n"
3961 struct rfapi_local_reg_delete_arg cda
;
3964 /* pfx vn un L2 VNI */
3965 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3966 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3969 clear_vnc_prefix(&cda
);
3970 print_cleared_stats(&cda
);
3974 DEFUN (clear_vnc_mac_un_prefix
,
3975 clear_vnc_mac_un_prefix_cmd
,
3976 "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>",
3979 "Clear mac registration information\n"
3983 "Any virtual network identifier\n"
3984 "Virtual network identifier\n"
3985 "UN address of NVE\n"
3986 "All UN addresses\n"
3987 "UN IPv4 interface address\n"
3988 "UN IPv6 interface address\n"
3989 "Clear prefix registration information\n"
3994 struct rfapi_local_reg_delete_arg cda
;
3997 /* pfx vn un L2 VNI */
3998 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3999 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4002 clear_vnc_prefix(&cda
);
4003 print_cleared_stats(&cda
);
4007 DEFUN (clear_vnc_mac_vn_prefix
,
4008 clear_vnc_mac_vn_prefix_cmd
,
4009 "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>",
4012 "Clear mac registration information\n"
4016 "Any virtual network identifier\n"
4017 "Virtual network identifier\n"
4018 "UN address of NVE\n"
4019 "All VN addresses\n"
4020 "VN IPv4 interface address\n"
4021 "VN IPv6 interface address\n"
4022 "Clear prefix registration information\n"
4027 struct rfapi_local_reg_delete_arg cda
;
4030 /* pfx vn un L2 VNI */
4031 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4032 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4035 clear_vnc_prefix(&cda
);
4036 print_cleared_stats(&cda
);
4040 DEFUN (clear_vnc_mac_all_prefix
,
4041 clear_vnc_mac_all_prefix_cmd
,
4042 "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>",
4045 "Clear mac registration information\n"
4049 "Any virtual network identifier\n"
4050 "Virtual network identifier\n"
4051 "UN address of NVE\n"
4052 "All VN addresses\n"
4053 "VN IPv4 interface address\n"
4054 "VN IPv6 interface address\n")
4056 struct rfapi_local_reg_delete_arg cda
;
4059 /* pfx vn un L2 VNI */
4060 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4061 argv
[5], NULL
, NULL
, &cda
)))
4064 clear_vnc_prefix(&cda
);
4065 print_cleared_stats(&cda
);
4069 /************************************************************************
4071 ************************************************************************/
4074 /* copied from rfp_vty.c */
4075 static int check_and_display_is_vnc_running(struct vty
*vty
)
4077 if (!bgp_rfapi_is_vnc_configured(NULL
))
4078 return 1; /* is running */
4082 "VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n");
4084 return 0; /* not running */
4087 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4088 show_nve_summary_t show_type
)
4090 struct bgp
*bgp_default
= bgp_get_default();
4092 int is_vnc_running
= !bgp_rfapi_is_vnc_configured(bgp_default
);
4094 int active_local_routes
;
4095 int active_remote_routes
;
4096 int holddown_remote_routes
;
4097 int imported_remote_routes
;
4102 h
= bgp_default
->rfapi
;
4107 /* don't show local info if not running RFP */
4108 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4110 switch (show_type
) {
4112 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4113 vty_out(vty
, "%-24s ", "NVEs:");
4114 vty_out(vty
, "%-8s %-8u ",
4115 "Active:", h
->descriptors
.count
);
4116 vty_out(vty
, "%-8s %-8u ",
4117 "Maximum:", h
->stat
.max_descriptors
);
4118 vty_out(vty
, "%-8s %-8u",
4119 "Unknown:", h
->stat
.count_unknown_nves
);
4122 case SHOW_NVE_SUMMARY_REGISTERED
:
4124 * NB: With the introduction of L2 route support, we no
4125 * longer have a one-to-one correspondence between
4126 * locally-originated route advertisements and routes in
4127 * the import tables that have local origin. This
4128 * discrepancy arises because a single advertisement
4129 * may contain both an IP prefix and a MAC address.
4130 * Such an advertisement results in two import table
4131 * entries: one indexed by IP prefix, the other indexed
4134 * TBD: update computation and display of registration
4135 * statistics to reflect the underlying semantics.
4137 if (is_vnc_running
) {
4138 vty_out(vty
, "%-24s ", "Registrations:");
4139 vty_out(vty
, "%-8s %-8u ", "Active:",
4140 rfapiApCountAll(bgp_default
));
4141 vty_out(vty
, "%-8s %-8u ", "Failed:",
4142 h
->stat
.count_registrations_failed
);
4143 vty_out(vty
, "%-8s %-8u",
4144 "Total:", h
->stat
.count_registrations
);
4147 vty_out(vty
, "%-24s ", "Prefixes registered:");
4150 rfapiCountAllItRoutes(&active_local_routes
,
4151 &active_remote_routes
,
4152 &holddown_remote_routes
,
4153 &imported_remote_routes
);
4156 if (is_vnc_running
) {
4157 vty_out(vty
, " %-20s ", "Locally:");
4158 vty_out(vty
, "%-8s %-8u ",
4159 "Active:", active_local_routes
);
4164 vty_out(vty
, " %-20s ", "Remotely:");
4165 vty_out(vty
, "%-8s %-8u",
4166 "Active:", active_remote_routes
);
4168 vty_out(vty
, " %-20s ", "In Holddown:");
4169 vty_out(vty
, "%-8s %-8u",
4170 "Active:", holddown_remote_routes
);
4172 vty_out(vty
, " %-20s ", "Imported:");
4173 vty_out(vty
, "%-8s %-8u",
4174 "Active:", imported_remote_routes
);
4177 case SHOW_NVE_SUMMARY_QUERIES
:
4178 vty_out(vty
, "%-24s ", "Queries:");
4179 vty_out(vty
, "%-8s %-8u ",
4180 "Active:", rfapi_monitor_count(NULL
));
4181 vty_out(vty
, "%-8s %-8u ",
4182 "Failed:", h
->stat
.count_queries_failed
);
4183 vty_out(vty
, "%-8s %-8u",
4184 "Total:", h
->stat
.count_queries
);
4187 case SHOW_NVE_SUMMARY_RESPONSES
:
4188 rfapiRibShowResponsesSummary(vty
);
4198 vty_out(vty
, "VNC is not configured.\n");
4202 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4203 struct prefix
*un_prefix
)
4205 // struct hash *rfds;
4206 // struct rfp_rfapi_descriptor_param param;
4208 struct bgp
*bgp_default
= bgp_get_default();
4210 struct listnode
*node
;
4211 struct rfapi_descriptor
*rfd
;
4220 h
= bgp_default
->rfapi
;
4225 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4229 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4231 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4234 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4242 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4243 if (!prefix_match(vn_prefix
, &pfx
))
4248 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4249 if (!prefix_match(un_prefix
, &pfx
))
4253 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4255 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4259 /* print out a header */
4261 " Active Next Hops\n");
4262 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4263 "VN Address", "UN Address", "Regis", "Resps",
4264 "Reach", "Remove", "Age");
4269 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4270 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4271 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4272 rfd
->stat_count_nh_removal
,
4273 rfapiFormatAge(rfd
->open_time
, age
, 10));
4276 if (printed
> 0 || vn_prefix
|| un_prefix
)
4277 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4283 vty_out(vty
, "VNC is not configured.\n");
4288 DEFUN (vnc_show_summary
,
4289 vnc_show_summary_cmd
,
4293 "Display VNC status summary\n")
4295 if (!check_and_display_is_vnc_running(vty
))
4297 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4299 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4300 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4301 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4302 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4306 DEFUN (vnc_show_nves
,
4311 "List known NVEs\n")
4313 rfapi_show_nves(vty
, NULL
, NULL
);
4317 DEFUN (vnc_show_nves_ptct
,
4318 vnc_show_nves_ptct_cmd
,
4319 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4323 "VN address of NVE\n"
4324 "UN address of NVE\n"
4325 "IPv4 interface address\n"
4326 "IPv6 interface address\n")
4330 if (!check_and_display_is_vnc_running(vty
))
4333 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4334 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4337 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4338 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4342 if (argv
[3]->arg
[0] == 'u') {
4343 rfapi_show_nves(vty
, NULL
, &pfx
);
4345 rfapi_show_nves(vty
, &pfx
, NULL
);
4351 /* adapted from rfp_registration_cache_log() */
4352 static void rfapi_show_registrations(struct vty
*vty
,
4353 struct prefix
*restrict_to
, int show_local
,
4354 int show_remote
, int show_holddown
,
4362 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4365 /* non-expiring, local */
4366 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4370 /* non-expiring, non-local */
4371 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4374 if (show_holddown
) {
4375 /* expiring, including local */
4376 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4379 if (show_imported
) {
4380 /* non-expiring, non-local */
4381 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4389 DEFUN (vnc_show_registrations_pfx
,
4390 vnc_show_registrations_pfx_cmd
,
4391 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4394 "List active prefix registrations\n"
4395 "Limit output to a particular IPv4 prefix\n"
4396 "Limit output to a particular IPv6 prefix\n"
4397 "Limit output to a particular IPv6 address\n")
4400 struct prefix
*p_addr
= NULL
;
4403 if (!str2prefix(argv
[3]->arg
, &p
)) {
4404 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4411 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4415 DEFUN (vnc_show_registrations_some_pfx
,
4416 vnc_show_registrations_some_pfx_cmd
,
4417 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4420 "List active prefix registrations\n"
4421 "show all registrations\n"
4422 "show only registrations in holddown\n"
4423 "show only imported prefixes\n"
4424 "show only local registrations\n"
4425 "show only remote registrations\n"
4426 "Limit output to a particular prefix or address\n"
4427 "Limit output to a particular prefix or address\n"
4428 "Limit output to a particular prefix or address\n")
4431 struct prefix
*p_addr
= NULL
;
4434 int show_remote
= 0;
4435 int show_holddown
= 0;
4436 int show_imported
= 0;
4439 if (!str2prefix(argv
[4]->arg
, &p
)) {
4440 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4446 switch (argv
[3]->arg
[0]) {
4471 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4472 show_holddown
, show_imported
);
4476 DEFUN (vnc_show_responses_pfx
,
4477 vnc_show_responses_pfx_cmd
,
4478 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4481 "List recent query responses\n"
4482 "Limit output to a particular IPv4 prefix\n"
4483 "Limit output to a particular IPv6 prefix\n"
4484 "Limit output to a particular IPv6 address\n" )
4487 struct prefix
*p_addr
= NULL
;
4490 if (!str2prefix(argv
[3]->arg
, &p
)) {
4491 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4497 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4499 rfapiRibShowResponsesSummary(vty
);
4501 rfapiRibShowResponses(vty
, p_addr
, 0);
4502 rfapiRibShowResponses(vty
, p_addr
, 1);
4507 DEFUN (vnc_show_responses_some_pfx
,
4508 vnc_show_responses_some_pfx_cmd
,
4509 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4512 "List recent query responses\n"
4513 "show only active query responses\n"
4514 "show only removed query responses\n"
4515 "Limit output to a particular IPv4 prefix\n"
4516 "Limit output to a particular IPv6 prefix\n"
4517 "Limit output to a particular IPV6 address\n")
4520 struct prefix
*p_addr
= NULL
;
4522 int show_active
= 0;
4523 int show_removed
= 0;
4525 if (!check_and_display_is_vnc_running(vty
))
4529 if (!str2prefix(argv
[4]->arg
, &p
)) {
4530 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4537 switch (argv
[3]->arg
[0]) {
4547 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4549 rfapiRibShowResponsesSummary(vty
);
4552 rfapiRibShowResponses(vty
, p_addr
, 0);
4554 rfapiRibShowResponses(vty
, p_addr
, 1);
4559 DEFUN (show_vnc_queries_pfx
,
4560 show_vnc_queries_pfx_cmd
,
4561 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4564 "List active queries\n"
4565 "Limit output to a particular IPv4 prefix or address\n"
4566 "Limit output to a particular IPv6 prefix\n"
4567 "Limit output to a particualr IPV6 address\n")
4570 struct prefix
*p
= NULL
;
4573 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4574 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4580 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4582 return rfapiShowVncQueries(vty
, p
);
4585 DEFUN (vnc_clear_counters
,
4586 vnc_clear_counters_cmd
,
4587 "clear vnc counters",
4590 "Reset VNC counters\n")
4592 struct bgp
*bgp_default
= bgp_get_default();
4594 struct listnode
*node
;
4595 struct rfapi_descriptor
*rfd
;
4600 h
= bgp_default
->rfapi
;
4606 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4607 rfd
->stat_count_nh_reachable
= 0;
4608 rfd
->stat_count_nh_removal
= 0;
4612 memset(&h
->stat
, 0, sizeof(h
->stat
));
4615 * 151122 per bug 103, set count_registrations = number active.
4616 * Do same for queries
4618 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4619 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4621 rfapiRibShowResponsesSummaryClear();
4626 vty_out(vty
, "VNC is not configured.\n");
4630 /************************************************************************
4631 * Add prefix with vrf
4633 * add [vrf <vrf-name>] prefix <prefix>
4634 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4635 ************************************************************************/
4636 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4637 const char *arg_prefix
,
4638 const char *arg_rd
, /* optional */
4639 const char *arg_label
, /* optional */
4640 const char *arg_pref
) /* optional */
4643 struct rfapi_nve_group_cfg
*rfg
;
4645 struct rfapi_ip_prefix rpfx
;
4647 struct rfapi_vn_option optary
[3];
4648 struct rfapi_vn_option
*opt
= NULL
;
4651 bgp
= bgp_get_default(); /* assume main instance for now */
4653 vty_out(vty
, "No BGP process is configured\n");
4654 return CMD_WARNING_CONFIG_FAILED
;
4656 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4657 vty_out(vty
, "VRF support not configured\n");
4658 return CMD_WARNING_CONFIG_FAILED
;
4661 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4664 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4666 return CMD_WARNING_CONFIG_FAILED
;
4668 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4670 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4672 return CMD_WARNING_CONFIG_FAILED
;
4674 if (!rfg
->rd
.family
&& !arg_rd
) {
4676 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4678 return CMD_WARNING_CONFIG_FAILED
;
4680 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4682 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4684 return CMD_WARNING_CONFIG_FAILED
;
4686 if (!str2prefix(arg_prefix
, &pfx
)) {
4687 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4688 return CMD_WARNING_CONFIG_FAILED
;
4690 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4691 memset(optary
, 0, sizeof(optary
));
4694 opt
->next
= &optary
[cur_opt
];
4695 opt
= &optary
[cur_opt
++];
4696 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4697 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4698 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4699 return CMD_WARNING_CONFIG_FAILED
;
4702 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4703 struct rfapi_l2address_option
*l2o
;
4705 opt
->next
= &optary
[cur_opt
];
4706 opt
= &optary
[cur_opt
++];
4707 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4708 l2o
= &opt
->v
.l2addr
;
4711 label
= strtoul(arg_label
, NULL
, 10);
4714 l2o
->label
= rfg
->label
;
4717 char *endptr
= NULL
;
4718 pref
= strtoul(arg_pref
, &endptr
, 10);
4719 if (*endptr
!= '\0') {
4721 "%% Invalid local-preference value \"%s\"\n",
4723 return CMD_WARNING_CONFIG_FAILED
;
4726 rpfx
.cost
= 255 - (pref
& 255);
4727 if (rfg
->rfd
== NULL
) /* need new rfapi_handle */
4729 /* based on rfapi_open */
4730 struct rfapi_descriptor
*rfd
;
4731 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4732 sizeof(struct rfapi_descriptor
));
4735 /* leave most fields empty as will get from (dynamic) config
4737 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4739 if (rfg
->vn_prefix
.family
4740 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4741 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4743 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4744 rfd
->vn_addr
.addr_family
= AF_INET
;
4745 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4747 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4749 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4751 rfapi_init_and_open(bgp
, rfd
, rfg
);
4754 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4755 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4756 struct rfapi_next_hop_entry
*head
= NULL
;
4757 struct rfapi_next_hop_entry
*tail
= NULL
;
4758 struct rfapi_vn_option
*vn_opt_new
;
4760 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4763 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4764 struct rfapi_descriptor
*r
=
4765 (struct rfapi_descriptor
*)rfg
->rfd
;
4766 vn_opt_new
= rfapi_vn_options_dup(opt
);
4768 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4770 RFAPI_INFINITE_LIFETIME
,
4771 vn_opt_new
, &head
, &tail
);
4773 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4774 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4776 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4780 vnc_zlog_debug_verbose(
4781 "%s completed, count=%d/%d", __func__
,
4782 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4783 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4787 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4788 vty_out(vty
, "Add failed.\n");
4789 return CMD_WARNING_CONFIG_FAILED
;
4792 DEFUN (add_vrf_prefix_rd_label_pref
,
4793 add_vrf_prefix_rd_label_pref_cmd
,
4794 "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)}]",
4798 "Add/modify prefix related information\n"
4801 "Override configured VRF Route Distinguisher\n"
4802 "<as-number>:<number> or <ip-address>:<number>\n"
4803 "Override configured VRF label\n"
4804 "Label Value <0-1048575>\n"
4805 "Set advertised local preference\n"
4806 "local preference (higher=more preferred)\n")
4808 char *arg_vrf
= argv
[2]->arg
;
4809 char *arg_prefix
= argv
[4]->arg
;
4810 char *arg_rd
= NULL
; /* optional */
4811 char *arg_label
= NULL
; /* optional */
4812 char *arg_pref
= NULL
; /* optional */
4814 argc
--; /* don't parse argument */
4815 while (pargc
< argc
) {
4816 switch (argv
[pargc
++]->arg
[0]) {
4818 arg_rd
= argv
[pargc
]->arg
;
4821 arg_label
= argv
[pargc
]->arg
;
4824 arg_pref
= argv
[pargc
]->arg
;
4832 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4836 /************************************************************************
4837 * del prefix with vrf
4839 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4840 ************************************************************************/
4841 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4844 afi_t afi
= AFI_MAX
;
4846 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4851 static void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4853 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4858 /* check if IT is empty */
4860 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4864 if (afi
== AFI_MAX
) {
4865 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4870 vnc_zlog_debug_verbose(
4871 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4872 rfg
->rfapi_import_table
->local_count
[afi
]);
4876 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4877 const char *arg_prefix
, /* NULL = all */
4878 const char *arg_rd
) /* optional */
4880 struct rfapi_nve_group_cfg
*rfg
;
4881 struct rfapi_local_reg_delete_arg cda
;
4886 bgp
= bgp_get_default(); /* assume main instance for now */
4888 vty_out(vty
, "No BGP process is configured\n");
4891 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4892 vty_out(vty
, "VRF support not configured\n");
4895 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4898 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4902 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4904 if (rc
!= CMD_SUCCESS
) /* parse error */
4907 start_count
= rfapi_cfg_group_it_count(rfg
);
4908 clear_vnc_prefix(&cda
);
4909 clear_vnc_vrf_closer(rfg
);
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
);