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/log_int.h"
29 #include "lib/linklist.h"
30 #include "lib/command.h"
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_ecommunity.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_mplsvpn.h"
38 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
39 #include "bgpd/rfapi/rfapi.h"
40 #include "bgpd/rfapi/rfapi_backend.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_aspath.h"
44 #include "bgpd/bgp_community.h"
45 #include "bgpd/bgp_vnc_types.h"
46 #include "bgpd/bgp_label.h"
48 #include "bgpd/rfapi/rfapi_import.h"
49 #include "bgpd/rfapi/rfapi_private.h"
50 #include "bgpd/rfapi/rfapi_monitor.h"
51 #include "bgpd/rfapi/rfapi_rib.h"
52 #include "bgpd/rfapi/rfapi_vty.h"
53 #include "bgpd/rfapi/rfapi_ap.h"
54 #include "bgpd/rfapi/rfapi_encap_tlv.h"
55 #include "bgpd/rfapi/vnc_debug.h"
57 #define DEBUG_L2_EXTRA 0
58 #define DEBUG_SHOW_EXTRA 0
60 #define VNC_SHOW_STR "VNC information\n"
62 /* format related utilies */
65 #define FMT_MIN 60 /* seconds */
66 #define FMT_HOUR (60 * FMT_MIN)
67 #define FMT_DAY (24 * FMT_HOUR)
68 #define FMT_YEAR (365 * FMT_DAY)
70 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
72 int year
, day
, hour
, min
;
74 if (seconds
>= FMT_YEAR
) {
75 year
= seconds
/ FMT_YEAR
;
76 seconds
-= year
* FMT_YEAR
;
80 if (seconds
>= FMT_DAY
) {
81 day
= seconds
/ FMT_DAY
;
82 seconds
-= day
* FMT_DAY
;
86 if (seconds
>= FMT_HOUR
) {
87 hour
= seconds
/ FMT_HOUR
;
88 seconds
-= hour
* FMT_HOUR
;
92 if (seconds
>= FMT_MIN
) {
93 min
= seconds
/ FMT_MIN
;
94 seconds
-= min
* FMT_MIN
;
99 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
100 } else if (day
> 0) {
101 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
103 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
109 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
111 time_t now
, age_adjusted
;
113 now
= rfapi_time(NULL
);
114 age_adjusted
= now
- age
;
116 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
121 * Reimplementation of quagga/lib/prefix.c function, but
122 * for RFAPI-style prefixes
124 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
130 static const uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
131 0xf8, 0xfc, 0xfe, 0xff};
133 switch (rprefix
->prefix
.addr_family
) {
135 index
= rprefix
->length
/ 8;
137 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
138 offset
= rprefix
->length
% 8;
139 pnt
[index
] &= maskbit
[offset
];
147 index
= rprefix
->length
/ 8;
149 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
150 offset
= rprefix
->length
% 8;
151 pnt
[index
] &= maskbit
[offset
];
164 * translate a quagga prefix into a rfapi IP address. The
165 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
172 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
174 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
175 raddr
->addr_family
= qprefix
->family
;
176 switch (qprefix
->family
) {
178 if (qprefix
->prefixlen
!= 32)
180 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
183 if (qprefix
->prefixlen
!= 128)
185 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
194 * Translate Quagga prefix to RFAPI prefix
196 /* rprefix->cost set to 0 */
197 void rfapiQprefix2Rprefix(struct prefix
*qprefix
,
198 struct rfapi_ip_prefix
*rprefix
)
200 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
201 rprefix
->length
= qprefix
->prefixlen
;
202 rprefix
->prefix
.addr_family
= qprefix
->family
;
203 switch (qprefix
->family
) {
205 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
208 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
215 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
216 struct prefix
*qprefix
)
218 memset(qprefix
, 0, sizeof(struct prefix
));
219 qprefix
->prefixlen
= rprefix
->length
;
220 qprefix
->family
= rprefix
->prefix
.addr_family
;
222 switch (rprefix
->prefix
.addr_family
) {
224 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
227 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
236 * returns 1 if prefixes have same addr family, prefix len, and address
237 * Note that host bits matter in this comparison!
239 * For paralellism with quagga/lib/prefix.c. if we need a comparison
240 * where host bits are ignored, call that function rfapiRprefixCmp.
242 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
244 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
246 if (hp1
->length
!= hp2
->length
)
248 if (hp1
->prefix
.addr_family
== AF_INET
)
249 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
251 if (hp1
->prefix
.addr_family
== AF_INET6
)
252 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
257 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
259 memset(pfx
, 0, sizeof(struct prefix
));
260 pfx
->family
= hia
->addr_family
;
262 switch (hia
->addr_family
) {
265 pfx
->u
.prefix4
= hia
->addr
.v4
;
268 pfx
->prefixlen
= 128;
269 pfx
->u
.prefix6
= hia
->addr
.v6
;
277 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
279 memset(pfx
, 0, sizeof(struct prefix
));
280 pfx
->family
= AF_ETHERNET
;
282 pfx
->u
.prefix_eth
= l2o
->macaddr
;
285 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
287 return prefix_mac2str(ea
, buf
, bufsize
);
290 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
295 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
302 for (i
= 0; i
< 6; ++i
)
303 ea
->octet
[i
] = a
[i
] & 0xff;
308 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
310 if (af
== AF_ETHERNET
) {
311 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
314 return inet_ntop(af
, src
, buf
, size
);
317 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
320 va_start(args
, format
);
321 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
);
374 return (vzlog_test(LOG_DEBUG
));
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
, 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
)) {
415 vty_out(vty
, "UN=%s",
416 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
421 if (bpi
->attr
->ecommunity
) {
422 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
423 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
424 vty_out(vty
, " EC{%s}", s
);
425 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
428 if (bpi
->extra
!= NULL
) {
429 if (bpi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
430 vty_out(vty
, " label=VRF2VRF");
432 vty_out(vty
, " label=%u",
433 decode_label(&bpi
->extra
->label
[0]));
435 if (bpi
->extra
->num_sids
) {
438 vty_out(vty
, " sid=%s",
439 inet_ntop(AF_INET6
, &bpi
->extra
->sid
[0], buf
,
444 if (!rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
445 vty_out(vty
, " life=%d", lifetime
);
448 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bpi
->type
),
451 vty_out(vty
, "%s", HVTYNL
);
454 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
456 int (*fp
)(void *, const char *, ...);
459 const char *vty_newline
;
463 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
466 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
471 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
472 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
474 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
475 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
476 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
477 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
479 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
480 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
481 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
482 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
483 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
484 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
488 * Print BPI in an Import Table
490 void rfapiPrintBi(void *stream
, struct bgp_path_info
*bpi
)
495 int (*fp
)(void *, const char *, ...);
498 const char *vty_newline
;
504 struct ethaddr macaddr
= {{0}};
505 struct rfapi_l2address_option l2o_buf
;
506 uint8_t l2hid
= 0; /* valid if has_macaddr */
508 #define REMAIN (BUFSIZ - (p-line))
509 #define INCP {p += (r > REMAIN)? REMAIN: r;}
511 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
517 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
518 && bpi
->extra
->vnc
.import
.timer
) {
520 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
521 r
= snprintf(p
, REMAIN
, " [%4lu] ",
522 thread_timer_remain_second(t
));
526 r
= snprintf(p
, REMAIN
, " ");
531 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
532 if (decode_rd_type(bpi
->extra
->vnc
.import
.rd
.val
)
533 == RD_TYPE_VNC_ETH
) {
535 memcpy(macaddr
.octet
, bpi
->extra
->vnc
.import
.rd
.val
+ 2,
537 l2hid
= bpi
->extra
->vnc
.import
.rd
.val
[1];
546 * RFP option sizes (they are opaque values)
547 * extended communities (RTs)
550 int printed_1st_gol
= 0;
551 struct bgp_attr_encap_subtlv
*pEncap
;
552 struct prefix pfx_un
;
553 int af
= BGP_MP_NEXTHOP_FAMILY(bpi
->attr
->mp_nexthop_len
);
557 r
= snprintf(p
, REMAIN
, "%s",
559 &bpi
->attr
->mp_nexthop_global_in
, buf
,
562 } else if (af
== AF_INET6
) {
563 r
= snprintf(p
, REMAIN
, "%s",
564 inet_ntop(AF_INET6
, &bpi
->attr
->mp_nexthop_global
,
568 r
= snprintf(p
, REMAIN
, "?");
573 * VNC tunnel subtlv, if present, contains UN address
575 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
578 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
, BUFSIZ
));
583 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
584 r
= snprintf(p
, REMAIN
, " nolife");
587 if (lifetime
== 0xffffffff)
588 r
= snprintf(p
, REMAIN
, " %6s", "infini");
590 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
594 /* RFP option lengths */
595 for (pEncap
= bpi
->attr
->vnc_subtlvs
; pEncap
; pEncap
= pEncap
->next
) {
597 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
598 if (printed_1st_gol
) {
599 r
= snprintf(p
, REMAIN
, ",");
602 r
= snprintf(p
, REMAIN
,
603 " "); /* leading space */
606 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
613 if (bpi
->attr
->ecommunity
) {
614 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
615 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
616 r
= snprintf(p
, REMAIN
, " %s", s
);
618 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
621 r
= snprintf(p
, REMAIN
, " bpi@%p", bpi
);
624 r
= snprintf(p
, REMAIN
, " p@%p", bpi
->peer
);
627 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
628 r
= snprintf(p
, REMAIN
, " HD=yes");
631 r
= snprintf(p
, REMAIN
, " HD=no");
635 if (bpi
->attr
->weight
) {
636 r
= snprintf(p
, REMAIN
, " W=%d", bpi
->attr
->weight
);
640 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
641 r
= snprintf(p
, REMAIN
, " LP=%d", bpi
->attr
->local_pref
);
644 r
= snprintf(p
, REMAIN
, " LP=unset");
648 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bpi
->type
),
652 fp(out
, "%s%s", line
, HVTYNL
);
655 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
656 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
657 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
661 if (!rfapiGetL2o(bpi
->attr
, &l2o_buf
)) {
663 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
664 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
665 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
666 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
667 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
670 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
673 sp
= rfapi_ntop(bpi
->extra
->vnc
.import
.aux_prefix
.family
,
674 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
678 fp(out
, " IP: %s%s", sp
, HVTYNL
);
682 struct rfapi_un_option
*uo
=
683 rfapi_encap_tlv_to_un_option(bpi
->attr
);
685 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
686 rfapi_un_options_free(uo
);
691 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
693 char buf_pfx
[BUFSIZ
];
698 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
699 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
701 rc
= snprintf(buf
, size
,
702 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
703 m
->next
, m
->rfd
, buf_vn
, buf_un
,
704 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
705 m
->p
.prefixlen
, m
->node
);
712 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
716 int (*fp
)(void *, const char *, ...);
719 const char *vty_newline
;
721 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
724 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
725 fp(out
, " Mon %s%s", buf
, HVTYNL
);
728 static void rfapiDebugPrintMonitorEncap(void *stream
,
729 struct rfapi_monitor_encap
*m
)
731 int (*fp
)(void *, const char *, ...);
734 const char *vty_newline
;
736 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
739 fp(out
, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m
, m
->next
, m
->node
,
743 void rfapiShowItNode(void *stream
, struct agg_node
*rn
)
745 struct bgp_path_info
*bpi
;
748 int (*fp
)(void *, const char *, ...);
751 const char *vty_newline
;
753 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
756 fp(out
, "%s/%d @%p #%d%s",
757 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
),
758 rn
->p
.prefixlen
, rn
, rn
->lock
, HVTYNL
);
760 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
761 rfapiPrintBi(stream
, bpi
);
764 /* doesn't show montors */
767 void rfapiShowImportTable(void *stream
, const char *label
, struct agg_table
*rt
,
773 int (*fp
)(void *, const char *, ...);
776 const char *vty_newline
;
778 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
781 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
783 for (rn
= agg_route_top(rt
); rn
; rn
= agg_route_next(rn
)) {
784 struct bgp_path_info
*bpi
;
786 if (rn
->p
.family
== AF_ETHERNET
) {
787 rfapiEthAddr2Str(&rn
->p
.u
.prefix_eth
, buf
, BUFSIZ
);
789 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
);
792 fp(out
, "%s/%d @%p #%d%s", buf
, rn
->p
.prefixlen
, rn
,
793 rn
->lock
- 1, /* account for loop iterator locking */
796 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
797 rfapiPrintBi(stream
, bpi
);
801 struct rfapi_monitor_vpn
*m
;
802 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
803 rfapiDebugPrintMonitorVpn(stream
, m
);
806 struct rfapi_monitor_encap
*m
;
807 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
808 rfapiDebugPrintMonitorEncap(stream
, m
);
814 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
818 struct listnode
*node
;
819 struct rfapi_descriptor
*rfd
;
821 int (*fp
)(void *, const char *, ...);
824 const char *vty_newline
;
826 int printedheader
= 0;
829 int nves_with_queries
= 0;
830 int nves_displayed
= 0;
832 int queries_total
= 0;
833 int queries_displayed
= 0;
835 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
838 bgp
= bgp_get_default(); /* assume 1 instance for now */
840 vty_out(vty
, "No BGP instance\n");
846 vty_out(vty
, "No RFAPI instance\n");
850 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
853 int printedquerier
= 0;
859 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
869 for (rn
= agg_route_top(rfd
->mon
); rn
;
870 rn
= agg_route_next(rn
)) {
871 struct rfapi_monitor_vpn
*m
;
872 char buf_remain
[BUFSIZ
];
873 char buf_pfx
[BUFSIZ
];
883 && !prefix_match(pfx_match
, &rn
->p
)
884 && !prefix_match(&rn
->p
, pfx_match
))
889 if (!printedheader
) {
892 fp(out
, "%-15s %-15s %-15s %-10s\n",
893 "VN Address", "UN Address", "Target",
897 if (!printedquerier
) {
901 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
903 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
906 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
911 fp(out
, "%-15s %-15s", "", "");
915 thread_timer_remain_second(
919 fp(out
, " %-15s %-10s\n",
920 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
929 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
933 struct rfapi_monitor_eth
*mon_eth
;
936 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
937 (void **)&mon_eth
, &cursor
);
939 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
940 (void **)&mon_eth
, &cursor
)) {
942 char buf_remain
[BUFSIZ
];
943 char buf_pfx
[BUFSIZ
];
944 struct prefix pfx_mac
;
948 vnc_zlog_debug_verbose(
949 "%s: checking rfd=%p mon_eth=%p",
950 __func__
, rfd
, mon_eth
);
952 memset((void *)&pfx_mac
, 0,
953 sizeof(struct prefix
));
954 pfx_mac
.family
= AF_ETHERNET
;
955 pfx_mac
.prefixlen
= 48;
956 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
959 && !prefix_match(pfx_match
, &pfx_mac
)
960 && !prefix_match(&pfx_mac
, pfx_match
))
965 if (!printedheader
) {
969 "%-15s %-15s %-17s %10s %-10s\n",
970 "VN Address", "UN Address", "Target",
974 if (!printedquerier
) {
978 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
980 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
983 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
988 fp(out
, "%-15s %-15s", "", "");
990 if (mon_eth
->timer
) {
992 thread_timer_remain_second(
996 fp(out
, " %-17s %10d %-10s\n",
997 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
999 mon_eth
->logical_net_id
, buf_remain
);
1004 if (queries_total
) {
1006 fp(out
, "Displayed %d out of %d total queries\n",
1007 queries_displayed
, queries_total
);
1012 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1013 struct agg_node
*rn
, struct bgp_path_info
*bpi
)
1015 int (*fp
)(void *, const char *, ...);
1018 const char *vty_newline
;
1019 struct prefix pfx_un
;
1020 struct prefix pfx_vn
;
1023 bgp_encap_types tun_type
= BGP_ENCAP_TYPE_MPLS
;/*Default tunnel type*/
1025 char buf_pfx
[BUFSIZ
];
1026 char buf_ntop
[BUFSIZ
];
1027 char buf_un
[BUFSIZ
];
1028 char buf_vn
[BUFSIZ
];
1029 char buf_lifetime
[BUFSIZ
];
1033 return 0; /* for debug log, print into buf & call output once */
1035 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1042 snprintf(buf_pfx
, BUFSIZ
, "%s/%d",
1043 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf_ntop
, BUFSIZ
),
1045 buf_pfx
[BUFSIZ
- 1] = 0;
1052 if (!rfapiGetUnAddrOfVpnBi(bpi
, &pfx_un
)) {
1053 snprintf(buf_un
, BUFSIZ
, "%s",
1054 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1058 bgp_attr_extcom_tunnel_type(bpi
->attr
, &tun_type
);
1063 rfapiNexthop2Prefix(bpi
->attr
, &pfx_vn
);
1064 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1065 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1067 snprintf(buf_un
, BUFSIZ
, "%s",
1068 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1071 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1072 snprintf(buf_vn
, BUFSIZ
, "Label: %d", l
);
1073 } else /* should never happen */
1075 snprintf(buf_vn
, BUFSIZ
, "Label: N/A");
1078 snprintf(buf_vn
, BUFSIZ
, "%s",
1079 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1082 buf_vn
[BUFSIZ
- 1] = 0;
1083 buf_un
[BUFSIZ
- 1] = 0;
1086 * Cost is encoded in local_pref as (255-cost)
1087 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1090 uint32_t local_pref
;
1092 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1093 local_pref
= bpi
->attr
->local_pref
;
1096 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1098 fp(out
, "%-20s ", buf_pfx
);
1099 fp(out
, "%-15s ", buf_vn
);
1100 fp(out
, "%-15s ", buf_un
);
1101 fp(out
, "%-4d ", cost
);
1104 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1105 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)
1106 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1108 fp(out
, "%-10s ", "infinite");
1110 time_t t_lifetime
= lifetime
;
1111 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1112 fp(out
, "%-10s ", buf_lifetime
);
1115 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
1116 && bpi
->extra
->vnc
.import
.timer
) {
1120 char buf_age
[BUFSIZ
];
1123 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
1124 remaining
= thread_timer_remain_second(t
);
1126 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1128 * Calculate when the timer started. Doing so here saves
1129 * us a timestamp field in "struct bgp_path_info".
1131 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1132 * original calculation.
1134 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1136 #else /* report remaining time */
1139 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1141 fp(out
, "%-10s ", buf_age
);
1143 } else if (RFAPI_LOCAL_BI(bpi
)) {
1145 char buf_age
[BUFSIZ
];
1147 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.create_time
) {
1148 rfapiFormatAge(bpi
->extra
->vnc
.import
.create_time
,
1154 fp(out
, "%-10s ", buf_age
);
1156 fp(out
, "%s", HVTYNL
);
1158 if (rn
->p
.family
== AF_ETHERNET
) {
1160 * If there is a corresponding IP address && != VN address,
1161 * print that on the next line
1164 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
1168 bpi
->extra
->vnc
.import
.aux_prefix
.family
,
1169 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1171 buf_ntop
[BUFSIZ
- 1] = 0;
1173 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1174 fp(out
, " IP: %s", sp
);
1180 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bpi
->extra
) {
1181 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1182 if (!MPLS_LABEL_IS_NULL(l
)) {
1183 fp(out
, " Label: %d", l
);
1189 fp(out
, "%s", HVTYNL
);
1194 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1195 struct rfapi_import_table
*it
,
1196 struct prefix
*prefix_only
,
1197 int show_expiring
, /* either/or */
1198 int show_local
, int show_remote
,
1199 int show_imported
, /* either/or */
1200 uint32_t *pLni
) /* AFI_L2VPN only */
1203 int printed_rtlist_hdr
= 0;
1205 int (*fp
)(void *, const char *, ...);
1208 const char *vty_newline
;
1212 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1215 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1217 struct agg_node
*rn
;
1219 if (!it
->imported_vpn
[afi
])
1222 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1223 rn
= agg_route_next(rn
)) {
1225 struct bgp_path_info
*bpi
;
1228 /* allow for wider or more narrow mask from user */
1229 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1230 && !prefix_match(&rn
->p
, prefix_only
))
1235 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
1237 if (!show_local
&& RFAPI_LOCAL_BI(bpi
)) {
1239 /* local route from RFP */
1243 if (!show_remote
&& !RFAPI_LOCAL_BI(bpi
)) {
1250 && !CHECK_FLAG(bpi
->flags
,
1255 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1258 if (bpi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1260 == ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1269 if (count_only
== 1)
1271 if (!printed_rtlist_hdr
) {
1272 const char *agetype
= "";
1274 const char *type
= "";
1275 if (show_imported
) {
1278 if (show_expiring
) {
1290 s
= ecommunity_ecom2str(
1292 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1296 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1297 HVTYNL
, type
, *pLni
,
1298 (*pLni
& 0xfff), s
);
1300 fp(out
, "%s[%s] Prefix RT={%s}",
1303 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1305 if (it
->rfg
&& it
->rfg
->name
) {
1306 fp(out
, " %s \"%s\"",
1307 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1312 fp(out
, "%s", HVTYNL
);
1313 if (show_expiring
) {
1314 #ifdef RFAPI_REGISTRATIONS_REPORT_AGE
1317 agetype
= "Remaining";
1319 } else if (show_local
) {
1323 printed_rtlist_hdr
= 1;
1326 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1327 (pLni
? "L2 Address/IP" : "Prefix"),
1328 "VN Address", "UN Address", "Cost",
1329 "Lifetime", agetype
, HVTYNL
);
1331 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1339 const char *type
= "prefixes";
1341 if (show_imported
) {
1342 type
= "imported prefixes";
1344 if (show_expiring
) {
1345 type
= "prefixes in holddown";
1347 if (show_local
&& !show_remote
) {
1348 type
= "locally registered prefixes";
1349 } else if (!show_local
&& show_remote
) {
1350 type
= "remotely registered prefixes";
1355 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1357 #if DEBUG_SHOW_EXTRA
1358 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1366 * rfapiShowRemoteRegistrations
1368 * Similar to rfapiShowImportTable() above. This function
1369 * is mean to produce the "remote" portion of the output
1370 * of "show vnc registrations".
1372 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1373 int show_expiring
, int show_local
,
1374 int show_remote
, int show_imported
)
1378 struct rfapi_import_table
*it
;
1381 bgp
= bgp_get_default();
1391 for (it
= h
->imports
; it
; it
= it
->next
) {
1392 printed
+= rfapiShowRemoteRegistrationsIt(
1393 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1394 show_remote
, show_imported
, NULL
);
1397 if (h
->import_mac
) {
1398 void *cursor
= NULL
;
1400 uintptr_t lni_as_ptr
;
1404 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1405 (void **)&it
, &cursor
);
1407 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1408 (void **)&it
, &cursor
)) {
1410 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1411 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1415 printed
+= rfapiShowRemoteRegistrationsIt(
1416 bgp
, stream
, it
, prefix_only
, show_expiring
,
1417 show_local
, show_remote
, show_imported
, pLni
);
1424 /*------------------------------------------
1425 * rfapiRfapiIpAddr2Str
1427 * UI helper: generate string from rfapi_ip_addr
1430 * a IP v4/v6 address
1433 * buf put string here
1434 * bufsize max space to write
1437 * NULL conversion failed
1438 * non-NULL pointer to buf
1439 --------------------------------------------*/
1440 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1443 const char *rc
= NULL
;
1445 switch (a
->addr_family
) {
1447 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1450 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1456 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1459 const char *rc
= NULL
;
1461 int (*fp
)(void *, const char *, ...);
1464 const char *vty_newline
;
1466 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1469 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1475 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1478 struct rfapi_ip_addr
*a
= &p
->prefix
;
1479 const char *rc
= NULL
;
1481 switch (a
->addr_family
) {
1483 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1486 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1491 int alen
= strlen(buf
);
1492 int remaining
= bufsize
- alen
- 1;
1495 if (remaining
> 0) {
1496 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1498 if (slen
< remaining
) /* see man page for snprintf(3) */
1506 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1511 int (*fp
)(void *, const char *, ...);
1514 const char *vty_newline
;
1516 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1519 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1522 fp(out
, "%s:%u", buf
, p
->cost
);
1527 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1529 char buf
[RD_ADDRSTRLEN
];
1531 prefix_rd2str(prd
, buf
, sizeof(buf
));
1532 vty_out(vty
, "%s", buf
);
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_node
*bn
;
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 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1568 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1570 for (bpi
= bgp_node_get_bgp_path_info(bn
); 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
;
1599 char buf
[PREFIX_STRLEN
];
1601 vty_out(vty
, "%-10p ", rfd
);
1602 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1604 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1605 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1606 rfapiPrintRd(vty
, &rfd
->rd
);
1607 vty_out(vty
, " %d", rfd
->response_lifetime
);
1608 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1609 vty_out(vty
, "%s", HVTYNL
);
1611 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1613 /* export RT list */
1614 if (rfd
->rt_export_list
) {
1615 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1616 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1617 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1618 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1620 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1623 /* import RT list */
1624 if (rfd
->import_table
) {
1625 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1626 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1627 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1628 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1630 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1633 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1636 family
= afi2family(afi
);
1641 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1642 (void **)&adb
, &cursor
);
1644 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1645 (void **)&adb
, &cursor
)) {
1647 /* group like family prefixes together in output */
1648 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1651 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1653 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1654 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1655 &adb
->u
.s
.prefix_ip
);
1658 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1659 (void **)&adb
, &cursor
);
1660 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1661 (void **)&adb
, &cursor
)) {
1663 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1665 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1667 /* TBD update the following function to print ethernet info */
1668 /* Also need to pass/use rd */
1669 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1670 &adb
->u
.s
.prefix_ip
);
1672 vty_out(vty
, "%s", HVTYNL
);
1676 * test scripts rely on first line for each nve starting in 1st column,
1677 * leading whitespace for additional detail of that nve
1679 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1680 struct prefix
*un_prefix
)
1684 struct listnode
*ln
;
1685 struct rfapi_descriptor
*rfd
;
1688 bgp
= bgp_get_default(); /* assume 1 instance for now */
1695 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1696 rfd
= listgetdata(ln
);
1701 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1702 if (!prefix_match(vn_prefix
, &pfx
))
1707 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1708 if (!prefix_match(un_prefix
, &pfx
))
1713 /* print column header */
1714 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1715 "un-addr", "vn-addr", "callback", "cookie",
1716 "RD", "lifetime", "group", HVTYNL
);
1718 rfapiPrintDescriptor(vty
, rfd
);
1725 * Parse an address and put into a struct prefix
1727 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1729 if (!str2prefix(str
, p
)) {
1730 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1734 switch (p
->family
) {
1736 if (p
->prefixlen
!= 32) {
1737 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1743 if (p
->prefixlen
!= 128) {
1744 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1750 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1756 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1757 struct rfapi_ip_addr
*hai
)
1762 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1766 hai
->addr_family
= pfx
.family
;
1767 if (pfx
.family
== AF_INET
)
1768 hai
->addr
.v4
= pfx
.u
.prefix4
;
1770 hai
->addr
.v6
= pfx
.u
.prefix6
;
1776 * Note: this function does not flush vty output, so if it is called
1777 * with a stream pointing to a vty, the user will have to type something
1778 * before the callback output shows up
1780 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1782 struct rfapi_next_hop_entry
*nh
;
1785 int (*fp
)(void *, const char *, ...);
1788 const char *vty_newline
;
1790 #define REMAIN (BUFSIZ - (p-line))
1791 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1793 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1796 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1802 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1805 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1806 /* it fit, so count length */
1814 r
= snprintf(p
, REMAIN
, ", un=");
1817 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1818 /* it fit, so count length */
1826 r
= snprintf(p
, REMAIN
, ", vn=");
1829 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1830 /* it fit, so count length */
1839 line
[BUFSIZ
- 1] = 0;
1840 fp(out
, "%s%s", line
, HVTYNL
);
1845 if (nh
->vn_options
) {
1846 struct rfapi_vn_option
*vo
;
1847 char offset
[] = " ";
1849 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1853 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1854 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1855 pbuf
, sizeof(pbuf
));
1857 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1859 (vo
->v
.l2addr
.label
& 0x00ffffff),
1860 (vo
->v
.l2addr
.logical_net_id
1862 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1865 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1866 prefix2str(&vo
->v
.local_nexthop
.addr
,
1867 pbuf
, sizeof(pbuf
));
1868 fp(out
, "%sLNH %s cost=%d%s", offset
,
1869 pbuf
, vo
->v
.local_nexthop
.cost
,
1875 "%svn option type %d (unknown)%s",
1876 offset
, vo
->type
, HVTYNL
);
1881 if (nh
->un_options
) {
1882 struct rfapi_un_option
*uo
;
1883 char offset
[] = " ";
1885 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1887 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1888 rfapi_print_tunneltype_option(
1889 stream
, 8, &uo
->v
.tunnel
);
1892 fp(out
, "%sUN Option type %d%s", offset
,
1893 uo
->type
, vty_newline
);
1901 /***********************************************************************
1903 ***********************************************************************/
1906 * Add another nexthop to the NHL
1908 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1909 struct rfapi_ip_addr
*vn_addr
,
1910 struct rfapi_ip_prefix
*rprefix
,
1912 uint32_t lifetime
, /* add only */
1913 struct rfapi_vn_option
*vn_options
,
1914 struct rfapi_next_hop_entry
**head
,
1915 struct rfapi_next_hop_entry
**tail
)
1917 struct rfapi_next_hop_entry
*new;
1923 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1924 new->prefix
= *rprefix
;
1925 new->un_address
= *un_addr
;
1926 new->vn_address
= *vn_addr
;
1928 new->vn_options
= vn_options
;
1930 new->lifetime
= lifetime
;
1932 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1936 (*tail
)->next
= new;
1945 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1946 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1947 struct cmd_token
*carg_cost
, /* optional */
1948 struct cmd_token
*carg_lifetime
, /* optional */
1949 struct cmd_token
*carg_macaddr
, /* optional */
1951 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1952 int argc
, struct cmd_token
**argv
)
1954 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1955 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1956 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1957 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1958 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1959 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1960 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1961 struct rfapi_ip_addr vn_address
;
1962 struct rfapi_ip_addr un_address
;
1964 struct rfapi_ip_prefix rpfx
;
1969 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1970 struct rfapi_vn_option
*opt
= NULL
;
1973 int rc
= CMD_WARNING_CONFIG_FAILED
;
1977 struct rfapi_cfg
*rfapi_cfg
;
1979 const char *arg_lnh
= NULL
;
1980 const char *arg_lnh_cost
= NULL
;
1982 bgp
= bgp_get_default(); /* assume 1 instance for now */
1985 vty_out(vty
, "BGP not configured\n");
1986 return CMD_WARNING_CONFIG_FAILED
;
1990 rfapi_cfg
= bgp
->rfapi_cfg
;
1991 if (!h
|| !rfapi_cfg
) {
1993 vty_out(vty
, "RFAPI not configured\n");
1994 return CMD_WARNING_CONFIG_FAILED
;
1997 for (; argc
; --argc
, ++argv
) {
1998 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2001 "local-next-hop specified more than once\n");
2002 return CMD_WARNING_CONFIG_FAILED
;
2006 "Missing parameter for local-next-hop\n");
2007 return CMD_WARNING_CONFIG_FAILED
;
2011 arg_lnh
= argv
[0]->arg
;
2013 if (strmatch(argv
[0]->text
, "local-cost")) {
2016 "local-cost specified more than once\n");
2017 return CMD_WARNING_CONFIG_FAILED
;
2021 "Missing parameter for local-cost\n");
2022 return CMD_WARNING_CONFIG_FAILED
;
2026 arg_lnh_cost
= argv
[0]->arg
;
2030 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2032 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2035 /* arg_prefix is optional if mac address is given */
2036 if (arg_macaddr
&& !arg_prefix
) {
2038 * fake up a 0/32 or 0/128 prefix
2040 switch (vn_address
.addr_family
) {
2042 arg_prefix
= "0.0.0.0/32";
2045 arg_prefix
= "0::0/128";
2049 "Internal error, unknown VN address family\n");
2050 return CMD_WARNING_CONFIG_FAILED
;
2054 if (!str2prefix(arg_prefix
, &pfx
)) {
2055 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2058 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2059 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2065 memset(optary
, 0, sizeof(optary
));
2069 cost
= strtoul(arg_cost
, &endptr
, 10);
2070 if (*endptr
!= '\0' || cost
> 255) {
2071 vty_out(vty
, "%% Invalid %s value\n", "cost");
2079 if (!strcmp(arg_lifetime
, "infinite")) {
2080 lifetime
= RFAPI_INFINITE_LIFETIME
;
2083 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2084 if (*endptr
!= '\0') {
2085 vty_out(vty
, "%% Invalid %s value\n",
2091 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2097 "%% %s may only be specified with local-next-hop\n",
2102 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2103 if (*endptr
!= '\0' || lnh_cost
> 255) {
2104 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2114 "%% %s may only be specified with prefix\n",
2118 if ((rc
= rfapiCliGetPrefixAddr(
2120 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2125 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2126 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2129 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2136 if (arg_vni
&& !arg_macaddr
) {
2137 vty_out(vty
, "%% %s may only be specified with mac address\n",
2138 "virtual-network-identifier");
2145 "Missing \"vni\" parameter (mandatory with mac)\n");
2146 return CMD_WARNING_CONFIG_FAILED
;
2148 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2149 strtoul(arg_vni
, NULL
, 10);
2151 if ((rc
= rfapiStr2EthAddr(
2153 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2154 vty_out(vty
, "Invalid %s value\n", "mac address");
2157 /* TBD label, NVE ID */
2159 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2162 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2169 vnc_zlog_debug_verbose(
2170 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2171 __func__
, arg_vn
, arg_un
, arg_prefix
,
2172 (arg_cost
? arg_cost
: "NULL"),
2173 (arg_lifetime
? arg_lifetime
: "NULL"),
2174 (arg_lnh
? arg_lnh
: "NULL"));
2176 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2178 rpfx
.cost
= cost
& 255;
2180 /* look up rf descriptor, call open if it doesn't exist */
2181 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2182 (struct rfapi_descriptor
**)&rfd
);
2185 struct rfapi_un_option uo
;
2188 * flag descriptor as provisionally opened for static
2190 * registration so that we can fix up the other
2192 * when the real open comes along
2194 memset(&uo
, 0, sizeof(uo
));
2195 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2197 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2198 &vn_address
, &un_address
,
2200 NULL
, NULL
, /* no userdata */
2204 "Can't open session for this NVE: %s\n",
2205 rfapi_error_str(rc
));
2206 rc
= CMD_WARNING_CONFIG_FAILED
;
2210 vty_out(vty
, "Can't find session for this NVE: %s\n",
2211 rfapi_error_str(rc
));
2216 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2217 RFAPI_REGISTER_ADD
);
2219 struct rfapi_next_hop_entry
*head
= NULL
;
2220 struct rfapi_next_hop_entry
*tail
= NULL
;
2221 struct rfapi_vn_option
*vn_opt_new
;
2223 vnc_zlog_debug_verbose(
2224 "%s: rfapi_register succeeded, returning 0", __func__
);
2226 if (h
->rfp_methods
.local_cb
) {
2227 struct rfapi_descriptor
*r
=
2228 (struct rfapi_descriptor
*)rfd
;
2229 vn_opt_new
= rfapi_vn_options_dup(opt
);
2231 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2233 vn_opt_new
, &head
, &tail
);
2235 h
->flags
|= RFAPI_INCALLBACK
;
2236 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2237 h
->flags
&= ~RFAPI_INCALLBACK
;
2244 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2246 vty_out(vty
, "Registration failed.\n");
2248 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2249 return CMD_WARNING_CONFIG_FAILED
;
2252 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2256 /************************************************************************
2257 * Add prefix With LNH_OPTIONS...
2258 ************************************************************************/
2259 DEFUN (add_vnc_prefix_cost_life_lnh
,
2260 add_vnc_prefix_cost_life_lnh_cmd
,
2261 "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...",
2262 "Add registration\n"
2264 "Add/modify prefix related information\n"
2267 "VN address of NVE\n"
2268 "VN IPv4 interface address\n"
2269 "VN IPv6 interface address\n"
2270 "UN address of NVE\n"
2271 "UN IPv4 interface address\n"
2272 "UN IPv6 interface address\n"
2273 "Administrative cost [default: 255]\n"
2274 "Administrative cost\n"
2275 "Registration lifetime [default: infinite]\n"
2276 "Lifetime value in seconds\n"
2277 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2279 /* pfx vn un cost life */
2280 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2282 NULL
, NULL
, argc
- 12, argv
+ 12);
2285 DEFUN (add_vnc_prefix_life_cost_lnh
,
2286 add_vnc_prefix_life_cost_lnh_cmd
,
2287 "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...",
2288 "Add registration\n"
2290 "Add/modify prefix related information\n"
2293 "VN address of NVE\n"
2294 "VN IPv4 interface address\n"
2295 "VN IPv6 interface address\n"
2296 "UN address of NVE\n"
2297 "UN IPv4 interface address\n"
2298 "UN IPv6 interface address\n"
2299 "Registration lifetime [default: infinite]\n"
2300 "Lifetime value in seconds\n"
2301 "Administrative cost [default: 255]\n"
2302 "Administrative cost\n"
2303 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2305 /* pfx vn un cost life */
2306 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2308 NULL
, NULL
, argc
- 12, argv
+ 12);
2311 DEFUN (add_vnc_prefix_cost_lnh
,
2312 add_vnc_prefix_cost_lnh_cmd
,
2313 "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...",
2314 "Add registration\n"
2316 "Add/modify prefix related information\n"
2319 "VN address of NVE\n"
2320 "VN IPv4 interface address\n"
2321 "VN IPv6 interface address\n"
2322 "UN address of NVE\n"
2323 "UN IPv4 interface address\n"
2324 "UN IPv6 interface address\n"
2325 "Administrative cost [default: 255]\n"
2326 "Administrative cost\n"
2327 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2329 /* pfx vn un cost life */
2330 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2332 NULL
, NULL
, argc
- 10, argv
+ 10);
2335 DEFUN (add_vnc_prefix_life_lnh
,
2336 add_vnc_prefix_life_lnh_cmd
,
2337 "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...",
2338 "Add registration\n"
2340 "Add/modify prefix related information\n"
2343 "VN address of NVE\n"
2344 "VN IPv4 interface address\n"
2345 "VN IPv6 interface address\n"
2346 "UN address of NVE\n"
2347 "UN IPv4 interface address\n"
2348 "UN IPv6 interface address\n"
2349 "Registration lifetime [default: infinite]\n"
2350 "Lifetime value in seconds\n"
2351 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2353 /* pfx vn un cost life */
2354 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2356 NULL
, NULL
, argc
- 10, argv
+ 10);
2359 DEFUN (add_vnc_prefix_lnh
,
2360 add_vnc_prefix_lnh_cmd
,
2361 "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...",
2362 "Add registration\n"
2364 "Add/modify prefix related information\n"
2367 "VN address of NVE\n"
2368 "VN IPv4 interface address\n"
2369 "VN IPv6 interface address\n"
2370 "UN address of NVE\n"
2371 "UN IPv4 interface address\n"
2372 "UN IPv6 interface address\n"
2373 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2375 /* pfx vn un cost life */
2376 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2378 NULL
, NULL
, argc
- 8, argv
+ 8);
2381 /************************************************************************
2382 * Add prefix Without LNH_OPTIONS...
2383 ************************************************************************/
2384 DEFUN (add_vnc_prefix_cost_life
,
2385 add_vnc_prefix_cost_life_cmd
,
2386 "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)",
2387 "Add registration\n"
2389 "Add/modify prefix related information\n"
2392 "VN address of NVE\n"
2393 "VN IPv4 interface address\n"
2394 "VN IPv6 interface address\n"
2395 "UN address of NVE\n"
2396 "UN IPv4 interface address\n"
2397 "UN IPv6 interface address\n"
2398 "Administrative cost [default: 255]\n"
2399 "Administrative cost\n"
2400 "Registration lifetime [default: infinite]\n"
2401 "Lifetime value in seconds\n")
2403 /* pfx vn un cost life */
2404 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2406 NULL
, NULL
, 0, NULL
);
2409 DEFUN (add_vnc_prefix_life_cost
,
2410 add_vnc_prefix_life_cost_cmd
,
2411 "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)",
2412 "Add registration\n"
2414 "Add/modify prefix related information\n"
2417 "VN address of NVE\n"
2418 "VN IPv4 interface address\n"
2419 "VN IPv6 interface address\n"
2420 "UN address of NVE\n"
2421 "UN IPv4 interface address\n"
2422 "UN IPv6 interface address\n"
2423 "Registration lifetime [default: infinite]\n"
2424 "Lifetime value in seconds\n"
2425 "Administrative cost [default: 255]\n"
2426 "Administrative cost\n")
2428 /* pfx vn un cost life */
2429 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2431 NULL
, NULL
, 0, NULL
);
2434 DEFUN (add_vnc_prefix_cost
,
2435 add_vnc_prefix_cost_cmd
,
2436 "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)",
2437 "Add registration\n"
2439 "Add/modify prefix related information\n"
2442 "VN address of NVE\n"
2443 "VN IPv4 interface address\n"
2444 "VN IPv6 interface address\n"
2445 "UN address of NVE\n"
2446 "UN IPv4 interface address\n"
2447 "UN IPv6 interface address\n"
2448 "Administrative cost [default: 255]\n"
2449 "Administrative cost\n")
2451 /* pfx vn un cost life */
2452 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2454 NULL
, NULL
, 0, NULL
);
2457 DEFUN (add_vnc_prefix_life
,
2458 add_vnc_prefix_life_cmd
,
2459 "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)",
2460 "Add registration\n"
2462 "Add/modify prefix related information\n"
2465 "VN address of NVE\n"
2466 "VN IPv4 interface address\n"
2467 "VN IPv6 interface address\n"
2468 "UN address of NVE\n"
2469 "UN IPv4 interface address\n"
2470 "UN IPv6 interface address\n"
2471 "Registration lifetime [default: infinite]\n"
2472 "Lifetime value in seconds\n")
2474 /* pfx vn un cost life */
2475 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2477 NULL
, NULL
, 0, NULL
);
2480 DEFUN (add_vnc_prefix
,
2482 "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>",
2483 "Add registration\n"
2485 "Add/modify prefix related information\n"
2488 "VN address of NVE\n"
2489 "VN IPv4 interface address\n"
2490 "VN IPv6 interface address\n"
2491 "UN address of NVE\n"
2492 "UN IPv4 interface address\n"
2493 "UN IPv6 interface address\n")
2495 /* pfx vn un cost life */
2496 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2498 NULL
, NULL
, 0, NULL
);
2501 /************************************************************************
2502 * Mac address registrations
2503 ************************************************************************/
2504 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2505 add_vnc_mac_vni_prefix_cost_life_cmd
,
2506 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
2507 "Add registration\n"
2509 "Add/modify mac address information\n"
2511 "Virtual Network Identifier follows\n"
2512 "Virtual Network Identifier\n"
2513 "VN address of NVE\n"
2514 "VN IPv4 interface address\n"
2515 "VN IPv6 interface address\n"
2516 "UN address of NVE\n"
2517 "UN IPv4 interface address\n"
2518 "UN IPv6 interface address\n"
2519 "Add/modify prefix related information\n"
2522 "Administrative cost [default: 255]\n"
2523 "Administrative cost\n"
2524 "Registration lifetime [default: infinite]\n"
2525 "Lifetime value in seconds\n")
2527 /* pfx vn un cost life */
2528 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2530 argv
[3], argv
[5], 0, NULL
);
2534 DEFUN (add_vnc_mac_vni_prefix_life
,
2535 add_vnc_mac_vni_prefix_life_cmd
,
2536 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
2537 "Add registration\n"
2539 "Add/modify mac address information\n"
2541 "Virtual Network Identifier follows\n"
2542 "Virtual Network Identifier\n"
2543 "VN address of NVE\n"
2544 "VN IPv4 interface address\n"
2545 "VN IPv6 interface address\n"
2546 "UN address of NVE\n"
2547 "UN IPv4 interface address\n"
2548 "UN IPv6 interface address\n"
2549 "Add/modify prefix related information\n"
2552 "Registration lifetime [default: infinite]\n"
2553 "Lifetime value in seconds\n")
2555 /* pfx vn un cost life */
2556 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2558 argv
[3], argv
[5], 0, NULL
);
2561 DEFUN (add_vnc_mac_vni_prefix_cost
,
2562 add_vnc_mac_vni_prefix_cost_cmd
,
2563 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
2564 "Add registration\n"
2566 "Add/modify mac address information\n"
2568 "Virtual Network Identifier follows\n"
2569 "Virtual Network Identifier\n"
2570 "VN address of NVE\n"
2571 "VN IPv4 interface address\n"
2572 "VN IPv6 interface address\n"
2573 "UN address of NVE\n"
2574 "UN IPv4 interface address\n"
2575 "UN IPv6 interface address\n"
2576 "Add/modify prefix related information\n"
2579 "Administrative cost [default: 255]\n" "Administrative cost\n")
2581 /* pfx vn un cost life */
2582 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2584 argv
[3], argv
[5], 0, NULL
);
2587 DEFUN (add_vnc_mac_vni_prefix
,
2588 add_vnc_mac_vni_prefix_cmd
,
2589 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
2590 "Add registration\n"
2592 "Add/modify mac address information\n"
2594 "Virtual Network Identifier follows\n"
2595 "Virtual Network Identifier\n"
2596 "VN address of NVE\n"
2597 "VN IPv4 interface address\n"
2598 "VN IPv6 interface address\n"
2599 "UN address of NVE\n"
2600 "UN IPv4 interface address\n"
2601 "UN IPv6 interface address\n"
2602 "Add/modify prefix related information\n"
2603 "IPv4 prefix\n" "IPv6 prefix\n")
2605 /* pfx vn un cost life */
2606 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2608 argv
[3], argv
[5], 0, NULL
);
2611 DEFUN (add_vnc_mac_vni_cost_life
,
2612 add_vnc_mac_vni_cost_life_cmd
,
2613 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
2614 "Add registration\n"
2616 "Add/modify mac address information\n"
2618 "Virtual Network Identifier follows\n"
2619 "Virtual Network Identifier\n"
2620 "VN address of NVE\n"
2621 "VN IPv4 interface address\n"
2622 "VN IPv6 interface address\n"
2623 "UN address of NVE\n"
2624 "UN IPv4 interface address\n"
2625 "UN IPv6 interface address\n"
2626 "Administrative cost [default: 255]\n"
2627 "Administrative cost\n"
2628 "Registration lifetime [default: infinite]\n"
2629 "Lifetime value in seconds\n")
2631 /* pfx vn un cost life */
2632 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2634 argv
[3], argv
[5], 0, NULL
);
2638 DEFUN (add_vnc_mac_vni_cost
,
2639 add_vnc_mac_vni_cost_cmd
,
2640 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
2641 "Add registration\n"
2643 "Add/modify mac address information\n"
2645 "Virtual Network Identifier follows\n"
2646 "Virtual Network Identifier\n"
2647 "VN address of NVE\n"
2648 "VN IPv4 interface address\n"
2649 "VN IPv6 interface address\n"
2650 "UN address of NVE\n"
2651 "UN IPv4 interface address\n"
2652 "UN IPv6 interface address\n"
2653 "Administrative cost [default: 255]\n" "Administrative cost\n")
2655 /* pfx vn un cost life */
2656 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2658 argv
[3], argv
[5], 0, NULL
);
2662 DEFUN (add_vnc_mac_vni_life
,
2663 add_vnc_mac_vni_life_cmd
,
2664 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
2665 "Add registration\n"
2667 "Add/modify mac address information\n"
2669 "Virtual Network Identifier follows\n"
2670 "Virtual Network Identifier\n"
2671 "VN address of NVE\n"
2672 "VN IPv4 interface address\n"
2673 "VN IPv6 interface address\n"
2674 "UN address of NVE\n"
2675 "UN IPv4 interface address\n"
2676 "UN IPv6 interface address\n"
2677 "Registration lifetime [default: infinite]\n"
2678 "Lifetime value in seconds\n")
2680 /* pfx vn un cost life */
2681 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2683 argv
[3], argv
[5], 0, NULL
);
2687 DEFUN (add_vnc_mac_vni
,
2688 add_vnc_mac_vni_cmd
,
2689 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2690 "Add registration\n"
2692 "Add/modify mac address information\n"
2694 "Virtual Network Identifier follows\n"
2695 "Virtual Network Identifier\n"
2696 "VN address of NVE\n"
2697 "VN IPv4 interface address\n"
2698 "VN IPv6 interface address\n"
2699 "UN address of NVE\n"
2700 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2702 /* pfx vn un cost life */
2703 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2705 argv
[3], argv
[5], 0, NULL
);
2708 /************************************************************************
2710 ************************************************************************/
2712 struct rfapi_local_reg_delete_arg
{
2717 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2718 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2719 struct prefix prefix
; /* AF==0: wildcard */
2720 struct prefix_rd rd
; /* plen!=64: wildcard */
2721 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2723 struct rfapi_l2address_option_match l2o
;
2731 uint32_t query_count
;
2733 uint32_t failed_pfx_count
;
2736 struct skiplist
*nves
;
2738 uint32_t remote_active_nve_count
;
2739 uint32_t remote_active_pfx_count
;
2740 uint32_t remote_holddown_nve_count
;
2741 uint32_t remote_holddown_pfx_count
;
2745 struct rfapi_ip_addr vn
;
2746 struct rfapi_ip_addr un
;
2747 struct rfapi_descriptor
*rfd
;
2748 struct rfapi_local_reg_delete_arg
*cda
;
2751 static void nve_addr_free(void *hap
)
2753 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2754 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2757 static int nve_addr_cmp(void *k1
, void *k2
)
2759 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2760 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2766 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2767 return (a
->un
.addr_family
- b
->un
.addr_family
);
2769 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2770 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2772 if (a
->un
.addr_family
== AF_INET
) {
2773 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2777 } else if (a
->un
.addr_family
== AF_INET6
) {
2778 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2785 if (a
->vn
.addr_family
== AF_INET
) {
2786 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2789 } else if (a
->vn
.addr_family
== AF_INET6
) {
2790 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2800 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2801 const char *arg_prefix
, const char *arg_vn
,
2802 const char *arg_un
, const char *arg_l2addr
,
2803 const char *arg_vni
, const char *arg_rd
,
2804 struct rfapi_nve_group_cfg
*arg_rfg
,
2805 struct rfapi_local_reg_delete_arg
*rcdarg
)
2807 int rc
= CMD_WARNING
;
2809 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2813 bgp
= bgp_get_default();
2815 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2817 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2818 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2819 &rcdarg
->vn_address
)))
2822 if (arg_un
&& strcmp(arg_un
, "*")) {
2823 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2824 &rcdarg
->un_address
)))
2827 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2829 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2830 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2837 vty_out(vty
, "Missing VNI\n");
2840 if (strcmp(arg_l2addr
, "*")) {
2841 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2842 &rcdarg
->l2o
.o
.macaddr
))) {
2843 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2847 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2849 if (strcmp(arg_vni
, "*")) {
2850 rcdarg
->l2o
.o
.logical_net_id
=
2851 strtoul(arg_vni
, NULL
, 10);
2852 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2856 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2857 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2866 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2867 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2868 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2869 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2870 struct rfapi_nve_group_cfg
*arg_rfg
,
2871 struct rfapi_local_reg_delete_arg
*rcdarg
)
2873 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2874 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2875 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2876 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2877 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2878 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2879 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2880 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2883 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2884 struct rfapi_ip_addr
*un_address
,
2885 struct rfapi_ip_addr
*vn_address
,
2886 struct rfapi_descriptor
*rfd
)
2889 struct nve_addr
*hap
;
2891 memset(&ha
, 0, sizeof(ha
));
2892 ha
.un
= *un_address
;
2893 ha
.vn
= *vn_address
;
2897 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2899 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2900 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2904 skiplist_insert(cda
->nves
, hap
, hap
);
2908 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2911 struct rfapi_descriptor
*rfd
;
2912 int query_count
= 0;
2913 struct listnode
*node
;
2914 struct bgp
*bgp_default
= bgp_get_default();
2916 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2920 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2921 &cda
->un_address
, &rfd
))
2925 rfapi_query_done_all(rfd
, &query_count
);
2926 cda
->query_count
+= query_count
;
2929 * Track unique nves seen
2931 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2942 h
= bgp_default
->rfapi
;
2947 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2949 * match un, vn addresses of NVEs
2951 if (cda
->un_address
.addr_family
2952 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2955 if (cda
->vn_address
.addr_family
2956 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2962 rfapi_query_done_all(rfd
, &query_count
);
2963 cda
->query_count
+= query_count
;
2966 * Track unique nves seen
2968 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2973 * TBD need to count deleted prefixes and nves?
2975 * ENXIO BGP or VNC not configured
2977 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2978 struct rfapi_descriptor
*rfd
)
2980 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2981 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2982 struct prefix
*pPrefix
; /* NULL = wildcard */
2983 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2985 struct rfapi_ip_prefix rprefix
;
2986 struct rfapi_next_hop_entry
*head
= NULL
;
2987 struct rfapi_next_hop_entry
*tail
= NULL
;
2990 vnc_zlog_debug_verbose("%s: entry", __func__
);
2993 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2994 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2995 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2996 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2999 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3002 do /* to preserve old code structure */
3004 struct rfapi
*h
= cda
->bgp
->rfapi
;
3006 struct rfapi_adb
*adb
;
3008 int deleted_from_this_nve
;
3010 struct nve_addr
*hap
;
3013 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3017 * match un, vn addresses of NVEs
3019 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3021 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3025 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3032 deleted_from_this_nve
= 0;
3035 struct skiplist
*sl
;
3036 struct rfapi_ip_prefix rp
;
3038 struct list
*adb_delete_list
;
3041 * The advertisements are stored in a skiplist.
3043 * the registration deletes the advertisement from the
3044 * skiplist, which we can't do while iterating over that
3045 * same skiplist using the current skiplist API.
3047 * Strategy: iterate over the skiplist and build another
3048 * list containing only the matching ADBs. Then delete
3049 * _everything_ in that second list (which can be done
3050 * using either skiplists or quagga linklists).
3052 adb_delete_list
= list_new();
3055 * Advertised IP prefixes (not 0/32 or 0/128)
3057 sl
= rfd
->advertised
.ipN_by_prefix
;
3060 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3062 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3066 if (!prefix_same(pPrefix
,
3067 &adb
->u
.s
.prefix_ip
)) {
3069 vnc_zlog_debug_verbose(
3070 "%s: adb=%p, prefix doesn't match, skipping",
3077 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3081 vnc_zlog_debug_verbose(
3082 "%s: adb=%p, RD doesn't match, skipping",
3088 if (CHECK_FLAG(cda
->l2o
.flags
,
3089 RFAPI_L2O_MACADDR
)) {
3090 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3091 adb
->u
.s
.prefix_eth
.u
3095 vnc_zlog_debug_verbose(
3096 "%s: adb=%p, macaddr doesn't match, skipping",
3103 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3104 if (cda
->l2o
.o
.logical_net_id
3105 != adb
->l2o
.logical_net_id
) {
3107 vnc_zlog_debug_verbose(
3108 "%s: adb=%p, LNI doesn't match, skipping",
3116 vnc_zlog_debug_verbose(
3117 "%s: ipN adding adb %p to delete list",
3121 listnode_add(adb_delete_list
, adb
);
3124 struct listnode
*node
;
3126 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3127 int this_advertisement_prefix_count
;
3128 struct rfapi_vn_option optary
[3];
3129 struct rfapi_vn_option
*opt
= NULL
;
3132 this_advertisement_prefix_count
= 1;
3134 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3136 memset(optary
, 0, sizeof(optary
));
3138 /* if mac addr present in advert, make l2o vn
3140 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3142 opt
->next
= &optary
[cur_opt
];
3143 opt
= &optary
[cur_opt
++];
3144 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3145 opt
->v
.l2addr
.macaddr
=
3146 adb
->u
.s
.prefix_eth
.u
3148 ++this_advertisement_prefix_count
;
3151 * use saved RD value instead of trying to
3153 * complex RD computation in rfapi_register()
3156 opt
->next
= &optary
[cur_opt
];
3157 opt
= &optary
[cur_opt
++];
3158 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3159 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3162 vnc_zlog_debug_verbose(
3163 "%s: ipN killing reg from adb %p ",
3167 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3168 (cur_opt
? optary
: NULL
),
3169 RFAPI_REGISTER_KILL
);
3172 this_advertisement_prefix_count
;
3173 cda
->reg_count
+= 1;
3174 deleted_from_this_nve
= 1;
3176 if (h
->rfp_methods
.local_cb
) {
3177 rfapiAddDeleteLocalRfpPrefix(
3178 &rfd
->un_addr
, &rfd
->vn_addr
,
3179 &rp
, 0, 0, NULL
, &head
, &tail
);
3182 list_delete_all_node(adb_delete_list
);
3184 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3186 * Caller didn't specify a prefix, or specified
3191 * Advertised 0/32 and 0/128 (indexed by
3194 sl
= rfd
->advertised
.ip0_by_ether
;
3197 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3200 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3203 if (CHECK_FLAG(cda
->l2o
.flags
,
3204 RFAPI_L2O_MACADDR
)) {
3205 if (memcmp(cda
->l2o
.o
.macaddr
3207 adb
->u
.s
.prefix_eth
.u
3215 if (CHECK_FLAG(cda
->l2o
.flags
,
3217 if (cda
->l2o
.o
.logical_net_id
3218 != adb
->l2o
.logical_net_id
) {
3223 vnc_zlog_debug_verbose(
3224 "%s: ip0 adding adb %p to delete list",
3227 listnode_add(adb_delete_list
, adb
);
3231 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3234 struct rfapi_vn_option vn
;
3236 rfapiQprefix2Rprefix(
3237 &adb
->u
.s
.prefix_ip
, &rp
);
3239 memset(&vn
, 0, sizeof(vn
));
3240 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3241 vn
.v
.l2addr
= adb
->l2o
;
3244 vnc_zlog_debug_verbose(
3245 "%s: ip0 killing reg from adb %p ",
3249 rc
= rfapi_register(
3250 rfd
, &rp
, 0, NULL
, &vn
,
3251 RFAPI_REGISTER_KILL
);
3253 cda
->pfx_count
+= 1;
3254 cda
->reg_count
+= 1;
3255 deleted_from_this_nve
= 1;
3257 if (h
->rfp_methods
.local_cb
) {
3258 struct rfapi_vn_option
3262 rfapi_vn_options_dup(
3264 rfapiAddDeleteLocalRfpPrefix(
3266 &rfd
->vn_addr
, &rp
, 0,
3267 0, vn_opt_new
, &head
,
3271 list_delete_all_node(adb_delete_list
);
3273 list_delete(&adb_delete_list
);
3277 if (head
) { /* should not be set if (NULL ==
3278 rfapi_cfg->local_cb) */
3279 h
->flags
|= RFAPI_INCALLBACK
;
3280 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3281 h
->flags
&= ~RFAPI_INCALLBACK
;
3285 if (deleted_from_this_nve
) {
3287 * track unique NVEs seen
3289 memset(&ha
, 0, sizeof(ha
));
3290 ha
.un
= rfd
->un_addr
;
3291 ha
.vn
= rfd
->vn_addr
;
3294 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3296 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3297 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3298 sizeof(struct nve_addr
));
3302 skiplist_insert(cda
->nves
, hap
, hap
);
3305 } while (0); /* to preserve old code structure */
3310 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3315 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3316 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3318 struct bgp
*bgp
= cda
->bgp
;
3320 struct rfapi_cfg
*rfapi_cfg
;
3322 struct listnode
*node
;
3323 struct rfapi_descriptor
*rfd
;
3327 rfapi_cfg
= bgp
->rfapi_cfg
;
3328 if (!h
|| !rfapi_cfg
)
3330 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3332 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3333 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3342 * Deletes local and remote prefixes that match
3344 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3346 struct prefix pfx_un
;
3347 struct prefix pfx_vn
;
3349 struct prefix
*pUN
= NULL
;
3350 struct prefix
*pVN
= NULL
;
3351 struct prefix
*pPrefix
= NULL
;
3353 struct rfapi_import_table
*it
= NULL
;
3356 * Delete matching remote prefixes in holddown
3358 if (cda
->vn_address
.addr_family
) {
3359 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3362 if (cda
->un_address
.addr_family
) {
3363 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3366 if (cda
->prefix
.family
) {
3367 pPrefix
= &cda
->prefix
;
3370 it
= cda
->rfg
->rfapi_import_table
;
3372 rfapiDeleteRemotePrefixes(
3373 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3374 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3375 &cda
->remote_holddown_nve_count
);
3378 * Now do local prefixes
3380 rfapiDeleteLocalPrefixes(cda
);
3383 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3385 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3387 /* Our special element-deleting function counts nves */
3389 skiplist_free(cda
->nves
);
3392 if (cda
->failed_pfx_count
)
3393 vty_out(vty
, "Failed to delete %d prefixes\n",
3394 cda
->failed_pfx_count
);
3396 /* left as "prefixes" even in single case for ease of machine parsing */
3398 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3399 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3403 * We don't currently allow deletion of active remote prefixes from
3407 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3408 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3412 * Caller has already deleted registrations and queries for this/these
3413 * NVEs. Now we just have to close their descriptors.
3415 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3417 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3418 struct nve_addr
*pKey
;
3419 struct nve_addr
*pValue
;
3420 void *cursor
= NULL
;
3426 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3427 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3431 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3432 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3433 rfapi_close(pValue
->rfd
);
3438 DEFUN (clear_vnc_nve_all
,
3439 clear_vnc_nve_all_cmd
,
3443 "Clear per NVE information\n"
3447 struct rfapi_local_reg_delete_arg cda
;
3450 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3456 clear_vnc_responses(&cda
);
3457 clear_vnc_prefix(&cda
);
3458 clear_vnc_nve_closer(&cda
);
3460 print_cleared_stats(&cda
);
3465 DEFUN (clear_vnc_nve_vn_un
,
3466 clear_vnc_nve_vn_un_cmd
,
3467 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3470 "Clear prefix registration information\n"
3471 "VN address of NVE\n"
3473 "VN IPv4 interface address\n"
3474 "VN IPv6 interface address\n"
3475 "UN address of NVE\n"
3476 "For all UN addresses\n"
3477 "UN IPv4 interface address\n"
3478 "UN IPv6 interface address\n")
3480 struct rfapi_local_reg_delete_arg cda
;
3483 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3484 NULL
, NULL
, NULL
, &cda
)))
3489 clear_vnc_responses(&cda
);
3490 clear_vnc_prefix(&cda
);
3491 clear_vnc_nve_closer(&cda
);
3493 print_cleared_stats(&cda
);
3498 DEFUN (clear_vnc_nve_un_vn
,
3499 clear_vnc_nve_un_vn_cmd
,
3500 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3503 "Clear prefix registration information\n"
3504 "UN address of NVE\n"
3506 "UN IPv4 interface address\n"
3507 "UN IPv6 interface address\n"
3508 "VN address of NVE\n"
3510 "VN IPv4 interface address\n"
3511 "VN IPv6 interface address\n")
3513 struct rfapi_local_reg_delete_arg cda
;
3516 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3517 NULL
, NULL
, NULL
, &cda
)))
3522 clear_vnc_responses(&cda
);
3523 clear_vnc_prefix(&cda
);
3524 clear_vnc_nve_closer(&cda
);
3526 print_cleared_stats(&cda
);
3531 DEFUN (clear_vnc_nve_vn
,
3532 clear_vnc_nve_vn_cmd
,
3533 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3536 "Clear prefix registration information\n"
3537 "VN address of NVE\n"
3539 "VN IPv4 interface address\n"
3540 "VN IPv6 interface address\n")
3542 struct rfapi_local_reg_delete_arg cda
;
3545 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3546 NULL
, NULL
, NULL
, &cda
)))
3551 clear_vnc_responses(&cda
);
3552 clear_vnc_prefix(&cda
);
3553 clear_vnc_nve_closer(&cda
);
3555 print_cleared_stats(&cda
);
3559 DEFUN (clear_vnc_nve_un
,
3560 clear_vnc_nve_un_cmd
,
3561 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3564 "Clear prefix registration information\n"
3565 "UN address of NVE\n"
3567 "UN IPv4 interface address\n"
3568 "UN IPv6 interface address\n")
3570 struct rfapi_local_reg_delete_arg cda
;
3573 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3574 NULL
, NULL
, NULL
, &cda
)))
3579 clear_vnc_responses(&cda
);
3580 clear_vnc_prefix(&cda
);
3581 clear_vnc_nve_closer(&cda
);
3583 print_cleared_stats(&cda
);
3587 /*-------------------------------------------------
3589 *-------------------------------------------------*/
3592 * This function is defined in this file (rather than in rfp_registration.c)
3593 * because here we have access to all the task handles.
3595 DEFUN (clear_vnc_prefix_vn_un
,
3596 clear_vnc_prefix_vn_un_cmd
,
3597 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3600 "Clear prefix registration information\n"
3604 "VN address of NVE\n"
3605 "All VN addresses\n"
3606 "VN IPv4 interface address\n"
3607 "VN IPv6 interface address\n"
3608 "UN address of NVE\n"
3609 "All UN addresses\n"
3610 "UN IPv4 interface address\n"
3611 "UN IPv6 interface address\n")
3613 struct rfapi_local_reg_delete_arg cda
;
3616 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3617 NULL
, NULL
, NULL
, NULL
, &cda
)))
3620 clear_vnc_prefix(&cda
);
3621 print_cleared_stats(&cda
);
3625 DEFUN (clear_vnc_prefix_un_vn
,
3626 clear_vnc_prefix_un_vn_cmd
,
3627 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3630 "Clear prefix registration information\n"
3634 "UN address of NVE\n"
3635 "All UN addresses\n"
3636 "UN IPv4 interface address\n"
3637 "UN IPv6 interface address\n"
3638 "VN address of NVE\n"
3639 "All VN addresses\n"
3640 "VN IPv4 interface address\n"
3641 "VN IPv6 interface address\n")
3643 struct rfapi_local_reg_delete_arg cda
;
3646 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3647 NULL
, NULL
, NULL
, NULL
, &cda
)))
3650 clear_vnc_prefix(&cda
);
3651 print_cleared_stats(&cda
);
3655 DEFUN (clear_vnc_prefix_un
,
3656 clear_vnc_prefix_un_cmd
,
3657 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3660 "Clear prefix registration information\n"
3664 "UN address of NVE\n"
3665 "All UN addresses\n"
3666 "UN IPv4 interface address\n"
3667 "UN IPv6 interface address\n")
3669 struct rfapi_local_reg_delete_arg cda
;
3672 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3673 NULL
, NULL
, NULL
, &cda
)))
3676 clear_vnc_prefix(&cda
);
3677 print_cleared_stats(&cda
);
3681 DEFUN (clear_vnc_prefix_vn
,
3682 clear_vnc_prefix_vn_cmd
,
3683 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3686 "Clear prefix registration information\n"
3690 "UN address of NVE\n"
3691 "All VN addresses\n"
3692 "VN IPv4 interface address\n"
3693 "VN IPv6 interface address\n")
3695 struct rfapi_local_reg_delete_arg cda
;
3698 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3699 NULL
, NULL
, NULL
, &cda
)))
3702 clear_vnc_prefix(&cda
);
3703 print_cleared_stats(&cda
);
3707 DEFUN (clear_vnc_prefix_all
,
3708 clear_vnc_prefix_all_cmd
,
3709 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3712 "Clear prefix registration information\n"
3718 struct rfapi_local_reg_delete_arg cda
;
3721 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3722 NULL
, NULL
, NULL
, &cda
)))
3725 clear_vnc_prefix(&cda
);
3726 print_cleared_stats(&cda
);
3730 /*-------------------------------------------------
3732 *-------------------------------------------------*/
3735 * This function is defined in this file (rather than in rfp_registration.c)
3736 * because here we have access to all the task handles.
3738 DEFUN (clear_vnc_mac_vn_un
,
3739 clear_vnc_mac_vn_un_cmd
,
3740 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3743 "Clear mac registration information\n"
3747 "Any virtual network identifier\n"
3748 "Virtual network identifier\n"
3749 "VN address of NVE\n"
3750 "All VN addresses\n"
3751 "VN IPv4 interface address\n"
3752 "VN IPv6 interface address\n"
3753 "UN address of NVE\n"
3754 "All UN addresses\n"
3755 "UN IPv4 interface address\n"
3756 "UN IPv6 interface address\n")
3758 struct rfapi_local_reg_delete_arg cda
;
3761 /* pfx vn un L2 VNI */
3762 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3763 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3766 clear_vnc_prefix(&cda
);
3767 print_cleared_stats(&cda
);
3771 DEFUN (clear_vnc_mac_un_vn
,
3772 clear_vnc_mac_un_vn_cmd
,
3773 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3776 "Clear mac registration information\n"
3780 "Any virtual network identifier\n"
3781 "Virtual network identifier\n"
3782 "UN address of NVE\n"
3783 "All UN addresses\n"
3784 "UN IPv4 interface address\n"
3785 "UN IPv6 interface address\n"
3786 "VN address of NVE\n"
3787 "All VN addresses\n"
3788 "VN IPv4 interface address\n"
3789 "VN IPv6 interface address\n")
3791 struct rfapi_local_reg_delete_arg cda
;
3794 /* pfx vn un L2 VNI */
3795 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3796 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3799 clear_vnc_prefix(&cda
);
3800 print_cleared_stats(&cda
);
3804 DEFUN (clear_vnc_mac_un
,
3805 clear_vnc_mac_un_cmd
,
3806 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3809 "Clear mac registration information\n"
3813 "Any virtual network identifier\n"
3814 "Virtual network identifier\n"
3815 "UN address of NVE\n"
3816 "All UN addresses\n"
3817 "UN IPv4 interface address\n"
3818 "UN IPv6 interface address\n")
3820 struct rfapi_local_reg_delete_arg cda
;
3823 /* pfx vn un L2 VNI */
3824 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3825 argv
[5], NULL
, NULL
, &cda
)))
3828 clear_vnc_prefix(&cda
);
3829 print_cleared_stats(&cda
);
3833 DEFUN (clear_vnc_mac_vn
,
3834 clear_vnc_mac_vn_cmd
,
3835 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3838 "Clear mac registration information\n"
3842 "Any virtual network identifier\n"
3843 "Virtual network identifier\n"
3844 "UN address of NVE\n"
3845 "All VN addresses\n"
3846 "VN IPv4 interface address\n"
3847 "VN IPv6 interface address\n")
3849 struct rfapi_local_reg_delete_arg cda
;
3852 /* pfx vn un L2 VNI */
3853 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3854 argv
[5], NULL
, NULL
, &cda
)))
3857 clear_vnc_prefix(&cda
);
3858 print_cleared_stats(&cda
);
3862 DEFUN (clear_vnc_mac_all
,
3863 clear_vnc_mac_all_cmd
,
3864 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3867 "Clear mac registration information\n"
3871 "Any virtual network identifier\n"
3872 "Virtual network identifier\n"
3875 struct rfapi_local_reg_delete_arg cda
;
3878 /* pfx vn un L2 VNI */
3879 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3880 argv
[5], NULL
, NULL
, &cda
)))
3883 clear_vnc_prefix(&cda
);
3884 print_cleared_stats(&cda
);
3888 /*-------------------------------------------------
3889 * Clear VNC MAC PREFIX
3890 *-------------------------------------------------*/
3892 DEFUN (clear_vnc_mac_vn_un_prefix
,
3893 clear_vnc_mac_vn_un_prefix_cmd
,
3894 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3897 "Clear mac registration information\n"
3901 "Any virtual network identifier\n"
3902 "Virtual network identifier\n"
3903 "VN address of NVE\n"
3904 "All VN addresses\n"
3905 "VN IPv4 interface address\n"
3906 "VN IPv6 interface address\n"
3907 "UN address of NVE\n"
3908 "All UN addresses\n"
3909 "UN IPv4 interface address\n"
3910 "UN IPv6 interface address\n"
3911 "Clear prefix registration information\n"
3916 struct rfapi_local_reg_delete_arg cda
;
3919 /* pfx vn un L2 VNI */
3920 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3921 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3924 clear_vnc_prefix(&cda
);
3925 print_cleared_stats(&cda
);
3929 DEFUN (clear_vnc_mac_un_vn_prefix
,
3930 clear_vnc_mac_un_vn_prefix_cmd
,
3931 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3934 "Clear mac registration information\n"
3938 "Any virtual network identifier\n"
3939 "Virtual network identifier\n"
3940 "UN address of NVE\n"
3941 "All UN addresses\n"
3942 "UN IPv4 interface address\n"
3943 "UN IPv6 interface address\n"
3944 "VN address of NVE\n"
3945 "All VN addresses\n"
3946 "VN IPv4 interface address\n"
3947 "VN IPv6 interface address\n"
3948 "Clear prefix registration information\n"
3952 "Clear prefix registration information\n"
3957 struct rfapi_local_reg_delete_arg cda
;
3960 /* pfx vn un L2 VNI */
3961 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3962 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3965 clear_vnc_prefix(&cda
);
3966 print_cleared_stats(&cda
);
3970 DEFUN (clear_vnc_mac_un_prefix
,
3971 clear_vnc_mac_un_prefix_cmd
,
3972 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3975 "Clear mac registration information\n"
3979 "Any virtual network identifier\n"
3980 "Virtual network identifier\n"
3981 "UN address of NVE\n"
3982 "All UN addresses\n"
3983 "UN IPv4 interface address\n"
3984 "UN IPv6 interface address\n"
3985 "Clear prefix registration information\n"
3990 struct rfapi_local_reg_delete_arg cda
;
3993 /* pfx vn un L2 VNI */
3994 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3995 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3998 clear_vnc_prefix(&cda
);
3999 print_cleared_stats(&cda
);
4003 DEFUN (clear_vnc_mac_vn_prefix
,
4004 clear_vnc_mac_vn_prefix_cmd
,
4005 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4008 "Clear mac registration information\n"
4012 "Any virtual network identifier\n"
4013 "Virtual network identifier\n"
4014 "UN address of NVE\n"
4015 "All VN addresses\n"
4016 "VN IPv4 interface address\n"
4017 "VN IPv6 interface address\n"
4018 "Clear prefix registration information\n"
4023 struct rfapi_local_reg_delete_arg cda
;
4026 /* pfx vn un L2 VNI */
4027 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4028 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4031 clear_vnc_prefix(&cda
);
4032 print_cleared_stats(&cda
);
4036 DEFUN (clear_vnc_mac_all_prefix
,
4037 clear_vnc_mac_all_prefix_cmd
,
4038 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4041 "Clear mac registration information\n"
4045 "Any virtual network identifier\n"
4046 "Virtual network identifier\n"
4047 "UN address of NVE\n"
4048 "All VN addresses\n"
4049 "VN IPv4 interface address\n"
4050 "VN IPv6 interface address\n")
4052 struct rfapi_local_reg_delete_arg cda
;
4055 /* pfx vn un L2 VNI */
4056 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4057 argv
[5], NULL
, NULL
, &cda
)))
4060 clear_vnc_prefix(&cda
);
4061 print_cleared_stats(&cda
);
4065 /************************************************************************
4067 ************************************************************************/
4070 /* copied from rfp_vty.c */
4071 static int check_and_display_is_vnc_running(struct vty
*vty
)
4073 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4074 return 1; /* is running */
4077 vty_out(vty
, "VNC is not configured.\n");
4079 return 0; /* not running */
4082 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4083 show_nve_summary_t show_type
)
4085 struct bgp
*bgp_default
= bgp_get_default();
4087 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4089 int active_local_routes
;
4090 int active_remote_routes
;
4091 int holddown_remote_routes
;
4092 int imported_remote_routes
;
4097 h
= bgp_default
->rfapi
;
4102 /* don't show local info if not running RFP */
4103 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4105 switch (show_type
) {
4107 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4108 vty_out(vty
, "%-24s ", "NVEs:");
4109 vty_out(vty
, "%-8s %-8u ",
4110 "Active:", h
->descriptors
.count
);
4111 vty_out(vty
, "%-8s %-8u ",
4112 "Maximum:", h
->stat
.max_descriptors
);
4113 vty_out(vty
, "%-8s %-8u",
4114 "Unknown:", h
->stat
.count_unknown_nves
);
4117 case SHOW_NVE_SUMMARY_REGISTERED
:
4119 * NB: With the introduction of L2 route support, we no
4120 * longer have a one-to-one correspondence between
4121 * locally-originated route advertisements and routes in
4122 * the import tables that have local origin. This
4123 * discrepancy arises because a single advertisement
4124 * may contain both an IP prefix and a MAC address.
4125 * Such an advertisement results in two import table
4126 * entries: one indexed by IP prefix, the other indexed
4129 * TBD: update computation and display of registration
4130 * statistics to reflect the underlying semantics.
4132 if (is_vnc_running
) {
4133 vty_out(vty
, "%-24s ", "Registrations:");
4134 vty_out(vty
, "%-8s %-8u ", "Active:",
4135 rfapiApCountAll(bgp_default
));
4136 vty_out(vty
, "%-8s %-8u ", "Failed:",
4137 h
->stat
.count_registrations_failed
);
4138 vty_out(vty
, "%-8s %-8u",
4139 "Total:", h
->stat
.count_registrations
);
4142 vty_out(vty
, "%-24s ", "Prefixes registered:");
4145 rfapiCountAllItRoutes(&active_local_routes
,
4146 &active_remote_routes
,
4147 &holddown_remote_routes
,
4148 &imported_remote_routes
);
4151 if (is_vnc_running
) {
4152 vty_out(vty
, " %-20s ", "Locally:");
4153 vty_out(vty
, "%-8s %-8u ",
4154 "Active:", active_local_routes
);
4159 vty_out(vty
, " %-20s ", "Remotely:");
4160 vty_out(vty
, "%-8s %-8u",
4161 "Active:", active_remote_routes
);
4163 vty_out(vty
, " %-20s ", "In Holddown:");
4164 vty_out(vty
, "%-8s %-8u",
4165 "Active:", holddown_remote_routes
);
4167 vty_out(vty
, " %-20s ", "Imported:");
4168 vty_out(vty
, "%-8s %-8u",
4169 "Active:", imported_remote_routes
);
4172 case SHOW_NVE_SUMMARY_QUERIES
:
4173 vty_out(vty
, "%-24s ", "Queries:");
4174 vty_out(vty
, "%-8s %-8u ",
4175 "Active:", rfapi_monitor_count(NULL
));
4176 vty_out(vty
, "%-8s %-8u ",
4177 "Failed:", h
->stat
.count_queries_failed
);
4178 vty_out(vty
, "%-8s %-8u",
4179 "Total:", h
->stat
.count_queries
);
4182 case SHOW_NVE_SUMMARY_RESPONSES
:
4183 rfapiRibShowResponsesSummary(vty
);
4193 vty_out(vty
, "VNC is not configured.\n");
4197 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4198 struct prefix
*un_prefix
)
4200 // struct hash *rfds;
4201 // struct rfp_rfapi_descriptor_param param;
4203 struct bgp
*bgp_default
= bgp_get_default();
4205 struct listnode
*node
;
4206 struct rfapi_descriptor
*rfd
;
4215 h
= bgp_default
->rfapi
;
4220 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4224 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4226 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4229 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4237 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4238 if (!prefix_match(vn_prefix
, &pfx
))
4243 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4244 if (!prefix_match(un_prefix
, &pfx
))
4248 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4250 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4254 /* print out a header */
4256 " Active Next Hops\n");
4257 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4258 "VN Address", "UN Address", "Regis", "Resps",
4259 "Reach", "Remove", "Age");
4264 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4265 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4266 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4267 rfd
->stat_count_nh_removal
,
4268 rfapiFormatAge(rfd
->open_time
, age
, 10));
4271 if (printed
> 0 || vn_prefix
|| un_prefix
)
4272 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4278 vty_out(vty
, "VNC is not configured.\n");
4283 DEFUN (vnc_show_summary
,
4284 vnc_show_summary_cmd
,
4288 "Display VNC status summary\n")
4290 if (!check_and_display_is_vnc_running(vty
))
4292 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4294 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4295 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4296 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4297 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4301 DEFUN (vnc_show_nves
,
4306 "List known NVEs\n")
4308 rfapi_show_nves(vty
, NULL
, NULL
);
4312 DEFUN (vnc_show_nves_ptct
,
4313 vnc_show_nves_ptct_cmd
,
4314 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4318 "VN address of NVE\n"
4319 "UN address of NVE\n"
4320 "IPv4 interface address\n"
4321 "IPv6 interface address\n")
4325 if (!check_and_display_is_vnc_running(vty
))
4328 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4329 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4332 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4333 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4337 if (argv
[3]->arg
[0] == 'u') {
4338 rfapi_show_nves(vty
, NULL
, &pfx
);
4340 rfapi_show_nves(vty
, &pfx
, NULL
);
4346 /* adapted from rfp_registration_cache_log() */
4347 static void rfapi_show_registrations(struct vty
*vty
,
4348 struct prefix
*restrict_to
, int show_local
,
4349 int show_remote
, int show_holddown
,
4357 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4360 /* non-expiring, local */
4361 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4365 /* non-expiring, non-local */
4366 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4369 if (show_holddown
) {
4370 /* expiring, including local */
4371 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4374 if (show_imported
) {
4375 /* non-expiring, non-local */
4376 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4384 DEFUN (vnc_show_registrations_pfx
,
4385 vnc_show_registrations_pfx_cmd
,
4386 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4389 "List active prefix registrations\n"
4390 "Limit output to a particular IPv4 prefix\n"
4391 "Limit output to a particular IPv6 prefix\n"
4392 "Limit output to a particular IPv6 address\n")
4395 struct prefix
*p_addr
= NULL
;
4398 if (!str2prefix(argv
[3]->arg
, &p
)) {
4399 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4406 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4410 DEFUN (vnc_show_registrations_some_pfx
,
4411 vnc_show_registrations_some_pfx_cmd
,
4412 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4415 "List active prefix registrations\n"
4416 "show all registrations\n"
4417 "show only registrations in holddown\n"
4418 "show only imported prefixes\n"
4419 "show only local registrations\n"
4420 "show only remote registrations\n"
4421 "Limit output to a particular prefix or address\n"
4422 "Limit output to a particular prefix or address\n"
4423 "Limit output to a particular prefix or address\n")
4426 struct prefix
*p_addr
= NULL
;
4429 int show_remote
= 0;
4430 int show_holddown
= 0;
4431 int show_imported
= 0;
4434 if (!str2prefix(argv
[4]->arg
, &p
)) {
4435 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4441 switch (argv
[3]->arg
[0]) {
4466 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4467 show_holddown
, show_imported
);
4471 DEFUN (vnc_show_responses_pfx
,
4472 vnc_show_responses_pfx_cmd
,
4473 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4476 "List recent query responses\n"
4477 "Limit output to a particular IPv4 prefix\n"
4478 "Limit output to a particular IPv6 prefix\n"
4479 "Limit output to a particular IPv6 address\n" )
4482 struct prefix
*p_addr
= NULL
;
4485 if (!str2prefix(argv
[3]->arg
, &p
)) {
4486 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4492 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4494 rfapiRibShowResponsesSummary(vty
);
4496 rfapiRibShowResponses(vty
, p_addr
, 0);
4497 rfapiRibShowResponses(vty
, p_addr
, 1);
4502 DEFUN (vnc_show_responses_some_pfx
,
4503 vnc_show_responses_some_pfx_cmd
,
4504 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4507 "List recent query responses\n"
4508 "show only active query responses\n"
4509 "show only removed query responses\n"
4510 "Limit output to a particular IPv4 prefix\n"
4511 "Limit output to a particular IPv6 prefix\n"
4512 "Limit output to a particular IPV6 address\n")
4515 struct prefix
*p_addr
= NULL
;
4517 int show_active
= 0;
4518 int show_removed
= 0;
4520 if (!check_and_display_is_vnc_running(vty
))
4524 if (!str2prefix(argv
[4]->arg
, &p
)) {
4525 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4532 switch (argv
[3]->arg
[0]) {
4542 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4544 rfapiRibShowResponsesSummary(vty
);
4547 rfapiRibShowResponses(vty
, p_addr
, 0);
4549 rfapiRibShowResponses(vty
, p_addr
, 1);
4554 DEFUN (show_vnc_queries_pfx
,
4555 show_vnc_queries_pfx_cmd
,
4556 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4559 "List active queries\n"
4560 "Limit output to a particular IPv4 prefix or address\n"
4561 "Limit output to a particular IPv6 prefix\n"
4562 "Limit output to a particualr IPV6 address\n")
4565 struct prefix
*p
= NULL
;
4568 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4569 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4575 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4577 return rfapiShowVncQueries(vty
, p
);
4580 DEFUN (vnc_clear_counters
,
4581 vnc_clear_counters_cmd
,
4582 "clear vnc counters",
4585 "Reset VNC counters\n")
4587 struct bgp
*bgp_default
= bgp_get_default();
4589 struct listnode
*node
;
4590 struct rfapi_descriptor
*rfd
;
4595 h
= bgp_default
->rfapi
;
4601 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4602 rfd
->stat_count_nh_reachable
= 0;
4603 rfd
->stat_count_nh_removal
= 0;
4607 memset(&h
->stat
, 0, sizeof(h
->stat
));
4610 * 151122 per bug 103, set count_registrations = number active.
4611 * Do same for queries
4613 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4614 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4616 rfapiRibShowResponsesSummaryClear();
4621 vty_out(vty
, "VNC is not configured.\n");
4625 /************************************************************************
4626 * Add prefix with vrf
4628 * add [vrf <vrf-name>] prefix <prefix>
4629 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4630 ************************************************************************/
4631 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4633 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4634 /* based on rfapi_open */
4635 struct rfapi_descriptor
*rfd
;
4637 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4638 sizeof(struct rfapi_descriptor
));
4641 /* leave most fields empty as will get from (dynamic) config
4643 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4645 if (rfg
->vn_prefix
.family
4646 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4647 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4649 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4650 rfd
->vn_addr
.addr_family
= AF_INET
;
4651 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4653 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4655 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4657 rfapi_init_and_open(bgp
, rfd
, rfg
);
4661 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4662 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4663 const char *arg_prefix
,
4664 const char *arg_rd
, /* optional */
4665 const char *arg_label
, /* optional */
4666 const char *arg_pref
) /* optional */
4669 struct rfapi_nve_group_cfg
*rfg
;
4671 struct rfapi_ip_prefix rpfx
;
4673 struct rfapi_vn_option optary
[3];
4674 struct rfapi_vn_option
*opt
= NULL
;
4677 bgp
= bgp_get_default(); /* assume main instance for now */
4679 vty_out(vty
, "No BGP process is configured\n");
4680 return CMD_WARNING_CONFIG_FAILED
;
4682 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4683 vty_out(vty
, "VRF support not configured\n");
4684 return CMD_WARNING_CONFIG_FAILED
;
4687 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4690 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4692 return CMD_WARNING_CONFIG_FAILED
;
4694 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4696 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4698 return CMD_WARNING_CONFIG_FAILED
;
4700 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4702 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4704 return CMD_WARNING_CONFIG_FAILED
;
4706 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4708 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4710 return CMD_WARNING_CONFIG_FAILED
;
4712 if (!str2prefix(arg_prefix
, &pfx
)) {
4713 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4714 return CMD_WARNING_CONFIG_FAILED
;
4716 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4717 memset(optary
, 0, sizeof(optary
));
4719 opt
= &optary
[cur_opt
++];
4720 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4721 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4722 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4723 return CMD_WARNING_CONFIG_FAILED
;
4726 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4727 struct rfapi_l2address_option
*l2o
;
4729 opt
->next
= &optary
[cur_opt
];
4730 opt
= &optary
[cur_opt
++];
4731 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4732 l2o
= &opt
->v
.l2addr
;
4735 label
= strtoul(arg_label
, NULL
, 10);
4738 l2o
->label
= rfg
->label
;
4741 char *endptr
= NULL
;
4742 pref
= strtoul(arg_pref
, &endptr
, 10);
4743 if (*endptr
!= '\0') {
4745 "%% Invalid local-preference value \"%s\"\n",
4747 return CMD_WARNING_CONFIG_FAILED
;
4750 rpfx
.cost
= 255 - (pref
& 255);
4751 vnc_add_vrf_opener(bgp
, rfg
);
4753 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4754 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4755 struct rfapi_next_hop_entry
*head
= NULL
;
4756 struct rfapi_next_hop_entry
*tail
= NULL
;
4757 struct rfapi_vn_option
*vn_opt_new
;
4759 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4762 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4763 struct rfapi_descriptor
*r
=
4764 (struct rfapi_descriptor
*)rfg
->rfd
;
4765 vn_opt_new
= rfapi_vn_options_dup(opt
);
4767 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4769 RFAPI_INFINITE_LIFETIME
,
4770 vn_opt_new
, &head
, &tail
);
4772 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4773 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4775 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4779 vnc_zlog_debug_verbose(
4780 "%s completed, count=%d/%d", __func__
,
4781 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4782 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4786 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4787 vty_out(vty
, "Add failed.\n");
4788 return CMD_WARNING_CONFIG_FAILED
;
4791 DEFUN (add_vrf_prefix_rd_label_pref
,
4792 add_vrf_prefix_rd_label_pref_cmd
,
4793 "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)}]",
4797 "Add/modify prefix related information\n"
4800 "Override configured VRF Route Distinguisher\n"
4801 "<as-number>:<number> or <ip-address>:<number>\n"
4802 "Override configured VRF label\n"
4803 "Label Value <0-1048575>\n"
4804 "Set advertised local preference\n"
4805 "local preference (higher=more preferred)\n")
4807 char *arg_vrf
= argv
[2]->arg
;
4808 char *arg_prefix
= argv
[4]->arg
;
4809 char *arg_rd
= NULL
; /* optional */
4810 char *arg_label
= NULL
; /* optional */
4811 char *arg_pref
= NULL
; /* optional */
4813 argc
--; /* don't parse argument */
4814 while (pargc
< argc
) {
4815 switch (argv
[pargc
++]->arg
[0]) {
4817 arg_rd
= argv
[pargc
]->arg
;
4820 arg_label
= argv
[pargc
]->arg
;
4823 arg_pref
= argv
[pargc
]->arg
;
4831 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4835 /************************************************************************
4836 * del prefix with vrf
4838 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4839 ************************************************************************/
4840 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4844 if (rfg
->rfapi_import_table
== NULL
)
4847 afi_t afi
= AFI_MAX
;
4849 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4854 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4856 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4861 /* check if IT is empty */
4863 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4867 if (afi
== AFI_MAX
) {
4868 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4873 vnc_zlog_debug_verbose(
4874 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4875 rfg
->rfapi_import_table
->local_count
[afi
]);
4879 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4880 const char *arg_prefix
, /* NULL = all */
4881 const char *arg_rd
) /* optional */
4883 struct rfapi_nve_group_cfg
*rfg
;
4884 struct rfapi_local_reg_delete_arg cda
;
4889 bgp
= bgp_get_default(); /* assume main instance for now */
4891 vty_out(vty
, "No BGP process is configured\n");
4894 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4895 vty_out(vty
, "VRF support not configured\n");
4898 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4901 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4905 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4907 if (rc
!= CMD_SUCCESS
) /* parse error */
4910 start_count
= rfapi_cfg_group_it_count(rfg
);
4911 clear_vnc_prefix(&cda
);
4912 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4917 DEFUN (clear_vrf_prefix_rd
,
4918 clear_vrf_prefix_rd_cmd
,
4919 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4920 "Clear stored data\n"
4923 "Prefix related information\n"
4926 "Specific VRF Route Distinguisher\n"
4927 "<as-number>:<number> or <ip-address>:<number>\n")
4929 char *arg_vrf
= argv
[2]->arg
;
4930 char *arg_prefix
= NULL
; /* optional */
4931 char *arg_rd
= NULL
; /* optional */
4933 argc
--; /* don't check parameter */
4934 while (pargc
< argc
) {
4935 switch (argv
[pargc
++]->arg
[0]) {
4937 arg_rd
= argv
[pargc
]->arg
;
4940 arg_prefix
= argv
[pargc
]->arg
;
4947 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4950 DEFUN (clear_vrf_all
,
4952 "clear vrf NAME all",
4953 "Clear stored data\n"
4958 char *arg_vrf
= argv
[2]->arg
;
4959 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4962 void rfapi_vty_init(void)
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4966 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4967 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4968 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4982 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4983 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4985 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4989 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4990 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4996 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5002 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5008 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5009 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5011 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5012 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5014 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5016 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5017 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5018 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5022 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5023 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5024 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);