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
21 #include "lib/zebra.h"
22 #include "lib/prefix.h"
23 #include "lib/agg_table.h"
25 #include "lib/memory.h"
26 #include "lib/routemap.h"
28 #include "lib/linklist.h"
29 #include "lib/command.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_ecommunity.h"
33 #include "bgpd/bgp_attr.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_mplsvpn.h"
37 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
38 #include "bgpd/rfapi/rfapi.h"
39 #include "bgpd/rfapi/rfapi_backend.h"
41 #include "bgpd/bgp_route.h"
42 #include "bgpd/bgp_aspath.h"
43 #include "bgpd/bgp_community.h"
44 #include "bgpd/bgp_vnc_types.h"
45 #include "bgpd/bgp_label.h"
47 #include "bgpd/rfapi/rfapi_import.h"
48 #include "bgpd/rfapi/rfapi_private.h"
49 #include "bgpd/rfapi/rfapi_monitor.h"
50 #include "bgpd/rfapi/rfapi_rib.h"
51 #include "bgpd/rfapi/rfapi_vty.h"
52 #include "bgpd/rfapi/rfapi_ap.h"
53 #include "bgpd/rfapi/rfapi_encap_tlv.h"
54 #include "bgpd/rfapi/vnc_debug.h"
56 #define DEBUG_L2_EXTRA 0
57 #define DEBUG_SHOW_EXTRA 0
59 #define VNC_SHOW_STR "VNC information\n"
61 /* format related utilies */
64 #define FMT_MIN 60 /* seconds */
65 #define FMT_HOUR (60 * FMT_MIN)
66 #define FMT_DAY (24 * FMT_HOUR)
67 #define FMT_YEAR (365 * FMT_DAY)
69 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
71 int year
, day
, hour
, min
;
73 if (seconds
>= FMT_YEAR
) {
74 year
= seconds
/ FMT_YEAR
;
75 seconds
-= year
* FMT_YEAR
;
79 if (seconds
>= FMT_DAY
) {
80 day
= seconds
/ FMT_DAY
;
81 seconds
-= day
* FMT_DAY
;
85 if (seconds
>= FMT_HOUR
) {
86 hour
= seconds
/ FMT_HOUR
;
87 seconds
-= hour
* FMT_HOUR
;
91 if (seconds
>= FMT_MIN
) {
92 min
= seconds
/ FMT_MIN
;
93 seconds
-= min
* FMT_MIN
;
98 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
100 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
102 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
108 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
110 time_t now
, age_adjusted
;
112 now
= rfapi_time(NULL
);
113 age_adjusted
= now
- age
;
115 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
120 * Reimplementation of quagga/lib/prefix.c function, but
121 * for RFAPI-style prefixes
123 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
129 static const uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
130 0xf8, 0xfc, 0xfe, 0xff};
132 switch (rprefix
->prefix
.addr_family
) {
134 index
= rprefix
->length
/ 8;
136 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
137 offset
= rprefix
->length
% 8;
138 pnt
[index
] &= maskbit
[offset
];
146 index
= rprefix
->length
/ 8;
148 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
149 offset
= rprefix
->length
% 8;
150 pnt
[index
] &= maskbit
[offset
];
163 * translate a quagga prefix into a rfapi IP address. The
164 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
171 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
173 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
174 raddr
->addr_family
= qprefix
->family
;
175 switch (qprefix
->family
) {
177 if (qprefix
->prefixlen
!= 32)
179 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
182 if (qprefix
->prefixlen
!= IPV6_MAX_BITLEN
)
184 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
193 * Translate Quagga prefix to RFAPI prefix
195 /* rprefix->cost set to 0 */
196 void rfapiQprefix2Rprefix(const struct prefix
*qprefix
,
197 struct rfapi_ip_prefix
*rprefix
)
199 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
200 rprefix
->length
= qprefix
->prefixlen
;
201 rprefix
->prefix
.addr_family
= qprefix
->family
;
202 switch (qprefix
->family
) {
204 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
207 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
214 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
215 struct prefix
*qprefix
)
217 memset(qprefix
, 0, sizeof(struct prefix
));
218 qprefix
->prefixlen
= rprefix
->length
;
219 qprefix
->family
= rprefix
->prefix
.addr_family
;
221 switch (rprefix
->prefix
.addr_family
) {
223 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
226 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
235 * returns 1 if prefixes have same addr family, prefix len, and address
236 * Note that host bits matter in this comparison!
238 * For paralellism with quagga/lib/prefix.c. if we need a comparison
239 * where host bits are ignored, call that function rfapiRprefixCmp.
241 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
243 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
245 if (hp1
->length
!= hp2
->length
)
247 if (hp1
->prefix
.addr_family
== AF_INET
)
248 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
250 if (hp1
->prefix
.addr_family
== AF_INET6
)
251 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
256 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
258 memset(pfx
, 0, sizeof(struct prefix
));
259 pfx
->family
= hia
->addr_family
;
261 switch (hia
->addr_family
) {
263 pfx
->prefixlen
= IPV4_MAX_BITLEN
;
264 pfx
->u
.prefix4
= hia
->addr
.v4
;
267 pfx
->prefixlen
= IPV6_MAX_BITLEN
;
268 pfx
->u
.prefix6
= hia
->addr
.v6
;
276 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
278 memset(pfx
, 0, sizeof(struct prefix
));
279 pfx
->family
= AF_ETHERNET
;
281 pfx
->u
.prefix_eth
= l2o
->macaddr
;
284 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
286 return prefix_mac2str(ea
, buf
, bufsize
);
289 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
294 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
301 for (i
= 0; i
< 6; ++i
)
302 ea
->octet
[i
] = a
[i
] & 0xff;
307 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
309 if (af
== AF_ETHERNET
) {
310 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
313 return inet_ntop(af
, src
, buf
, size
);
316 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
319 va_start(args
, format
);
320 vzlog(LOG_DEBUG
, format
, args
);
325 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
330 va_start(args
, format
);
332 switch ((uintptr_t)stream
) {
343 vfprintf(file
, format
, args
);
348 /* Fake out for debug logging */
349 static struct vty vty_dummy_zlog
;
350 static struct vty vty_dummy_stdio
;
351 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
353 static const char *str_vty_newline(struct vty
*vty
)
355 if (vty
== &vty_dummy_zlog
)
360 int rfapiStream2Vty(void *stream
, /* input */
361 int (**fp
)(void *, const char *, ...), /* output */
362 struct vty
**vty
, /* output */
363 void **outstream
, /* output */
364 const char **vty_newline
) /* output */
368 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
369 *vty
= &vty_dummy_zlog
;
370 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
372 *vty_newline
= str_vty_newline(*vty
);
376 if (((uintptr_t)stream
== (uintptr_t)1)
377 || ((uintptr_t)stream
== (uintptr_t)2)) {
379 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
380 *vty
= &vty_dummy_stdio
;
381 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
383 *vty_newline
= str_vty_newline(*vty
);
387 *vty
= stream
; /* VTYNL requires vty to be legit */
388 *fp
= (int (*)(void *, const char *, ...))vty_out
;
390 *vty_newline
= str_vty_newline(*vty
);
394 /* called from bgpd/bgp_vty.c'route_vty_out() */
395 void rfapi_vty_out_vncinfo(struct vty
*vty
, const struct prefix
*p
,
396 struct bgp_path_info
*bpi
, safi_t safi
)
402 * Print, on an indented line:
403 * UN address [if VPN route and VNC UN addr subtlv]
409 if (safi
== SAFI_MPLS_VPN
) {
410 struct prefix pfx_un
;
412 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
414 vty_out(vty
, "UN=%s",
415 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
420 if (bpi
->attr
->ecommunity
) {
421 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
422 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
423 vty_out(vty
, " EC{%s}", s
);
424 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
427 if (bpi
->extra
!= NULL
) {
428 if (bpi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
429 vty_out(vty
, " label=VRF2VRF");
431 vty_out(vty
, " label=%u",
432 decode_label(&bpi
->extra
->label
[0]));
434 if (bpi
->extra
->num_sids
) {
437 vty_out(vty
, " sid=%s",
438 inet_ntop(AF_INET6
, &bpi
->extra
->sid
[0], buf
,
443 if (!rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
444 vty_out(vty
, " life=%d", lifetime
);
447 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bpi
->type
),
450 vty_out(vty
, "%s", HVTYNL
);
453 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
455 int (*fp
)(void *, const char *, ...);
458 const char *vty_newline
;
459 struct transit
*transit
;
460 struct cluster_list
*cluster
;
463 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
466 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
471 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
472 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
474 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
475 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
476 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
477 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
479 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
480 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
482 cluster
= bgp_attr_get_cluster(attr
);
483 fp(out
, " cluster=%p, refcnt=%d%s", cluster
,
484 (cluster
? cluster
->refcnt
: 0), HVTYNL
);
486 transit
= bgp_attr_get_transit(attr
);
487 fp(out
, " transit=%p, refcnt=%d%s", transit
,
488 (transit
? transit
->refcnt
: 0), HVTYNL
);
492 * Print BPI in an Import Table
494 void rfapiPrintBi(void *stream
, struct bgp_path_info
*bpi
)
499 int (*fp
)(void *, const char *, ...);
502 const char *vty_newline
;
508 struct ethaddr macaddr
= {{0}};
509 struct rfapi_l2address_option l2o_buf
;
510 uint8_t l2hid
= 0; /* valid if has_macaddr */
512 #define REMAIN (BUFSIZ - (p-line))
513 #define INCP {p += (r > REMAIN)? REMAIN: r;}
515 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
521 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
522 && bpi
->extra
->vnc
.import
.timer
) {
524 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
525 r
= snprintf(p
, REMAIN
, " [%4lu] ",
526 thread_timer_remain_second(t
));
530 r
= snprintf(p
, REMAIN
, " ");
535 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
536 if (decode_rd_type(bpi
->extra
->vnc
.import
.rd
.val
)
537 == RD_TYPE_VNC_ETH
) {
539 memcpy(macaddr
.octet
, bpi
->extra
->vnc
.import
.rd
.val
+ 2,
541 l2hid
= bpi
->extra
->vnc
.import
.rd
.val
[1];
550 * RFP option sizes (they are opaque values)
551 * extended communities (RTs)
554 int printed_1st_gol
= 0;
555 struct bgp_attr_encap_subtlv
*pEncap
;
556 struct prefix pfx_un
;
557 int af
= BGP_MP_NEXTHOP_FAMILY(bpi
->attr
->mp_nexthop_len
);
561 r
= snprintf(p
, REMAIN
, "%s",
563 &bpi
->attr
->mp_nexthop_global_in
, buf
,
566 } else if (af
== AF_INET6
) {
567 r
= snprintf(p
, REMAIN
, "%s",
568 inet_ntop(AF_INET6
, &bpi
->attr
->mp_nexthop_global
,
572 r
= snprintf(p
, REMAIN
, "?");
577 * VNC tunnel subtlv, if present, contains UN address
579 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
582 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
, BUFSIZ
));
587 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
588 r
= snprintf(p
, REMAIN
, " nolife");
591 if (lifetime
== 0xffffffff)
592 r
= snprintf(p
, REMAIN
, " %6s", "infini");
594 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
598 /* RFP option lengths */
599 for (pEncap
= bgp_attr_get_vnc_subtlvs(bpi
->attr
); pEncap
;
600 pEncap
= pEncap
->next
) {
602 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
603 if (printed_1st_gol
) {
604 r
= snprintf(p
, REMAIN
, ",");
607 r
= snprintf(p
, REMAIN
,
608 " "); /* leading space */
611 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
618 if (bpi
->attr
->ecommunity
) {
619 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
620 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
621 r
= snprintf(p
, REMAIN
, " %s", s
);
623 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
626 r
= snprintf(p
, REMAIN
, " bpi@%p", bpi
);
629 r
= snprintf(p
, REMAIN
, " p@%p", bpi
->peer
);
632 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
633 r
= snprintf(p
, REMAIN
, " HD=yes");
636 r
= snprintf(p
, REMAIN
, " HD=no");
640 if (bpi
->attr
->weight
) {
641 r
= snprintf(p
, REMAIN
, " W=%d", bpi
->attr
->weight
);
645 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
646 r
= snprintf(p
, REMAIN
, " LP=%d", bpi
->attr
->local_pref
);
649 r
= snprintf(p
, REMAIN
, " LP=unset");
653 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bpi
->type
),
657 fp(out
, "%s%s", line
, HVTYNL
);
660 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
661 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
662 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
666 if (!rfapiGetL2o(bpi
->attr
, &l2o_buf
)) {
668 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
669 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
670 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
671 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
672 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
675 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
678 sp
= rfapi_ntop(bpi
->extra
->vnc
.import
.aux_prefix
.family
,
679 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
683 fp(out
, " IP: %s%s", sp
, HVTYNL
);
687 struct rfapi_un_option
*uo
=
688 rfapi_encap_tlv_to_un_option(bpi
->attr
);
690 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
691 rfapi_un_options_free(uo
);
696 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
698 char buf_pfx
[BUFSIZ
];
703 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
704 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
706 rc
= snprintf(buf
, size
,
707 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
708 m
->next
, m
->rfd
, buf_vn
, buf_un
,
709 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
710 m
->p
.prefixlen
, m
->node
);
717 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
721 int (*fp
)(void *, const char *, ...);
724 const char *vty_newline
;
726 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
729 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
730 fp(out
, " Mon %s%s", buf
, HVTYNL
);
733 static void rfapiDebugPrintMonitorEncap(void *stream
,
734 struct rfapi_monitor_encap
*m
)
736 int (*fp
)(void *, const char *, ...);
739 const char *vty_newline
;
741 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
744 fp(out
, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m
, m
->next
, m
->node
,
748 void rfapiShowItNode(void *stream
, struct agg_node
*rn
)
750 struct bgp_path_info
*bpi
;
752 int (*fp
)(void *, const char *, ...);
755 const char *vty_newline
;
757 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
760 fp(out
, "%pRN @%p #%d%s", rn
, rn
, agg_node_get_lock_count(rn
), HVTYNL
);
762 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
763 rfapiPrintBi(stream
, bpi
);
766 /* doesn't show montors */
769 void rfapiShowImportTable(void *stream
, const char *label
, struct agg_table
*rt
,
775 int (*fp
)(void *, const char *, ...);
778 const char *vty_newline
;
780 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
783 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
785 for (rn
= agg_route_top(rt
); rn
; rn
= agg_route_next(rn
)) {
786 struct bgp_path_info
*bpi
;
787 const struct prefix
*p
= agg_node_get_prefix(rn
);
789 if (p
->family
== AF_ETHERNET
) {
790 rfapiEthAddr2Str(&p
->u
.prefix_eth
, buf
, BUFSIZ
);
792 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
);
795 fp(out
, "%s/%d @%p #%d%s", buf
, p
->prefixlen
, rn
,
796 agg_node_get_lock_count(rn
)
797 - 1, /* account for loop iterator locking */
800 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
801 rfapiPrintBi(stream
, bpi
);
805 struct rfapi_monitor_vpn
*m
;
806 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
807 rfapiDebugPrintMonitorVpn(stream
, m
);
810 struct rfapi_monitor_encap
*m
;
811 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
812 rfapiDebugPrintMonitorEncap(stream
, m
);
818 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
822 struct listnode
*node
;
823 struct rfapi_descriptor
*rfd
;
825 int (*fp
)(void *, const char *, ...);
828 const char *vty_newline
;
830 int printedheader
= 0;
833 int nves_with_queries
= 0;
834 int nves_displayed
= 0;
836 int queries_total
= 0;
837 int queries_displayed
= 0;
839 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
842 bgp
= bgp_get_default(); /* assume 1 instance for now */
844 vty_out(vty
, "No BGP instance\n");
850 vty_out(vty
, "No RFAPI instance\n");
854 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
857 int printedquerier
= 0;
863 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
873 for (rn
= agg_route_top(rfd
->mon
); rn
;
874 rn
= agg_route_next(rn
)) {
875 const struct prefix
*p
=
876 agg_node_get_prefix(rn
);
877 struct rfapi_monitor_vpn
*m
;
878 char buf_remain
[BUFSIZ
];
879 char buf_pfx
[BUFSIZ
];
888 if (pfx_match
&& !prefix_match(pfx_match
, p
)
889 && !prefix_match(p
, pfx_match
))
894 if (!printedheader
) {
897 fp(out
, "%-15s %-15s %-15s %-10s\n",
898 "VN Address", "UN Address", "Target",
902 if (!printedquerier
) {
906 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
908 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
911 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
916 fp(out
, "%-15s %-15s", "", "");
920 thread_timer_remain_second(
924 fp(out
, " %-15s %-10s\n",
925 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
934 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
938 struct rfapi_monitor_eth
*mon_eth
;
941 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
942 (void **)&mon_eth
, &cursor
);
944 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
945 (void **)&mon_eth
, &cursor
)) {
947 char buf_remain
[BUFSIZ
];
948 char buf_pfx
[BUFSIZ
];
949 struct prefix pfx_mac
;
953 vnc_zlog_debug_verbose(
954 "%s: checking rfd=%p mon_eth=%p",
955 __func__
, rfd
, mon_eth
);
957 memset((void *)&pfx_mac
, 0,
958 sizeof(struct prefix
));
959 pfx_mac
.family
= AF_ETHERNET
;
960 pfx_mac
.prefixlen
= 48;
961 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
964 && !prefix_match(pfx_match
, &pfx_mac
)
965 && !prefix_match(&pfx_mac
, pfx_match
))
970 if (!printedheader
) {
974 "%-15s %-15s %-17s %10s %-10s\n",
975 "VN Address", "UN Address", "Target",
979 if (!printedquerier
) {
983 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
985 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
988 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
993 fp(out
, "%-15s %-15s", "", "");
995 if (mon_eth
->timer
) {
997 thread_timer_remain_second(
1001 fp(out
, " %-17s %10d %-10s\n",
1002 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
1004 mon_eth
->logical_net_id
, buf_remain
);
1009 if (queries_total
) {
1011 fp(out
, "Displayed %d out of %d total queries\n",
1012 queries_displayed
, queries_total
);
1017 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1018 struct agg_node
*rn
, struct bgp_path_info
*bpi
)
1020 int (*fp
)(void *, const char *, ...);
1023 const char *vty_newline
;
1024 struct prefix pfx_un
;
1025 struct prefix pfx_vn
;
1028 bgp_encap_types tun_type
= BGP_ENCAP_TYPE_MPLS
;/*Default tunnel type*/
1030 char buf_pfx
[BUFSIZ
];
1031 char buf_ntop
[BUFSIZ
];
1032 char buf_un
[BUFSIZ
];
1033 char buf_vn
[BUFSIZ
];
1034 char buf_lifetime
[BUFSIZ
];
1036 const struct prefix
*p
= agg_node_get_prefix(rn
);
1039 return 0; /* for debug log, print into buf & call output once */
1041 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1048 snprintf(buf_pfx
, sizeof(buf_pfx
), "%s/%d",
1049 rfapi_ntop(p
->family
, &p
->u
.prefix
, buf_ntop
, BUFSIZ
),
1051 buf_pfx
[BUFSIZ
- 1] = 0;
1058 if (!rfapiGetUnAddrOfVpnBi(bpi
, &pfx_un
)) {
1059 snprintf(buf_un
, sizeof(buf_un
), "%s",
1060 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1064 bgp_attr_extcom_tunnel_type(bpi
->attr
, &tun_type
);
1069 rfapiNexthop2Prefix(bpi
->attr
, &pfx_vn
);
1070 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1071 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1073 snprintf(buf_un
, sizeof(buf_un
), "%s",
1074 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1077 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1078 snprintf(buf_vn
, sizeof(buf_vn
), "Label: %d", l
);
1079 } else /* should never happen */
1081 snprintf(buf_vn
, sizeof(buf_vn
), "Label: N/A");
1084 snprintf(buf_vn
, sizeof(buf_vn
), "%s",
1085 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1088 buf_vn
[BUFSIZ
- 1] = 0;
1089 buf_un
[BUFSIZ
- 1] = 0;
1092 * Cost is encoded in local_pref as (255-cost)
1093 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1096 uint32_t local_pref
;
1098 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1099 local_pref
= bpi
->attr
->local_pref
;
1102 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1104 fp(out
, "%-20s ", buf_pfx
);
1105 fp(out
, "%-15s ", buf_vn
);
1106 fp(out
, "%-15s ", buf_un
);
1107 fp(out
, "%-4d ", cost
);
1110 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1111 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)
1112 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1114 fp(out
, "%-10s ", "infinite");
1116 time_t t_lifetime
= lifetime
;
1117 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1118 fp(out
, "%-10s ", buf_lifetime
);
1121 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
1122 && bpi
->extra
->vnc
.import
.timer
) {
1126 char buf_age
[BUFSIZ
];
1129 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
1130 remaining
= thread_timer_remain_second(t
);
1132 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1134 * Calculate when the timer started. Doing so here saves
1135 * us a timestamp field in "struct bgp_path_info".
1137 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1138 * original calculation.
1140 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1142 #else /* report remaining time */
1145 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1147 fp(out
, "%-10s ", buf_age
);
1149 } else if (RFAPI_LOCAL_BI(bpi
)) {
1151 char buf_age
[BUFSIZ
];
1153 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.create_time
) {
1154 rfapiFormatAge(bpi
->extra
->vnc
.import
.create_time
,
1160 fp(out
, "%-10s ", buf_age
);
1162 fp(out
, "%s", HVTYNL
);
1164 if (p
->family
== AF_ETHERNET
) {
1166 * If there is a corresponding IP address && != VN address,
1167 * print that on the next line
1170 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
1174 bpi
->extra
->vnc
.import
.aux_prefix
.family
,
1175 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1177 buf_ntop
[BUFSIZ
- 1] = 0;
1179 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1180 fp(out
, " IP: %s", sp
);
1186 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bpi
->extra
) {
1187 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1188 if (!MPLS_LABEL_IS_NULL(l
)) {
1189 fp(out
, " Label: %d", l
);
1195 fp(out
, "%s", HVTYNL
);
1200 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1201 struct rfapi_import_table
*it
,
1202 struct prefix
*prefix_only
,
1203 int show_expiring
, /* either/or */
1204 int show_local
, int show_remote
,
1205 int show_imported
, /* either/or */
1206 uint32_t *pLni
) /* AFI_L2VPN only */
1209 int printed_rtlist_hdr
= 0;
1211 int (*fp
)(void *, const char *, ...);
1214 const char *vty_newline
;
1218 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1221 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1223 struct agg_node
*rn
;
1225 if (!it
->imported_vpn
[afi
])
1228 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1229 rn
= agg_route_next(rn
)) {
1230 const struct prefix
*p
= agg_node_get_prefix(rn
);
1231 struct bgp_path_info
*bpi
;
1234 /* allow for wider or more narrow mask from user */
1235 if (prefix_only
&& !prefix_match(prefix_only
, p
)
1236 && !prefix_match(p
, prefix_only
))
1241 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
1243 if (!show_local
&& RFAPI_LOCAL_BI(bpi
)) {
1245 /* local route from RFP */
1249 if (!show_remote
&& !RFAPI_LOCAL_BI(bpi
)) {
1256 && !CHECK_FLAG(bpi
->flags
,
1261 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1264 if (bpi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1266 == ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1275 if (count_only
== 1)
1277 if (!printed_rtlist_hdr
) {
1278 const char *agetype
= "";
1280 const char *type
= "";
1281 if (show_imported
) {
1284 if (show_expiring
) {
1296 s
= ecommunity_ecom2str(
1298 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1302 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1303 HVTYNL
, type
, *pLni
,
1304 (*pLni
& 0xfff), s
);
1306 fp(out
, "%s[%s] Prefix RT={%s}",
1309 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1311 if (it
->rfg
&& it
->rfg
->name
) {
1312 fp(out
, " %s \"%s\"",
1313 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1318 fp(out
, "%s", HVTYNL
);
1319 if (show_expiring
) {
1320 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1323 agetype
= "Remaining";
1325 } else if (show_local
) {
1329 printed_rtlist_hdr
= 1;
1332 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1333 (pLni
? "L2 Address/IP" : "Prefix"),
1334 "VN Address", "UN Address", "Cost",
1335 "Lifetime", agetype
, HVTYNL
);
1337 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1345 const char *type
= "prefixes";
1347 if (show_imported
) {
1348 type
= "imported prefixes";
1350 if (show_expiring
) {
1351 type
= "prefixes in holddown";
1353 if (show_local
&& !show_remote
) {
1354 type
= "locally registered prefixes";
1355 } else if (!show_local
&& show_remote
) {
1356 type
= "remotely registered prefixes";
1361 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1363 #if DEBUG_SHOW_EXTRA
1364 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1372 * rfapiShowRemoteRegistrations
1374 * Similar to rfapiShowImportTable() above. This function
1375 * is mean to produce the "remote" portion of the output
1376 * of "show vnc registrations".
1378 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1379 int show_expiring
, int show_local
,
1380 int show_remote
, int show_imported
)
1384 struct rfapi_import_table
*it
;
1387 bgp
= bgp_get_default();
1397 for (it
= h
->imports
; it
; it
= it
->next
) {
1398 printed
+= rfapiShowRemoteRegistrationsIt(
1399 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1400 show_remote
, show_imported
, NULL
);
1403 if (h
->import_mac
) {
1404 void *cursor
= NULL
;
1406 uintptr_t lni_as_ptr
;
1410 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1411 (void **)&it
, &cursor
);
1413 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1414 (void **)&it
, &cursor
)) {
1416 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1417 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1421 printed
+= rfapiShowRemoteRegistrationsIt(
1422 bgp
, stream
, it
, prefix_only
, show_expiring
,
1423 show_local
, show_remote
, show_imported
, pLni
);
1430 /*------------------------------------------
1431 * rfapiRfapiIpAddr2Str
1433 * UI helper: generate string from rfapi_ip_addr
1436 * a IP v4/v6 address
1439 * buf put string here
1440 * bufsize max space to write
1443 * NULL conversion failed
1444 * non-NULL pointer to buf
1445 --------------------------------------------*/
1446 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1449 const char *rc
= NULL
;
1451 switch (a
->addr_family
) {
1453 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1456 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1462 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1465 const char *rc
= NULL
;
1467 int (*fp
)(void *, const char *, ...);
1470 const char *vty_newline
;
1472 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1475 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1481 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1484 struct rfapi_ip_addr
*a
= &p
->prefix
;
1485 const char *rc
= NULL
;
1487 switch (a
->addr_family
) {
1489 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1492 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1497 int alen
= strlen(buf
);
1498 int remaining
= bufsize
- alen
- 1;
1501 if (remaining
> 0) {
1502 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1504 if (slen
< remaining
) /* see man page for snprintf(3) */
1512 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1517 int (*fp
)(void *, const char *, ...);
1520 const char *vty_newline
;
1522 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1525 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1528 fp(out
, "%s:%u", buf
, p
->cost
);
1533 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1535 char buf
[RD_ADDRSTRLEN
];
1537 prefix_rd2str(prd
, buf
, sizeof(buf
));
1538 vty_out(vty
, "%s", buf
);
1541 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1542 safi_t safi
, struct prefix
*p
)
1544 afi_t afi
; /* of the VN address */
1545 struct bgp_dest
*bd
;
1546 struct bgp_path_info
*bpi
;
1547 uint8_t type
= ZEBRA_ROUTE_BGP
;
1550 struct prefix_rd prd0
;
1551 struct prefix_rd
*prd
;
1554 * Find the bgp_path in the RIB corresponding to this
1558 afi
= family2afi(p
->family
);
1559 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1561 bgp
= bgp_get_default(); /* assume 1 instance for now */
1564 if (safi
== SAFI_ENCAP
) {
1565 memset(&prd0
, 0, sizeof(prd0
));
1566 prd0
.family
= AF_UNSPEC
;
1567 prd0
.prefixlen
= 64;
1572 bd
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1574 vty_out(vty
, " bd=%p%s", bd
, HVTYNL
);
1576 for (bpi
= bgp_dest_get_bgp_path_info(bd
); bpi
; bpi
= bpi
->next
) {
1577 if (bpi
->peer
== rfd
->peer
&& bpi
->type
== type
1578 && bpi
->sub_type
== BGP_ROUTE_RFP
&& bpi
->extra
1579 && bpi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1581 rfapiPrintBi(vty
, bpi
);
1587 vty_out(vty
, " --?--%s", HVTYNL
);
1592 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1594 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1595 /* RT export list */
1596 /* RT import list */
1597 /* list of advertised prefixes */
1598 /* dump import table */
1604 struct rfapi_adb
*adb
;
1606 vty_out(vty
, "%-10p ", rfd
);
1607 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1609 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1610 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1611 rfapiPrintRd(vty
, &rfd
->rd
);
1612 vty_out(vty
, " %d", rfd
->response_lifetime
);
1613 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1614 vty_out(vty
, "%s", HVTYNL
);
1616 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1618 /* export RT list */
1619 if (rfd
->rt_export_list
) {
1620 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1621 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1622 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1623 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1625 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1628 /* import RT list */
1629 if (rfd
->import_table
) {
1630 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1631 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1632 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1633 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1635 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1638 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1641 family
= afi2family(afi
);
1646 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1647 (void **)&adb
, &cursor
);
1649 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1650 (void **)&adb
, &cursor
)) {
1652 /* group like family prefixes together in output */
1653 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1656 vty_out(vty
, " Adv Pfx: %pFX%s", &adb
->u
.s
.prefix_ip
,
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
)) {
1666 vty_out(vty
, " Adv Pfx: %pFX%s", &adb
->u
.s
.prefix_eth
, HVTYNL
);
1668 /* TBD update the following function to print ethernet info */
1669 /* Also need to pass/use rd */
1670 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1671 &adb
->u
.s
.prefix_ip
);
1673 vty_out(vty
, "%s", HVTYNL
);
1677 * test scripts rely on first line for each nve starting in 1st column,
1678 * leading whitespace for additional detail of that nve
1680 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1681 struct prefix
*un_prefix
)
1685 struct listnode
*ln
;
1686 struct rfapi_descriptor
*rfd
;
1689 bgp
= bgp_get_default(); /* assume 1 instance for now */
1696 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1697 rfd
= listgetdata(ln
);
1702 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1703 if (!prefix_match(vn_prefix
, &pfx
))
1708 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1709 if (!prefix_match(un_prefix
, &pfx
))
1714 /* print column header */
1715 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1716 "un-addr", "vn-addr", "callback", "cookie",
1717 "RD", "lifetime", "group", HVTYNL
);
1719 rfapiPrintDescriptor(vty
, rfd
);
1726 * Parse an address and put into a struct prefix
1728 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1730 if (!str2prefix(str
, p
)) {
1731 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1735 switch (p
->family
) {
1737 if (p
->prefixlen
!= 32) {
1738 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1744 if (p
->prefixlen
!= IPV6_MAX_BITLEN
) {
1745 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1751 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1757 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1758 struct rfapi_ip_addr
*hai
)
1763 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1767 hai
->addr_family
= pfx
.family
;
1768 if (pfx
.family
== AF_INET
)
1769 hai
->addr
.v4
= pfx
.u
.prefix4
;
1771 hai
->addr
.v6
= pfx
.u
.prefix6
;
1777 * Note: this function does not flush vty output, so if it is called
1778 * with a stream pointing to a vty, the user will have to type something
1779 * before the callback output shows up
1781 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1783 struct rfapi_next_hop_entry
*nh
;
1786 int (*fp
)(void *, const char *, ...);
1789 const char *vty_newline
;
1791 #define REMAIN (BUFSIZ - (p-line))
1792 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1794 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1797 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1803 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1806 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1807 /* it fit, so count length */
1815 r
= snprintf(p
, REMAIN
, ", un=");
1818 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1819 /* it fit, so count length */
1827 r
= snprintf(p
, REMAIN
, ", vn=");
1830 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1831 /* it fit, so count length */
1840 line
[BUFSIZ
- 1] = 0;
1841 fp(out
, "%s%s", line
, HVTYNL
);
1846 if (nh
->vn_options
) {
1847 struct rfapi_vn_option
*vo
;
1848 char offset
[] = " ";
1850 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1854 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1855 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1856 pbuf
, sizeof(pbuf
));
1858 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1860 (vo
->v
.l2addr
.label
& 0x00ffffff),
1861 (vo
->v
.l2addr
.logical_net_id
1863 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1866 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1867 fp(out
, "%sLNH %pFX cost=%d%s", offset
,
1868 &vo
->v
.local_nexthop
.addr
,
1869 vo
->v
.local_nexthop
.cost
, HVTYNL
);
1874 "%svn option type %d (unknown)%s",
1875 offset
, vo
->type
, HVTYNL
);
1880 if (nh
->un_options
) {
1881 struct rfapi_un_option
*uo
;
1882 char offset
[] = " ";
1884 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1886 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1887 rfapi_print_tunneltype_option(
1888 stream
, 8, &uo
->v
.tunnel
);
1891 fp(out
, "%sUN Option type %d%s", offset
,
1892 uo
->type
, vty_newline
);
1900 /***********************************************************************
1902 ***********************************************************************/
1905 * Add another nexthop to the NHL
1907 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1908 struct rfapi_ip_addr
*vn_addr
,
1909 struct rfapi_ip_prefix
*rprefix
,
1911 uint32_t lifetime
, /* add only */
1912 struct rfapi_vn_option
*vn_options
,
1913 struct rfapi_next_hop_entry
**head
,
1914 struct rfapi_next_hop_entry
**tail
)
1916 struct rfapi_next_hop_entry
*new;
1922 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1923 new->prefix
= *rprefix
;
1924 new->un_address
= *un_addr
;
1925 new->vn_address
= *vn_addr
;
1927 new->vn_options
= vn_options
;
1929 new->lifetime
= lifetime
;
1931 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1935 (*tail
)->next
= new;
1944 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1945 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1946 struct cmd_token
*carg_cost
, /* optional */
1947 struct cmd_token
*carg_lifetime
, /* optional */
1948 struct cmd_token
*carg_macaddr
, /* optional */
1950 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1951 int argc
, struct cmd_token
**argv
)
1953 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1954 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1955 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1956 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1957 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1958 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1959 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1960 struct rfapi_ip_addr vn_address
;
1961 struct rfapi_ip_addr un_address
;
1963 struct rfapi_ip_prefix rpfx
;
1968 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1969 struct rfapi_vn_option
*opt
= NULL
;
1972 int rc
= CMD_WARNING_CONFIG_FAILED
;
1976 struct rfapi_cfg
*rfapi_cfg
;
1978 const char *arg_lnh
= NULL
;
1979 const char *arg_lnh_cost
= NULL
;
1981 bgp
= bgp_get_default(); /* assume 1 instance for now */
1984 vty_out(vty
, "BGP not configured\n");
1985 return CMD_WARNING_CONFIG_FAILED
;
1989 rfapi_cfg
= bgp
->rfapi_cfg
;
1990 if (!h
|| !rfapi_cfg
) {
1992 vty_out(vty
, "RFAPI not configured\n");
1993 return CMD_WARNING_CONFIG_FAILED
;
1996 for (; argc
; --argc
, ++argv
) {
1997 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2000 "local-next-hop specified more than once\n");
2001 return CMD_WARNING_CONFIG_FAILED
;
2005 "Missing parameter for local-next-hop\n");
2006 return CMD_WARNING_CONFIG_FAILED
;
2010 arg_lnh
= argv
[0]->arg
;
2012 if (strmatch(argv
[0]->text
, "local-cost")) {
2015 "local-cost specified more than once\n");
2016 return CMD_WARNING_CONFIG_FAILED
;
2020 "Missing parameter for local-cost\n");
2021 return CMD_WARNING_CONFIG_FAILED
;
2025 arg_lnh_cost
= argv
[0]->arg
;
2029 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2031 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2034 /* arg_prefix is optional if mac address is given */
2035 if (arg_macaddr
&& !arg_prefix
) {
2037 * fake up a 0/32 or 0/128 prefix
2039 switch (vn_address
.addr_family
) {
2041 arg_prefix
= "0.0.0.0/32";
2044 arg_prefix
= "0::0/128";
2048 "Internal error, unknown VN address family\n");
2049 return CMD_WARNING_CONFIG_FAILED
;
2053 if (!str2prefix(arg_prefix
, &pfx
)) {
2054 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2057 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2058 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2064 memset(optary
, 0, sizeof(optary
));
2068 cost
= strtoul(arg_cost
, &endptr
, 10);
2069 if (*endptr
!= '\0' || cost
> 255) {
2070 vty_out(vty
, "%% Invalid %s value\n", "cost");
2078 if (!strcmp(arg_lifetime
, "infinite")) {
2079 lifetime
= RFAPI_INFINITE_LIFETIME
;
2082 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2083 if (*endptr
!= '\0') {
2084 vty_out(vty
, "%% Invalid %s value\n",
2090 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2096 "%% %s may only be specified with local-next-hop\n",
2101 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2102 if (*endptr
!= '\0' || lnh_cost
> 255) {
2103 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2113 "%% %s may only be specified with prefix\n",
2117 if ((rc
= rfapiCliGetPrefixAddr(
2119 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2124 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2125 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2128 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2135 if (arg_vni
&& !arg_macaddr
) {
2136 vty_out(vty
, "%% %s may only be specified with mac address\n",
2137 "virtual-network-identifier");
2144 "Missing \"vni\" parameter (mandatory with mac)\n");
2145 return CMD_WARNING_CONFIG_FAILED
;
2147 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2148 strtoul(arg_vni
, NULL
, 10);
2150 if ((rc
= rfapiStr2EthAddr(
2152 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2153 vty_out(vty
, "Invalid %s value\n", "mac address");
2156 /* TBD label, NVE ID */
2158 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2161 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2168 vnc_zlog_debug_verbose(
2169 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2170 __func__
, arg_vn
, arg_un
, arg_prefix
,
2171 (arg_cost
? arg_cost
: "NULL"),
2172 (arg_lifetime
? arg_lifetime
: "NULL"),
2173 (arg_lnh
? arg_lnh
: "NULL"));
2175 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2177 rpfx
.cost
= cost
& 255;
2179 /* look up rf descriptor, call open if it doesn't exist */
2180 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2181 (struct rfapi_descriptor
**)&rfd
);
2184 struct rfapi_un_option uo
;
2187 * flag descriptor as provisionally opened for static
2189 * registration so that we can fix up the other
2191 * when the real open comes along
2193 memset(&uo
, 0, sizeof(uo
));
2194 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2196 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2197 &vn_address
, &un_address
,
2199 NULL
, NULL
, /* no userdata */
2203 "Can't open session for this NVE: %s\n",
2204 rfapi_error_str(rc
));
2205 rc
= CMD_WARNING_CONFIG_FAILED
;
2209 vty_out(vty
, "Can't find session for this NVE: %s\n",
2210 rfapi_error_str(rc
));
2215 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2216 RFAPI_REGISTER_ADD
);
2218 struct rfapi_next_hop_entry
*head
= NULL
;
2219 struct rfapi_next_hop_entry
*tail
= NULL
;
2220 struct rfapi_vn_option
*vn_opt_new
;
2222 vnc_zlog_debug_verbose(
2223 "%s: rfapi_register succeeded, returning 0", __func__
);
2225 if (h
->rfp_methods
.local_cb
) {
2226 struct rfapi_descriptor
*r
=
2227 (struct rfapi_descriptor
*)rfd
;
2228 vn_opt_new
= rfapi_vn_options_dup(opt
);
2230 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2232 vn_opt_new
, &head
, &tail
);
2234 h
->flags
|= RFAPI_INCALLBACK
;
2235 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2236 h
->flags
&= ~RFAPI_INCALLBACK
;
2243 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2245 vty_out(vty
, "Registration failed.\n");
2247 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2248 return CMD_WARNING_CONFIG_FAILED
;
2251 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2255 /************************************************************************
2256 * Add prefix With LNH_OPTIONS...
2257 ************************************************************************/
2258 DEFUN (add_vnc_prefix_cost_life_lnh
,
2259 add_vnc_prefix_cost_life_lnh_cmd
,
2260 "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...",
2261 "Add registration\n"
2263 "Add/modify prefix related information\n"
2266 "VN address of NVE\n"
2267 "VN IPv4 interface address\n"
2268 "VN IPv6 interface address\n"
2269 "UN address of NVE\n"
2270 "UN IPv4 interface address\n"
2271 "UN IPv6 interface address\n"
2272 "Administrative cost [default: 255]\n"
2273 "Administrative cost\n"
2274 "Registration lifetime [default: infinite]\n"
2275 "Lifetime value in seconds\n"
2276 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2278 /* pfx vn un cost life */
2279 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2281 NULL
, NULL
, argc
- 12, argv
+ 12);
2284 DEFUN (add_vnc_prefix_life_cost_lnh
,
2285 add_vnc_prefix_life_cost_lnh_cmd
,
2286 "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...",
2287 "Add registration\n"
2289 "Add/modify prefix related information\n"
2292 "VN address of NVE\n"
2293 "VN IPv4 interface address\n"
2294 "VN IPv6 interface address\n"
2295 "UN address of NVE\n"
2296 "UN IPv4 interface address\n"
2297 "UN IPv6 interface address\n"
2298 "Registration lifetime [default: infinite]\n"
2299 "Lifetime value in seconds\n"
2300 "Administrative cost [default: 255]\n"
2301 "Administrative cost\n"
2302 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2304 /* pfx vn un cost life */
2305 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2307 NULL
, NULL
, argc
- 12, argv
+ 12);
2310 DEFUN (add_vnc_prefix_cost_lnh
,
2311 add_vnc_prefix_cost_lnh_cmd
,
2312 "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...",
2313 "Add registration\n"
2315 "Add/modify prefix related information\n"
2318 "VN address of NVE\n"
2319 "VN IPv4 interface address\n"
2320 "VN IPv6 interface address\n"
2321 "UN address of NVE\n"
2322 "UN IPv4 interface address\n"
2323 "UN IPv6 interface address\n"
2324 "Administrative cost [default: 255]\n"
2325 "Administrative cost\n"
2326 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2328 /* pfx vn un cost life */
2329 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2331 NULL
, NULL
, argc
- 10, argv
+ 10);
2334 DEFUN (add_vnc_prefix_life_lnh
,
2335 add_vnc_prefix_life_lnh_cmd
,
2336 "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...",
2337 "Add registration\n"
2339 "Add/modify prefix related information\n"
2342 "VN address of NVE\n"
2343 "VN IPv4 interface address\n"
2344 "VN IPv6 interface address\n"
2345 "UN address of NVE\n"
2346 "UN IPv4 interface address\n"
2347 "UN IPv6 interface address\n"
2348 "Registration lifetime [default: infinite]\n"
2349 "Lifetime value in seconds\n"
2350 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2352 /* pfx vn un cost life */
2353 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2355 NULL
, NULL
, argc
- 10, argv
+ 10);
2358 DEFUN (add_vnc_prefix_lnh
,
2359 add_vnc_prefix_lnh_cmd
,
2360 "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...",
2361 "Add registration\n"
2363 "Add/modify prefix related information\n"
2366 "VN address of NVE\n"
2367 "VN IPv4 interface address\n"
2368 "VN IPv6 interface address\n"
2369 "UN address of NVE\n"
2370 "UN IPv4 interface address\n"
2371 "UN IPv6 interface address\n"
2372 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2374 /* pfx vn un cost life */
2375 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2377 NULL
, NULL
, argc
- 8, argv
+ 8);
2380 /************************************************************************
2381 * Add prefix Without LNH_OPTIONS...
2382 ************************************************************************/
2383 DEFUN (add_vnc_prefix_cost_life
,
2384 add_vnc_prefix_cost_life_cmd
,
2385 "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)",
2386 "Add registration\n"
2388 "Add/modify prefix related information\n"
2391 "VN address of NVE\n"
2392 "VN IPv4 interface address\n"
2393 "VN IPv6 interface address\n"
2394 "UN address of NVE\n"
2395 "UN IPv4 interface address\n"
2396 "UN IPv6 interface address\n"
2397 "Administrative cost [default: 255]\n"
2398 "Administrative cost\n"
2399 "Registration lifetime [default: infinite]\n"
2400 "Lifetime value in seconds\n")
2402 /* pfx vn un cost life */
2403 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2405 NULL
, NULL
, 0, NULL
);
2408 DEFUN (add_vnc_prefix_life_cost
,
2409 add_vnc_prefix_life_cost_cmd
,
2410 "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)",
2411 "Add registration\n"
2413 "Add/modify prefix related information\n"
2416 "VN address of NVE\n"
2417 "VN IPv4 interface address\n"
2418 "VN IPv6 interface address\n"
2419 "UN address of NVE\n"
2420 "UN IPv4 interface address\n"
2421 "UN IPv6 interface address\n"
2422 "Registration lifetime [default: infinite]\n"
2423 "Lifetime value in seconds\n"
2424 "Administrative cost [default: 255]\n"
2425 "Administrative cost\n")
2427 /* pfx vn un cost life */
2428 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2430 NULL
, NULL
, 0, NULL
);
2433 DEFUN (add_vnc_prefix_cost
,
2434 add_vnc_prefix_cost_cmd
,
2435 "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)",
2436 "Add registration\n"
2438 "Add/modify prefix related information\n"
2441 "VN address of NVE\n"
2442 "VN IPv4 interface address\n"
2443 "VN IPv6 interface address\n"
2444 "UN address of NVE\n"
2445 "UN IPv4 interface address\n"
2446 "UN IPv6 interface address\n"
2447 "Administrative cost [default: 255]\n"
2448 "Administrative cost\n")
2450 /* pfx vn un cost life */
2451 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2453 NULL
, NULL
, 0, NULL
);
2456 DEFUN (add_vnc_prefix_life
,
2457 add_vnc_prefix_life_cmd
,
2458 "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)",
2459 "Add registration\n"
2461 "Add/modify prefix related information\n"
2464 "VN address of NVE\n"
2465 "VN IPv4 interface address\n"
2466 "VN IPv6 interface address\n"
2467 "UN address of NVE\n"
2468 "UN IPv4 interface address\n"
2469 "UN IPv6 interface address\n"
2470 "Registration lifetime [default: infinite]\n"
2471 "Lifetime value in seconds\n")
2473 /* pfx vn un cost life */
2474 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2476 NULL
, NULL
, 0, NULL
);
2479 DEFUN (add_vnc_prefix
,
2481 "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>",
2482 "Add registration\n"
2484 "Add/modify prefix related information\n"
2487 "VN address of NVE\n"
2488 "VN IPv4 interface address\n"
2489 "VN IPv6 interface address\n"
2490 "UN address of NVE\n"
2491 "UN IPv4 interface address\n"
2492 "UN IPv6 interface address\n")
2494 /* pfx vn un cost life */
2495 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2497 NULL
, NULL
, 0, NULL
);
2500 /************************************************************************
2501 * Mac address registrations
2502 ************************************************************************/
2503 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2504 add_vnc_mac_vni_prefix_cost_life_cmd
,
2505 "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)",
2506 "Add registration\n"
2508 "Add/modify mac address information\n"
2510 "Virtual Network Identifier follows\n"
2511 "Virtual Network Identifier\n"
2512 "VN address of NVE\n"
2513 "VN IPv4 interface address\n"
2514 "VN IPv6 interface address\n"
2515 "UN address of NVE\n"
2516 "UN IPv4 interface address\n"
2517 "UN IPv6 interface address\n"
2518 "Add/modify prefix related information\n"
2521 "Administrative cost [default: 255]\n"
2522 "Administrative cost\n"
2523 "Registration lifetime [default: infinite]\n"
2524 "Lifetime value in seconds\n")
2526 /* pfx vn un cost life */
2527 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2529 argv
[3], argv
[5], 0, NULL
);
2533 DEFUN (add_vnc_mac_vni_prefix_life
,
2534 add_vnc_mac_vni_prefix_life_cmd
,
2535 "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)",
2536 "Add registration\n"
2538 "Add/modify mac address information\n"
2540 "Virtual Network Identifier follows\n"
2541 "Virtual Network Identifier\n"
2542 "VN address of NVE\n"
2543 "VN IPv4 interface address\n"
2544 "VN IPv6 interface address\n"
2545 "UN address of NVE\n"
2546 "UN IPv4 interface address\n"
2547 "UN IPv6 interface address\n"
2548 "Add/modify prefix related information\n"
2551 "Registration lifetime [default: infinite]\n"
2552 "Lifetime value in seconds\n")
2554 /* pfx vn un cost life */
2555 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2557 argv
[3], argv
[5], 0, NULL
);
2560 DEFUN (add_vnc_mac_vni_prefix_cost
,
2561 add_vnc_mac_vni_prefix_cost_cmd
,
2562 "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)",
2563 "Add registration\n"
2565 "Add/modify mac address information\n"
2567 "Virtual Network Identifier follows\n"
2568 "Virtual Network Identifier\n"
2569 "VN address of NVE\n"
2570 "VN IPv4 interface address\n"
2571 "VN IPv6 interface address\n"
2572 "UN address of NVE\n"
2573 "UN IPv4 interface address\n"
2574 "UN IPv6 interface address\n"
2575 "Add/modify prefix related information\n"
2578 "Administrative cost [default: 255]\n" "Administrative cost\n")
2580 /* pfx vn un cost life */
2581 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2583 argv
[3], argv
[5], 0, NULL
);
2586 DEFUN (add_vnc_mac_vni_prefix
,
2587 add_vnc_mac_vni_prefix_cmd
,
2588 "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>",
2589 "Add registration\n"
2591 "Add/modify mac address information\n"
2593 "Virtual Network Identifier follows\n"
2594 "Virtual Network Identifier\n"
2595 "VN address of NVE\n"
2596 "VN IPv4 interface address\n"
2597 "VN IPv6 interface address\n"
2598 "UN address of NVE\n"
2599 "UN IPv4 interface address\n"
2600 "UN IPv6 interface address\n"
2601 "Add/modify prefix related information\n"
2602 "IPv4 prefix\n" "IPv6 prefix\n")
2604 /* pfx vn un cost life */
2605 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2607 argv
[3], argv
[5], 0, NULL
);
2610 DEFUN (add_vnc_mac_vni_cost_life
,
2611 add_vnc_mac_vni_cost_life_cmd
,
2612 "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)",
2613 "Add registration\n"
2615 "Add/modify mac address information\n"
2617 "Virtual Network Identifier follows\n"
2618 "Virtual Network Identifier\n"
2619 "VN address of NVE\n"
2620 "VN IPv4 interface address\n"
2621 "VN IPv6 interface address\n"
2622 "UN address of NVE\n"
2623 "UN IPv4 interface address\n"
2624 "UN IPv6 interface address\n"
2625 "Administrative cost [default: 255]\n"
2626 "Administrative cost\n"
2627 "Registration lifetime [default: infinite]\n"
2628 "Lifetime value in seconds\n")
2630 /* pfx vn un cost life */
2631 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2633 argv
[3], argv
[5], 0, NULL
);
2637 DEFUN (add_vnc_mac_vni_cost
,
2638 add_vnc_mac_vni_cost_cmd
,
2639 "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)",
2640 "Add registration\n"
2642 "Add/modify mac address information\n"
2644 "Virtual Network Identifier follows\n"
2645 "Virtual Network Identifier\n"
2646 "VN address of NVE\n"
2647 "VN IPv4 interface address\n"
2648 "VN IPv6 interface address\n"
2649 "UN address of NVE\n"
2650 "UN IPv4 interface address\n"
2651 "UN IPv6 interface address\n"
2652 "Administrative cost [default: 255]\n" "Administrative cost\n")
2654 /* pfx vn un cost life */
2655 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2657 argv
[3], argv
[5], 0, NULL
);
2661 DEFUN (add_vnc_mac_vni_life
,
2662 add_vnc_mac_vni_life_cmd
,
2663 "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)",
2664 "Add registration\n"
2666 "Add/modify mac address information\n"
2668 "Virtual Network Identifier follows\n"
2669 "Virtual Network Identifier\n"
2670 "VN address of NVE\n"
2671 "VN IPv4 interface address\n"
2672 "VN IPv6 interface address\n"
2673 "UN address of NVE\n"
2674 "UN IPv4 interface address\n"
2675 "UN IPv6 interface address\n"
2676 "Registration lifetime [default: infinite]\n"
2677 "Lifetime value in seconds\n")
2679 /* pfx vn un cost life */
2680 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2682 argv
[3], argv
[5], 0, NULL
);
2686 DEFUN (add_vnc_mac_vni
,
2687 add_vnc_mac_vni_cmd
,
2688 "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>",
2689 "Add registration\n"
2691 "Add/modify mac address information\n"
2693 "Virtual Network Identifier follows\n"
2694 "Virtual Network Identifier\n"
2695 "VN address of NVE\n"
2696 "VN IPv4 interface address\n"
2697 "VN IPv6 interface address\n"
2698 "UN address of NVE\n"
2699 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2701 /* pfx vn un cost life */
2702 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2704 argv
[3], argv
[5], 0, NULL
);
2707 /************************************************************************
2709 ************************************************************************/
2711 struct rfapi_local_reg_delete_arg
{
2716 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2717 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2718 struct prefix prefix
; /* AF==0: wildcard */
2719 struct prefix_rd rd
; /* plen!=64: wildcard */
2720 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2722 struct rfapi_l2address_option_match l2o
;
2730 uint32_t query_count
;
2732 uint32_t failed_pfx_count
;
2735 struct skiplist
*nves
;
2737 uint32_t remote_active_nve_count
;
2738 uint32_t remote_active_pfx_count
;
2739 uint32_t remote_holddown_nve_count
;
2740 uint32_t remote_holddown_pfx_count
;
2744 struct rfapi_ip_addr vn
;
2745 struct rfapi_ip_addr un
;
2746 struct rfapi_descriptor
*rfd
;
2747 struct rfapi_local_reg_delete_arg
*cda
;
2750 static void nve_addr_free(void *hap
)
2752 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2753 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2756 static int nve_addr_cmp(const void *k1
, const void *k2
)
2758 const struct nve_addr
*a
= (struct nve_addr
*)k1
;
2759 const struct nve_addr
*b
= (struct nve_addr
*)k2
;
2765 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2766 return (a
->un
.addr_family
- b
->un
.addr_family
);
2768 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2769 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2771 if (a
->un
.addr_family
== AF_INET
) {
2772 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2776 } else if (a
->un
.addr_family
== AF_INET6
) {
2777 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2784 if (a
->vn
.addr_family
== AF_INET
) {
2785 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2788 } else if (a
->vn
.addr_family
== AF_INET6
) {
2789 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2799 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2800 const char *arg_prefix
, const char *arg_vn
,
2801 const char *arg_un
, const char *arg_l2addr
,
2802 const char *arg_vni
, const char *arg_rd
,
2803 struct rfapi_nve_group_cfg
*arg_rfg
,
2804 struct rfapi_local_reg_delete_arg
*rcdarg
)
2806 int rc
= CMD_WARNING
;
2808 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2812 bgp
= bgp_get_default();
2814 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2816 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2817 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2818 &rcdarg
->vn_address
)))
2821 if (arg_un
&& strcmp(arg_un
, "*")) {
2822 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2823 &rcdarg
->un_address
)))
2826 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2828 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2829 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2836 vty_out(vty
, "Missing VNI\n");
2839 if (strcmp(arg_l2addr
, "*")) {
2840 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2841 &rcdarg
->l2o
.o
.macaddr
))) {
2842 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2846 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2848 if (strcmp(arg_vni
, "*")) {
2849 rcdarg
->l2o
.o
.logical_net_id
=
2850 strtoul(arg_vni
, NULL
, 10);
2851 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2855 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2856 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2865 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2866 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2867 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2868 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2869 struct rfapi_nve_group_cfg
*arg_rfg
,
2870 struct rfapi_local_reg_delete_arg
*rcdarg
)
2872 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2873 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2874 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2875 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2876 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2877 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2878 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2879 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2882 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2883 struct rfapi_ip_addr
*un_address
,
2884 struct rfapi_ip_addr
*vn_address
,
2885 struct rfapi_descriptor
*rfd
)
2888 struct nve_addr
*hap
;
2890 memset(&ha
, 0, sizeof(ha
));
2891 ha
.un
= *un_address
;
2892 ha
.vn
= *vn_address
;
2896 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2898 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2899 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2903 skiplist_insert(cda
->nves
, hap
, hap
);
2907 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2910 struct rfapi_descriptor
*rfd
;
2911 int query_count
= 0;
2912 struct listnode
*node
;
2913 struct bgp
*bgp_default
= bgp_get_default();
2915 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2919 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2920 &cda
->un_address
, &rfd
))
2924 rfapi_query_done_all(rfd
, &query_count
);
2925 cda
->query_count
+= query_count
;
2928 * Track unique nves seen
2930 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2941 h
= bgp_default
->rfapi
;
2946 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2948 * match un, vn addresses of NVEs
2950 if (cda
->un_address
.addr_family
2951 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2954 if (cda
->vn_address
.addr_family
2955 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2961 rfapi_query_done_all(rfd
, &query_count
);
2962 cda
->query_count
+= query_count
;
2965 * Track unique nves seen
2967 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2972 * TBD need to count deleted prefixes and nves?
2974 * ENXIO BGP or VNC not configured
2976 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2977 struct rfapi_descriptor
*rfd
)
2979 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2980 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2981 struct prefix
*pPrefix
; /* NULL = wildcard */
2982 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2984 struct rfapi_ip_prefix rprefix
;
2985 struct rfapi_next_hop_entry
*head
= NULL
;
2986 struct rfapi_next_hop_entry
*tail
= NULL
;
2989 vnc_zlog_debug_verbose("%s: entry", __func__
);
2992 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2993 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2994 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2995 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2998 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3001 do /* to preserve old code structure */
3003 struct rfapi
*h
= cda
->bgp
->rfapi
;
3005 struct rfapi_adb
*adb
;
3007 int deleted_from_this_nve
;
3009 struct nve_addr
*hap
;
3012 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3016 * match un, vn addresses of NVEs
3018 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3020 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3024 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3031 deleted_from_this_nve
= 0;
3034 struct skiplist
*sl
;
3035 struct rfapi_ip_prefix rp
;
3037 struct list
*adb_delete_list
;
3040 * The advertisements are stored in a skiplist.
3042 * the registration deletes the advertisement from the
3043 * skiplist, which we can't do while iterating over that
3044 * same skiplist using the current skiplist API.
3046 * Strategy: iterate over the skiplist and build another
3047 * list containing only the matching ADBs. Then delete
3048 * _everything_ in that second list (which can be done
3049 * using either skiplists or quagga linklists).
3051 adb_delete_list
= list_new();
3054 * Advertised IP prefixes (not 0/32 or 0/128)
3056 sl
= rfd
->advertised
.ipN_by_prefix
;
3059 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3061 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3065 if (!prefix_same(pPrefix
,
3066 &adb
->u
.s
.prefix_ip
)) {
3068 vnc_zlog_debug_verbose(
3069 "%s: adb=%p, prefix doesn't match, skipping",
3076 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3080 vnc_zlog_debug_verbose(
3081 "%s: adb=%p, RD doesn't match, skipping",
3087 if (CHECK_FLAG(cda
->l2o
.flags
,
3088 RFAPI_L2O_MACADDR
)) {
3089 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3090 adb
->u
.s
.prefix_eth
.u
3094 vnc_zlog_debug_verbose(
3095 "%s: adb=%p, macaddr doesn't match, skipping",
3102 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3103 if (cda
->l2o
.o
.logical_net_id
3104 != adb
->l2o
.logical_net_id
) {
3106 vnc_zlog_debug_verbose(
3107 "%s: adb=%p, LNI doesn't match, skipping",
3115 vnc_zlog_debug_verbose(
3116 "%s: ipN adding adb %p to delete list",
3120 listnode_add(adb_delete_list
, adb
);
3123 struct listnode
*node
;
3125 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3126 int this_advertisement_prefix_count
;
3127 struct rfapi_vn_option optary
[3];
3128 struct rfapi_vn_option
*opt
= NULL
;
3131 this_advertisement_prefix_count
= 1;
3133 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3135 memset(optary
, 0, sizeof(optary
));
3137 /* if mac addr present in advert, make l2o vn
3139 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3141 opt
->next
= &optary
[cur_opt
];
3142 opt
= &optary
[cur_opt
++];
3143 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3144 opt
->v
.l2addr
.macaddr
=
3145 adb
->u
.s
.prefix_eth
.u
3147 ++this_advertisement_prefix_count
;
3150 * use saved RD value instead of trying to
3152 * complex RD computation in rfapi_register()
3155 opt
->next
= &optary
[cur_opt
];
3156 opt
= &optary
[cur_opt
++];
3157 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3158 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3161 vnc_zlog_debug_verbose(
3162 "%s: ipN killing reg from adb %p ",
3166 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3167 (cur_opt
? optary
: NULL
),
3168 RFAPI_REGISTER_KILL
);
3171 this_advertisement_prefix_count
;
3172 cda
->reg_count
+= 1;
3173 deleted_from_this_nve
= 1;
3175 if (h
->rfp_methods
.local_cb
) {
3176 rfapiAddDeleteLocalRfpPrefix(
3177 &rfd
->un_addr
, &rfd
->vn_addr
,
3178 &rp
, 0, 0, NULL
, &head
, &tail
);
3181 list_delete_all_node(adb_delete_list
);
3183 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3185 * Caller didn't specify a prefix, or specified
3190 * Advertised 0/32 and 0/128 (indexed by
3193 sl
= rfd
->advertised
.ip0_by_ether
;
3196 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3199 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3202 if (CHECK_FLAG(cda
->l2o
.flags
,
3203 RFAPI_L2O_MACADDR
)) {
3204 if (memcmp(cda
->l2o
.o
.macaddr
3206 adb
->u
.s
.prefix_eth
.u
3214 if (CHECK_FLAG(cda
->l2o
.flags
,
3216 if (cda
->l2o
.o
.logical_net_id
3217 != adb
->l2o
.logical_net_id
) {
3222 vnc_zlog_debug_verbose(
3223 "%s: ip0 adding adb %p to delete list",
3226 listnode_add(adb_delete_list
, adb
);
3230 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3233 struct rfapi_vn_option vn
;
3235 rfapiQprefix2Rprefix(
3236 &adb
->u
.s
.prefix_ip
, &rp
);
3238 memset(&vn
, 0, sizeof(vn
));
3239 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3240 vn
.v
.l2addr
= adb
->l2o
;
3243 vnc_zlog_debug_verbose(
3244 "%s: ip0 killing reg from adb %p ",
3248 rc
= rfapi_register(
3249 rfd
, &rp
, 0, NULL
, &vn
,
3250 RFAPI_REGISTER_KILL
);
3252 cda
->pfx_count
+= 1;
3253 cda
->reg_count
+= 1;
3254 deleted_from_this_nve
= 1;
3256 if (h
->rfp_methods
.local_cb
) {
3257 struct rfapi_vn_option
3261 rfapi_vn_options_dup(
3263 rfapiAddDeleteLocalRfpPrefix(
3265 &rfd
->vn_addr
, &rp
, 0,
3266 0, vn_opt_new
, &head
,
3270 list_delete_all_node(adb_delete_list
);
3272 list_delete(&adb_delete_list
);
3276 if (head
) { /* should not be set if (NULL ==
3277 rfapi_cfg->local_cb) */
3278 h
->flags
|= RFAPI_INCALLBACK
;
3279 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3280 h
->flags
&= ~RFAPI_INCALLBACK
;
3284 if (deleted_from_this_nve
) {
3286 * track unique NVEs seen
3288 memset(&ha
, 0, sizeof(ha
));
3289 ha
.un
= rfd
->un_addr
;
3290 ha
.vn
= rfd
->vn_addr
;
3293 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3295 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3296 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3297 sizeof(struct nve_addr
));
3301 skiplist_insert(cda
->nves
, hap
, hap
);
3304 } while (0); /* to preserve old code structure */
3309 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3314 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3315 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3317 struct bgp
*bgp
= cda
->bgp
;
3319 struct rfapi_cfg
*rfapi_cfg
;
3321 struct listnode
*node
;
3322 struct rfapi_descriptor
*rfd
;
3326 rfapi_cfg
= bgp
->rfapi_cfg
;
3327 if (!h
|| !rfapi_cfg
)
3329 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3331 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3332 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3341 * Deletes local and remote prefixes that match
3343 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3345 struct prefix pfx_un
;
3346 struct prefix pfx_vn
;
3348 struct prefix
*pUN
= NULL
;
3349 struct prefix
*pVN
= NULL
;
3350 struct prefix
*pPrefix
= NULL
;
3352 struct rfapi_import_table
*it
= NULL
;
3355 * Delete matching remote prefixes in holddown
3357 if (cda
->vn_address
.addr_family
) {
3358 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3361 if (cda
->un_address
.addr_family
) {
3362 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3365 if (cda
->prefix
.family
) {
3366 pPrefix
= &cda
->prefix
;
3369 it
= cda
->rfg
->rfapi_import_table
;
3371 rfapiDeleteRemotePrefixes(
3372 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3373 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3374 &cda
->remote_holddown_nve_count
);
3377 * Now do local prefixes
3379 rfapiDeleteLocalPrefixes(cda
);
3382 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3384 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3386 /* Our special element-deleting function counts nves */
3388 skiplist_free(cda
->nves
);
3391 if (cda
->failed_pfx_count
)
3392 vty_out(vty
, "Failed to delete %d prefixes\n",
3393 cda
->failed_pfx_count
);
3395 /* left as "prefixes" even in single case for ease of machine parsing */
3397 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3398 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3402 * We don't currently allow deletion of active remote prefixes from
3406 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3407 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3411 * Caller has already deleted registrations and queries for this/these
3412 * NVEs. Now we just have to close their descriptors.
3414 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3416 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3417 struct nve_addr
*pKey
;
3418 struct nve_addr
*pValue
;
3419 void *cursor
= NULL
;
3425 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3426 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3430 pValue
->rfd
->flags
|=
3431 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3432 rfapi_close(pValue
->rfd
);
3437 DEFUN (clear_vnc_nve_all
,
3438 clear_vnc_nve_all_cmd
,
3442 "Clear per NVE information\n"
3446 struct rfapi_local_reg_delete_arg cda
;
3449 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3455 clear_vnc_responses(&cda
);
3456 clear_vnc_prefix(&cda
);
3457 clear_vnc_nve_closer(&cda
);
3459 print_cleared_stats(&cda
);
3464 DEFUN (clear_vnc_nve_vn_un
,
3465 clear_vnc_nve_vn_un_cmd
,
3466 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3469 "Clear prefix registration information\n"
3470 "VN address of NVE\n"
3472 "VN IPv4 interface address\n"
3473 "VN IPv6 interface address\n"
3474 "UN address of NVE\n"
3475 "For all UN addresses\n"
3476 "UN IPv4 interface address\n"
3477 "UN IPv6 interface address\n")
3479 struct rfapi_local_reg_delete_arg cda
;
3482 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3483 NULL
, NULL
, NULL
, &cda
)))
3488 clear_vnc_responses(&cda
);
3489 clear_vnc_prefix(&cda
);
3490 clear_vnc_nve_closer(&cda
);
3492 print_cleared_stats(&cda
);
3497 DEFUN (clear_vnc_nve_un_vn
,
3498 clear_vnc_nve_un_vn_cmd
,
3499 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3502 "Clear prefix registration information\n"
3503 "UN address of NVE\n"
3505 "UN IPv4 interface address\n"
3506 "UN IPv6 interface address\n"
3507 "VN address of NVE\n"
3509 "VN IPv4 interface address\n"
3510 "VN IPv6 interface address\n")
3512 struct rfapi_local_reg_delete_arg cda
;
3515 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3516 NULL
, NULL
, NULL
, &cda
)))
3521 clear_vnc_responses(&cda
);
3522 clear_vnc_prefix(&cda
);
3523 clear_vnc_nve_closer(&cda
);
3525 print_cleared_stats(&cda
);
3530 DEFUN (clear_vnc_nve_vn
,
3531 clear_vnc_nve_vn_cmd
,
3532 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3535 "Clear prefix registration information\n"
3536 "VN address of NVE\n"
3538 "VN IPv4 interface address\n"
3539 "VN IPv6 interface address\n")
3541 struct rfapi_local_reg_delete_arg cda
;
3544 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3545 NULL
, NULL
, NULL
, &cda
)))
3550 clear_vnc_responses(&cda
);
3551 clear_vnc_prefix(&cda
);
3552 clear_vnc_nve_closer(&cda
);
3554 print_cleared_stats(&cda
);
3558 DEFUN (clear_vnc_nve_un
,
3559 clear_vnc_nve_un_cmd
,
3560 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3563 "Clear prefix registration information\n"
3564 "UN address of NVE\n"
3566 "UN IPv4 interface address\n"
3567 "UN IPv6 interface address\n")
3569 struct rfapi_local_reg_delete_arg cda
;
3572 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3573 NULL
, NULL
, NULL
, &cda
)))
3578 clear_vnc_responses(&cda
);
3579 clear_vnc_prefix(&cda
);
3580 clear_vnc_nve_closer(&cda
);
3582 print_cleared_stats(&cda
);
3586 /*-------------------------------------------------
3588 *-------------------------------------------------*/
3591 * This function is defined in this file (rather than in rfp_registration.c)
3592 * because here we have access to all the task handles.
3594 DEFUN (clear_vnc_prefix_vn_un
,
3595 clear_vnc_prefix_vn_un_cmd
,
3596 "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>",
3599 "Clear prefix registration information\n"
3603 "VN address of NVE\n"
3604 "All VN addresses\n"
3605 "VN IPv4 interface address\n"
3606 "VN IPv6 interface address\n"
3607 "UN address of NVE\n"
3608 "All UN addresses\n"
3609 "UN IPv4 interface address\n"
3610 "UN IPv6 interface address\n")
3612 struct rfapi_local_reg_delete_arg cda
;
3615 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3616 NULL
, NULL
, NULL
, NULL
, &cda
)))
3619 clear_vnc_prefix(&cda
);
3620 print_cleared_stats(&cda
);
3624 DEFUN (clear_vnc_prefix_un_vn
,
3625 clear_vnc_prefix_un_vn_cmd
,
3626 "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>",
3629 "Clear prefix registration information\n"
3633 "UN address of NVE\n"
3634 "All UN addresses\n"
3635 "UN IPv4 interface address\n"
3636 "UN IPv6 interface address\n"
3637 "VN address of NVE\n"
3638 "All VN addresses\n"
3639 "VN IPv4 interface address\n"
3640 "VN IPv6 interface address\n")
3642 struct rfapi_local_reg_delete_arg cda
;
3645 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3646 NULL
, NULL
, NULL
, NULL
, &cda
)))
3649 clear_vnc_prefix(&cda
);
3650 print_cleared_stats(&cda
);
3654 DEFUN (clear_vnc_prefix_un
,
3655 clear_vnc_prefix_un_cmd
,
3656 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3659 "Clear prefix registration information\n"
3663 "UN address of NVE\n"
3664 "All UN addresses\n"
3665 "UN IPv4 interface address\n"
3666 "UN IPv6 interface address\n")
3668 struct rfapi_local_reg_delete_arg cda
;
3671 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3672 NULL
, NULL
, NULL
, &cda
)))
3675 clear_vnc_prefix(&cda
);
3676 print_cleared_stats(&cda
);
3680 DEFUN (clear_vnc_prefix_vn
,
3681 clear_vnc_prefix_vn_cmd
,
3682 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3685 "Clear prefix registration information\n"
3689 "UN address of NVE\n"
3690 "All VN addresses\n"
3691 "VN IPv4 interface address\n"
3692 "VN IPv6 interface address\n")
3694 struct rfapi_local_reg_delete_arg cda
;
3697 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3698 NULL
, NULL
, NULL
, &cda
)))
3701 clear_vnc_prefix(&cda
);
3702 print_cleared_stats(&cda
);
3706 DEFUN (clear_vnc_prefix_all
,
3707 clear_vnc_prefix_all_cmd
,
3708 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3711 "Clear prefix registration information\n"
3717 struct rfapi_local_reg_delete_arg cda
;
3720 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3721 NULL
, NULL
, NULL
, &cda
)))
3724 clear_vnc_prefix(&cda
);
3725 print_cleared_stats(&cda
);
3729 /*-------------------------------------------------
3731 *-------------------------------------------------*/
3734 * This function is defined in this file (rather than in rfp_registration.c)
3735 * because here we have access to all the task handles.
3737 DEFUN (clear_vnc_mac_vn_un
,
3738 clear_vnc_mac_vn_un_cmd
,
3739 "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>",
3742 "Clear mac registration information\n"
3746 "Any virtual network identifier\n"
3747 "Virtual network identifier\n"
3748 "VN address of NVE\n"
3749 "All VN addresses\n"
3750 "VN IPv4 interface address\n"
3751 "VN IPv6 interface address\n"
3752 "UN address of NVE\n"
3753 "All UN addresses\n"
3754 "UN IPv4 interface address\n"
3755 "UN IPv6 interface address\n")
3757 struct rfapi_local_reg_delete_arg cda
;
3760 /* pfx vn un L2 VNI */
3761 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3762 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3765 clear_vnc_prefix(&cda
);
3766 print_cleared_stats(&cda
);
3770 DEFUN (clear_vnc_mac_un_vn
,
3771 clear_vnc_mac_un_vn_cmd
,
3772 "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>",
3775 "Clear mac registration information\n"
3779 "Any virtual network identifier\n"
3780 "Virtual network identifier\n"
3781 "UN address of NVE\n"
3782 "All UN addresses\n"
3783 "UN IPv4 interface address\n"
3784 "UN IPv6 interface address\n"
3785 "VN address of NVE\n"
3786 "All VN addresses\n"
3787 "VN IPv4 interface address\n"
3788 "VN IPv6 interface address\n")
3790 struct rfapi_local_reg_delete_arg cda
;
3793 /* pfx vn un L2 VNI */
3794 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3795 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3798 clear_vnc_prefix(&cda
);
3799 print_cleared_stats(&cda
);
3803 DEFUN (clear_vnc_mac_un
,
3804 clear_vnc_mac_un_cmd
,
3805 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3808 "Clear mac registration information\n"
3812 "Any virtual network identifier\n"
3813 "Virtual network identifier\n"
3814 "UN address of NVE\n"
3815 "All UN addresses\n"
3816 "UN IPv4 interface address\n"
3817 "UN IPv6 interface address\n")
3819 struct rfapi_local_reg_delete_arg cda
;
3822 /* pfx vn un L2 VNI */
3823 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3824 argv
[5], NULL
, NULL
, &cda
)))
3827 clear_vnc_prefix(&cda
);
3828 print_cleared_stats(&cda
);
3832 DEFUN (clear_vnc_mac_vn
,
3833 clear_vnc_mac_vn_cmd
,
3834 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3837 "Clear mac registration information\n"
3841 "Any virtual network identifier\n"
3842 "Virtual network identifier\n"
3843 "UN address of NVE\n"
3844 "All VN addresses\n"
3845 "VN IPv4 interface address\n"
3846 "VN IPv6 interface address\n")
3848 struct rfapi_local_reg_delete_arg cda
;
3851 /* pfx vn un L2 VNI */
3852 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3853 argv
[5], NULL
, NULL
, &cda
)))
3856 clear_vnc_prefix(&cda
);
3857 print_cleared_stats(&cda
);
3861 DEFUN (clear_vnc_mac_all
,
3862 clear_vnc_mac_all_cmd
,
3863 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3866 "Clear mac registration information\n"
3870 "Any virtual network identifier\n"
3871 "Virtual network identifier\n"
3874 struct rfapi_local_reg_delete_arg cda
;
3877 /* pfx vn un L2 VNI */
3878 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3879 argv
[5], NULL
, NULL
, &cda
)))
3882 clear_vnc_prefix(&cda
);
3883 print_cleared_stats(&cda
);
3887 /*-------------------------------------------------
3888 * Clear VNC MAC PREFIX
3889 *-------------------------------------------------*/
3891 DEFUN (clear_vnc_mac_vn_un_prefix
,
3892 clear_vnc_mac_vn_un_prefix_cmd
,
3893 "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>",
3896 "Clear mac registration information\n"
3900 "Any virtual network identifier\n"
3901 "Virtual network identifier\n"
3902 "VN address of NVE\n"
3903 "All VN addresses\n"
3904 "VN IPv4 interface address\n"
3905 "VN IPv6 interface address\n"
3906 "UN address of NVE\n"
3907 "All UN addresses\n"
3908 "UN IPv4 interface address\n"
3909 "UN IPv6 interface address\n"
3910 "Clear prefix registration information\n"
3915 struct rfapi_local_reg_delete_arg cda
;
3918 /* pfx vn un L2 VNI */
3919 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3920 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3923 clear_vnc_prefix(&cda
);
3924 print_cleared_stats(&cda
);
3928 DEFUN (clear_vnc_mac_un_vn_prefix
,
3929 clear_vnc_mac_un_vn_prefix_cmd
,
3930 "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>",
3933 "Clear mac registration information\n"
3937 "Any virtual network identifier\n"
3938 "Virtual network identifier\n"
3939 "UN address of NVE\n"
3940 "All UN addresses\n"
3941 "UN IPv4 interface address\n"
3942 "UN IPv6 interface address\n"
3943 "VN address of NVE\n"
3944 "All VN addresses\n"
3945 "VN IPv4 interface address\n"
3946 "VN IPv6 interface address\n"
3947 "Clear prefix registration information\n"
3951 "Clear prefix registration information\n"
3956 struct rfapi_local_reg_delete_arg cda
;
3959 /* pfx vn un L2 VNI */
3960 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3961 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3964 clear_vnc_prefix(&cda
);
3965 print_cleared_stats(&cda
);
3969 DEFUN (clear_vnc_mac_un_prefix
,
3970 clear_vnc_mac_un_prefix_cmd
,
3971 "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>",
3974 "Clear mac registration information\n"
3978 "Any virtual network identifier\n"
3979 "Virtual network identifier\n"
3980 "UN address of NVE\n"
3981 "All UN addresses\n"
3982 "UN IPv4 interface address\n"
3983 "UN IPv6 interface address\n"
3984 "Clear prefix registration information\n"
3989 struct rfapi_local_reg_delete_arg cda
;
3992 /* pfx vn un L2 VNI */
3993 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3994 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3997 clear_vnc_prefix(&cda
);
3998 print_cleared_stats(&cda
);
4002 DEFUN (clear_vnc_mac_vn_prefix
,
4003 clear_vnc_mac_vn_prefix_cmd
,
4004 "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>",
4007 "Clear mac registration information\n"
4011 "Any virtual network identifier\n"
4012 "Virtual network identifier\n"
4013 "UN address of NVE\n"
4014 "All VN addresses\n"
4015 "VN IPv4 interface address\n"
4016 "VN IPv6 interface address\n"
4017 "Clear prefix registration information\n"
4022 struct rfapi_local_reg_delete_arg cda
;
4025 /* pfx vn un L2 VNI */
4026 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4027 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4030 clear_vnc_prefix(&cda
);
4031 print_cleared_stats(&cda
);
4035 DEFUN (clear_vnc_mac_all_prefix
,
4036 clear_vnc_mac_all_prefix_cmd
,
4037 "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>",
4040 "Clear mac registration information\n"
4044 "Any virtual network identifier\n"
4045 "Virtual network identifier\n"
4046 "UN address of NVE\n"
4047 "All VN addresses\n"
4048 "VN IPv4 interface address\n"
4049 "VN IPv6 interface address\n")
4051 struct rfapi_local_reg_delete_arg cda
;
4054 /* pfx vn un L2 VNI */
4055 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4056 argv
[5], NULL
, NULL
, &cda
)))
4059 clear_vnc_prefix(&cda
);
4060 print_cleared_stats(&cda
);
4064 /************************************************************************
4066 ************************************************************************/
4069 /* copied from rfp_vty.c */
4070 static int check_and_display_is_vnc_running(struct vty
*vty
)
4072 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4073 return 1; /* is running */
4076 vty_out(vty
, "VNC is not configured.\n");
4078 return 0; /* not running */
4081 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4082 show_nve_summary_t show_type
)
4084 struct bgp
*bgp_default
= bgp_get_default();
4086 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4088 int active_local_routes
;
4089 int active_remote_routes
;
4090 int holddown_remote_routes
;
4091 int imported_remote_routes
;
4096 h
= bgp_default
->rfapi
;
4101 /* don't show local info if not running RFP */
4102 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4104 switch (show_type
) {
4106 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4107 vty_out(vty
, "%-24s ", "NVEs:");
4108 vty_out(vty
, "%-8s %-8u ",
4109 "Active:", h
->descriptors
.count
);
4110 vty_out(vty
, "%-8s %-8u ",
4111 "Maximum:", h
->stat
.max_descriptors
);
4112 vty_out(vty
, "%-8s %-8u",
4113 "Unknown:", h
->stat
.count_unknown_nves
);
4116 case SHOW_NVE_SUMMARY_REGISTERED
:
4118 * NB: With the introduction of L2 route support, we no
4119 * longer have a one-to-one correspondence between
4120 * locally-originated route advertisements and routes in
4121 * the import tables that have local origin. This
4122 * discrepancy arises because a single advertisement
4123 * may contain both an IP prefix and a MAC address.
4124 * Such an advertisement results in two import table
4125 * entries: one indexed by IP prefix, the other indexed
4128 * TBD: update computation and display of registration
4129 * statistics to reflect the underlying semantics.
4131 if (is_vnc_running
) {
4132 vty_out(vty
, "%-24s ", "Registrations:");
4133 vty_out(vty
, "%-8s %-8u ", "Active:",
4134 rfapiApCountAll(bgp_default
));
4135 vty_out(vty
, "%-8s %-8u ", "Failed:",
4136 h
->stat
.count_registrations_failed
);
4137 vty_out(vty
, "%-8s %-8u",
4138 "Total:", h
->stat
.count_registrations
);
4141 vty_out(vty
, "%-24s ", "Prefixes registered:");
4144 rfapiCountAllItRoutes(&active_local_routes
,
4145 &active_remote_routes
,
4146 &holddown_remote_routes
,
4147 &imported_remote_routes
);
4150 if (is_vnc_running
) {
4151 vty_out(vty
, " %-20s ", "Locally:");
4152 vty_out(vty
, "%-8s %-8u ",
4153 "Active:", active_local_routes
);
4158 vty_out(vty
, " %-20s ", "Remotely:");
4159 vty_out(vty
, "%-8s %-8u",
4160 "Active:", active_remote_routes
);
4162 vty_out(vty
, " %-20s ", "In Holddown:");
4163 vty_out(vty
, "%-8s %-8u",
4164 "Active:", holddown_remote_routes
);
4166 vty_out(vty
, " %-20s ", "Imported:");
4167 vty_out(vty
, "%-8s %-8u",
4168 "Active:", imported_remote_routes
);
4171 case SHOW_NVE_SUMMARY_QUERIES
:
4172 vty_out(vty
, "%-24s ", "Queries:");
4173 vty_out(vty
, "%-8s %-8u ",
4174 "Active:", rfapi_monitor_count(NULL
));
4175 vty_out(vty
, "%-8s %-8u ",
4176 "Failed:", h
->stat
.count_queries_failed
);
4177 vty_out(vty
, "%-8s %-8u",
4178 "Total:", h
->stat
.count_queries
);
4181 case SHOW_NVE_SUMMARY_RESPONSES
:
4182 rfapiRibShowResponsesSummary(vty
);
4192 vty_out(vty
, "VNC is not configured.\n");
4196 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4197 struct prefix
*un_prefix
)
4199 // struct hash *rfds;
4200 // struct rfp_rfapi_descriptor_param param;
4202 struct bgp
*bgp_default
= bgp_get_default();
4204 struct listnode
*node
;
4205 struct rfapi_descriptor
*rfd
;
4214 h
= bgp_default
->rfapi
;
4219 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4223 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4225 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4228 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4236 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4237 if (!prefix_match(vn_prefix
, &pfx
))
4242 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4243 if (!prefix_match(un_prefix
, &pfx
))
4247 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4249 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4253 /* print out a header */
4255 " Active Next Hops\n");
4256 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4257 "VN Address", "UN Address", "Regis", "Resps",
4258 "Reach", "Remove", "Age");
4263 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4264 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4265 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4266 rfd
->stat_count_nh_removal
,
4267 rfapiFormatAge(rfd
->open_time
, age
, 10));
4270 if (printed
> 0 || vn_prefix
|| un_prefix
)
4271 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4277 vty_out(vty
, "VNC is not configured.\n");
4282 DEFUN (vnc_show_summary
,
4283 vnc_show_summary_cmd
,
4287 "Display VNC status summary\n")
4289 if (!check_and_display_is_vnc_running(vty
))
4291 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4293 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4294 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4295 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4296 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4300 DEFUN (vnc_show_nves
,
4305 "List known NVEs\n")
4307 rfapi_show_nves(vty
, NULL
, NULL
);
4311 DEFUN (vnc_show_nves_ptct
,
4312 vnc_show_nves_ptct_cmd
,
4313 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4317 "VN address of NVE\n"
4318 "UN address of NVE\n"
4319 "IPv4 interface address\n"
4320 "IPv6 interface address\n")
4324 if (!check_and_display_is_vnc_running(vty
))
4327 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4328 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4331 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4332 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4336 if (argv
[3]->arg
[0] == 'u') {
4337 rfapi_show_nves(vty
, NULL
, &pfx
);
4339 rfapi_show_nves(vty
, &pfx
, NULL
);
4345 /* adapted from rfp_registration_cache_log() */
4346 static void rfapi_show_registrations(struct vty
*vty
,
4347 struct prefix
*restrict_to
, int show_local
,
4348 int show_remote
, int show_holddown
,
4356 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4359 /* non-expiring, local */
4360 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4364 /* non-expiring, non-local */
4365 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4368 if (show_holddown
) {
4369 /* expiring, including local */
4370 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4373 if (show_imported
) {
4374 /* non-expiring, non-local */
4375 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4383 DEFUN (vnc_show_registrations_pfx
,
4384 vnc_show_registrations_pfx_cmd
,
4385 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4388 "List active prefix registrations\n"
4389 "Limit output to a particular IPv4 prefix\n"
4390 "Limit output to a particular IPv6 prefix\n"
4391 "Limit output to a particular IPv6 address\n")
4394 struct prefix
*p_addr
= NULL
;
4397 if (!str2prefix(argv
[3]->arg
, &p
)) {
4398 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4405 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4409 DEFUN (vnc_show_registrations_some_pfx
,
4410 vnc_show_registrations_some_pfx_cmd
,
4411 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4414 "List active prefix registrations\n"
4415 "show all registrations\n"
4416 "show only registrations in holddown\n"
4417 "show only imported prefixes\n"
4418 "show only local registrations\n"
4419 "show only remote registrations\n"
4420 "Limit output to a particular prefix or address\n"
4421 "Limit output to a particular prefix or address\n"
4422 "Limit output to a particular prefix or address\n")
4425 struct prefix
*p_addr
= NULL
;
4428 int show_remote
= 0;
4429 int show_holddown
= 0;
4430 int show_imported
= 0;
4433 if (!str2prefix(argv
[4]->arg
, &p
)) {
4434 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4440 switch (argv
[3]->arg
[0]) {
4465 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4466 show_holddown
, show_imported
);
4470 DEFUN (vnc_show_responses_pfx
,
4471 vnc_show_responses_pfx_cmd
,
4472 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4475 "List recent query responses\n"
4476 "Limit output to a particular IPv4 prefix\n"
4477 "Limit output to a particular IPv6 prefix\n"
4478 "Limit output to a particular IPv6 address\n" )
4481 struct prefix
*p_addr
= NULL
;
4484 if (!str2prefix(argv
[3]->arg
, &p
)) {
4485 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4491 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4493 rfapiRibShowResponsesSummary(vty
);
4495 rfapiRibShowResponses(vty
, p_addr
, 0);
4496 rfapiRibShowResponses(vty
, p_addr
, 1);
4501 DEFUN (vnc_show_responses_some_pfx
,
4502 vnc_show_responses_some_pfx_cmd
,
4503 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4506 "List recent query responses\n"
4507 "show only active query responses\n"
4508 "show only removed query responses\n"
4509 "Limit output to a particular IPv4 prefix\n"
4510 "Limit output to a particular IPv6 prefix\n"
4511 "Limit output to a particular IPV6 address\n")
4514 struct prefix
*p_addr
= NULL
;
4516 int show_active
= 0;
4517 int show_removed
= 0;
4519 if (!check_and_display_is_vnc_running(vty
))
4523 if (!str2prefix(argv
[4]->arg
, &p
)) {
4524 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4531 switch (argv
[3]->arg
[0]) {
4541 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4543 rfapiRibShowResponsesSummary(vty
);
4546 rfapiRibShowResponses(vty
, p_addr
, 0);
4548 rfapiRibShowResponses(vty
, p_addr
, 1);
4553 DEFUN (show_vnc_queries_pfx
,
4554 show_vnc_queries_pfx_cmd
,
4555 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4558 "List active queries\n"
4559 "Limit output to a particular IPv4 prefix or address\n"
4560 "Limit output to a particular IPv6 prefix\n"
4561 "Limit output to a particualr IPV6 address\n")
4564 struct prefix
*p
= NULL
;
4567 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4568 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4574 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4576 return rfapiShowVncQueries(vty
, p
);
4579 DEFUN (vnc_clear_counters
,
4580 vnc_clear_counters_cmd
,
4581 "clear vnc counters",
4584 "Reset VNC counters\n")
4586 struct bgp
*bgp_default
= bgp_get_default();
4588 struct listnode
*node
;
4589 struct rfapi_descriptor
*rfd
;
4594 h
= bgp_default
->rfapi
;
4600 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4601 rfd
->stat_count_nh_reachable
= 0;
4602 rfd
->stat_count_nh_removal
= 0;
4606 memset(&h
->stat
, 0, sizeof(h
->stat
));
4609 * 151122 per bug 103, set count_registrations = number active.
4610 * Do same for queries
4612 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4613 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4615 rfapiRibShowResponsesSummaryClear();
4620 vty_out(vty
, "VNC is not configured.\n");
4624 /************************************************************************
4625 * Add prefix with vrf
4627 * add [vrf <vrf-name>] prefix <prefix>
4628 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4629 ************************************************************************/
4630 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4632 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4633 /* based on rfapi_open */
4634 struct rfapi_descriptor
*rfd
;
4636 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4637 sizeof(struct rfapi_descriptor
));
4640 /* leave most fields empty as will get from (dynamic) config
4642 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4644 if (rfg
->vn_prefix
.family
4645 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4646 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4648 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4649 rfd
->vn_addr
.addr_family
= AF_INET
;
4650 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4652 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4654 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4656 rfapi_init_and_open(bgp
, rfd
, rfg
);
4660 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4661 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4662 const char *arg_prefix
,
4663 const char *arg_rd
, /* optional */
4664 const char *arg_label
, /* optional */
4665 const char *arg_pref
) /* optional */
4668 struct rfapi_nve_group_cfg
*rfg
;
4670 struct rfapi_ip_prefix rpfx
;
4672 struct rfapi_vn_option optary
[3];
4673 struct rfapi_vn_option
*opt
= NULL
;
4676 bgp
= bgp_get_default(); /* assume main instance for now */
4678 vty_out(vty
, "No BGP process is configured\n");
4679 return CMD_WARNING_CONFIG_FAILED
;
4681 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4682 vty_out(vty
, "VRF support not configured\n");
4683 return CMD_WARNING_CONFIG_FAILED
;
4686 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4689 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4691 return CMD_WARNING_CONFIG_FAILED
;
4693 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4695 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4697 return CMD_WARNING_CONFIG_FAILED
;
4699 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4701 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4703 return CMD_WARNING_CONFIG_FAILED
;
4705 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4707 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4709 return CMD_WARNING_CONFIG_FAILED
;
4711 if (!str2prefix(arg_prefix
, &pfx
)) {
4712 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4713 return CMD_WARNING_CONFIG_FAILED
;
4715 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4716 memset(optary
, 0, sizeof(optary
));
4718 opt
= &optary
[cur_opt
++];
4719 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4720 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4721 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4722 return CMD_WARNING_CONFIG_FAILED
;
4725 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4726 struct rfapi_l2address_option
*l2o
;
4728 opt
->next
= &optary
[cur_opt
];
4729 opt
= &optary
[cur_opt
++];
4730 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4731 l2o
= &opt
->v
.l2addr
;
4734 label
= strtoul(arg_label
, NULL
, 10);
4737 l2o
->label
= rfg
->label
;
4740 char *endptr
= NULL
;
4741 pref
= strtoul(arg_pref
, &endptr
, 10);
4742 if (*endptr
!= '\0') {
4744 "%% Invalid local-preference value \"%s\"\n",
4746 return CMD_WARNING_CONFIG_FAILED
;
4749 rpfx
.cost
= 255 - (pref
& 255);
4750 vnc_add_vrf_opener(bgp
, rfg
);
4752 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4753 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4754 struct rfapi_next_hop_entry
*head
= NULL
;
4755 struct rfapi_next_hop_entry
*tail
= NULL
;
4756 struct rfapi_vn_option
*vn_opt_new
;
4758 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4761 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4762 struct rfapi_descriptor
*r
=
4763 (struct rfapi_descriptor
*)rfg
->rfd
;
4764 vn_opt_new
= rfapi_vn_options_dup(opt
);
4766 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4768 RFAPI_INFINITE_LIFETIME
,
4769 vn_opt_new
, &head
, &tail
);
4771 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4772 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4774 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4778 vnc_zlog_debug_verbose(
4779 "%s completed, count=%d/%d", __func__
,
4780 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4781 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4785 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4786 vty_out(vty
, "Add failed.\n");
4787 return CMD_WARNING_CONFIG_FAILED
;
4790 DEFUN (add_vrf_prefix_rd_label_pref
,
4791 add_vrf_prefix_rd_label_pref_cmd
,
4792 "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)}]",
4796 "Add/modify prefix related information\n"
4799 "Override configured VRF Route Distinguisher\n"
4800 "<as-number>:<number> or <ip-address>:<number>\n"
4801 "Override configured VRF label\n"
4802 "Label Value <0-1048575>\n"
4803 "Set advertised local preference\n"
4804 "local preference (higher=more preferred)\n")
4806 char *arg_vrf
= argv
[2]->arg
;
4807 char *arg_prefix
= argv
[4]->arg
;
4808 char *arg_rd
= NULL
; /* optional */
4809 char *arg_label
= NULL
; /* optional */
4810 char *arg_pref
= NULL
; /* optional */
4812 argc
--; /* don't parse argument */
4813 while (pargc
< argc
) {
4814 switch (argv
[pargc
++]->arg
[0]) {
4816 arg_rd
= argv
[pargc
]->arg
;
4819 arg_label
= argv
[pargc
]->arg
;
4822 arg_pref
= argv
[pargc
]->arg
;
4830 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4834 /************************************************************************
4835 * del prefix with vrf
4837 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4838 ************************************************************************/
4839 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4843 if (rfg
->rfapi_import_table
== NULL
)
4846 afi_t afi
= AFI_MAX
;
4848 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4853 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4855 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4860 /* check if IT is empty */
4862 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4866 if (afi
== AFI_MAX
) {
4867 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4872 vnc_zlog_debug_verbose(
4873 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4874 rfg
->rfapi_import_table
->local_count
[afi
]);
4878 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4879 const char *arg_prefix
, /* NULL = all */
4880 const char *arg_rd
) /* optional */
4882 struct rfapi_nve_group_cfg
*rfg
;
4883 struct rfapi_local_reg_delete_arg cda
;
4888 bgp
= bgp_get_default(); /* assume main instance for now */
4890 vty_out(vty
, "No BGP process is configured\n");
4893 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4894 vty_out(vty
, "VRF support not configured\n");
4897 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4900 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4904 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4906 if (rc
!= CMD_SUCCESS
) /* parse error */
4909 start_count
= rfapi_cfg_group_it_count(rfg
);
4910 clear_vnc_prefix(&cda
);
4911 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4916 DEFUN (clear_vrf_prefix_rd
,
4917 clear_vrf_prefix_rd_cmd
,
4918 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4919 "Clear stored data\n"
4922 "Prefix related information\n"
4925 "Specific VRF Route Distinguisher\n"
4926 "<as-number>:<number> or <ip-address>:<number>\n")
4928 char *arg_vrf
= argv
[2]->arg
;
4929 char *arg_prefix
= NULL
; /* optional */
4930 char *arg_rd
= NULL
; /* optional */
4932 argc
--; /* don't check parameter */
4933 while (pargc
< argc
) {
4934 switch (argv
[pargc
++]->arg
[0]) {
4936 arg_rd
= argv
[pargc
]->arg
;
4939 arg_prefix
= argv
[pargc
]->arg
;
4946 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4949 DEFUN (clear_vrf_all
,
4951 "clear vrf NAME all",
4952 "Clear stored data\n"
4957 char *arg_vrf
= argv
[2]->arg
;
4958 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4961 void rfapi_vty_init(void)
4963 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4966 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4967 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4969 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4982 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4984 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4986 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4989 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4990 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4996 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5002 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5008 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5010 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5011 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5013 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5015 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5016 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5017 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5019 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5022 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5023 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);