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
= monotime(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
!= IPV4_MAX_BITLEN
)
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
);
326 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
331 va_start(args
, format
);
333 switch ((uintptr_t)stream
) {
344 vfprintf(file
, format
, args
);
349 /* Fake out for debug logging */
350 static struct vty vty_dummy_zlog
;
351 static struct vty vty_dummy_stdio
;
352 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
354 static const char *str_vty_newline(struct vty
*vty
)
356 if (vty
== &vty_dummy_zlog
)
361 int rfapiStream2Vty(void *stream
, /* input */
362 int (**fp
)(void *, const char *, ...), /* output */
363 struct vty
**vty
, /* output */
364 void **outstream
, /* output */
365 const char **vty_newline
) /* output */
369 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
370 *vty
= &vty_dummy_zlog
;
371 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
373 *vty_newline
= str_vty_newline(*vty
);
377 if (((uintptr_t)stream
== (uintptr_t)1)
378 || ((uintptr_t)stream
== (uintptr_t)2)) {
380 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
381 *vty
= &vty_dummy_stdio
;
382 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
384 *vty_newline
= str_vty_newline(*vty
);
388 *vty
= stream
; /* VTYNL requires vty to be legit */
389 *fp
= (int (*)(void *, const char *, ...))vty_out
;
391 *vty_newline
= str_vty_newline(*vty
);
395 /* called from bgpd/bgp_vty.c'route_vty_out() */
396 void rfapi_vty_out_vncinfo(struct vty
*vty
, const struct prefix
*p
,
397 struct bgp_path_info
*bpi
, safi_t safi
)
403 * Print, on an indented line:
404 * UN address [if VPN route and VNC UN addr subtlv]
410 if (safi
== SAFI_MPLS_VPN
) {
411 struct prefix pfx_un
;
413 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
416 vty_out(vty
, "UN=%s",
417 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
422 if (bgp_attr_get_ecommunity(bpi
->attr
)) {
423 s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(bpi
->attr
),
424 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
425 vty_out(vty
, " EC{%s}", s
);
426 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
429 if (bpi
->extra
!= NULL
) {
430 if (bpi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
431 vty_out(vty
, " label=VRF2VRF");
433 vty_out(vty
, " label=%u",
434 decode_label(&bpi
->extra
->label
[0]));
436 if (bpi
->extra
->num_sids
) {
437 vty_out(vty
, " sid=%pI6", &bpi
->extra
->sid
[0].sid
);
439 if (bpi
->extra
->sid
[0].loc_block_len
!= 0) {
440 vty_out(vty
, " sid_structure=[%d,%d,%d,%d]",
441 bpi
->extra
->sid
[0].loc_block_len
,
442 bpi
->extra
->sid
[0].loc_node_len
,
443 bpi
->extra
->sid
[0].func_len
,
444 bpi
->extra
->sid
[0].arg_len
);
449 if (!rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
450 vty_out(vty
, " life=%d", lifetime
);
453 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bpi
->type
),
456 vty_out(vty
, "%s", HVTYNL
);
459 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
461 int (*fp
)(void *, const char *, ...);
464 const char *vty_newline
;
465 struct transit
*transit
;
466 struct cluster_list
*cluster
;
467 struct ecommunity
*ecomm
;
468 struct community
*comm
;
470 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
473 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
478 fp(out
, " nexthop=%pI4%s", &attr
->nexthop
, HVTYNL
);
480 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
481 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
483 comm
= bgp_attr_get_community(attr
);
484 fp(out
, " community=%p, refcnt=%d%s", comm
, (comm
? comm
->refcnt
: 0),
487 ecomm
= bgp_attr_get_ecommunity(attr
);
488 fp(out
, " ecommunity=%p, refcnt=%d%s", ecomm
,
489 (ecomm
? ecomm
->refcnt
: 0), HVTYNL
);
491 cluster
= bgp_attr_get_cluster(attr
);
492 fp(out
, " cluster=%p, refcnt=%d%s", cluster
,
493 (cluster
? cluster
->refcnt
: 0), HVTYNL
);
495 transit
= bgp_attr_get_transit(attr
);
496 fp(out
, " transit=%p, refcnt=%d%s", transit
,
497 (transit
? transit
->refcnt
: 0), HVTYNL
);
501 * Print BPI in an Import Table
503 void rfapiPrintBi(void *stream
, struct bgp_path_info
*bpi
)
508 int (*fp
)(void *, const char *, ...);
511 const char *vty_newline
;
517 struct ethaddr macaddr
= {{0}};
518 struct rfapi_l2address_option l2o_buf
;
519 uint8_t l2hid
= 0; /* valid if has_macaddr */
521 #define REMAIN (BUFSIZ - (p-line))
522 #define INCP {p += (r > REMAIN)? REMAIN: r;}
524 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
530 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
531 && bpi
->extra
->vnc
.import
.timer
) {
533 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
534 r
= snprintf(p
, REMAIN
, " [%4lu] ",
535 thread_timer_remain_second(t
));
539 r
= snprintf(p
, REMAIN
, " ");
544 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
545 if (decode_rd_type(bpi
->extra
->vnc
.import
.rd
.val
)
546 == RD_TYPE_VNC_ETH
) {
548 memcpy(macaddr
.octet
, bpi
->extra
->vnc
.import
.rd
.val
+ 2,
550 l2hid
= bpi
->extra
->vnc
.import
.rd
.val
[1];
559 * RFP option sizes (they are opaque values)
560 * extended communities (RTs)
563 int printed_1st_gol
= 0;
564 struct bgp_attr_encap_subtlv
*pEncap
;
565 struct prefix pfx_un
;
566 int af
= BGP_MP_NEXTHOP_FAMILY(bpi
->attr
->mp_nexthop_len
);
570 r
= snprintfrr(p
, REMAIN
, "%pI4",
571 &bpi
->attr
->mp_nexthop_global_in
);
573 } else if (af
== AF_INET6
) {
574 r
= snprintfrr(p
, REMAIN
, "%pI6",
575 &bpi
->attr
->mp_nexthop_global
);
578 r
= snprintf(p
, REMAIN
, "?");
583 * VNC tunnel subtlv, if present, contains UN address
585 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
586 r
= snprintf(p
, REMAIN
, " un=%s",
587 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
593 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
594 r
= snprintf(p
, REMAIN
, " nolife");
597 if (lifetime
== 0xffffffff)
598 r
= snprintf(p
, REMAIN
, " %6s", "infini");
600 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
604 /* RFP option lengths */
605 for (pEncap
= bgp_attr_get_vnc_subtlvs(bpi
->attr
); pEncap
;
606 pEncap
= pEncap
->next
) {
608 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
609 if (printed_1st_gol
) {
610 r
= snprintf(p
, REMAIN
, ",");
613 r
= snprintf(p
, REMAIN
,
614 " "); /* leading space */
617 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
624 if (bgp_attr_get_ecommunity(bpi
->attr
)) {
625 s
= ecommunity_ecom2str(bgp_attr_get_ecommunity(bpi
->attr
),
626 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
627 r
= snprintf(p
, REMAIN
, " %s", s
);
629 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
632 r
= snprintf(p
, REMAIN
, " bpi@%p", bpi
);
635 r
= snprintf(p
, REMAIN
, " p@%p", bpi
->peer
);
638 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
639 r
= snprintf(p
, REMAIN
, " HD=yes");
642 r
= snprintf(p
, REMAIN
, " HD=no");
646 if (bpi
->attr
->weight
) {
647 r
= snprintf(p
, REMAIN
, " W=%d", bpi
->attr
->weight
);
651 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
652 r
= snprintf(p
, REMAIN
, " LP=%d", bpi
->attr
->local_pref
);
655 r
= snprintf(p
, REMAIN
, " LP=unset");
659 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bpi
->type
),
663 fp(out
, "%s%s", line
, HVTYNL
);
666 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
667 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
668 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
672 if (!rfapiGetL2o(bpi
->attr
, &l2o_buf
)) {
674 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
675 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
676 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
677 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
678 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
681 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
684 sp
= rfapi_ntop(bpi
->extra
->vnc
.import
.aux_prefix
.family
,
685 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
689 fp(out
, " IP: %s%s", sp
, HVTYNL
);
693 struct rfapi_un_option
*uo
=
694 rfapi_encap_tlv_to_un_option(bpi
->attr
);
696 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
697 rfapi_un_options_free(uo
);
702 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
704 char buf_pfx
[BUFSIZ
];
709 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
710 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
712 rc
= snprintf(buf
, size
,
713 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
714 m
->next
, m
->rfd
, buf_vn
, buf_un
,
715 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
,
717 m
->p
.prefixlen
, m
->node
);
724 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
728 int (*fp
)(void *, const char *, ...);
731 const char *vty_newline
;
733 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
736 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
737 fp(out
, " Mon %s%s", buf
, HVTYNL
);
740 static void rfapiDebugPrintMonitorEncap(void *stream
,
741 struct rfapi_monitor_encap
*m
)
743 int (*fp
)(void *, const char *, ...);
746 const char *vty_newline
;
748 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
751 fp(out
, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m
, m
->next
, m
->node
,
755 void rfapiShowItNode(void *stream
, struct agg_node
*rn
)
757 struct bgp_path_info
*bpi
;
759 int (*fp
)(void *, const char *, ...);
762 const char *vty_newline
;
764 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
767 fp(out
, "%pRN @%p #%d%s", rn
, rn
, agg_node_get_lock_count(rn
), HVTYNL
);
769 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
770 rfapiPrintBi(stream
, bpi
);
773 /* doesn't show montors */
776 void rfapiShowImportTable(void *stream
, const char *label
, struct agg_table
*rt
,
782 int (*fp
)(void *, const char *, ...);
785 const char *vty_newline
;
787 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
790 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
792 for (rn
= agg_route_top(rt
); rn
; rn
= agg_route_next(rn
)) {
793 struct bgp_path_info
*bpi
;
794 const struct prefix
*p
= agg_node_get_prefix(rn
);
796 if (p
->family
== AF_ETHERNET
) {
797 rfapiEthAddr2Str(&p
->u
.prefix_eth
, buf
, sizeof(buf
));
799 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, sizeof(buf
));
802 fp(out
, "%s/%d @%p #%d%s", buf
, p
->prefixlen
, rn
,
803 agg_node_get_lock_count(rn
)
804 - 1, /* account for loop iterator locking */
807 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
808 rfapiPrintBi(stream
, bpi
);
812 struct rfapi_monitor_vpn
*m
;
813 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
814 rfapiDebugPrintMonitorVpn(stream
, m
);
817 struct rfapi_monitor_encap
*m
;
818 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
819 rfapiDebugPrintMonitorEncap(stream
, m
);
825 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
829 struct listnode
*node
;
830 struct rfapi_descriptor
*rfd
;
832 int (*fp
)(void *, const char *, ...);
835 const char *vty_newline
;
837 int printedheader
= 0;
840 int nves_with_queries
= 0;
841 int nves_displayed
= 0;
843 int queries_total
= 0;
844 int queries_displayed
= 0;
846 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
849 bgp
= bgp_get_default(); /* assume 1 instance for now */
851 vty_out(vty
, "No BGP instance\n");
857 vty_out(vty
, "No RFAPI instance\n");
861 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
864 int printedquerier
= 0;
870 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
880 for (rn
= agg_route_top(rfd
->mon
); rn
;
881 rn
= agg_route_next(rn
)) {
882 const struct prefix
*p
=
883 agg_node_get_prefix(rn
);
884 struct rfapi_monitor_vpn
*m
;
885 char buf_remain
[BUFSIZ
];
886 char buf_pfx
[BUFSIZ
];
895 if (pfx_match
&& !prefix_match(pfx_match
, p
)
896 && !prefix_match(p
, pfx_match
))
901 if (!printedheader
) {
904 fp(out
, "%-15s %-15s %-15s %-10s\n",
905 "VN Address", "UN Address", "Target",
909 if (!printedquerier
) {
913 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
915 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
918 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
923 fp(out
, "%-15s %-15s", "", "");
926 thread_timer_remain_second(m
->timer
),
928 fp(out
, " %-15s %-10s\n",
929 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
930 buf_pfx
, sizeof(buf_pfx
)),
938 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
942 struct rfapi_monitor_eth
*mon_eth
;
945 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
946 (void **)&mon_eth
, &cursor
);
948 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
949 (void **)&mon_eth
, &cursor
)) {
951 char buf_remain
[BUFSIZ
];
952 char buf_pfx
[BUFSIZ
];
953 struct prefix pfx_mac
;
957 vnc_zlog_debug_verbose(
958 "%s: checking rfd=%p mon_eth=%p",
959 __func__
, rfd
, mon_eth
);
961 memset((void *)&pfx_mac
, 0,
962 sizeof(struct prefix
));
963 pfx_mac
.family
= AF_ETHERNET
;
964 pfx_mac
.prefixlen
= 48;
965 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
968 && !prefix_match(pfx_match
, &pfx_mac
)
969 && !prefix_match(&pfx_mac
, pfx_match
))
974 if (!printedheader
) {
978 "%-15s %-15s %-17s %10s %-10s\n",
979 "VN Address", "UN Address", "Target",
983 if (!printedquerier
) {
987 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
989 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
992 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
997 fp(out
, "%-15s %-15s", "", "");
999 rfapiFormatSeconds(thread_timer_remain_second(
1001 buf_remain
, BUFSIZ
);
1002 fp(out
, " %-17s %10d %-10s\n",
1003 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
1005 mon_eth
->logical_net_id
, buf_remain
);
1010 if (queries_total
) {
1012 fp(out
, "Displayed %d out of %d total queries\n",
1013 queries_displayed
, queries_total
);
1018 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1019 struct agg_node
*rn
, struct bgp_path_info
*bpi
)
1021 int (*fp
)(void *, const char *, ...);
1024 const char *vty_newline
;
1025 struct prefix pfx_un
;
1026 struct prefix pfx_vn
;
1029 bgp_encap_types tun_type
= BGP_ENCAP_TYPE_MPLS
;/*Default tunnel type*/
1031 char buf_pfx
[BUFSIZ
];
1032 char buf_ntop
[BUFSIZ
];
1033 char buf_un
[BUFSIZ
];
1034 char buf_vn
[BUFSIZ
];
1035 char buf_lifetime
[BUFSIZ
];
1037 const struct prefix
*p
= agg_node_get_prefix(rn
);
1040 return 0; /* for debug log, print into buf & call output once */
1042 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1050 buf_pfx
, sizeof(buf_pfx
), "%s/%d",
1051 rfapi_ntop(p
->family
, &p
->u
.prefix
, buf_ntop
, sizeof(buf_ntop
)),
1053 buf_pfx
[BUFSIZ
- 1] = 0;
1060 if (!rfapiGetUnAddrOfVpnBi(bpi
, &pfx_un
)) {
1061 snprintf(buf_un
, sizeof(buf_un
), "%s",
1062 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1066 bgp_attr_extcom_tunnel_type(bpi
->attr
, &tun_type
);
1071 rfapiNexthop2Prefix(bpi
->attr
, &pfx_vn
);
1072 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1073 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1075 snprintf(buf_un
, sizeof(buf_un
), "%s",
1076 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1079 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1080 snprintf(buf_vn
, sizeof(buf_vn
), "Label: %d", l
);
1081 } else /* should never happen */
1083 snprintf(buf_vn
, sizeof(buf_vn
), "Label: N/A");
1086 snprintf(buf_vn
, sizeof(buf_vn
), "%s",
1087 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1090 buf_vn
[BUFSIZ
- 1] = 0;
1091 buf_un
[BUFSIZ
- 1] = 0;
1094 * Cost is encoded in local_pref as (255-cost)
1095 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1098 uint32_t local_pref
;
1100 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1101 local_pref
= bpi
->attr
->local_pref
;
1104 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1106 fp(out
, "%-20s ", buf_pfx
);
1107 fp(out
, "%-15s ", buf_vn
);
1108 fp(out
, "%-15s ", buf_un
);
1109 fp(out
, "%-4d ", cost
);
1112 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1113 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)
1114 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1116 fp(out
, "%-10s ", "infinite");
1118 time_t t_lifetime
= lifetime
;
1119 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1120 fp(out
, "%-10s ", buf_lifetime
);
1123 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
1124 && bpi
->extra
->vnc
.import
.timer
) {
1128 char buf_age
[BUFSIZ
];
1131 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
1132 remaining
= thread_timer_remain_second(t
);
1134 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1136 * Calculate when the timer started. Doing so here saves
1137 * us a timestamp field in "struct bgp_path_info".
1139 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1140 * original calculation.
1142 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1144 #else /* report remaining time */
1147 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1149 fp(out
, "%-10s ", buf_age
);
1151 } else if (RFAPI_LOCAL_BI(bpi
)) {
1153 char buf_age
[BUFSIZ
];
1155 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.create_time
) {
1156 rfapiFormatAge(bpi
->extra
->vnc
.import
.create_time
,
1162 fp(out
, "%-10s ", buf_age
);
1164 fp(out
, "%s", HVTYNL
);
1166 if (p
->family
== AF_ETHERNET
) {
1168 * If there is a corresponding IP address && != VN address,
1169 * print that on the next line
1172 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
1176 bpi
->extra
->vnc
.import
.aux_prefix
.family
,
1177 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1179 buf_ntop
[BUFSIZ
- 1] = 0;
1181 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1182 fp(out
, " IP: %s", sp
);
1188 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bpi
->extra
) {
1189 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1190 if (!MPLS_LABEL_IS_NULL(l
)) {
1191 fp(out
, " Label: %d", l
);
1197 fp(out
, "%s", HVTYNL
);
1202 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1203 struct rfapi_import_table
*it
,
1204 struct prefix
*prefix_only
,
1205 int show_expiring
, /* either/or */
1206 int show_local
, int show_remote
,
1207 int show_imported
, /* either/or */
1208 uint32_t *pLni
) /* AFI_L2VPN only */
1211 int printed_rtlist_hdr
= 0;
1213 int (*fp
)(void *, const char *, ...);
1216 const char *vty_newline
;
1220 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1223 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1225 struct agg_node
*rn
;
1227 if (!it
->imported_vpn
[afi
])
1230 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1231 rn
= agg_route_next(rn
)) {
1232 const struct prefix
*p
= agg_node_get_prefix(rn
);
1233 struct bgp_path_info
*bpi
;
1236 /* allow for wider or more narrow mask from user */
1237 if (prefix_only
&& !prefix_match(prefix_only
, p
)
1238 && !prefix_match(p
, prefix_only
))
1243 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
1245 if (!show_local
&& RFAPI_LOCAL_BI(bpi
)) {
1247 /* local route from RFP */
1251 if (!show_remote
&& !RFAPI_LOCAL_BI(bpi
)) {
1258 && !CHECK_FLAG(bpi
->flags
,
1263 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1266 if (bpi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1268 == ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1277 if (count_only
== 1)
1279 if (!printed_rtlist_hdr
) {
1280 const char *agetype
= "";
1282 const char *type
= "";
1283 if (show_imported
) {
1286 if (show_expiring
) {
1298 s
= ecommunity_ecom2str(
1300 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1304 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1305 HVTYNL
, type
, *pLni
,
1306 (*pLni
& 0xfff), s
);
1308 fp(out
, "%s[%s] Prefix RT={%s}",
1311 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1313 if (it
->rfg
&& it
->rfg
->name
) {
1314 fp(out
, " %s \"%s\"",
1315 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1320 fp(out
, "%s", HVTYNL
);
1321 if (show_expiring
) {
1322 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1325 agetype
= "Remaining";
1327 } else if (show_local
) {
1331 printed_rtlist_hdr
= 1;
1334 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1335 (pLni
? "L2 Address/IP" : "Prefix"),
1336 "VN Address", "UN Address", "Cost",
1337 "Lifetime", agetype
, HVTYNL
);
1339 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1347 const char *type
= "prefixes";
1349 if (show_imported
) {
1350 type
= "imported prefixes";
1352 if (show_expiring
) {
1353 type
= "prefixes in holddown";
1355 if (show_local
&& !show_remote
) {
1356 type
= "locally registered prefixes";
1357 } else if (!show_local
&& show_remote
) {
1358 type
= "remotely registered prefixes";
1363 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1365 #if DEBUG_SHOW_EXTRA
1366 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1374 * rfapiShowRemoteRegistrations
1376 * Similar to rfapiShowImportTable() above. This function
1377 * is mean to produce the "remote" portion of the output
1378 * of "show vnc registrations".
1380 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1381 int show_expiring
, int show_local
,
1382 int show_remote
, int show_imported
)
1386 struct rfapi_import_table
*it
;
1389 bgp
= bgp_get_default();
1399 for (it
= h
->imports
; it
; it
= it
->next
) {
1400 printed
+= rfapiShowRemoteRegistrationsIt(
1401 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1402 show_remote
, show_imported
, NULL
);
1405 if (h
->import_mac
) {
1406 void *cursor
= NULL
;
1408 uintptr_t lni_as_ptr
;
1412 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1413 (void **)&it
, &cursor
);
1415 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1416 (void **)&it
, &cursor
)) {
1418 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1419 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1423 printed
+= rfapiShowRemoteRegistrationsIt(
1424 bgp
, stream
, it
, prefix_only
, show_expiring
,
1425 show_local
, show_remote
, show_imported
, pLni
);
1432 /*------------------------------------------
1433 * rfapiRfapiIpAddr2Str
1435 * UI helper: generate string from rfapi_ip_addr
1438 * a IP v4/v6 address
1441 * buf put string here
1442 * bufsize max space to write
1445 * NULL conversion failed
1446 * non-NULL pointer to buf
1447 --------------------------------------------*/
1448 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1451 const char *rc
= NULL
;
1453 switch (a
->addr_family
) {
1455 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1458 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1464 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1467 const char *rc
= NULL
;
1469 int (*fp
)(void *, const char *, ...);
1472 const char *vty_newline
;
1474 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1477 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1483 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1486 struct rfapi_ip_addr
*a
= &p
->prefix
;
1487 const char *rc
= NULL
;
1489 switch (a
->addr_family
) {
1491 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1494 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1499 int alen
= strlen(buf
);
1500 int remaining
= bufsize
- alen
- 1;
1503 if (remaining
> 0) {
1504 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1506 if (slen
< remaining
) /* see man page for snprintf(3) */
1514 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1519 int (*fp
)(void *, const char *, ...);
1522 const char *vty_newline
;
1524 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1527 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1530 fp(out
, "%s:%u", buf
, p
->cost
);
1535 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1536 safi_t safi
, struct prefix
*p
)
1538 afi_t afi
; /* of the VN address */
1539 struct bgp_dest
*bd
;
1540 struct bgp_path_info
*bpi
;
1541 uint8_t type
= ZEBRA_ROUTE_BGP
;
1544 struct prefix_rd prd0
;
1545 struct prefix_rd
*prd
;
1548 * Find the bgp_path in the RIB corresponding to this
1552 afi
= family2afi(p
->family
);
1553 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1555 bgp
= bgp_get_default(); /* assume 1 instance for now */
1558 if (safi
== SAFI_ENCAP
) {
1559 memset(&prd0
, 0, sizeof(prd0
));
1560 prd0
.family
= AF_UNSPEC
;
1561 prd0
.prefixlen
= 64;
1566 bd
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1568 vty_out(vty
, " bd=%p%s", bd
, HVTYNL
);
1570 for (bpi
= bgp_dest_get_bgp_path_info(bd
); bpi
; bpi
= bpi
->next
) {
1571 if (bpi
->peer
== rfd
->peer
&& bpi
->type
== type
1572 && bpi
->sub_type
== BGP_ROUTE_RFP
&& bpi
->extra
1573 && bpi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1575 rfapiPrintBi(vty
, bpi
);
1581 vty_out(vty
, " --?--%s", HVTYNL
);
1586 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1588 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1589 /* RT export list */
1590 /* RT import list */
1591 /* list of advertised prefixes */
1592 /* dump import table */
1598 struct rfapi_adb
*adb
;
1600 vty_out(vty
, "%-10p ", rfd
);
1601 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1603 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1604 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1605 vty_out(vty
, "%pRD", &rfd
->rd
);
1606 vty_out(vty
, " %d", rfd
->response_lifetime
);
1607 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1608 vty_out(vty
, "%s", HVTYNL
);
1610 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1612 /* export RT list */
1613 if (rfd
->rt_export_list
) {
1614 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1615 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1616 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1617 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1619 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1622 /* import RT list */
1623 if (rfd
->import_table
) {
1624 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1625 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1626 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1627 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1629 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1632 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1635 family
= afi2family(afi
);
1640 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1641 (void **)&adb
, &cursor
);
1643 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1644 (void **)&adb
, &cursor
)) {
1646 /* group like family prefixes together in output */
1647 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1650 vty_out(vty
, " Adv Pfx: %pFX%s", &adb
->u
.s
.prefix_ip
,
1652 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1653 &adb
->u
.s
.prefix_ip
);
1656 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1657 (void **)&adb
, &cursor
);
1658 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1659 (void **)&adb
, &cursor
)) {
1660 vty_out(vty
, " Adv Pfx: %pFX%s", &adb
->u
.s
.prefix_eth
, HVTYNL
);
1662 /* TBD update the following function to print ethernet info */
1663 /* Also need to pass/use rd */
1664 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1665 &adb
->u
.s
.prefix_ip
);
1667 vty_out(vty
, "%s", HVTYNL
);
1671 * test scripts rely on first line for each nve starting in 1st column,
1672 * leading whitespace for additional detail of that nve
1674 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1675 struct prefix
*un_prefix
)
1679 struct listnode
*ln
;
1680 struct rfapi_descriptor
*rfd
;
1683 bgp
= bgp_get_default(); /* assume 1 instance for now */
1690 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1691 rfd
= listgetdata(ln
);
1696 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1697 if (!prefix_match(vn_prefix
, &pfx
))
1702 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1703 if (!prefix_match(un_prefix
, &pfx
))
1708 /* print column header */
1709 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1710 "un-addr", "vn-addr", "callback", "cookie",
1711 "RD", "lifetime", "group", HVTYNL
);
1713 rfapiPrintDescriptor(vty
, rfd
);
1720 * Parse an address and put into a struct prefix
1722 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1724 if (!str2prefix(str
, p
)) {
1725 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1729 switch (p
->family
) {
1731 if (p
->prefixlen
!= IPV4_MAX_BITLEN
) {
1732 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1738 if (p
->prefixlen
!= IPV6_MAX_BITLEN
) {
1739 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1745 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1751 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1752 struct rfapi_ip_addr
*hai
)
1757 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1761 hai
->addr_family
= pfx
.family
;
1762 if (pfx
.family
== AF_INET
)
1763 hai
->addr
.v4
= pfx
.u
.prefix4
;
1765 hai
->addr
.v6
= pfx
.u
.prefix6
;
1771 * Note: this function does not flush vty output, so if it is called
1772 * with a stream pointing to a vty, the user will have to type something
1773 * before the callback output shows up
1775 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1777 struct rfapi_next_hop_entry
*nh
;
1780 int (*fp
)(void *, const char *, ...);
1783 const char *vty_newline
;
1785 #define REMAIN (BUFSIZ - (p-line))
1786 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1788 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1791 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1797 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1800 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1801 /* it fit, so count length */
1809 r
= snprintf(p
, REMAIN
, ", un=");
1812 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1813 /* it fit, so count length */
1821 r
= snprintf(p
, REMAIN
, ", vn=");
1824 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1825 /* it fit, so count length */
1834 line
[BUFSIZ
- 1] = 0;
1835 fp(out
, "%s%s", line
, HVTYNL
);
1840 if (nh
->vn_options
) {
1841 struct rfapi_vn_option
*vo
;
1842 char offset
[] = " ";
1844 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1848 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1849 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1850 pbuf
, sizeof(pbuf
));
1852 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1854 (vo
->v
.l2addr
.label
& 0x00ffffff),
1855 (vo
->v
.l2addr
.logical_net_id
1857 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1860 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1861 fp(out
, "%sLNH %pFX cost=%d%s", offset
,
1862 &vo
->v
.local_nexthop
.addr
,
1863 vo
->v
.local_nexthop
.cost
, HVTYNL
);
1868 "%svn option type %d (unknown)%s",
1869 offset
, vo
->type
, HVTYNL
);
1874 if (nh
->un_options
) {
1875 struct rfapi_un_option
*uo
;
1876 char offset
[] = " ";
1878 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1880 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1881 rfapi_print_tunneltype_option(
1882 stream
, 8, &uo
->v
.tunnel
);
1885 fp(out
, "%sUN Option type %d%s", offset
,
1886 uo
->type
, vty_newline
);
1894 /***********************************************************************
1896 ***********************************************************************/
1899 * Add another nexthop to the NHL
1901 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1902 struct rfapi_ip_addr
*vn_addr
,
1903 struct rfapi_ip_prefix
*rprefix
,
1905 uint32_t lifetime
, /* add only */
1906 struct rfapi_vn_option
*vn_options
,
1907 struct rfapi_next_hop_entry
**head
,
1908 struct rfapi_next_hop_entry
**tail
)
1910 struct rfapi_next_hop_entry
*new;
1916 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1917 new->prefix
= *rprefix
;
1918 new->un_address
= *un_addr
;
1919 new->vn_address
= *vn_addr
;
1921 new->vn_options
= vn_options
;
1923 new->lifetime
= lifetime
;
1925 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1929 (*tail
)->next
= new;
1938 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1939 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1940 struct cmd_token
*carg_cost
, /* optional */
1941 struct cmd_token
*carg_lifetime
, /* optional */
1942 struct cmd_token
*carg_macaddr
, /* optional */
1944 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1945 int argc
, struct cmd_token
**argv
)
1947 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1948 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1949 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1950 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1951 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1952 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1953 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1954 struct rfapi_ip_addr vn_address
;
1955 struct rfapi_ip_addr un_address
;
1957 struct rfapi_ip_prefix rpfx
;
1962 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1963 struct rfapi_vn_option
*opt
= NULL
;
1966 int rc
= CMD_WARNING_CONFIG_FAILED
;
1970 struct rfapi_cfg
*rfapi_cfg
;
1972 const char *arg_lnh
= NULL
;
1973 const char *arg_lnh_cost
= NULL
;
1975 bgp
= bgp_get_default(); /* assume 1 instance for now */
1978 vty_out(vty
, "BGP not configured\n");
1979 return CMD_WARNING_CONFIG_FAILED
;
1983 rfapi_cfg
= bgp
->rfapi_cfg
;
1984 if (!h
|| !rfapi_cfg
) {
1986 vty_out(vty
, "RFAPI not configured\n");
1987 return CMD_WARNING_CONFIG_FAILED
;
1990 for (; argc
; --argc
, ++argv
) {
1991 if (strmatch(argv
[0]->text
, "local-next-hop")) {
1994 "local-next-hop specified more than once\n");
1995 return CMD_WARNING_CONFIG_FAILED
;
1999 "Missing parameter for local-next-hop\n");
2000 return CMD_WARNING_CONFIG_FAILED
;
2004 arg_lnh
= argv
[0]->arg
;
2006 if (strmatch(argv
[0]->text
, "local-cost")) {
2009 "local-cost specified more than once\n");
2010 return CMD_WARNING_CONFIG_FAILED
;
2014 "Missing parameter for local-cost\n");
2015 return CMD_WARNING_CONFIG_FAILED
;
2019 arg_lnh_cost
= argv
[0]->arg
;
2023 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2025 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2028 /* arg_prefix is optional if mac address is given */
2029 if (arg_macaddr
&& !arg_prefix
) {
2031 * fake up a 0/32 or 0/128 prefix
2033 switch (vn_address
.addr_family
) {
2035 arg_prefix
= "0.0.0.0/32";
2038 arg_prefix
= "0::0/128";
2042 "Internal error, unknown VN address family\n");
2043 return CMD_WARNING_CONFIG_FAILED
;
2047 if (!str2prefix(arg_prefix
, &pfx
)) {
2048 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2051 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2052 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2058 memset(optary
, 0, sizeof(optary
));
2062 cost
= strtoul(arg_cost
, &endptr
, 10);
2063 if (*endptr
!= '\0' || cost
> 255) {
2064 vty_out(vty
, "%% Invalid %s value\n", "cost");
2072 if (!strcmp(arg_lifetime
, "infinite")) {
2073 lifetime
= RFAPI_INFINITE_LIFETIME
;
2076 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2077 if (*endptr
!= '\0') {
2078 vty_out(vty
, "%% Invalid %s value\n",
2084 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2090 "%% %s may only be specified with local-next-hop\n",
2095 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2096 if (*endptr
!= '\0' || lnh_cost
> 255) {
2097 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2107 "%% %s may only be specified with prefix\n",
2111 if ((rc
= rfapiCliGetPrefixAddr(
2113 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2118 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2119 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2122 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2129 if (arg_vni
&& !arg_macaddr
) {
2130 vty_out(vty
, "%% %s may only be specified with mac address\n",
2131 "virtual-network-identifier");
2138 "Missing \"vni\" parameter (mandatory with mac)\n");
2139 return CMD_WARNING_CONFIG_FAILED
;
2141 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2142 strtoul(arg_vni
, NULL
, 10);
2144 if ((rc
= rfapiStr2EthAddr(
2146 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2147 vty_out(vty
, "Invalid %s value\n", "mac address");
2150 /* TBD label, NVE ID */
2152 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2155 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2162 vnc_zlog_debug_verbose(
2163 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2164 __func__
, arg_vn
, arg_un
, arg_prefix
,
2165 (arg_cost
? arg_cost
: "NULL"),
2166 (arg_lifetime
? arg_lifetime
: "NULL"),
2167 (arg_lnh
? arg_lnh
: "NULL"));
2169 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2171 rpfx
.cost
= cost
& 255;
2173 /* look up rf descriptor, call open if it doesn't exist */
2174 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2175 (struct rfapi_descriptor
**)&rfd
);
2178 struct rfapi_un_option uo
;
2181 * flag descriptor as provisionally opened for static
2183 * registration so that we can fix up the other
2185 * when the real open comes along
2187 memset(&uo
, 0, sizeof(uo
));
2188 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2190 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2191 &vn_address
, &un_address
,
2193 NULL
, NULL
, /* no userdata */
2197 "Can't open session for this NVE: %s\n",
2198 rfapi_error_str(rc
));
2199 rc
= CMD_WARNING_CONFIG_FAILED
;
2203 vty_out(vty
, "Can't find session for this NVE: %s\n",
2204 rfapi_error_str(rc
));
2209 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2210 RFAPI_REGISTER_ADD
);
2212 struct rfapi_next_hop_entry
*head
= NULL
;
2213 struct rfapi_next_hop_entry
*tail
= NULL
;
2214 struct rfapi_vn_option
*vn_opt_new
;
2216 vnc_zlog_debug_verbose(
2217 "%s: rfapi_register succeeded, returning 0", __func__
);
2219 if (h
->rfp_methods
.local_cb
) {
2220 struct rfapi_descriptor
*r
=
2221 (struct rfapi_descriptor
*)rfd
;
2222 vn_opt_new
= rfapi_vn_options_dup(opt
);
2224 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2226 vn_opt_new
, &head
, &tail
);
2228 h
->flags
|= RFAPI_INCALLBACK
;
2229 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2230 h
->flags
&= ~RFAPI_INCALLBACK
;
2237 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2239 vty_out(vty
, "Registration failed.\n");
2241 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2242 return CMD_WARNING_CONFIG_FAILED
;
2245 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2249 /************************************************************************
2250 * Add prefix With LNH_OPTIONS...
2251 ************************************************************************/
2252 DEFUN (add_vnc_prefix_cost_life_lnh
,
2253 add_vnc_prefix_cost_life_lnh_cmd
,
2254 "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...",
2255 "Add registration\n"
2257 "Add/modify prefix related information\n"
2260 "VN address of NVE\n"
2261 "VN IPv4 interface address\n"
2262 "VN IPv6 interface address\n"
2263 "UN address of NVE\n"
2264 "UN IPv4 interface address\n"
2265 "UN IPv6 interface address\n"
2266 "Administrative cost [default: 255]\n"
2267 "Administrative cost\n"
2268 "Registration lifetime [default: infinite]\n"
2269 "Lifetime value in seconds\n"
2270 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2272 /* pfx vn un cost life */
2273 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2275 NULL
, NULL
, argc
- 12, argv
+ 12);
2278 DEFUN (add_vnc_prefix_life_cost_lnh
,
2279 add_vnc_prefix_life_cost_lnh_cmd
,
2280 "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...",
2281 "Add registration\n"
2283 "Add/modify prefix related information\n"
2286 "VN address of NVE\n"
2287 "VN IPv4 interface address\n"
2288 "VN IPv6 interface address\n"
2289 "UN address of NVE\n"
2290 "UN IPv4 interface address\n"
2291 "UN IPv6 interface address\n"
2292 "Registration lifetime [default: infinite]\n"
2293 "Lifetime value in seconds\n"
2294 "Administrative cost [default: 255]\n"
2295 "Administrative cost\n"
2296 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2298 /* pfx vn un cost life */
2299 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2301 NULL
, NULL
, argc
- 12, argv
+ 12);
2304 DEFUN (add_vnc_prefix_cost_lnh
,
2305 add_vnc_prefix_cost_lnh_cmd
,
2306 "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...",
2307 "Add registration\n"
2309 "Add/modify prefix related information\n"
2312 "VN address of NVE\n"
2313 "VN IPv4 interface address\n"
2314 "VN IPv6 interface address\n"
2315 "UN address of NVE\n"
2316 "UN IPv4 interface address\n"
2317 "UN IPv6 interface address\n"
2318 "Administrative cost [default: 255]\n"
2319 "Administrative cost\n"
2320 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2322 /* pfx vn un cost life */
2323 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2325 NULL
, NULL
, argc
- 10, argv
+ 10);
2328 DEFUN (add_vnc_prefix_life_lnh
,
2329 add_vnc_prefix_life_lnh_cmd
,
2330 "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...",
2331 "Add registration\n"
2333 "Add/modify prefix related information\n"
2336 "VN address of NVE\n"
2337 "VN IPv4 interface address\n"
2338 "VN IPv6 interface address\n"
2339 "UN address of NVE\n"
2340 "UN IPv4 interface address\n"
2341 "UN IPv6 interface address\n"
2342 "Registration lifetime [default: infinite]\n"
2343 "Lifetime value in seconds\n"
2344 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2346 /* pfx vn un cost life */
2347 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2349 NULL
, NULL
, argc
- 10, argv
+ 10);
2352 DEFUN (add_vnc_prefix_lnh
,
2353 add_vnc_prefix_lnh_cmd
,
2354 "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...",
2355 "Add registration\n"
2357 "Add/modify prefix related information\n"
2360 "VN address of NVE\n"
2361 "VN IPv4 interface address\n"
2362 "VN IPv6 interface address\n"
2363 "UN address of NVE\n"
2364 "UN IPv4 interface address\n"
2365 "UN IPv6 interface address\n"
2366 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2368 /* pfx vn un cost life */
2369 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2371 NULL
, NULL
, argc
- 8, argv
+ 8);
2374 /************************************************************************
2375 * Add prefix Without LNH_OPTIONS...
2376 ************************************************************************/
2377 DEFUN (add_vnc_prefix_cost_life
,
2378 add_vnc_prefix_cost_life_cmd
,
2379 "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)",
2380 "Add registration\n"
2382 "Add/modify prefix related information\n"
2385 "VN address of NVE\n"
2386 "VN IPv4 interface address\n"
2387 "VN IPv6 interface address\n"
2388 "UN address of NVE\n"
2389 "UN IPv4 interface address\n"
2390 "UN IPv6 interface address\n"
2391 "Administrative cost [default: 255]\n"
2392 "Administrative cost\n"
2393 "Registration lifetime [default: infinite]\n"
2394 "Lifetime value in seconds\n")
2396 /* pfx vn un cost life */
2397 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2399 NULL
, NULL
, 0, NULL
);
2402 DEFUN (add_vnc_prefix_life_cost
,
2403 add_vnc_prefix_life_cost_cmd
,
2404 "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)",
2405 "Add registration\n"
2407 "Add/modify prefix related information\n"
2410 "VN address of NVE\n"
2411 "VN IPv4 interface address\n"
2412 "VN IPv6 interface address\n"
2413 "UN address of NVE\n"
2414 "UN IPv4 interface address\n"
2415 "UN IPv6 interface address\n"
2416 "Registration lifetime [default: infinite]\n"
2417 "Lifetime value in seconds\n"
2418 "Administrative cost [default: 255]\n"
2419 "Administrative cost\n")
2421 /* pfx vn un cost life */
2422 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2424 NULL
, NULL
, 0, NULL
);
2427 DEFUN (add_vnc_prefix_cost
,
2428 add_vnc_prefix_cost_cmd
,
2429 "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)",
2430 "Add registration\n"
2432 "Add/modify prefix related information\n"
2435 "VN address of NVE\n"
2436 "VN IPv4 interface address\n"
2437 "VN IPv6 interface address\n"
2438 "UN address of NVE\n"
2439 "UN IPv4 interface address\n"
2440 "UN IPv6 interface address\n"
2441 "Administrative cost [default: 255]\n"
2442 "Administrative cost\n")
2444 /* pfx vn un cost life */
2445 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2447 NULL
, NULL
, 0, NULL
);
2450 DEFUN (add_vnc_prefix_life
,
2451 add_vnc_prefix_life_cmd
,
2452 "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)",
2453 "Add registration\n"
2455 "Add/modify prefix related information\n"
2458 "VN address of NVE\n"
2459 "VN IPv4 interface address\n"
2460 "VN IPv6 interface address\n"
2461 "UN address of NVE\n"
2462 "UN IPv4 interface address\n"
2463 "UN IPv6 interface address\n"
2464 "Registration lifetime [default: infinite]\n"
2465 "Lifetime value in seconds\n")
2467 /* pfx vn un cost life */
2468 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2470 NULL
, NULL
, 0, NULL
);
2473 DEFUN (add_vnc_prefix
,
2475 "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>",
2476 "Add registration\n"
2478 "Add/modify prefix related information\n"
2481 "VN address of NVE\n"
2482 "VN IPv4 interface address\n"
2483 "VN IPv6 interface address\n"
2484 "UN address of NVE\n"
2485 "UN IPv4 interface address\n"
2486 "UN IPv6 interface address\n")
2488 /* pfx vn un cost life */
2489 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2491 NULL
, NULL
, 0, NULL
);
2494 /************************************************************************
2495 * Mac address registrations
2496 ************************************************************************/
2497 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2498 add_vnc_mac_vni_prefix_cost_life_cmd
,
2499 "add vnc mac X:X:X:X:X:X 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)",
2500 "Add registration\n"
2502 "Add/modify mac address information\n"
2504 "Virtual Network Identifier follows\n"
2505 "Virtual Network Identifier\n"
2506 "VN address of NVE\n"
2507 "VN IPv4 interface address\n"
2508 "VN IPv6 interface address\n"
2509 "UN address of NVE\n"
2510 "UN IPv4 interface address\n"
2511 "UN IPv6 interface address\n"
2512 "Add/modify prefix related information\n"
2515 "Administrative cost [default: 255]\n"
2516 "Administrative cost\n"
2517 "Registration lifetime [default: infinite]\n"
2518 "Lifetime value in seconds\n")
2520 /* pfx vn un cost life */
2521 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2523 argv
[3], argv
[5], 0, NULL
);
2527 DEFUN (add_vnc_mac_vni_prefix_life
,
2528 add_vnc_mac_vni_prefix_life_cmd
,
2529 "add vnc mac X:X:X:X:X:X 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)",
2530 "Add registration\n"
2532 "Add/modify mac address information\n"
2534 "Virtual Network Identifier follows\n"
2535 "Virtual Network Identifier\n"
2536 "VN address of NVE\n"
2537 "VN IPv4 interface address\n"
2538 "VN IPv6 interface address\n"
2539 "UN address of NVE\n"
2540 "UN IPv4 interface address\n"
2541 "UN IPv6 interface address\n"
2542 "Add/modify prefix related information\n"
2545 "Registration lifetime [default: infinite]\n"
2546 "Lifetime value in seconds\n")
2548 /* pfx vn un cost life */
2549 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2551 argv
[3], argv
[5], 0, NULL
);
2554 DEFUN (add_vnc_mac_vni_prefix_cost
,
2555 add_vnc_mac_vni_prefix_cost_cmd
,
2556 "add vnc mac X:X:X:X:X:X 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)",
2557 "Add registration\n"
2559 "Add/modify mac address information\n"
2561 "Virtual Network Identifier follows\n"
2562 "Virtual Network Identifier\n"
2563 "VN address of NVE\n"
2564 "VN IPv4 interface address\n"
2565 "VN IPv6 interface address\n"
2566 "UN address of NVE\n"
2567 "UN IPv4 interface address\n"
2568 "UN IPv6 interface address\n"
2569 "Add/modify prefix related information\n"
2572 "Administrative cost [default: 255]\n" "Administrative cost\n")
2574 /* pfx vn un cost life */
2575 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2577 argv
[3], argv
[5], 0, NULL
);
2580 DEFUN (add_vnc_mac_vni_prefix
,
2581 add_vnc_mac_vni_prefix_cmd
,
2582 "add vnc mac X:X:X:X:X:X 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>",
2583 "Add registration\n"
2585 "Add/modify mac address information\n"
2587 "Virtual Network Identifier follows\n"
2588 "Virtual Network Identifier\n"
2589 "VN address of NVE\n"
2590 "VN IPv4 interface address\n"
2591 "VN IPv6 interface address\n"
2592 "UN address of NVE\n"
2593 "UN IPv4 interface address\n"
2594 "UN IPv6 interface address\n"
2595 "Add/modify prefix related information\n"
2596 "IPv4 prefix\n" "IPv6 prefix\n")
2598 /* pfx vn un cost life */
2599 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2601 argv
[3], argv
[5], 0, NULL
);
2604 DEFUN (add_vnc_mac_vni_cost_life
,
2605 add_vnc_mac_vni_cost_life_cmd
,
2606 "add vnc mac X:X:X:X:X:X 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)",
2607 "Add registration\n"
2609 "Add/modify mac address information\n"
2611 "Virtual Network Identifier follows\n"
2612 "Virtual Network Identifier\n"
2613 "VN address of NVE\n"
2614 "VN IPv4 interface address\n"
2615 "VN IPv6 interface address\n"
2616 "UN address of NVE\n"
2617 "UN IPv4 interface address\n"
2618 "UN IPv6 interface address\n"
2619 "Administrative cost [default: 255]\n"
2620 "Administrative cost\n"
2621 "Registration lifetime [default: infinite]\n"
2622 "Lifetime value in seconds\n")
2624 /* pfx vn un cost life */
2625 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2627 argv
[3], argv
[5], 0, NULL
);
2631 DEFUN (add_vnc_mac_vni_cost
,
2632 add_vnc_mac_vni_cost_cmd
,
2633 "add vnc mac X:X:X:X:X:X 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)",
2634 "Add registration\n"
2636 "Add/modify mac address information\n"
2638 "Virtual Network Identifier follows\n"
2639 "Virtual Network Identifier\n"
2640 "VN address of NVE\n"
2641 "VN IPv4 interface address\n"
2642 "VN IPv6 interface address\n"
2643 "UN address of NVE\n"
2644 "UN IPv4 interface address\n"
2645 "UN IPv6 interface address\n"
2646 "Administrative cost [default: 255]\n" "Administrative cost\n")
2648 /* pfx vn un cost life */
2649 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2651 argv
[3], argv
[5], 0, NULL
);
2655 DEFUN (add_vnc_mac_vni_life
,
2656 add_vnc_mac_vni_life_cmd
,
2657 "add vnc mac X:X:X:X:X:X 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)",
2658 "Add registration\n"
2660 "Add/modify mac address information\n"
2662 "Virtual Network Identifier follows\n"
2663 "Virtual Network Identifier\n"
2664 "VN address of NVE\n"
2665 "VN IPv4 interface address\n"
2666 "VN IPv6 interface address\n"
2667 "UN address of NVE\n"
2668 "UN IPv4 interface address\n"
2669 "UN IPv6 interface address\n"
2670 "Registration lifetime [default: infinite]\n"
2671 "Lifetime value in seconds\n")
2673 /* pfx vn un cost life */
2674 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2676 argv
[3], argv
[5], 0, NULL
);
2680 DEFUN (add_vnc_mac_vni
,
2681 add_vnc_mac_vni_cmd
,
2682 "add vnc mac X:X:X:X:X:X virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2683 "Add registration\n"
2685 "Add/modify mac address information\n"
2687 "Virtual Network Identifier follows\n"
2688 "Virtual Network Identifier\n"
2689 "VN address of NVE\n"
2690 "VN IPv4 interface address\n"
2691 "VN IPv6 interface address\n"
2692 "UN address of NVE\n"
2693 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2695 /* pfx vn un cost life */
2696 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2698 argv
[3], argv
[5], 0, NULL
);
2701 /************************************************************************
2703 ************************************************************************/
2705 struct rfapi_local_reg_delete_arg
{
2710 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2711 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2712 struct prefix prefix
; /* AF==0: wildcard */
2713 struct prefix_rd rd
; /* plen!=64: wildcard */
2714 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2716 struct rfapi_l2address_option_match l2o
;
2724 uint32_t query_count
;
2726 uint32_t failed_pfx_count
;
2729 struct skiplist
*nves
;
2731 uint32_t remote_active_nve_count
;
2732 uint32_t remote_active_pfx_count
;
2733 uint32_t remote_holddown_nve_count
;
2734 uint32_t remote_holddown_pfx_count
;
2738 struct rfapi_ip_addr vn
;
2739 struct rfapi_ip_addr un
;
2740 struct rfapi_descriptor
*rfd
;
2741 struct rfapi_local_reg_delete_arg
*cda
;
2744 static void nve_addr_free(void *hap
)
2746 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2747 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2750 static int nve_addr_cmp(const void *k1
, const void *k2
)
2752 const struct nve_addr
*a
= (struct nve_addr
*)k1
;
2753 const struct nve_addr
*b
= (struct nve_addr
*)k2
;
2759 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2760 return (a
->un
.addr_family
- b
->un
.addr_family
);
2762 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2763 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2765 if (a
->un
.addr_family
== AF_INET
) {
2766 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2770 } else if (a
->un
.addr_family
== AF_INET6
) {
2771 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2778 if (a
->vn
.addr_family
== AF_INET
) {
2779 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2782 } else if (a
->vn
.addr_family
== AF_INET6
) {
2783 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2793 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2794 const char *arg_prefix
, const char *arg_vn
,
2795 const char *arg_un
, const char *arg_l2addr
,
2796 const char *arg_vni
, const char *arg_rd
,
2797 struct rfapi_nve_group_cfg
*arg_rfg
,
2798 struct rfapi_local_reg_delete_arg
*rcdarg
)
2800 int rc
= CMD_WARNING
;
2802 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2806 bgp
= bgp_get_default();
2808 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2810 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2811 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2812 &rcdarg
->vn_address
)))
2815 if (arg_un
&& strcmp(arg_un
, "*")) {
2816 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2817 &rcdarg
->un_address
)))
2820 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2822 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2823 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2830 vty_out(vty
, "Missing VNI\n");
2833 if (strcmp(arg_l2addr
, "*")) {
2834 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2835 &rcdarg
->l2o
.o
.macaddr
))) {
2836 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2840 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2842 if (strcmp(arg_vni
, "*")) {
2843 rcdarg
->l2o
.o
.logical_net_id
=
2844 strtoul(arg_vni
, NULL
, 10);
2845 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2849 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2850 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2859 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2860 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2861 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2862 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2863 struct rfapi_nve_group_cfg
*arg_rfg
,
2864 struct rfapi_local_reg_delete_arg
*rcdarg
)
2866 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2867 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2868 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2869 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2870 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2871 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2872 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2873 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2876 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2877 struct rfapi_ip_addr
*un_address
,
2878 struct rfapi_ip_addr
*vn_address
,
2879 struct rfapi_descriptor
*rfd
)
2882 struct nve_addr
*hap
;
2884 memset(&ha
, 0, sizeof(ha
));
2885 ha
.un
= *un_address
;
2886 ha
.vn
= *vn_address
;
2890 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2892 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2893 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2897 skiplist_insert(cda
->nves
, hap
, hap
);
2901 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2904 struct rfapi_descriptor
*rfd
;
2905 int query_count
= 0;
2906 struct listnode
*node
;
2907 struct bgp
*bgp_default
= bgp_get_default();
2909 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2913 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2914 &cda
->un_address
, &rfd
))
2918 rfapi_query_done_all(rfd
, &query_count
);
2919 cda
->query_count
+= query_count
;
2922 * Track unique nves seen
2924 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2935 h
= bgp_default
->rfapi
;
2940 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2942 * match un, vn addresses of NVEs
2944 if (cda
->un_address
.addr_family
2945 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2948 if (cda
->vn_address
.addr_family
2949 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2955 rfapi_query_done_all(rfd
, &query_count
);
2956 cda
->query_count
+= query_count
;
2959 * Track unique nves seen
2961 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2966 * TBD need to count deleted prefixes and nves?
2968 * ENXIO BGP or VNC not configured
2970 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2971 struct rfapi_descriptor
*rfd
)
2973 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2974 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2975 struct prefix
*pPrefix
; /* NULL = wildcard */
2976 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2978 struct rfapi_ip_prefix rprefix
;
2979 struct rfapi_next_hop_entry
*head
= NULL
;
2980 struct rfapi_next_hop_entry
*tail
= NULL
;
2983 vnc_zlog_debug_verbose("%s: entry", __func__
);
2986 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2987 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2988 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2989 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2992 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
2995 do /* to preserve old code structure */
2997 struct rfapi
*h
= cda
->bgp
->rfapi
;
2999 struct rfapi_adb
*adb
;
3001 int deleted_from_this_nve
;
3003 struct nve_addr
*hap
;
3006 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3010 * match un, vn addresses of NVEs
3012 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3014 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3018 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3025 deleted_from_this_nve
= 0;
3028 struct skiplist
*sl
;
3029 struct rfapi_ip_prefix rp
;
3031 struct list
*adb_delete_list
;
3034 * The advertisements are stored in a skiplist.
3036 * the registration deletes the advertisement from the
3037 * skiplist, which we can't do while iterating over that
3038 * same skiplist using the current skiplist API.
3040 * Strategy: iterate over the skiplist and build another
3041 * list containing only the matching ADBs. Then delete
3042 * _everything_ in that second list (which can be done
3043 * using either skiplists or quagga linklists).
3045 adb_delete_list
= list_new();
3048 * Advertised IP prefixes (not 0/32 or 0/128)
3050 sl
= rfd
->advertised
.ipN_by_prefix
;
3053 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3055 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3059 if (!prefix_same(pPrefix
,
3060 &adb
->u
.s
.prefix_ip
)) {
3062 vnc_zlog_debug_verbose(
3063 "%s: adb=%p, prefix doesn't match, skipping",
3070 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3074 vnc_zlog_debug_verbose(
3075 "%s: adb=%p, RD doesn't match, skipping",
3081 if (CHECK_FLAG(cda
->l2o
.flags
,
3082 RFAPI_L2O_MACADDR
)) {
3083 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3084 adb
->u
.s
.prefix_eth
.u
3088 vnc_zlog_debug_verbose(
3089 "%s: adb=%p, macaddr doesn't match, skipping",
3096 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3097 if (cda
->l2o
.o
.logical_net_id
3098 != adb
->l2o
.logical_net_id
) {
3100 vnc_zlog_debug_verbose(
3101 "%s: adb=%p, LNI doesn't match, skipping",
3109 vnc_zlog_debug_verbose(
3110 "%s: ipN adding adb %p to delete list",
3114 listnode_add(adb_delete_list
, adb
);
3117 struct listnode
*node
;
3119 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3120 int this_advertisement_prefix_count
;
3121 struct rfapi_vn_option optary
[3];
3122 struct rfapi_vn_option
*opt
= NULL
;
3125 this_advertisement_prefix_count
= 1;
3127 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3129 memset(optary
, 0, sizeof(optary
));
3131 /* if mac addr present in advert, make l2o vn
3133 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3135 opt
->next
= &optary
[cur_opt
];
3136 opt
= &optary
[cur_opt
++];
3137 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3138 opt
->v
.l2addr
.macaddr
=
3139 adb
->u
.s
.prefix_eth
.u
3141 ++this_advertisement_prefix_count
;
3144 * use saved RD value instead of trying to
3146 * complex RD computation in rfapi_register()
3149 opt
->next
= &optary
[cur_opt
];
3150 opt
= &optary
[cur_opt
++];
3151 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3152 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3155 vnc_zlog_debug_verbose(
3156 "%s: ipN killing reg from adb %p ",
3160 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3161 (cur_opt
? optary
: NULL
),
3162 RFAPI_REGISTER_KILL
);
3165 this_advertisement_prefix_count
;
3166 cda
->reg_count
+= 1;
3167 deleted_from_this_nve
= 1;
3169 if (h
->rfp_methods
.local_cb
) {
3170 rfapiAddDeleteLocalRfpPrefix(
3171 &rfd
->un_addr
, &rfd
->vn_addr
,
3172 &rp
, 0, 0, NULL
, &head
, &tail
);
3175 list_delete_all_node(adb_delete_list
);
3177 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3179 * Caller didn't specify a prefix, or specified
3184 * Advertised 0/32 and 0/128 (indexed by
3187 sl
= rfd
->advertised
.ip0_by_ether
;
3190 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3193 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3196 if (CHECK_FLAG(cda
->l2o
.flags
,
3197 RFAPI_L2O_MACADDR
)) {
3198 if (memcmp(cda
->l2o
.o
.macaddr
3200 adb
->u
.s
.prefix_eth
.u
3208 if (CHECK_FLAG(cda
->l2o
.flags
,
3210 if (cda
->l2o
.o
.logical_net_id
3211 != adb
->l2o
.logical_net_id
) {
3216 vnc_zlog_debug_verbose(
3217 "%s: ip0 adding adb %p to delete list",
3220 listnode_add(adb_delete_list
, adb
);
3224 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3227 struct rfapi_vn_option vn
;
3229 rfapiQprefix2Rprefix(
3230 &adb
->u
.s
.prefix_ip
, &rp
);
3232 memset(&vn
, 0, sizeof(vn
));
3233 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3234 vn
.v
.l2addr
= adb
->l2o
;
3237 vnc_zlog_debug_verbose(
3238 "%s: ip0 killing reg from adb %p ",
3242 rc
= rfapi_register(
3243 rfd
, &rp
, 0, NULL
, &vn
,
3244 RFAPI_REGISTER_KILL
);
3246 cda
->pfx_count
+= 1;
3247 cda
->reg_count
+= 1;
3248 deleted_from_this_nve
= 1;
3250 if (h
->rfp_methods
.local_cb
) {
3251 struct rfapi_vn_option
3255 rfapi_vn_options_dup(
3257 rfapiAddDeleteLocalRfpPrefix(
3259 &rfd
->vn_addr
, &rp
, 0,
3260 0, vn_opt_new
, &head
,
3264 list_delete_all_node(adb_delete_list
);
3266 list_delete(&adb_delete_list
);
3270 if (head
) { /* should not be set if (NULL ==
3271 rfapi_cfg->local_cb) */
3272 h
->flags
|= RFAPI_INCALLBACK
;
3273 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3274 h
->flags
&= ~RFAPI_INCALLBACK
;
3278 if (deleted_from_this_nve
) {
3280 * track unique NVEs seen
3282 memset(&ha
, 0, sizeof(ha
));
3283 ha
.un
= rfd
->un_addr
;
3284 ha
.vn
= rfd
->vn_addr
;
3287 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3289 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3290 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3291 sizeof(struct nve_addr
));
3295 skiplist_insert(cda
->nves
, hap
, hap
);
3298 } while (0); /* to preserve old code structure */
3303 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3308 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3309 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3311 struct bgp
*bgp
= cda
->bgp
;
3313 struct rfapi_cfg
*rfapi_cfg
;
3315 struct listnode
*node
;
3316 struct rfapi_descriptor
*rfd
;
3320 rfapi_cfg
= bgp
->rfapi_cfg
;
3321 if (!h
|| !rfapi_cfg
)
3323 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3325 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3326 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3335 * Deletes local and remote prefixes that match
3337 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3339 struct prefix pfx_un
;
3340 struct prefix pfx_vn
;
3342 struct prefix
*pUN
= NULL
;
3343 struct prefix
*pVN
= NULL
;
3344 struct prefix
*pPrefix
= NULL
;
3346 struct rfapi_import_table
*it
= NULL
;
3349 * Delete matching remote prefixes in holddown
3351 if (cda
->vn_address
.addr_family
) {
3352 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3355 if (cda
->un_address
.addr_family
) {
3356 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3359 if (cda
->prefix
.family
) {
3360 pPrefix
= &cda
->prefix
;
3363 it
= cda
->rfg
->rfapi_import_table
;
3365 rfapiDeleteRemotePrefixes(
3366 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3367 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3368 &cda
->remote_holddown_nve_count
);
3371 * Now do local prefixes
3373 rfapiDeleteLocalPrefixes(cda
);
3376 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3378 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3380 /* Our special element-deleting function counts nves */
3382 skiplist_free(cda
->nves
);
3385 if (cda
->failed_pfx_count
)
3386 vty_out(vty
, "Failed to delete %d prefixes\n",
3387 cda
->failed_pfx_count
);
3389 /* left as "prefixes" even in single case for ease of machine parsing */
3391 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3392 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3396 * We don't currently allow deletion of active remote prefixes from
3400 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3401 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3405 * Caller has already deleted registrations and queries for this/these
3406 * NVEs. Now we just have to close their descriptors.
3408 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3410 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3411 struct nve_addr
*pKey
;
3412 struct nve_addr
*pValue
;
3413 void *cursor
= NULL
;
3419 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3420 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3424 pValue
->rfd
->flags
|=
3425 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3426 rfapi_close(pValue
->rfd
);
3431 DEFUN (clear_vnc_nve_all
,
3432 clear_vnc_nve_all_cmd
,
3436 "Clear per NVE information\n"
3440 struct rfapi_local_reg_delete_arg cda
;
3443 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3449 clear_vnc_responses(&cda
);
3450 clear_vnc_prefix(&cda
);
3451 clear_vnc_nve_closer(&cda
);
3453 print_cleared_stats(&cda
);
3458 DEFUN (clear_vnc_nve_vn_un
,
3459 clear_vnc_nve_vn_un_cmd
,
3460 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3463 "Clear prefix registration information\n"
3464 "VN address of NVE\n"
3466 "VN IPv4 interface address\n"
3467 "VN IPv6 interface address\n"
3468 "UN address of NVE\n"
3469 "For all UN addresses\n"
3470 "UN IPv4 interface address\n"
3471 "UN IPv6 interface address\n")
3473 struct rfapi_local_reg_delete_arg cda
;
3476 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3477 NULL
, NULL
, NULL
, &cda
)))
3482 clear_vnc_responses(&cda
);
3483 clear_vnc_prefix(&cda
);
3484 clear_vnc_nve_closer(&cda
);
3486 print_cleared_stats(&cda
);
3491 DEFUN (clear_vnc_nve_un_vn
,
3492 clear_vnc_nve_un_vn_cmd
,
3493 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3496 "Clear prefix registration information\n"
3497 "UN address of NVE\n"
3499 "UN IPv4 interface address\n"
3500 "UN IPv6 interface address\n"
3501 "VN address of NVE\n"
3503 "VN IPv4 interface address\n"
3504 "VN IPv6 interface address\n")
3506 struct rfapi_local_reg_delete_arg cda
;
3509 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3510 NULL
, NULL
, NULL
, &cda
)))
3515 clear_vnc_responses(&cda
);
3516 clear_vnc_prefix(&cda
);
3517 clear_vnc_nve_closer(&cda
);
3519 print_cleared_stats(&cda
);
3524 DEFUN (clear_vnc_nve_vn
,
3525 clear_vnc_nve_vn_cmd
,
3526 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3529 "Clear prefix registration information\n"
3530 "VN address of NVE\n"
3532 "VN IPv4 interface address\n"
3533 "VN IPv6 interface address\n")
3535 struct rfapi_local_reg_delete_arg cda
;
3538 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3539 NULL
, NULL
, NULL
, &cda
)))
3544 clear_vnc_responses(&cda
);
3545 clear_vnc_prefix(&cda
);
3546 clear_vnc_nve_closer(&cda
);
3548 print_cleared_stats(&cda
);
3552 DEFUN (clear_vnc_nve_un
,
3553 clear_vnc_nve_un_cmd
,
3554 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3557 "Clear prefix registration information\n"
3558 "UN address of NVE\n"
3560 "UN IPv4 interface address\n"
3561 "UN IPv6 interface address\n")
3563 struct rfapi_local_reg_delete_arg cda
;
3566 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3567 NULL
, NULL
, NULL
, &cda
)))
3572 clear_vnc_responses(&cda
);
3573 clear_vnc_prefix(&cda
);
3574 clear_vnc_nve_closer(&cda
);
3576 print_cleared_stats(&cda
);
3580 /*-------------------------------------------------
3582 *-------------------------------------------------*/
3585 * This function is defined in this file (rather than in rfp_registration.c)
3586 * because here we have access to all the task handles.
3588 DEFUN (clear_vnc_prefix_vn_un
,
3589 clear_vnc_prefix_vn_un_cmd
,
3590 "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>",
3593 "Clear prefix registration information\n"
3597 "VN address of NVE\n"
3598 "All VN addresses\n"
3599 "VN IPv4 interface address\n"
3600 "VN IPv6 interface address\n"
3601 "UN address of NVE\n"
3602 "All UN addresses\n"
3603 "UN IPv4 interface address\n"
3604 "UN IPv6 interface address\n")
3606 struct rfapi_local_reg_delete_arg cda
;
3609 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3610 NULL
, NULL
, NULL
, NULL
, &cda
)))
3613 clear_vnc_prefix(&cda
);
3614 print_cleared_stats(&cda
);
3618 DEFUN (clear_vnc_prefix_un_vn
,
3619 clear_vnc_prefix_un_vn_cmd
,
3620 "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>",
3623 "Clear prefix registration information\n"
3627 "UN address of NVE\n"
3628 "All UN addresses\n"
3629 "UN IPv4 interface address\n"
3630 "UN IPv6 interface address\n"
3631 "VN address of NVE\n"
3632 "All VN addresses\n"
3633 "VN IPv4 interface address\n"
3634 "VN IPv6 interface address\n")
3636 struct rfapi_local_reg_delete_arg cda
;
3639 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3640 NULL
, NULL
, NULL
, NULL
, &cda
)))
3643 clear_vnc_prefix(&cda
);
3644 print_cleared_stats(&cda
);
3648 DEFUN (clear_vnc_prefix_un
,
3649 clear_vnc_prefix_un_cmd
,
3650 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3653 "Clear prefix registration information\n"
3657 "UN address of NVE\n"
3658 "All UN addresses\n"
3659 "UN IPv4 interface address\n"
3660 "UN IPv6 interface address\n")
3662 struct rfapi_local_reg_delete_arg cda
;
3665 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3666 NULL
, NULL
, NULL
, &cda
)))
3669 clear_vnc_prefix(&cda
);
3670 print_cleared_stats(&cda
);
3674 DEFUN (clear_vnc_prefix_vn
,
3675 clear_vnc_prefix_vn_cmd
,
3676 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3679 "Clear prefix registration information\n"
3683 "UN address of NVE\n"
3684 "All VN addresses\n"
3685 "VN IPv4 interface address\n"
3686 "VN IPv6 interface address\n")
3688 struct rfapi_local_reg_delete_arg cda
;
3691 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3692 NULL
, NULL
, NULL
, &cda
)))
3695 clear_vnc_prefix(&cda
);
3696 print_cleared_stats(&cda
);
3700 DEFUN (clear_vnc_prefix_all
,
3701 clear_vnc_prefix_all_cmd
,
3702 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3705 "Clear prefix registration information\n"
3711 struct rfapi_local_reg_delete_arg cda
;
3714 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3715 NULL
, NULL
, NULL
, &cda
)))
3718 clear_vnc_prefix(&cda
);
3719 print_cleared_stats(&cda
);
3723 /*-------------------------------------------------
3725 *-------------------------------------------------*/
3728 * This function is defined in this file (rather than in rfp_registration.c)
3729 * because here we have access to all the task handles.
3731 DEFUN (clear_vnc_mac_vn_un
,
3732 clear_vnc_mac_vn_un_cmd
,
3733 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3736 "Clear mac registration information\n"
3740 "Any virtual network identifier\n"
3741 "Virtual network identifier\n"
3742 "VN address of NVE\n"
3743 "All VN addresses\n"
3744 "VN IPv4 interface address\n"
3745 "VN IPv6 interface address\n"
3746 "UN address of NVE\n"
3747 "All UN addresses\n"
3748 "UN IPv4 interface address\n"
3749 "UN IPv6 interface address\n")
3751 struct rfapi_local_reg_delete_arg cda
;
3754 /* pfx vn un L2 VNI */
3755 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3756 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3759 clear_vnc_prefix(&cda
);
3760 print_cleared_stats(&cda
);
3764 DEFUN (clear_vnc_mac_un_vn
,
3765 clear_vnc_mac_un_vn_cmd
,
3766 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3769 "Clear mac registration information\n"
3773 "Any virtual network identifier\n"
3774 "Virtual network identifier\n"
3775 "UN address of NVE\n"
3776 "All UN addresses\n"
3777 "UN IPv4 interface address\n"
3778 "UN IPv6 interface address\n"
3779 "VN address of NVE\n"
3780 "All VN addresses\n"
3781 "VN IPv4 interface address\n"
3782 "VN IPv6 interface address\n")
3784 struct rfapi_local_reg_delete_arg cda
;
3787 /* pfx vn un L2 VNI */
3788 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3789 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3792 clear_vnc_prefix(&cda
);
3793 print_cleared_stats(&cda
);
3797 DEFUN (clear_vnc_mac_un
,
3798 clear_vnc_mac_un_cmd
,
3799 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3802 "Clear mac registration information\n"
3806 "Any virtual network identifier\n"
3807 "Virtual network identifier\n"
3808 "UN address of NVE\n"
3809 "All UN addresses\n"
3810 "UN IPv4 interface address\n"
3811 "UN IPv6 interface address\n")
3813 struct rfapi_local_reg_delete_arg cda
;
3816 /* pfx vn un L2 VNI */
3817 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3818 argv
[5], NULL
, NULL
, &cda
)))
3821 clear_vnc_prefix(&cda
);
3822 print_cleared_stats(&cda
);
3826 DEFUN (clear_vnc_mac_vn
,
3827 clear_vnc_mac_vn_cmd
,
3828 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3831 "Clear mac registration information\n"
3835 "Any virtual network identifier\n"
3836 "Virtual network identifier\n"
3837 "UN address of NVE\n"
3838 "All VN addresses\n"
3839 "VN IPv4 interface address\n"
3840 "VN IPv6 interface address\n")
3842 struct rfapi_local_reg_delete_arg cda
;
3845 /* pfx vn un L2 VNI */
3846 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3847 argv
[5], NULL
, NULL
, &cda
)))
3850 clear_vnc_prefix(&cda
);
3851 print_cleared_stats(&cda
);
3855 DEFUN (clear_vnc_mac_all
,
3856 clear_vnc_mac_all_cmd
,
3857 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> *",
3860 "Clear mac registration information\n"
3864 "Any virtual network identifier\n"
3865 "Virtual network identifier\n"
3868 struct rfapi_local_reg_delete_arg cda
;
3871 /* pfx vn un L2 VNI */
3872 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3873 argv
[5], NULL
, NULL
, &cda
)))
3876 clear_vnc_prefix(&cda
);
3877 print_cleared_stats(&cda
);
3881 /*-------------------------------------------------
3882 * Clear VNC MAC PREFIX
3883 *-------------------------------------------------*/
3885 DEFUN (clear_vnc_mac_vn_un_prefix
,
3886 clear_vnc_mac_vn_un_prefix_cmd
,
3887 "clear vnc mac <*|X:X:X:X:X:X> 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>",
3890 "Clear mac registration information\n"
3894 "Any virtual network identifier\n"
3895 "Virtual network identifier\n"
3896 "VN address of NVE\n"
3897 "All VN addresses\n"
3898 "VN IPv4 interface address\n"
3899 "VN IPv6 interface address\n"
3900 "UN address of NVE\n"
3901 "All UN addresses\n"
3902 "UN IPv4 interface address\n"
3903 "UN IPv6 interface address\n"
3904 "Clear prefix registration information\n"
3909 struct rfapi_local_reg_delete_arg cda
;
3912 /* pfx vn un L2 VNI */
3913 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3914 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3917 clear_vnc_prefix(&cda
);
3918 print_cleared_stats(&cda
);
3922 DEFUN (clear_vnc_mac_un_vn_prefix
,
3923 clear_vnc_mac_un_vn_prefix_cmd
,
3924 "clear vnc mac <*|X:X:X:X:X:X> 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>",
3927 "Clear mac registration information\n"
3931 "Any virtual network identifier\n"
3932 "Virtual network identifier\n"
3933 "UN address of NVE\n"
3934 "All UN addresses\n"
3935 "UN IPv4 interface address\n"
3936 "UN IPv6 interface address\n"
3937 "VN address of NVE\n"
3938 "All VN addresses\n"
3939 "VN IPv4 interface address\n"
3940 "VN IPv6 interface address\n"
3941 "Clear prefix registration information\n"
3945 "Clear prefix registration information\n"
3950 struct rfapi_local_reg_delete_arg cda
;
3953 /* pfx vn un L2 VNI */
3954 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3955 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3958 clear_vnc_prefix(&cda
);
3959 print_cleared_stats(&cda
);
3963 DEFUN (clear_vnc_mac_un_prefix
,
3964 clear_vnc_mac_un_prefix_cmd
,
3965 "clear vnc mac <*|X:X:X:X:X:X> 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>",
3968 "Clear mac registration information\n"
3972 "Any virtual network identifier\n"
3973 "Virtual network identifier\n"
3974 "UN address of NVE\n"
3975 "All UN addresses\n"
3976 "UN IPv4 interface address\n"
3977 "UN IPv6 interface address\n"
3978 "Clear prefix registration information\n"
3983 struct rfapi_local_reg_delete_arg cda
;
3986 /* pfx vn un L2 VNI */
3987 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3988 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3991 clear_vnc_prefix(&cda
);
3992 print_cleared_stats(&cda
);
3996 DEFUN (clear_vnc_mac_vn_prefix
,
3997 clear_vnc_mac_vn_prefix_cmd
,
3998 "clear vnc mac <*|X:X:X:X:X:X> 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>",
4001 "Clear mac registration information\n"
4005 "Any virtual network identifier\n"
4006 "Virtual network identifier\n"
4007 "UN address of NVE\n"
4008 "All VN addresses\n"
4009 "VN IPv4 interface address\n"
4010 "VN IPv6 interface address\n"
4011 "Clear prefix registration information\n"
4016 struct rfapi_local_reg_delete_arg cda
;
4019 /* pfx vn un L2 VNI */
4020 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4021 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4024 clear_vnc_prefix(&cda
);
4025 print_cleared_stats(&cda
);
4029 DEFUN (clear_vnc_mac_all_prefix
,
4030 clear_vnc_mac_all_prefix_cmd
,
4031 "clear vnc mac <*|X:X:X:X:X:X> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4034 "Clear mac registration information\n"
4038 "Any virtual network identifier\n"
4039 "Virtual network identifier\n"
4040 "UN address of NVE\n"
4041 "All VN addresses\n"
4042 "VN IPv4 interface address\n"
4043 "VN IPv6 interface address\n")
4045 struct rfapi_local_reg_delete_arg cda
;
4048 /* pfx vn un L2 VNI */
4049 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4050 argv
[5], NULL
, NULL
, &cda
)))
4053 clear_vnc_prefix(&cda
);
4054 print_cleared_stats(&cda
);
4058 /************************************************************************
4060 ************************************************************************/
4063 /* copied from rfp_vty.c */
4064 static int check_and_display_is_vnc_running(struct vty
*vty
)
4066 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4067 return 1; /* is running */
4070 vty_out(vty
, "VNC is not configured.\n");
4072 return 0; /* not running */
4075 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4076 show_nve_summary_t show_type
)
4078 struct bgp
*bgp_default
= bgp_get_default();
4080 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4082 int active_local_routes
;
4083 int active_remote_routes
;
4084 int holddown_remote_routes
;
4085 int imported_remote_routes
;
4090 h
= bgp_default
->rfapi
;
4095 /* don't show local info if not running RFP */
4096 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4098 switch (show_type
) {
4100 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4101 vty_out(vty
, "%-24s ", "NVEs:");
4102 vty_out(vty
, "%-8s %-8u ",
4103 "Active:", h
->descriptors
.count
);
4104 vty_out(vty
, "%-8s %-8u ",
4105 "Maximum:", h
->stat
.max_descriptors
);
4106 vty_out(vty
, "%-8s %-8u",
4107 "Unknown:", h
->stat
.count_unknown_nves
);
4110 case SHOW_NVE_SUMMARY_REGISTERED
:
4112 * NB: With the introduction of L2 route support, we no
4113 * longer have a one-to-one correspondence between
4114 * locally-originated route advertisements and routes in
4115 * the import tables that have local origin. This
4116 * discrepancy arises because a single advertisement
4117 * may contain both an IP prefix and a MAC address.
4118 * Such an advertisement results in two import table
4119 * entries: one indexed by IP prefix, the other indexed
4122 * TBD: update computation and display of registration
4123 * statistics to reflect the underlying semantics.
4125 if (is_vnc_running
) {
4126 vty_out(vty
, "%-24s ", "Registrations:");
4127 vty_out(vty
, "%-8s %-8u ", "Active:",
4128 rfapiApCountAll(bgp_default
));
4129 vty_out(vty
, "%-8s %-8u ", "Failed:",
4130 h
->stat
.count_registrations_failed
);
4131 vty_out(vty
, "%-8s %-8u",
4132 "Total:", h
->stat
.count_registrations
);
4135 vty_out(vty
, "%-24s ", "Prefixes registered:");
4138 rfapiCountAllItRoutes(&active_local_routes
,
4139 &active_remote_routes
,
4140 &holddown_remote_routes
,
4141 &imported_remote_routes
);
4144 if (is_vnc_running
) {
4145 vty_out(vty
, " %-20s ", "Locally:");
4146 vty_out(vty
, "%-8s %-8u ",
4147 "Active:", active_local_routes
);
4152 vty_out(vty
, " %-20s ", "Remotely:");
4153 vty_out(vty
, "%-8s %-8u",
4154 "Active:", active_remote_routes
);
4156 vty_out(vty
, " %-20s ", "In Holddown:");
4157 vty_out(vty
, "%-8s %-8u",
4158 "Active:", holddown_remote_routes
);
4160 vty_out(vty
, " %-20s ", "Imported:");
4161 vty_out(vty
, "%-8s %-8u",
4162 "Active:", imported_remote_routes
);
4165 case SHOW_NVE_SUMMARY_QUERIES
:
4166 vty_out(vty
, "%-24s ", "Queries:");
4167 vty_out(vty
, "%-8s %-8u ",
4168 "Active:", rfapi_monitor_count(NULL
));
4169 vty_out(vty
, "%-8s %-8u ",
4170 "Failed:", h
->stat
.count_queries_failed
);
4171 vty_out(vty
, "%-8s %-8u",
4172 "Total:", h
->stat
.count_queries
);
4175 case SHOW_NVE_SUMMARY_RESPONSES
:
4176 rfapiRibShowResponsesSummary(vty
);
4186 vty_out(vty
, "VNC is not configured.\n");
4190 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4191 struct prefix
*un_prefix
)
4193 // struct hash *rfds;
4194 // struct rfp_rfapi_descriptor_param param;
4196 struct bgp
*bgp_default
= bgp_get_default();
4198 struct listnode
*node
;
4199 struct rfapi_descriptor
*rfd
;
4208 h
= bgp_default
->rfapi
;
4213 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4217 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4219 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4222 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4230 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4231 if (!prefix_match(vn_prefix
, &pfx
))
4236 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4237 if (!prefix_match(un_prefix
, &pfx
))
4241 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4243 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4247 /* print out a header */
4249 " Active Next Hops\n");
4250 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4251 "VN Address", "UN Address", "Regis", "Resps",
4252 "Reach", "Remove", "Age");
4257 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4258 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4259 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4260 rfd
->stat_count_nh_removal
,
4261 rfapiFormatAge(rfd
->open_time
, age
, 10));
4264 if (printed
> 0 || vn_prefix
|| un_prefix
)
4265 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4271 vty_out(vty
, "VNC is not configured.\n");
4276 DEFUN (vnc_show_summary
,
4277 vnc_show_summary_cmd
,
4281 "Display VNC status summary\n")
4283 if (!check_and_display_is_vnc_running(vty
))
4285 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4287 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4288 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4289 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4290 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4294 DEFUN (vnc_show_nves
,
4299 "List known NVEs\n")
4301 rfapi_show_nves(vty
, NULL
, NULL
);
4305 DEFUN (vnc_show_nves_ptct
,
4306 vnc_show_nves_ptct_cmd
,
4307 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4311 "VN address of NVE\n"
4312 "UN address of NVE\n"
4313 "IPv4 interface address\n"
4314 "IPv6 interface address\n")
4318 if (!check_and_display_is_vnc_running(vty
))
4321 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4322 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4325 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4326 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4330 if (argv
[3]->arg
[0] == 'u') {
4331 rfapi_show_nves(vty
, NULL
, &pfx
);
4333 rfapi_show_nves(vty
, &pfx
, NULL
);
4339 /* adapted from rfp_registration_cache_log() */
4340 static void rfapi_show_registrations(struct vty
*vty
,
4341 struct prefix
*restrict_to
, int show_local
,
4342 int show_remote
, int show_holddown
,
4350 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4353 /* non-expiring, local */
4354 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4358 /* non-expiring, non-local */
4359 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4362 if (show_holddown
) {
4363 /* expiring, including local */
4364 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4367 if (show_imported
) {
4368 /* non-expiring, non-local */
4369 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4377 DEFUN (vnc_show_registrations_pfx
,
4378 vnc_show_registrations_pfx_cmd
,
4379 "show vnc registrations [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
4382 "List active prefix registrations\n"
4383 "Limit output to a particualr IPV4 address\n"
4384 "Limit output to a particular IPv4 prefix\n"
4385 "Limit output to a particualr IPV6 address\n"
4386 "Limit output to a particular IPv6 prefix\n"
4387 "Limit output to a particular MAC address\n")
4390 struct prefix
*p_addr
= NULL
;
4393 if (!str2prefix(argv
[3]->arg
, &p
)) {
4394 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4401 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4405 DEFUN (vnc_show_registrations_some_pfx
,
4406 vnc_show_registrations_some_pfx_cmd
,
4407 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
4410 "List active prefix registrations\n"
4411 "show all registrations\n"
4412 "show only registrations in holddown\n"
4413 "show only imported prefixes\n"
4414 "show only local registrations\n"
4415 "show only remote registrations\n"
4416 "Limit output to a particualr IPV4 address\n"
4417 "Limit output to a particular IPv4 prefix\n"
4418 "Limit output to a particualr IPV6 address\n"
4419 "Limit output to a particular IPv6 prefix\n"
4420 "Limit output to a particular MAC address\n")
4423 struct prefix
*p_addr
= NULL
;
4426 int show_remote
= 0;
4427 int show_holddown
= 0;
4428 int show_imported
= 0;
4431 if (!str2prefix(argv
[4]->arg
, &p
)) {
4432 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4438 switch (argv
[3]->arg
[0]) {
4463 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4464 show_holddown
, show_imported
);
4468 DEFUN (vnc_show_responses_pfx
,
4469 vnc_show_responses_pfx_cmd
,
4470 "show vnc responses [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
4473 "List recent query responses\n"
4474 "Limit output to a particualr IPV4 address\n"
4475 "Limit output to a particular IPv4 prefix\n"
4476 "Limit output to a particualr IPV6 address\n"
4477 "Limit output to a particular IPv6 prefix\n"
4478 "Limit output to a particular MAC 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|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
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 particualr IPV4 address\n"
4510 "Limit output to a particular IPv4 prefix\n"
4511 "Limit output to a particualr IPV6 address\n"
4512 "Limit output to a particular IPv6 prefix\n"
4513 "Limit output to a particular MAC address\n")
4516 struct prefix
*p_addr
= NULL
;
4518 int show_active
= 0;
4519 int show_removed
= 0;
4521 if (!check_and_display_is_vnc_running(vty
))
4525 if (!str2prefix(argv
[4]->arg
, &p
)) {
4526 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4533 switch (argv
[3]->arg
[0]) {
4543 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4545 rfapiRibShowResponsesSummary(vty
);
4548 rfapiRibShowResponses(vty
, p_addr
, 0);
4550 rfapiRibShowResponses(vty
, p_addr
, 1);
4555 DEFUN (show_vnc_queries_pfx
,
4556 show_vnc_queries_pfx_cmd
,
4557 "show vnc queries [<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M|X:X:X:X:X:X>]",
4560 "List active queries\n"
4561 "Limit output to a particualr IPV4 address\n"
4562 "Limit output to a particular IPv4 prefix\n"
4563 "Limit output to a particualr IPV6 address\n"
4564 "Limit output to a particular IPv6 prefix\n"
4565 "Limit output to a particualr MAC address\n")
4568 struct prefix
*p
= NULL
;
4571 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4572 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4578 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4580 return rfapiShowVncQueries(vty
, p
);
4583 DEFUN (vnc_clear_counters
,
4584 vnc_clear_counters_cmd
,
4585 "clear vnc counters",
4588 "Reset VNC counters\n")
4590 struct bgp
*bgp_default
= bgp_get_default();
4592 struct listnode
*node
;
4593 struct rfapi_descriptor
*rfd
;
4598 h
= bgp_default
->rfapi
;
4604 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4605 rfd
->stat_count_nh_reachable
= 0;
4606 rfd
->stat_count_nh_removal
= 0;
4610 memset(&h
->stat
, 0, sizeof(h
->stat
));
4613 * 151122 per bug 103, set count_registrations = number active.
4614 * Do same for queries
4616 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4617 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4619 rfapiRibShowResponsesSummaryClear();
4624 vty_out(vty
, "VNC is not configured.\n");
4628 /************************************************************************
4629 * Add prefix with vrf
4631 * add [vrf <vrf-name>] prefix <prefix>
4632 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4633 ************************************************************************/
4634 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4636 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4637 /* based on rfapi_open */
4638 struct rfapi_descriptor
*rfd
;
4640 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4641 sizeof(struct rfapi_descriptor
));
4644 /* leave most fields empty as will get from (dynamic) config
4646 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4648 if (rfg
->vn_prefix
.family
4649 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4650 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4652 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4653 rfd
->vn_addr
.addr_family
= AF_INET
;
4654 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4656 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4658 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4660 rfapi_init_and_open(bgp
, rfd
, rfg
);
4664 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4665 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4666 const char *arg_prefix
,
4667 const char *arg_rd
, /* optional */
4668 const char *arg_label
, /* optional */
4669 const char *arg_pref
) /* optional */
4672 struct rfapi_nve_group_cfg
*rfg
;
4674 struct rfapi_ip_prefix rpfx
;
4676 struct rfapi_vn_option optary
[3];
4677 struct rfapi_vn_option
*opt
= NULL
;
4680 bgp
= bgp_get_default(); /* assume main instance for now */
4682 vty_out(vty
, "No BGP process is configured\n");
4683 return CMD_WARNING_CONFIG_FAILED
;
4685 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4686 vty_out(vty
, "VRF support not configured\n");
4687 return CMD_WARNING_CONFIG_FAILED
;
4690 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4693 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4695 return CMD_WARNING_CONFIG_FAILED
;
4697 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4699 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4701 return CMD_WARNING_CONFIG_FAILED
;
4703 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4705 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4707 return CMD_WARNING_CONFIG_FAILED
;
4709 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4711 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4713 return CMD_WARNING_CONFIG_FAILED
;
4715 if (!str2prefix(arg_prefix
, &pfx
)) {
4716 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4717 return CMD_WARNING_CONFIG_FAILED
;
4719 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4720 memset(optary
, 0, sizeof(optary
));
4722 opt
= &optary
[cur_opt
++];
4723 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4724 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4725 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4726 return CMD_WARNING_CONFIG_FAILED
;
4729 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4730 struct rfapi_l2address_option
*l2o
;
4732 opt
->next
= &optary
[cur_opt
];
4733 opt
= &optary
[cur_opt
++];
4734 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4735 l2o
= &opt
->v
.l2addr
;
4738 label
= strtoul(arg_label
, NULL
, 10);
4741 l2o
->label
= rfg
->label
;
4744 char *endptr
= NULL
;
4745 pref
= strtoul(arg_pref
, &endptr
, 10);
4746 if (*endptr
!= '\0') {
4748 "%% Invalid local-preference value \"%s\"\n",
4750 return CMD_WARNING_CONFIG_FAILED
;
4753 rpfx
.cost
= 255 - (pref
& 255);
4754 vnc_add_vrf_opener(bgp
, rfg
);
4756 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4757 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4758 struct rfapi_next_hop_entry
*head
= NULL
;
4759 struct rfapi_next_hop_entry
*tail
= NULL
;
4760 struct rfapi_vn_option
*vn_opt_new
;
4762 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4765 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4766 struct rfapi_descriptor
*r
=
4767 (struct rfapi_descriptor
*)rfg
->rfd
;
4768 vn_opt_new
= rfapi_vn_options_dup(opt
);
4770 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4772 RFAPI_INFINITE_LIFETIME
,
4773 vn_opt_new
, &head
, &tail
);
4775 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4776 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4778 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4782 vnc_zlog_debug_verbose(
4783 "%s completed, count=%d/%d", __func__
,
4784 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4785 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4789 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4790 vty_out(vty
, "Add failed.\n");
4791 return CMD_WARNING_CONFIG_FAILED
;
4794 DEFUN (add_vrf_prefix_rd_label_pref
,
4795 add_vrf_prefix_rd_label_pref_cmd
,
4796 "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)}]",
4800 "Add/modify prefix related information\n"
4803 "Override configured VRF Route Distinguisher\n"
4804 "<as-number>:<number> or <ip-address>:<number>\n"
4805 "Override configured VRF label\n"
4806 "Label Value <0-1048575>\n"
4807 "Set advertised local preference\n"
4808 "local preference (higher=more preferred)\n")
4810 char *arg_vrf
= argv
[2]->arg
;
4811 char *arg_prefix
= argv
[4]->arg
;
4812 char *arg_rd
= NULL
; /* optional */
4813 char *arg_label
= NULL
; /* optional */
4814 char *arg_pref
= NULL
; /* optional */
4816 argc
--; /* don't parse argument */
4817 while (pargc
< argc
) {
4818 switch (argv
[pargc
++]->arg
[0]) {
4820 arg_rd
= argv
[pargc
]->arg
;
4823 arg_label
= argv
[pargc
]->arg
;
4826 arg_pref
= argv
[pargc
]->arg
;
4834 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4838 /************************************************************************
4839 * del prefix with vrf
4841 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4842 ************************************************************************/
4843 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4847 if (rfg
->rfapi_import_table
== NULL
)
4850 afi_t afi
= AFI_MAX
;
4852 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4857 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4859 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4864 /* check if IT is empty */
4866 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4870 if (afi
== AFI_MAX
) {
4871 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4876 vnc_zlog_debug_verbose(
4877 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4878 rfg
->rfapi_import_table
->local_count
[afi
]);
4882 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4883 const char *arg_prefix
, /* NULL = all */
4884 const char *arg_rd
) /* optional */
4886 struct rfapi_nve_group_cfg
*rfg
;
4887 struct rfapi_local_reg_delete_arg cda
;
4892 bgp
= bgp_get_default(); /* assume main instance for now */
4894 vty_out(vty
, "No BGP process is configured\n");
4897 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4898 vty_out(vty
, "VRF support not configured\n");
4901 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4904 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4908 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4910 if (rc
!= CMD_SUCCESS
) /* parse error */
4913 start_count
= rfapi_cfg_group_it_count(rfg
);
4914 clear_vnc_prefix(&cda
);
4915 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4917 print_cleared_stats(&cda
); /* frees lists in cda */
4921 DEFUN (clear_vrf_prefix_rd
,
4922 clear_vrf_prefix_rd_cmd
,
4923 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4924 "Clear stored data\n"
4927 "Prefix related information\n"
4930 "Specific VRF Route Distinguisher\n"
4931 "<as-number>:<number> or <ip-address>:<number>\n")
4933 char *arg_vrf
= argv
[2]->arg
;
4934 char *arg_prefix
= NULL
; /* optional */
4935 char *arg_rd
= NULL
; /* optional */
4937 argc
--; /* don't check parameter */
4938 while (pargc
< argc
) {
4939 switch (argv
[pargc
++]->arg
[0]) {
4941 arg_rd
= argv
[pargc
]->arg
;
4944 arg_prefix
= argv
[pargc
]->arg
;
4951 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4954 DEFUN (clear_vrf_all
,
4956 "clear vrf NAME all",
4957 "Clear stored data\n"
4962 char *arg_vrf
= argv
[2]->arg
;
4963 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4966 void rfapi_vty_init(void)
4968 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4969 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4982 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4983 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4984 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4985 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4986 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4987 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4989 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5009 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5010 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5011 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5012 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5013 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5015 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5016 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5018 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5022 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5024 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5025 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5026 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5027 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5028 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);