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 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
&& 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]));
436 if (!rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
437 vty_out(vty
, " life=%d", lifetime
);
440 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bpi
->type
),
443 vty_out(vty
, "%s", HVTYNL
);
446 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
448 int (*fp
)(void *, const char *, ...);
451 const char *vty_newline
;
455 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
458 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
463 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
464 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
466 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
467 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
468 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
469 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
471 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
472 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
473 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
474 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
475 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
476 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
480 * Print BPI in an Import Table
482 void rfapiPrintBi(void *stream
, struct bgp_path_info
*bpi
)
487 int (*fp
)(void *, const char *, ...);
490 const char *vty_newline
;
496 struct ethaddr macaddr
= {{0}};
497 struct rfapi_l2address_option l2o_buf
;
498 uint8_t l2hid
= 0; /* valid if has_macaddr */
500 #define REMAIN (BUFSIZ - (p-line))
501 #define INCP {p += (r > REMAIN)? REMAIN: r;}
503 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
509 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
510 && bpi
->extra
->vnc
.import
.timer
) {
512 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
513 r
= snprintf(p
, REMAIN
, " [%4lu] ",
514 thread_timer_remain_second(t
));
518 r
= snprintf(p
, REMAIN
, " ");
523 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
524 if (decode_rd_type(bpi
->extra
->vnc
.import
.rd
.val
)
525 == RD_TYPE_VNC_ETH
) {
527 memcpy(macaddr
.octet
, bpi
->extra
->vnc
.import
.rd
.val
+ 2,
529 l2hid
= bpi
->extra
->vnc
.import
.rd
.val
[1];
538 * RFP option sizes (they are opaque values)
539 * extended communities (RTs)
543 int printed_1st_gol
= 0;
544 struct bgp_attr_encap_subtlv
*pEncap
;
545 struct prefix pfx_un
;
546 int af
= BGP_MP_NEXTHOP_FAMILY(bpi
->attr
->mp_nexthop_len
);
550 r
= snprintf(p
, REMAIN
, "%s",
552 &bpi
->attr
->mp_nexthop_global_in
,
555 } else if (af
== AF_INET6
) {
556 r
= snprintf(p
, REMAIN
, "%s",
558 &bpi
->attr
->mp_nexthop_global
,
562 r
= snprintf(p
, REMAIN
, "?");
567 * VNC tunnel subtlv, if present, contains UN address
569 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
570 r
= snprintf(p
, REMAIN
, " un=%s",
571 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
577 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
578 r
= snprintf(p
, REMAIN
, " nolife");
581 if (lifetime
== 0xffffffff)
582 r
= snprintf(p
, REMAIN
, " %6s", "infini");
584 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
588 /* RFP option lengths */
589 for (pEncap
= bpi
->attr
->vnc_subtlvs
; pEncap
;
590 pEncap
= pEncap
->next
) {
592 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
593 if (printed_1st_gol
) {
594 r
= snprintf(p
, REMAIN
, ",");
597 r
= snprintf(p
, REMAIN
,
598 " "); /* leading space */
601 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
608 if (bpi
->attr
->ecommunity
) {
609 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
610 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
611 r
= snprintf(p
, REMAIN
, " %s", s
);
613 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
617 r
= snprintf(p
, REMAIN
, " bpi@%p", bpi
);
620 r
= snprintf(p
, REMAIN
, " p@%p", bpi
->peer
);
623 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
624 r
= snprintf(p
, REMAIN
, " HD=yes");
627 r
= snprintf(p
, REMAIN
, " HD=no");
633 if (bpi
->attr
->weight
) {
634 r
= snprintf(p
, REMAIN
, " W=%d", bpi
->attr
->weight
);
638 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
639 r
= snprintf(p
, REMAIN
, " LP=%d",
640 bpi
->attr
->local_pref
);
643 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
;
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 rfapiGetTunnelType(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
1091 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
;
1101 fp(out
, "%-20s ", buf_pfx
);
1102 fp(out
, "%-15s ", buf_vn
);
1103 fp(out
, "%-15s ", buf_un
);
1104 fp(out
, "%-4d ", cost
);
1107 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1108 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)
1109 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1111 fp(out
, "%-10s ", "infinite");
1113 time_t t_lifetime
= lifetime
;
1114 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1115 fp(out
, "%-10s ", buf_lifetime
);
1118 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
1119 && bpi
->extra
->vnc
.import
.timer
) {
1123 char buf_age
[BUFSIZ
];
1126 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
1127 remaining
= thread_timer_remain_second(t
);
1129 #if RFAPI_REGISTRATIONS_REPORT_AGE
1131 * Calculate when the timer started. Doing so here saves
1132 * us a timestamp field in "struct bgp_path_info".
1134 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1135 * original calculation.
1137 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1139 #else /* report remaining time */
1142 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1144 fp(out
, "%-10s ", buf_age
);
1146 } else if (RFAPI_LOCAL_BI(bpi
)) {
1148 char buf_age
[BUFSIZ
];
1150 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.create_time
) {
1151 rfapiFormatAge(bpi
->extra
->vnc
.import
.create_time
,
1157 fp(out
, "%-10s ", buf_age
);
1159 fp(out
, "%s", HVTYNL
);
1161 if (rn
->p
.family
== AF_ETHERNET
) {
1163 * If there is a corresponding IP address && != VN address,
1164 * print that on the next line
1167 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
1171 bpi
->extra
->vnc
.import
.aux_prefix
.family
,
1172 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1174 buf_ntop
[BUFSIZ
- 1] = 0;
1176 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1177 fp(out
, " IP: %s", sp
);
1183 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bpi
->extra
) {
1184 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1185 if (!MPLS_LABEL_IS_NULL(l
)) {
1186 fp(out
, " Label: %d", l
);
1192 fp(out
, "%s", HVTYNL
);
1197 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1198 struct rfapi_import_table
*it
,
1199 struct prefix
*prefix_only
,
1200 int show_expiring
, /* either/or */
1201 int show_local
, int show_remote
,
1202 int show_imported
, /* either/or */
1203 uint32_t *pLni
) /* AFI_L2VPN only */
1206 int printed_rtlist_hdr
= 0;
1208 int (*fp
)(void *, const char *, ...);
1211 const char *vty_newline
;
1215 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1218 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1220 struct agg_node
*rn
;
1222 if (!it
->imported_vpn
[afi
])
1225 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1226 rn
= agg_route_next(rn
)) {
1228 struct bgp_path_info
*bpi
;
1231 /* allow for wider or more narrow mask from user */
1232 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1233 && !prefix_match(&rn
->p
, prefix_only
))
1238 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
1240 if (!show_local
&& RFAPI_LOCAL_BI(bpi
)) {
1242 /* local route from RFP */
1246 if (!show_remote
&& !RFAPI_LOCAL_BI(bpi
)) {
1253 && !CHECK_FLAG(bpi
->flags
,
1258 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1261 if (bpi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1263 == ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1272 if (count_only
== 1)
1274 if (!printed_rtlist_hdr
) {
1275 const char *agetype
= "";
1277 const char *type
= "";
1278 if (show_imported
) {
1281 if (show_expiring
) {
1293 s
= ecommunity_ecom2str(
1295 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1299 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1300 HVTYNL
, type
, *pLni
,
1301 (*pLni
& 0xfff), s
);
1303 fp(out
, "%s[%s] Prefix RT={%s}",
1306 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1308 if (it
->rfg
&& it
->rfg
->name
) {
1309 fp(out
, " %s \"%s\"",
1310 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1315 fp(out
, "%s", HVTYNL
);
1316 if (show_expiring
) {
1317 #if RFAPI_REGISTRATIONS_REPORT_AGE
1320 agetype
= "Remaining";
1322 } else if (show_local
) {
1326 printed_rtlist_hdr
= 1;
1329 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1330 (pLni
? "L2 Address/IP" : "Prefix"),
1331 "VN Address", "UN Address", "Cost",
1332 "Lifetime", agetype
, HVTYNL
);
1334 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1342 const char *type
= "prefixes";
1344 if (show_imported
) {
1345 type
= "imported prefixes";
1347 if (show_expiring
) {
1348 type
= "prefixes in holddown";
1350 if (show_local
&& !show_remote
) {
1351 type
= "locally registered prefixes";
1352 } else if (!show_local
&& show_remote
) {
1353 type
= "remotely registered prefixes";
1358 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1360 #if DEBUG_SHOW_EXTRA
1361 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1369 * rfapiShowRemoteRegistrations
1371 * Similar to rfapiShowImportTable() above. This function
1372 * is mean to produce the "remote" portion of the output
1373 * of "show vnc registrations".
1375 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1376 int show_expiring
, int show_local
,
1377 int show_remote
, int show_imported
)
1381 struct rfapi_import_table
*it
;
1384 bgp
= bgp_get_default();
1394 for (it
= h
->imports
; it
; it
= it
->next
) {
1395 printed
+= rfapiShowRemoteRegistrationsIt(
1396 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1397 show_remote
, show_imported
, NULL
);
1400 if (h
->import_mac
) {
1401 void *cursor
= NULL
;
1403 uintptr_t lni_as_ptr
;
1407 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1408 (void **)&it
, &cursor
);
1410 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1411 (void **)&it
, &cursor
)) {
1413 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1414 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1418 printed
+= rfapiShowRemoteRegistrationsIt(
1419 bgp
, stream
, it
, prefix_only
, show_expiring
,
1420 show_local
, show_remote
, show_imported
, pLni
);
1427 /*------------------------------------------
1428 * rfapiRfapiIpAddr2Str
1430 * UI helper: generate string from rfapi_ip_addr
1433 * a IP v4/v6 address
1436 * buf put string here
1437 * bufsize max space to write
1440 * NULL conversion failed
1441 * non-NULL pointer to buf
1442 --------------------------------------------*/
1443 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1446 const char *rc
= NULL
;
1448 switch (a
->addr_family
) {
1450 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1453 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1459 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1462 const char *rc
= NULL
;
1464 int (*fp
)(void *, const char *, ...);
1467 const char *vty_newline
;
1469 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1472 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1478 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1481 struct rfapi_ip_addr
*a
= &p
->prefix
;
1482 const char *rc
= NULL
;
1484 switch (a
->addr_family
) {
1486 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1489 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1494 int alen
= strlen(buf
);
1495 int remaining
= bufsize
- alen
- 1;
1498 if (remaining
> 0) {
1499 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1501 if (slen
< remaining
) /* see man page for snprintf(3) */
1509 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1514 int (*fp
)(void *, const char *, ...);
1517 const char *vty_newline
;
1519 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1522 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1525 fp(out
, "%s:%u", buf
, p
->cost
);
1530 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1532 char buf
[RD_ADDRSTRLEN
];
1534 prefix_rd2str(prd
, buf
, sizeof(buf
));
1535 vty_out(vty
, "%s", buf
);
1538 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1539 safi_t safi
, struct prefix
*p
)
1541 afi_t afi
; /* of the VN address */
1542 struct bgp_node
*bn
;
1543 struct bgp_path_info
*bpi
;
1544 uint8_t type
= ZEBRA_ROUTE_BGP
;
1547 struct prefix_rd prd0
;
1548 struct prefix_rd
*prd
;
1551 * Find the bgp_path in the RIB corresponding to this
1555 afi
= family2afi(p
->family
);
1556 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1558 bgp
= bgp_get_default(); /* assume 1 instance for now */
1561 if (safi
== SAFI_ENCAP
) {
1562 memset(&prd0
, 0, sizeof(prd0
));
1563 prd0
.family
= AF_UNSPEC
;
1564 prd0
.prefixlen
= 64;
1569 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1571 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1573 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1574 if (bpi
->peer
== rfd
->peer
&& bpi
->type
== type
1575 && bpi
->sub_type
== BGP_ROUTE_RFP
&& bpi
->extra
1576 && bpi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1578 rfapiPrintBi(vty
, bpi
);
1584 vty_out(vty
, " --?--%s", HVTYNL
);
1589 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1591 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1592 /* RT export list */
1593 /* RT import list */
1594 /* list of advertised prefixes */
1595 /* dump import table */
1601 struct rfapi_adb
*adb
;
1602 char buf
[PREFIX_STRLEN
];
1604 vty_out(vty
, "%-10p ", rfd
);
1605 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1607 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1608 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1609 rfapiPrintRd(vty
, &rfd
->rd
);
1610 vty_out(vty
, " %d", rfd
->response_lifetime
);
1611 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1612 vty_out(vty
, "%s", HVTYNL
);
1614 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1616 /* export RT list */
1617 if (rfd
->rt_export_list
) {
1618 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1619 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1620 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1621 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1623 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1626 /* import RT list */
1627 if (rfd
->import_table
) {
1628 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1629 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1630 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1631 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1633 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1636 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1639 family
= afi2family(afi
);
1644 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1645 (void **)&adb
, &cursor
);
1647 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1648 (void **)&adb
, &cursor
)) {
1650 /* group like family prefixes together in output */
1651 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1654 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1656 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1657 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1658 &adb
->u
.s
.prefix_ip
);
1661 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1662 (void **)&adb
, &cursor
);
1663 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1664 (void **)&adb
, &cursor
)) {
1666 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1668 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1670 /* TBD update the following function to print ethernet info */
1671 /* Also need to pass/use rd */
1672 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1673 &adb
->u
.s
.prefix_ip
);
1675 vty_out(vty
, "%s", HVTYNL
);
1679 * test scripts rely on first line for each nve starting in 1st column,
1680 * leading whitespace for additional detail of that nve
1682 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1683 struct prefix
*un_prefix
)
1687 struct listnode
*ln
;
1688 struct rfapi_descriptor
*rfd
;
1691 bgp
= bgp_get_default(); /* assume 1 instance for now */
1698 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1699 rfd
= listgetdata(ln
);
1704 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1705 if (!prefix_match(vn_prefix
, &pfx
))
1710 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1711 if (!prefix_match(un_prefix
, &pfx
))
1716 /* print column header */
1717 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1718 "un-addr", "vn-addr", "callback", "cookie",
1719 "RD", "lifetime", "group", HVTYNL
);
1721 rfapiPrintDescriptor(vty
, rfd
);
1728 * Parse an address and put into a struct prefix
1730 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1732 if (!str2prefix(str
, p
)) {
1733 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1737 switch (p
->family
) {
1739 if (p
->prefixlen
!= 32) {
1740 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1746 if (p
->prefixlen
!= 128) {
1747 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1753 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1759 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1760 struct rfapi_ip_addr
*hai
)
1765 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1769 hai
->addr_family
= pfx
.family
;
1770 if (pfx
.family
== AF_INET
)
1771 hai
->addr
.v4
= pfx
.u
.prefix4
;
1773 hai
->addr
.v6
= pfx
.u
.prefix6
;
1779 * Note: this function does not flush vty output, so if it is called
1780 * with a stream pointing to a vty, the user will have to type something
1781 * before the callback output shows up
1783 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1785 struct rfapi_next_hop_entry
*nh
;
1788 int (*fp
)(void *, const char *, ...);
1791 const char *vty_newline
;
1793 #define REMAIN (BUFSIZ - (p-line))
1794 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1796 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1799 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1805 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1808 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1809 /* it fit, so count length */
1817 r
= snprintf(p
, REMAIN
, ", un=");
1820 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1821 /* it fit, so count length */
1829 r
= snprintf(p
, REMAIN
, ", vn=");
1832 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1833 /* it fit, so count length */
1842 line
[BUFSIZ
- 1] = 0;
1843 fp(out
, "%s%s", line
, HVTYNL
);
1848 if (nh
->vn_options
) {
1849 struct rfapi_vn_option
*vo
;
1850 char offset
[] = " ";
1852 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1856 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1857 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1858 pbuf
, sizeof(pbuf
));
1860 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1862 (vo
->v
.l2addr
.label
& 0x00ffffff),
1863 (vo
->v
.l2addr
.logical_net_id
1865 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1868 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1869 prefix2str(&vo
->v
.local_nexthop
.addr
,
1870 pbuf
, sizeof(pbuf
));
1871 fp(out
, "%sLNH %s cost=%d%s", offset
,
1872 pbuf
, vo
->v
.local_nexthop
.cost
,
1878 "%svn option type %d (unknown)%s",
1879 offset
, vo
->type
, HVTYNL
);
1884 if (nh
->un_options
) {
1885 struct rfapi_un_option
*uo
;
1886 char offset
[] = " ";
1888 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1890 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1891 rfapi_print_tunneltype_option(
1892 stream
, 8, &uo
->v
.tunnel
);
1895 fp(out
, "%sUN Option type %d%s", offset
,
1896 uo
->type
, vty_newline
);
1904 /***********************************************************************
1906 ***********************************************************************/
1909 * Add another nexthop to the NHL
1911 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1912 struct rfapi_ip_addr
*vn_addr
,
1913 struct rfapi_ip_prefix
*rprefix
,
1915 uint32_t lifetime
, /* add only */
1916 struct rfapi_vn_option
*vn_options
,
1917 struct rfapi_next_hop_entry
**head
,
1918 struct rfapi_next_hop_entry
**tail
)
1920 struct rfapi_next_hop_entry
*new;
1926 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1927 new->prefix
= *rprefix
;
1928 new->un_address
= *un_addr
;
1929 new->vn_address
= *vn_addr
;
1931 new->vn_options
= vn_options
;
1933 new->lifetime
= lifetime
;
1935 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1939 (*tail
)->next
= new;
1948 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1949 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1950 struct cmd_token
*carg_cost
, /* optional */
1951 struct cmd_token
*carg_lifetime
, /* optional */
1952 struct cmd_token
*carg_macaddr
, /* optional */
1954 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1955 int argc
, struct cmd_token
**argv
)
1957 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1958 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1959 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1960 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1961 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1962 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1963 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1964 struct rfapi_ip_addr vn_address
;
1965 struct rfapi_ip_addr un_address
;
1967 struct rfapi_ip_prefix rpfx
;
1972 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1973 struct rfapi_vn_option
*opt
= NULL
;
1976 int rc
= CMD_WARNING_CONFIG_FAILED
;
1980 struct rfapi_cfg
*rfapi_cfg
;
1982 const char *arg_lnh
= NULL
;
1983 const char *arg_lnh_cost
= NULL
;
1985 bgp
= bgp_get_default(); /* assume 1 instance for now */
1988 vty_out(vty
, "BGP not configured\n");
1989 return CMD_WARNING_CONFIG_FAILED
;
1993 rfapi_cfg
= bgp
->rfapi_cfg
;
1994 if (!h
|| !rfapi_cfg
) {
1996 vty_out(vty
, "RFAPI not configured\n");
1997 return CMD_WARNING_CONFIG_FAILED
;
2000 for (; argc
; --argc
, ++argv
) {
2001 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2004 "local-next-hop specified more than once\n");
2005 return CMD_WARNING_CONFIG_FAILED
;
2009 "Missing parameter for local-next-hop\n");
2010 return CMD_WARNING_CONFIG_FAILED
;
2014 arg_lnh
= argv
[0]->arg
;
2016 if (strmatch(argv
[0]->text
, "local-cost")) {
2019 "local-cost specified more than once\n");
2020 return CMD_WARNING_CONFIG_FAILED
;
2024 "Missing parameter for local-cost\n");
2025 return CMD_WARNING_CONFIG_FAILED
;
2029 arg_lnh_cost
= argv
[0]->arg
;
2033 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2035 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2038 /* arg_prefix is optional if mac address is given */
2039 if (arg_macaddr
&& !arg_prefix
) {
2041 * fake up a 0/32 or 0/128 prefix
2043 switch (vn_address
.addr_family
) {
2045 arg_prefix
= "0.0.0.0/32";
2048 arg_prefix
= "0::0/128";
2052 "Internal error, unknown VN address family\n");
2053 return CMD_WARNING_CONFIG_FAILED
;
2057 if (!str2prefix(arg_prefix
, &pfx
)) {
2058 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2061 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2062 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2068 memset(optary
, 0, sizeof(optary
));
2072 cost
= strtoul(arg_cost
, &endptr
, 10);
2073 if (*endptr
!= '\0' || cost
> 255) {
2074 vty_out(vty
, "%% Invalid %s value\n", "cost");
2082 if (!strcmp(arg_lifetime
, "infinite")) {
2083 lifetime
= RFAPI_INFINITE_LIFETIME
;
2086 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2087 if (*endptr
!= '\0') {
2088 vty_out(vty
, "%% Invalid %s value\n",
2094 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2100 "%% %s may only be specified with local-next-hop\n",
2105 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2106 if (*endptr
!= '\0' || lnh_cost
> 255) {
2107 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2117 "%% %s may only be specified with prefix\n",
2121 if ((rc
= rfapiCliGetPrefixAddr(
2123 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2128 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2129 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2132 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2139 if (arg_vni
&& !arg_macaddr
) {
2140 vty_out(vty
, "%% %s may only be specified with mac address\n",
2141 "virtual-network-identifier");
2148 "Missing \"vni\" parameter (mandatory with mac)\n");
2149 return CMD_WARNING_CONFIG_FAILED
;
2151 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2152 strtoul(arg_vni
, NULL
, 10);
2154 if ((rc
= rfapiStr2EthAddr(
2156 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2157 vty_out(vty
, "Invalid %s value\n", "mac address");
2160 /* TBD label, NVE ID */
2162 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2165 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2172 vnc_zlog_debug_verbose(
2173 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2174 __func__
, arg_vn
, arg_un
, arg_prefix
,
2175 (arg_cost
? arg_cost
: "NULL"),
2176 (arg_lifetime
? arg_lifetime
: "NULL"),
2177 (arg_lnh
? arg_lnh
: "NULL"));
2179 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2181 rpfx
.cost
= cost
& 255;
2183 /* look up rf descriptor, call open if it doesn't exist */
2184 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2185 (struct rfapi_descriptor
**)&rfd
);
2188 struct rfapi_un_option uo
;
2191 * flag descriptor as provisionally opened for static
2193 * registration so that we can fix up the other
2195 * when the real open comes along
2197 memset(&uo
, 0, sizeof(uo
));
2198 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2200 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2201 &vn_address
, &un_address
,
2203 NULL
, NULL
, /* no userdata */
2207 "Can't open session for this NVE: %s\n",
2208 rfapi_error_str(rc
));
2209 rc
= CMD_WARNING_CONFIG_FAILED
;
2213 vty_out(vty
, "Can't find session for this NVE: %s\n",
2214 rfapi_error_str(rc
));
2219 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2220 RFAPI_REGISTER_ADD
);
2222 struct rfapi_next_hop_entry
*head
= NULL
;
2223 struct rfapi_next_hop_entry
*tail
= NULL
;
2224 struct rfapi_vn_option
*vn_opt_new
;
2226 vnc_zlog_debug_verbose(
2227 "%s: rfapi_register succeeded, returning 0", __func__
);
2229 if (h
->rfp_methods
.local_cb
) {
2230 struct rfapi_descriptor
*r
=
2231 (struct rfapi_descriptor
*)rfd
;
2232 vn_opt_new
= rfapi_vn_options_dup(opt
);
2234 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2236 vn_opt_new
, &head
, &tail
);
2238 h
->flags
|= RFAPI_INCALLBACK
;
2239 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2240 h
->flags
&= ~RFAPI_INCALLBACK
;
2247 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2249 vty_out(vty
, "Registration failed.\n");
2251 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2252 return CMD_WARNING_CONFIG_FAILED
;
2255 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2259 /************************************************************************
2260 * Add prefix With LNH_OPTIONS...
2261 ************************************************************************/
2262 DEFUN (add_vnc_prefix_cost_life_lnh
,
2263 add_vnc_prefix_cost_life_lnh_cmd
,
2264 "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...",
2265 "Add registration\n"
2267 "Add/modify prefix related information\n"
2270 "VN address of NVE\n"
2271 "VN IPv4 interface address\n"
2272 "VN IPv6 interface address\n"
2273 "UN address of NVE\n"
2274 "UN IPv4 interface address\n"
2275 "UN IPv6 interface address\n"
2276 "Administrative cost [default: 255]\n"
2277 "Administrative cost\n"
2278 "Registration lifetime [default: infinite]\n"
2279 "Lifetime value in seconds\n"
2280 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2282 /* pfx vn un cost life */
2283 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2285 NULL
, NULL
, argc
- 12, argv
+ 12);
2288 DEFUN (add_vnc_prefix_life_cost_lnh
,
2289 add_vnc_prefix_life_cost_lnh_cmd
,
2290 "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...",
2291 "Add registration\n"
2293 "Add/modify prefix related information\n"
2296 "VN address of NVE\n"
2297 "VN IPv4 interface address\n"
2298 "VN IPv6 interface address\n"
2299 "UN address of NVE\n"
2300 "UN IPv4 interface address\n"
2301 "UN IPv6 interface address\n"
2302 "Registration lifetime [default: infinite]\n"
2303 "Lifetime value in seconds\n"
2304 "Administrative cost [default: 255]\n"
2305 "Administrative cost\n"
2306 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2308 /* pfx vn un cost life */
2309 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2311 NULL
, NULL
, argc
- 12, argv
+ 12);
2314 DEFUN (add_vnc_prefix_cost_lnh
,
2315 add_vnc_prefix_cost_lnh_cmd
,
2316 "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...",
2317 "Add registration\n"
2319 "Add/modify prefix related information\n"
2322 "VN address of NVE\n"
2323 "VN IPv4 interface address\n"
2324 "VN IPv6 interface address\n"
2325 "UN address of NVE\n"
2326 "UN IPv4 interface address\n"
2327 "UN IPv6 interface address\n"
2328 "Administrative cost [default: 255]\n"
2329 "Administrative cost\n"
2330 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2332 /* pfx vn un cost life */
2333 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2335 NULL
, NULL
, argc
- 10, argv
+ 10);
2338 DEFUN (add_vnc_prefix_life_lnh
,
2339 add_vnc_prefix_life_lnh_cmd
,
2340 "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...",
2341 "Add registration\n"
2343 "Add/modify prefix related information\n"
2346 "VN address of NVE\n"
2347 "VN IPv4 interface address\n"
2348 "VN IPv6 interface address\n"
2349 "UN address of NVE\n"
2350 "UN IPv4 interface address\n"
2351 "UN IPv6 interface address\n"
2352 "Registration lifetime [default: infinite]\n"
2353 "Lifetime value in seconds\n"
2354 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2356 /* pfx vn un cost life */
2357 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2359 NULL
, NULL
, argc
- 10, argv
+ 10);
2362 DEFUN (add_vnc_prefix_lnh
,
2363 add_vnc_prefix_lnh_cmd
,
2364 "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...",
2365 "Add registration\n"
2367 "Add/modify prefix related information\n"
2370 "VN address of NVE\n"
2371 "VN IPv4 interface address\n"
2372 "VN IPv6 interface address\n"
2373 "UN address of NVE\n"
2374 "UN IPv4 interface address\n"
2375 "UN IPv6 interface address\n"
2376 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2378 /* pfx vn un cost life */
2379 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2381 NULL
, NULL
, argc
- 8, argv
+ 8);
2384 /************************************************************************
2385 * Add prefix Without LNH_OPTIONS...
2386 ************************************************************************/
2387 DEFUN (add_vnc_prefix_cost_life
,
2388 add_vnc_prefix_cost_life_cmd
,
2389 "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)",
2390 "Add registration\n"
2392 "Add/modify prefix related information\n"
2395 "VN address of NVE\n"
2396 "VN IPv4 interface address\n"
2397 "VN IPv6 interface address\n"
2398 "UN address of NVE\n"
2399 "UN IPv4 interface address\n"
2400 "UN IPv6 interface address\n"
2401 "Administrative cost [default: 255]\n"
2402 "Administrative cost\n"
2403 "Registration lifetime [default: infinite]\n"
2404 "Lifetime value in seconds\n")
2406 /* pfx vn un cost life */
2407 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2409 NULL
, NULL
, 0, NULL
);
2412 DEFUN (add_vnc_prefix_life_cost
,
2413 add_vnc_prefix_life_cost_cmd
,
2414 "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)",
2415 "Add registration\n"
2417 "Add/modify prefix related information\n"
2420 "VN address of NVE\n"
2421 "VN IPv4 interface address\n"
2422 "VN IPv6 interface address\n"
2423 "UN address of NVE\n"
2424 "UN IPv4 interface address\n"
2425 "UN IPv6 interface address\n"
2426 "Registration lifetime [default: infinite]\n"
2427 "Lifetime value in seconds\n"
2428 "Administrative cost [default: 255]\n"
2429 "Administrative cost\n")
2431 /* pfx vn un cost life */
2432 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2434 NULL
, NULL
, 0, NULL
);
2437 DEFUN (add_vnc_prefix_cost
,
2438 add_vnc_prefix_cost_cmd
,
2439 "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)",
2440 "Add registration\n"
2442 "Add/modify prefix related information\n"
2445 "VN address of NVE\n"
2446 "VN IPv4 interface address\n"
2447 "VN IPv6 interface address\n"
2448 "UN address of NVE\n"
2449 "UN IPv4 interface address\n"
2450 "UN IPv6 interface address\n"
2451 "Administrative cost [default: 255]\n"
2452 "Administrative cost\n")
2454 /* pfx vn un cost life */
2455 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2457 NULL
, NULL
, 0, NULL
);
2460 DEFUN (add_vnc_prefix_life
,
2461 add_vnc_prefix_life_cmd
,
2462 "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)",
2463 "Add registration\n"
2465 "Add/modify prefix related information\n"
2468 "VN address of NVE\n"
2469 "VN IPv4 interface address\n"
2470 "VN IPv6 interface address\n"
2471 "UN address of NVE\n"
2472 "UN IPv4 interface address\n"
2473 "UN IPv6 interface address\n"
2474 "Registration lifetime [default: infinite]\n"
2475 "Lifetime value in seconds\n")
2477 /* pfx vn un cost life */
2478 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2480 NULL
, NULL
, 0, NULL
);
2483 DEFUN (add_vnc_prefix
,
2485 "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>",
2486 "Add registration\n"
2488 "Add/modify prefix related information\n"
2491 "VN address of NVE\n"
2492 "VN IPv4 interface address\n"
2493 "VN IPv6 interface address\n"
2494 "UN address of NVE\n"
2495 "UN IPv4 interface address\n"
2496 "UN IPv6 interface address\n")
2498 /* pfx vn un cost life */
2499 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2501 NULL
, NULL
, 0, NULL
);
2504 /************************************************************************
2505 * Mac address registrations
2506 ************************************************************************/
2507 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2508 add_vnc_mac_vni_prefix_cost_life_cmd
,
2509 "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)",
2510 "Add registration\n"
2512 "Add/modify mac address information\n"
2514 "Virtual Network Identifier follows\n"
2515 "Virtual Network Identifier\n"
2516 "VN address of NVE\n"
2517 "VN IPv4 interface address\n"
2518 "VN IPv6 interface address\n"
2519 "UN address of NVE\n"
2520 "UN IPv4 interface address\n"
2521 "UN IPv6 interface address\n"
2522 "Add/modify prefix related information\n"
2525 "Administrative cost [default: 255]\n"
2526 "Administrative cost\n"
2527 "Registration lifetime [default: infinite]\n"
2528 "Lifetime value in seconds\n")
2530 /* pfx vn un cost life */
2531 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2533 argv
[3], argv
[5], 0, NULL
);
2537 DEFUN (add_vnc_mac_vni_prefix_life
,
2538 add_vnc_mac_vni_prefix_life_cmd
,
2539 "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)",
2540 "Add registration\n"
2542 "Add/modify mac address information\n"
2544 "Virtual Network Identifier follows\n"
2545 "Virtual Network Identifier\n"
2546 "VN address of NVE\n"
2547 "VN IPv4 interface address\n"
2548 "VN IPv6 interface address\n"
2549 "UN address of NVE\n"
2550 "UN IPv4 interface address\n"
2551 "UN IPv6 interface address\n"
2552 "Add/modify prefix related information\n"
2555 "Registration lifetime [default: infinite]\n"
2556 "Lifetime value in seconds\n")
2558 /* pfx vn un cost life */
2559 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2561 argv
[3], argv
[5], 0, NULL
);
2564 DEFUN (add_vnc_mac_vni_prefix_cost
,
2565 add_vnc_mac_vni_prefix_cost_cmd
,
2566 "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)",
2567 "Add registration\n"
2569 "Add/modify mac address information\n"
2571 "Virtual Network Identifier follows\n"
2572 "Virtual Network Identifier\n"
2573 "VN address of NVE\n"
2574 "VN IPv4 interface address\n"
2575 "VN IPv6 interface address\n"
2576 "UN address of NVE\n"
2577 "UN IPv4 interface address\n"
2578 "UN IPv6 interface address\n"
2579 "Add/modify prefix related information\n"
2582 "Administrative cost [default: 255]\n" "Administrative cost\n")
2584 /* pfx vn un cost life */
2585 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2587 argv
[3], argv
[5], 0, NULL
);
2590 DEFUN (add_vnc_mac_vni_prefix
,
2591 add_vnc_mac_vni_prefix_cmd
,
2592 "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>",
2593 "Add registration\n"
2595 "Add/modify mac address information\n"
2597 "Virtual Network Identifier follows\n"
2598 "Virtual Network Identifier\n"
2599 "VN address of NVE\n"
2600 "VN IPv4 interface address\n"
2601 "VN IPv6 interface address\n"
2602 "UN address of NVE\n"
2603 "UN IPv4 interface address\n"
2604 "UN IPv6 interface address\n"
2605 "Add/modify prefix related information\n"
2606 "IPv4 prefix\n" "IPv6 prefix\n")
2608 /* pfx vn un cost life */
2609 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2611 argv
[3], argv
[5], 0, NULL
);
2614 DEFUN (add_vnc_mac_vni_cost_life
,
2615 add_vnc_mac_vni_cost_life_cmd
,
2616 "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)",
2617 "Add registration\n"
2619 "Add/modify mac address information\n"
2621 "Virtual Network Identifier follows\n"
2622 "Virtual Network Identifier\n"
2623 "VN address of NVE\n"
2624 "VN IPv4 interface address\n"
2625 "VN IPv6 interface address\n"
2626 "UN address of NVE\n"
2627 "UN IPv4 interface address\n"
2628 "UN IPv6 interface address\n"
2629 "Administrative cost [default: 255]\n"
2630 "Administrative cost\n"
2631 "Registration lifetime [default: infinite]\n"
2632 "Lifetime value in seconds\n")
2634 /* pfx vn un cost life */
2635 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2637 argv
[3], argv
[5], 0, NULL
);
2641 DEFUN (add_vnc_mac_vni_cost
,
2642 add_vnc_mac_vni_cost_cmd
,
2643 "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)",
2644 "Add registration\n"
2646 "Add/modify mac address information\n"
2648 "Virtual Network Identifier follows\n"
2649 "Virtual Network Identifier\n"
2650 "VN address of NVE\n"
2651 "VN IPv4 interface address\n"
2652 "VN IPv6 interface address\n"
2653 "UN address of NVE\n"
2654 "UN IPv4 interface address\n"
2655 "UN IPv6 interface address\n"
2656 "Administrative cost [default: 255]\n" "Administrative cost\n")
2658 /* pfx vn un cost life */
2659 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2661 argv
[3], argv
[5], 0, NULL
);
2665 DEFUN (add_vnc_mac_vni_life
,
2666 add_vnc_mac_vni_life_cmd
,
2667 "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)",
2668 "Add registration\n"
2670 "Add/modify mac address information\n"
2672 "Virtual Network Identifier follows\n"
2673 "Virtual Network Identifier\n"
2674 "VN address of NVE\n"
2675 "VN IPv4 interface address\n"
2676 "VN IPv6 interface address\n"
2677 "UN address of NVE\n"
2678 "UN IPv4 interface address\n"
2679 "UN IPv6 interface address\n"
2680 "Registration lifetime [default: infinite]\n"
2681 "Lifetime value in seconds\n")
2683 /* pfx vn un cost life */
2684 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2686 argv
[3], argv
[5], 0, NULL
);
2690 DEFUN (add_vnc_mac_vni
,
2691 add_vnc_mac_vni_cmd
,
2692 "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>",
2693 "Add registration\n"
2695 "Add/modify mac address information\n"
2697 "Virtual Network Identifier follows\n"
2698 "Virtual Network Identifier\n"
2699 "VN address of NVE\n"
2700 "VN IPv4 interface address\n"
2701 "VN IPv6 interface address\n"
2702 "UN address of NVE\n"
2703 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2705 /* pfx vn un cost life */
2706 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2708 argv
[3], argv
[5], 0, NULL
);
2711 /************************************************************************
2713 ************************************************************************/
2715 struct rfapi_local_reg_delete_arg
{
2720 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2721 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2722 struct prefix prefix
; /* AF==0: wildcard */
2723 struct prefix_rd rd
; /* plen!=64: wildcard */
2724 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2726 struct rfapi_l2address_option_match l2o
;
2734 uint32_t query_count
;
2736 uint32_t failed_pfx_count
;
2739 struct skiplist
*nves
;
2741 uint32_t remote_active_nve_count
;
2742 uint32_t remote_active_pfx_count
;
2743 uint32_t remote_holddown_nve_count
;
2744 uint32_t remote_holddown_pfx_count
;
2748 struct rfapi_ip_addr vn
;
2749 struct rfapi_ip_addr un
;
2750 struct rfapi_descriptor
*rfd
;
2751 struct rfapi_local_reg_delete_arg
*cda
;
2754 static void nve_addr_free(void *hap
)
2756 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2757 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2760 static int nve_addr_cmp(void *k1
, void *k2
)
2762 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2763 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2769 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2770 return (a
->un
.addr_family
- b
->un
.addr_family
);
2772 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2773 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2775 if (a
->un
.addr_family
== AF_INET
) {
2776 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2780 } else if (a
->un
.addr_family
== AF_INET6
) {
2781 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2788 if (a
->vn
.addr_family
== AF_INET
) {
2789 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2792 } else if (a
->vn
.addr_family
== AF_INET6
) {
2793 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2803 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2804 const char *arg_prefix
, const char *arg_vn
,
2805 const char *arg_un
, const char *arg_l2addr
,
2806 const char *arg_vni
, const char *arg_rd
,
2807 struct rfapi_nve_group_cfg
*arg_rfg
,
2808 struct rfapi_local_reg_delete_arg
*rcdarg
)
2810 int rc
= CMD_WARNING
;
2812 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2816 bgp
= bgp_get_default();
2818 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2820 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2821 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2822 &rcdarg
->vn_address
)))
2825 if (arg_un
&& strcmp(arg_un
, "*")) {
2826 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2827 &rcdarg
->un_address
)))
2830 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2832 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2833 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2840 vty_out(vty
, "Missing VNI\n");
2843 if (strcmp(arg_l2addr
, "*")) {
2844 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2845 &rcdarg
->l2o
.o
.macaddr
))) {
2846 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2850 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2852 if (strcmp(arg_vni
, "*")) {
2853 rcdarg
->l2o
.o
.logical_net_id
=
2854 strtoul(arg_vni
, NULL
, 10);
2855 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2859 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2860 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2869 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2870 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2871 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2872 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2873 struct rfapi_nve_group_cfg
*arg_rfg
,
2874 struct rfapi_local_reg_delete_arg
*rcdarg
)
2876 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2877 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2878 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2879 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2880 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2881 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2882 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2883 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2886 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2887 struct rfapi_ip_addr
*un_address
,
2888 struct rfapi_ip_addr
*vn_address
,
2889 struct rfapi_descriptor
*rfd
)
2892 struct nve_addr
*hap
;
2894 memset(&ha
, 0, sizeof(ha
));
2895 ha
.un
= *un_address
;
2896 ha
.vn
= *vn_address
;
2900 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2902 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2903 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2907 skiplist_insert(cda
->nves
, hap
, hap
);
2911 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2914 struct rfapi_descriptor
*rfd
;
2915 int query_count
= 0;
2916 struct listnode
*node
;
2917 struct bgp
*bgp_default
= bgp_get_default();
2919 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2923 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2924 &cda
->un_address
, &rfd
))
2928 rfapi_query_done_all(rfd
, &query_count
);
2929 cda
->query_count
+= query_count
;
2932 * Track unique nves seen
2934 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2945 h
= bgp_default
->rfapi
;
2950 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2952 * match un, vn addresses of NVEs
2954 if (cda
->un_address
.addr_family
2955 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2958 if (cda
->vn_address
.addr_family
2959 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2965 rfapi_query_done_all(rfd
, &query_count
);
2966 cda
->query_count
+= query_count
;
2969 * Track unique nves seen
2971 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2976 * TBD need to count deleted prefixes and nves?
2978 * ENXIO BGP or VNC not configured
2980 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2981 struct rfapi_descriptor
*rfd
)
2983 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2984 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2985 struct prefix
*pPrefix
; /* NULL = wildcard */
2986 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2988 struct rfapi_ip_prefix rprefix
;
2989 struct rfapi_next_hop_entry
*head
= NULL
;
2990 struct rfapi_next_hop_entry
*tail
= NULL
;
2993 vnc_zlog_debug_verbose("%s: entry", __func__
);
2996 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2997 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2998 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2999 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
3002 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3005 do /* to preserve old code structure */
3007 struct rfapi
*h
= cda
->bgp
->rfapi
;
3009 struct rfapi_adb
*adb
;
3011 int deleted_from_this_nve
;
3013 struct nve_addr
*hap
;
3016 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3020 * match un, vn addresses of NVEs
3022 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3024 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3028 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3035 deleted_from_this_nve
= 0;
3038 struct skiplist
*sl
;
3039 struct rfapi_ip_prefix rp
;
3041 struct list
*adb_delete_list
;
3044 * The advertisements are stored in a skiplist.
3046 * the registration deletes the advertisement from the
3047 * skiplist, which we can't do while iterating over that
3048 * same skiplist using the current skiplist API.
3050 * Strategy: iterate over the skiplist and build another
3051 * list containing only the matching ADBs. Then delete
3052 * _everything_ in that second list (which can be done
3053 * using either skiplists or quagga linklists).
3055 adb_delete_list
= list_new();
3058 * Advertised IP prefixes (not 0/32 or 0/128)
3060 sl
= rfd
->advertised
.ipN_by_prefix
;
3063 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3065 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3069 if (!prefix_same(pPrefix
,
3070 &adb
->u
.s
.prefix_ip
)) {
3072 vnc_zlog_debug_verbose(
3073 "%s: adb=%p, prefix doesn't match, skipping",
3080 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3084 vnc_zlog_debug_verbose(
3085 "%s: adb=%p, RD doesn't match, skipping",
3091 if (CHECK_FLAG(cda
->l2o
.flags
,
3092 RFAPI_L2O_MACADDR
)) {
3093 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3094 adb
->u
.s
.prefix_eth
.u
3098 vnc_zlog_debug_verbose(
3099 "%s: adb=%p, macaddr doesn't match, skipping",
3106 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3107 if (cda
->l2o
.o
.logical_net_id
3108 != adb
->l2o
.logical_net_id
) {
3110 vnc_zlog_debug_verbose(
3111 "%s: adb=%p, LNI doesn't match, skipping",
3119 vnc_zlog_debug_verbose(
3120 "%s: ipN adding adb %p to delete list",
3124 listnode_add(adb_delete_list
, adb
);
3127 struct listnode
*node
;
3129 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3130 int this_advertisement_prefix_count
;
3131 struct rfapi_vn_option optary
[3];
3132 struct rfapi_vn_option
*opt
= NULL
;
3135 this_advertisement_prefix_count
= 1;
3137 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3139 memset(optary
, 0, sizeof(optary
));
3141 /* if mac addr present in advert, make l2o vn
3143 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3145 opt
->next
= &optary
[cur_opt
];
3146 opt
= &optary
[cur_opt
++];
3147 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3148 opt
->v
.l2addr
.macaddr
=
3149 adb
->u
.s
.prefix_eth
.u
3151 ++this_advertisement_prefix_count
;
3154 * use saved RD value instead of trying to
3156 * complex RD computation in rfapi_register()
3159 opt
->next
= &optary
[cur_opt
];
3160 opt
= &optary
[cur_opt
++];
3161 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3162 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3165 vnc_zlog_debug_verbose(
3166 "%s: ipN killing reg from adb %p ",
3170 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3171 (cur_opt
? optary
: NULL
),
3172 RFAPI_REGISTER_KILL
);
3175 this_advertisement_prefix_count
;
3176 cda
->reg_count
+= 1;
3177 deleted_from_this_nve
= 1;
3179 if (h
->rfp_methods
.local_cb
) {
3180 rfapiAddDeleteLocalRfpPrefix(
3181 &rfd
->un_addr
, &rfd
->vn_addr
,
3182 &rp
, 0, 0, NULL
, &head
, &tail
);
3185 list_delete_all_node(adb_delete_list
);
3187 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3189 * Caller didn't specify a prefix, or specified
3194 * Advertised 0/32 and 0/128 (indexed by
3197 sl
= rfd
->advertised
.ip0_by_ether
;
3200 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3203 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3206 if (CHECK_FLAG(cda
->l2o
.flags
,
3207 RFAPI_L2O_MACADDR
)) {
3208 if (memcmp(cda
->l2o
.o
.macaddr
3210 adb
->u
.s
.prefix_eth
.u
3218 if (CHECK_FLAG(cda
->l2o
.flags
,
3220 if (cda
->l2o
.o
.logical_net_id
3221 != adb
->l2o
.logical_net_id
) {
3226 vnc_zlog_debug_verbose(
3227 "%s: ip0 adding adb %p to delete list",
3230 listnode_add(adb_delete_list
, adb
);
3234 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3237 struct rfapi_vn_option vn
;
3239 rfapiQprefix2Rprefix(
3240 &adb
->u
.s
.prefix_ip
, &rp
);
3242 memset(&vn
, 0, sizeof(vn
));
3243 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3244 vn
.v
.l2addr
= adb
->l2o
;
3247 vnc_zlog_debug_verbose(
3248 "%s: ip0 killing reg from adb %p ",
3252 rc
= rfapi_register(
3253 rfd
, &rp
, 0, NULL
, &vn
,
3254 RFAPI_REGISTER_KILL
);
3256 cda
->pfx_count
+= 1;
3257 cda
->reg_count
+= 1;
3258 deleted_from_this_nve
= 1;
3260 if (h
->rfp_methods
.local_cb
) {
3261 struct rfapi_vn_option
3265 rfapi_vn_options_dup(
3267 rfapiAddDeleteLocalRfpPrefix(
3269 &rfd
->vn_addr
, &rp
, 0,
3270 0, vn_opt_new
, &head
,
3274 list_delete_all_node(adb_delete_list
);
3276 list_delete(&adb_delete_list
);
3280 if (head
) { /* should not be set if (NULL ==
3281 rfapi_cfg->local_cb) */
3282 h
->flags
|= RFAPI_INCALLBACK
;
3283 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3284 h
->flags
&= ~RFAPI_INCALLBACK
;
3288 if (deleted_from_this_nve
) {
3290 * track unique NVEs seen
3292 memset(&ha
, 0, sizeof(ha
));
3293 ha
.un
= rfd
->un_addr
;
3294 ha
.vn
= rfd
->vn_addr
;
3297 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3299 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3300 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3301 sizeof(struct nve_addr
));
3305 skiplist_insert(cda
->nves
, hap
, hap
);
3308 } while (0); /* to preserve old code structure */
3313 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3318 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3319 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3321 struct bgp
*bgp
= cda
->bgp
;
3323 struct rfapi_cfg
*rfapi_cfg
;
3325 struct listnode
*node
;
3326 struct rfapi_descriptor
*rfd
;
3330 rfapi_cfg
= bgp
->rfapi_cfg
;
3331 if (!h
|| !rfapi_cfg
)
3333 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3335 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3336 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3345 * Deletes local and remote prefixes that match
3347 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3349 struct prefix pfx_un
;
3350 struct prefix pfx_vn
;
3352 struct prefix
*pUN
= NULL
;
3353 struct prefix
*pVN
= NULL
;
3354 struct prefix
*pPrefix
= NULL
;
3356 struct rfapi_import_table
*it
= NULL
;
3359 * Delete matching remote prefixes in holddown
3361 if (cda
->vn_address
.addr_family
) {
3362 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3365 if (cda
->un_address
.addr_family
) {
3366 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3369 if (cda
->prefix
.family
) {
3370 pPrefix
= &cda
->prefix
;
3373 it
= cda
->rfg
->rfapi_import_table
;
3375 rfapiDeleteRemotePrefixes(
3376 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3377 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3378 &cda
->remote_holddown_nve_count
);
3381 * Now do local prefixes
3383 rfapiDeleteLocalPrefixes(cda
);
3386 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3388 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3390 /* Our special element-deleting function counts nves */
3392 skiplist_free(cda
->nves
);
3395 if (cda
->failed_pfx_count
)
3396 vty_out(vty
, "Failed to delete %d prefixes\n",
3397 cda
->failed_pfx_count
);
3399 /* left as "prefixes" even in single case for ease of machine parsing */
3401 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3402 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3406 * We don't currently allow deletion of active remote prefixes from
3410 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3411 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3415 * Caller has already deleted registrations and queries for this/these
3416 * NVEs. Now we just have to close their descriptors.
3418 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3420 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3421 struct nve_addr
*pKey
;
3422 struct nve_addr
*pValue
;
3423 void *cursor
= NULL
;
3429 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3430 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3434 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3435 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3436 rfapi_close(pValue
->rfd
);
3441 DEFUN (clear_vnc_nve_all
,
3442 clear_vnc_nve_all_cmd
,
3446 "Clear per NVE information\n"
3450 struct rfapi_local_reg_delete_arg cda
;
3453 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3459 clear_vnc_responses(&cda
);
3460 clear_vnc_prefix(&cda
);
3461 clear_vnc_nve_closer(&cda
);
3463 print_cleared_stats(&cda
);
3468 DEFUN (clear_vnc_nve_vn_un
,
3469 clear_vnc_nve_vn_un_cmd
,
3470 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3473 "Clear prefix registration information\n"
3474 "VN address of NVE\n"
3476 "VN IPv4 interface address\n"
3477 "VN IPv6 interface address\n"
3478 "UN address of NVE\n"
3479 "For all UN addresses\n"
3480 "UN IPv4 interface address\n"
3481 "UN IPv6 interface address\n")
3483 struct rfapi_local_reg_delete_arg cda
;
3486 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3487 NULL
, NULL
, NULL
, &cda
)))
3492 clear_vnc_responses(&cda
);
3493 clear_vnc_prefix(&cda
);
3494 clear_vnc_nve_closer(&cda
);
3496 print_cleared_stats(&cda
);
3501 DEFUN (clear_vnc_nve_un_vn
,
3502 clear_vnc_nve_un_vn_cmd
,
3503 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3506 "Clear prefix registration information\n"
3507 "UN address of NVE\n"
3509 "UN IPv4 interface address\n"
3510 "UN IPv6 interface address\n"
3511 "VN address of NVE\n"
3513 "VN IPv4 interface address\n"
3514 "VN IPv6 interface address\n")
3516 struct rfapi_local_reg_delete_arg cda
;
3519 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3520 NULL
, NULL
, NULL
, &cda
)))
3525 clear_vnc_responses(&cda
);
3526 clear_vnc_prefix(&cda
);
3527 clear_vnc_nve_closer(&cda
);
3529 print_cleared_stats(&cda
);
3534 DEFUN (clear_vnc_nve_vn
,
3535 clear_vnc_nve_vn_cmd
,
3536 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3539 "Clear prefix registration information\n"
3540 "VN address of NVE\n"
3542 "VN IPv4 interface address\n"
3543 "VN IPv6 interface address\n")
3545 struct rfapi_local_reg_delete_arg cda
;
3548 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3549 NULL
, NULL
, NULL
, &cda
)))
3554 clear_vnc_responses(&cda
);
3555 clear_vnc_prefix(&cda
);
3556 clear_vnc_nve_closer(&cda
);
3558 print_cleared_stats(&cda
);
3562 DEFUN (clear_vnc_nve_un
,
3563 clear_vnc_nve_un_cmd
,
3564 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3567 "Clear prefix registration information\n"
3568 "UN address of NVE\n"
3570 "UN IPv4 interface address\n"
3571 "UN IPv6 interface address\n")
3573 struct rfapi_local_reg_delete_arg cda
;
3576 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3577 NULL
, NULL
, NULL
, &cda
)))
3582 clear_vnc_responses(&cda
);
3583 clear_vnc_prefix(&cda
);
3584 clear_vnc_nve_closer(&cda
);
3586 print_cleared_stats(&cda
);
3590 /*-------------------------------------------------
3592 *-------------------------------------------------*/
3595 * This function is defined in this file (rather than in rfp_registration.c)
3596 * because here we have access to all the task handles.
3598 DEFUN (clear_vnc_prefix_vn_un
,
3599 clear_vnc_prefix_vn_un_cmd
,
3600 "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>",
3603 "Clear prefix registration information\n"
3607 "VN address of NVE\n"
3608 "All VN addresses\n"
3609 "VN IPv4 interface address\n"
3610 "VN IPv6 interface address\n"
3611 "UN address of NVE\n"
3612 "All UN addresses\n"
3613 "UN IPv4 interface address\n"
3614 "UN IPv6 interface address\n")
3616 struct rfapi_local_reg_delete_arg cda
;
3619 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3620 NULL
, NULL
, NULL
, NULL
, &cda
)))
3623 clear_vnc_prefix(&cda
);
3624 print_cleared_stats(&cda
);
3628 DEFUN (clear_vnc_prefix_un_vn
,
3629 clear_vnc_prefix_un_vn_cmd
,
3630 "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>",
3633 "Clear prefix registration information\n"
3637 "UN address of NVE\n"
3638 "All UN addresses\n"
3639 "UN IPv4 interface address\n"
3640 "UN IPv6 interface address\n"
3641 "VN address of NVE\n"
3642 "All VN addresses\n"
3643 "VN IPv4 interface address\n"
3644 "VN IPv6 interface address\n")
3646 struct rfapi_local_reg_delete_arg cda
;
3649 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3650 NULL
, NULL
, NULL
, NULL
, &cda
)))
3653 clear_vnc_prefix(&cda
);
3654 print_cleared_stats(&cda
);
3658 DEFUN (clear_vnc_prefix_un
,
3659 clear_vnc_prefix_un_cmd
,
3660 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3663 "Clear prefix registration information\n"
3667 "UN address of NVE\n"
3668 "All UN addresses\n"
3669 "UN IPv4 interface address\n"
3670 "UN IPv6 interface address\n")
3672 struct rfapi_local_reg_delete_arg cda
;
3675 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3676 NULL
, NULL
, NULL
, &cda
)))
3679 clear_vnc_prefix(&cda
);
3680 print_cleared_stats(&cda
);
3684 DEFUN (clear_vnc_prefix_vn
,
3685 clear_vnc_prefix_vn_cmd
,
3686 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3689 "Clear prefix registration information\n"
3693 "UN address of NVE\n"
3694 "All VN addresses\n"
3695 "VN IPv4 interface address\n"
3696 "VN IPv6 interface address\n")
3698 struct rfapi_local_reg_delete_arg cda
;
3701 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3702 NULL
, NULL
, NULL
, &cda
)))
3705 clear_vnc_prefix(&cda
);
3706 print_cleared_stats(&cda
);
3710 DEFUN (clear_vnc_prefix_all
,
3711 clear_vnc_prefix_all_cmd
,
3712 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3715 "Clear prefix registration information\n"
3721 struct rfapi_local_reg_delete_arg cda
;
3724 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3725 NULL
, NULL
, NULL
, &cda
)))
3728 clear_vnc_prefix(&cda
);
3729 print_cleared_stats(&cda
);
3733 /*-------------------------------------------------
3735 *-------------------------------------------------*/
3738 * This function is defined in this file (rather than in rfp_registration.c)
3739 * because here we have access to all the task handles.
3741 DEFUN (clear_vnc_mac_vn_un
,
3742 clear_vnc_mac_vn_un_cmd
,
3743 "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>",
3746 "Clear mac registration information\n"
3750 "Any virtual network identifier\n"
3751 "Virtual network identifier\n"
3752 "VN address of NVE\n"
3753 "All VN addresses\n"
3754 "VN IPv4 interface address\n"
3755 "VN IPv6 interface address\n"
3756 "UN address of NVE\n"
3757 "All UN addresses\n"
3758 "UN IPv4 interface address\n"
3759 "UN IPv6 interface address\n")
3761 struct rfapi_local_reg_delete_arg cda
;
3764 /* pfx vn un L2 VNI */
3765 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3766 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3769 clear_vnc_prefix(&cda
);
3770 print_cleared_stats(&cda
);
3774 DEFUN (clear_vnc_mac_un_vn
,
3775 clear_vnc_mac_un_vn_cmd
,
3776 "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>",
3779 "Clear mac registration information\n"
3783 "Any virtual network identifier\n"
3784 "Virtual network identifier\n"
3785 "UN address of NVE\n"
3786 "All UN addresses\n"
3787 "UN IPv4 interface address\n"
3788 "UN IPv6 interface address\n"
3789 "VN address of NVE\n"
3790 "All VN addresses\n"
3791 "VN IPv4 interface address\n"
3792 "VN IPv6 interface address\n")
3794 struct rfapi_local_reg_delete_arg cda
;
3797 /* pfx vn un L2 VNI */
3798 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3799 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3802 clear_vnc_prefix(&cda
);
3803 print_cleared_stats(&cda
);
3807 DEFUN (clear_vnc_mac_un
,
3808 clear_vnc_mac_un_cmd
,
3809 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3812 "Clear mac registration information\n"
3816 "Any virtual network identifier\n"
3817 "Virtual network identifier\n"
3818 "UN address of NVE\n"
3819 "All UN addresses\n"
3820 "UN IPv4 interface address\n"
3821 "UN IPv6 interface address\n")
3823 struct rfapi_local_reg_delete_arg cda
;
3826 /* pfx vn un L2 VNI */
3827 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3828 argv
[5], NULL
, NULL
, &cda
)))
3831 clear_vnc_prefix(&cda
);
3832 print_cleared_stats(&cda
);
3836 DEFUN (clear_vnc_mac_vn
,
3837 clear_vnc_mac_vn_cmd
,
3838 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3841 "Clear mac registration information\n"
3845 "Any virtual network identifier\n"
3846 "Virtual network identifier\n"
3847 "UN address of NVE\n"
3848 "All VN addresses\n"
3849 "VN IPv4 interface address\n"
3850 "VN IPv6 interface address\n")
3852 struct rfapi_local_reg_delete_arg cda
;
3855 /* pfx vn un L2 VNI */
3856 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3857 argv
[5], NULL
, NULL
, &cda
)))
3860 clear_vnc_prefix(&cda
);
3861 print_cleared_stats(&cda
);
3865 DEFUN (clear_vnc_mac_all
,
3866 clear_vnc_mac_all_cmd
,
3867 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3870 "Clear mac registration information\n"
3874 "Any virtual network identifier\n"
3875 "Virtual network identifier\n"
3878 struct rfapi_local_reg_delete_arg cda
;
3881 /* pfx vn un L2 VNI */
3882 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3883 argv
[5], NULL
, NULL
, &cda
)))
3886 clear_vnc_prefix(&cda
);
3887 print_cleared_stats(&cda
);
3891 /*-------------------------------------------------
3892 * Clear VNC MAC PREFIX
3893 *-------------------------------------------------*/
3895 DEFUN (clear_vnc_mac_vn_un_prefix
,
3896 clear_vnc_mac_vn_un_prefix_cmd
,
3897 "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>",
3900 "Clear mac registration information\n"
3904 "Any virtual network identifier\n"
3905 "Virtual network identifier\n"
3906 "VN address of NVE\n"
3907 "All VN addresses\n"
3908 "VN IPv4 interface address\n"
3909 "VN IPv6 interface address\n"
3910 "UN address of NVE\n"
3911 "All UN addresses\n"
3912 "UN IPv4 interface address\n"
3913 "UN IPv6 interface address\n"
3914 "Clear prefix registration information\n"
3919 struct rfapi_local_reg_delete_arg cda
;
3922 /* pfx vn un L2 VNI */
3923 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3924 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3927 clear_vnc_prefix(&cda
);
3928 print_cleared_stats(&cda
);
3932 DEFUN (clear_vnc_mac_un_vn_prefix
,
3933 clear_vnc_mac_un_vn_prefix_cmd
,
3934 "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>",
3937 "Clear mac registration information\n"
3941 "Any virtual network identifier\n"
3942 "Virtual network identifier\n"
3943 "UN address of NVE\n"
3944 "All UN addresses\n"
3945 "UN IPv4 interface address\n"
3946 "UN IPv6 interface address\n"
3947 "VN address of NVE\n"
3948 "All VN addresses\n"
3949 "VN IPv4 interface address\n"
3950 "VN IPv6 interface address\n"
3951 "Clear prefix registration information\n"
3955 "Clear prefix registration information\n"
3960 struct rfapi_local_reg_delete_arg cda
;
3963 /* pfx vn un L2 VNI */
3964 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3965 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3968 clear_vnc_prefix(&cda
);
3969 print_cleared_stats(&cda
);
3973 DEFUN (clear_vnc_mac_un_prefix
,
3974 clear_vnc_mac_un_prefix_cmd
,
3975 "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>",
3978 "Clear mac registration information\n"
3982 "Any virtual network identifier\n"
3983 "Virtual network identifier\n"
3984 "UN address of NVE\n"
3985 "All UN addresses\n"
3986 "UN IPv4 interface address\n"
3987 "UN IPv6 interface address\n"
3988 "Clear prefix registration information\n"
3993 struct rfapi_local_reg_delete_arg cda
;
3996 /* pfx vn un L2 VNI */
3997 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3998 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4001 clear_vnc_prefix(&cda
);
4002 print_cleared_stats(&cda
);
4006 DEFUN (clear_vnc_mac_vn_prefix
,
4007 clear_vnc_mac_vn_prefix_cmd
,
4008 "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>",
4011 "Clear mac registration information\n"
4015 "Any virtual network identifier\n"
4016 "Virtual network identifier\n"
4017 "UN address of NVE\n"
4018 "All VN addresses\n"
4019 "VN IPv4 interface address\n"
4020 "VN IPv6 interface address\n"
4021 "Clear prefix registration information\n"
4026 struct rfapi_local_reg_delete_arg cda
;
4029 /* pfx vn un L2 VNI */
4030 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4031 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4034 clear_vnc_prefix(&cda
);
4035 print_cleared_stats(&cda
);
4039 DEFUN (clear_vnc_mac_all_prefix
,
4040 clear_vnc_mac_all_prefix_cmd
,
4041 "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>",
4044 "Clear mac registration information\n"
4048 "Any virtual network identifier\n"
4049 "Virtual network identifier\n"
4050 "UN address of NVE\n"
4051 "All VN addresses\n"
4052 "VN IPv4 interface address\n"
4053 "VN IPv6 interface address\n")
4055 struct rfapi_local_reg_delete_arg cda
;
4058 /* pfx vn un L2 VNI */
4059 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4060 argv
[5], NULL
, NULL
, &cda
)))
4063 clear_vnc_prefix(&cda
);
4064 print_cleared_stats(&cda
);
4068 /************************************************************************
4070 ************************************************************************/
4073 /* copied from rfp_vty.c */
4074 static int check_and_display_is_vnc_running(struct vty
*vty
)
4076 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4077 return 1; /* is running */
4080 vty_out(vty
, "VNC is not configured.\n");
4082 return 0; /* not running */
4085 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4086 show_nve_summary_t show_type
)
4088 struct bgp
*bgp_default
= bgp_get_default();
4090 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4092 int active_local_routes
;
4093 int active_remote_routes
;
4094 int holddown_remote_routes
;
4095 int imported_remote_routes
;
4100 h
= bgp_default
->rfapi
;
4105 /* don't show local info if not running RFP */
4106 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4108 switch (show_type
) {
4110 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4111 vty_out(vty
, "%-24s ", "NVEs:");
4112 vty_out(vty
, "%-8s %-8u ",
4113 "Active:", h
->descriptors
.count
);
4114 vty_out(vty
, "%-8s %-8u ",
4115 "Maximum:", h
->stat
.max_descriptors
);
4116 vty_out(vty
, "%-8s %-8u",
4117 "Unknown:", h
->stat
.count_unknown_nves
);
4120 case SHOW_NVE_SUMMARY_REGISTERED
:
4122 * NB: With the introduction of L2 route support, we no
4123 * longer have a one-to-one correspondence between
4124 * locally-originated route advertisements and routes in
4125 * the import tables that have local origin. This
4126 * discrepancy arises because a single advertisement
4127 * may contain both an IP prefix and a MAC address.
4128 * Such an advertisement results in two import table
4129 * entries: one indexed by IP prefix, the other indexed
4132 * TBD: update computation and display of registration
4133 * statistics to reflect the underlying semantics.
4135 if (is_vnc_running
) {
4136 vty_out(vty
, "%-24s ", "Registrations:");
4137 vty_out(vty
, "%-8s %-8u ", "Active:",
4138 rfapiApCountAll(bgp_default
));
4139 vty_out(vty
, "%-8s %-8u ", "Failed:",
4140 h
->stat
.count_registrations_failed
);
4141 vty_out(vty
, "%-8s %-8u",
4142 "Total:", h
->stat
.count_registrations
);
4145 vty_out(vty
, "%-24s ", "Prefixes registered:");
4148 rfapiCountAllItRoutes(&active_local_routes
,
4149 &active_remote_routes
,
4150 &holddown_remote_routes
,
4151 &imported_remote_routes
);
4154 if (is_vnc_running
) {
4155 vty_out(vty
, " %-20s ", "Locally:");
4156 vty_out(vty
, "%-8s %-8u ",
4157 "Active:", active_local_routes
);
4162 vty_out(vty
, " %-20s ", "Remotely:");
4163 vty_out(vty
, "%-8s %-8u",
4164 "Active:", active_remote_routes
);
4166 vty_out(vty
, " %-20s ", "In Holddown:");
4167 vty_out(vty
, "%-8s %-8u",
4168 "Active:", holddown_remote_routes
);
4170 vty_out(vty
, " %-20s ", "Imported:");
4171 vty_out(vty
, "%-8s %-8u",
4172 "Active:", imported_remote_routes
);
4175 case SHOW_NVE_SUMMARY_QUERIES
:
4176 vty_out(vty
, "%-24s ", "Queries:");
4177 vty_out(vty
, "%-8s %-8u ",
4178 "Active:", rfapi_monitor_count(NULL
));
4179 vty_out(vty
, "%-8s %-8u ",
4180 "Failed:", h
->stat
.count_queries_failed
);
4181 vty_out(vty
, "%-8s %-8u",
4182 "Total:", h
->stat
.count_queries
);
4185 case SHOW_NVE_SUMMARY_RESPONSES
:
4186 rfapiRibShowResponsesSummary(vty
);
4196 vty_out(vty
, "VNC is not configured.\n");
4200 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4201 struct prefix
*un_prefix
)
4203 // struct hash *rfds;
4204 // struct rfp_rfapi_descriptor_param param;
4206 struct bgp
*bgp_default
= bgp_get_default();
4208 struct listnode
*node
;
4209 struct rfapi_descriptor
*rfd
;
4218 h
= bgp_default
->rfapi
;
4223 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4227 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4229 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4232 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4240 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4241 if (!prefix_match(vn_prefix
, &pfx
))
4246 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4247 if (!prefix_match(un_prefix
, &pfx
))
4251 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4253 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4257 /* print out a header */
4259 " Active Next Hops\n");
4260 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4261 "VN Address", "UN Address", "Regis", "Resps",
4262 "Reach", "Remove", "Age");
4267 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4268 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4269 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4270 rfd
->stat_count_nh_removal
,
4271 rfapiFormatAge(rfd
->open_time
, age
, 10));
4274 if (printed
> 0 || vn_prefix
|| un_prefix
)
4275 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4281 vty_out(vty
, "VNC is not configured.\n");
4286 DEFUN (vnc_show_summary
,
4287 vnc_show_summary_cmd
,
4291 "Display VNC status summary\n")
4293 if (!check_and_display_is_vnc_running(vty
))
4295 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4297 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4298 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4299 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4300 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4304 DEFUN (vnc_show_nves
,
4309 "List known NVEs\n")
4311 rfapi_show_nves(vty
, NULL
, NULL
);
4315 DEFUN (vnc_show_nves_ptct
,
4316 vnc_show_nves_ptct_cmd
,
4317 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4321 "VN address of NVE\n"
4322 "UN address of NVE\n"
4323 "IPv4 interface address\n"
4324 "IPv6 interface address\n")
4328 if (!check_and_display_is_vnc_running(vty
))
4331 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4332 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4335 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4336 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4340 if (argv
[3]->arg
[0] == 'u') {
4341 rfapi_show_nves(vty
, NULL
, &pfx
);
4343 rfapi_show_nves(vty
, &pfx
, NULL
);
4349 /* adapted from rfp_registration_cache_log() */
4350 static void rfapi_show_registrations(struct vty
*vty
,
4351 struct prefix
*restrict_to
, int show_local
,
4352 int show_remote
, int show_holddown
,
4360 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4363 /* non-expiring, local */
4364 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4368 /* non-expiring, non-local */
4369 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4372 if (show_holddown
) {
4373 /* expiring, including local */
4374 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4377 if (show_imported
) {
4378 /* non-expiring, non-local */
4379 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4387 DEFUN (vnc_show_registrations_pfx
,
4388 vnc_show_registrations_pfx_cmd
,
4389 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4392 "List active prefix registrations\n"
4393 "Limit output to a particular IPv4 prefix\n"
4394 "Limit output to a particular IPv6 prefix\n"
4395 "Limit output to a particular IPv6 address\n")
4398 struct prefix
*p_addr
= NULL
;
4401 if (!str2prefix(argv
[3]->arg
, &p
)) {
4402 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4409 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4413 DEFUN (vnc_show_registrations_some_pfx
,
4414 vnc_show_registrations_some_pfx_cmd
,
4415 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4418 "List active prefix registrations\n"
4419 "show all registrations\n"
4420 "show only registrations in holddown\n"
4421 "show only imported prefixes\n"
4422 "show only local registrations\n"
4423 "show only remote registrations\n"
4424 "Limit output to a particular prefix or address\n"
4425 "Limit output to a particular prefix or address\n"
4426 "Limit output to a particular prefix or address\n")
4429 struct prefix
*p_addr
= NULL
;
4432 int show_remote
= 0;
4433 int show_holddown
= 0;
4434 int show_imported
= 0;
4437 if (!str2prefix(argv
[4]->arg
, &p
)) {
4438 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4444 switch (argv
[3]->arg
[0]) {
4469 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4470 show_holddown
, show_imported
);
4474 DEFUN (vnc_show_responses_pfx
,
4475 vnc_show_responses_pfx_cmd
,
4476 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4479 "List recent query responses\n"
4480 "Limit output to a particular IPv4 prefix\n"
4481 "Limit output to a particular IPv6 prefix\n"
4482 "Limit output to a particular IPv6 address\n" )
4485 struct prefix
*p_addr
= NULL
;
4488 if (!str2prefix(argv
[3]->arg
, &p
)) {
4489 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4495 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4497 rfapiRibShowResponsesSummary(vty
);
4499 rfapiRibShowResponses(vty
, p_addr
, 0);
4500 rfapiRibShowResponses(vty
, p_addr
, 1);
4505 DEFUN (vnc_show_responses_some_pfx
,
4506 vnc_show_responses_some_pfx_cmd
,
4507 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4510 "List recent query responses\n"
4511 "show only active query responses\n"
4512 "show only removed query responses\n"
4513 "Limit output to a particular IPv4 prefix\n"
4514 "Limit output to a particular IPv6 prefix\n"
4515 "Limit output to a particular IPV6 address\n")
4518 struct prefix
*p_addr
= NULL
;
4520 int show_active
= 0;
4521 int show_removed
= 0;
4523 if (!check_and_display_is_vnc_running(vty
))
4527 if (!str2prefix(argv
[4]->arg
, &p
)) {
4528 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4535 switch (argv
[3]->arg
[0]) {
4545 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4547 rfapiRibShowResponsesSummary(vty
);
4550 rfapiRibShowResponses(vty
, p_addr
, 0);
4552 rfapiRibShowResponses(vty
, p_addr
, 1);
4557 DEFUN (show_vnc_queries_pfx
,
4558 show_vnc_queries_pfx_cmd
,
4559 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4562 "List active queries\n"
4563 "Limit output to a particular IPv4 prefix or address\n"
4564 "Limit output to a particular IPv6 prefix\n"
4565 "Limit output to a particualr IPV6 address\n")
4568 struct prefix
*p
= NULL
;
4571 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4572 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4578 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4580 return rfapiShowVncQueries(vty
, p
);
4583 DEFUN (vnc_clear_counters
,
4584 vnc_clear_counters_cmd
,
4585 "clear vnc counters",
4588 "Reset VNC counters\n")
4590 struct bgp
*bgp_default
= bgp_get_default();
4592 struct listnode
*node
;
4593 struct rfapi_descriptor
*rfd
;
4598 h
= bgp_default
->rfapi
;
4604 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4605 rfd
->stat_count_nh_reachable
= 0;
4606 rfd
->stat_count_nh_removal
= 0;
4610 memset(&h
->stat
, 0, sizeof(h
->stat
));
4613 * 151122 per bug 103, set count_registrations = number active.
4614 * Do same for queries
4616 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4617 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4619 rfapiRibShowResponsesSummaryClear();
4624 vty_out(vty
, "VNC is not configured.\n");
4628 /************************************************************************
4629 * Add prefix with vrf
4631 * add [vrf <vrf-name>] prefix <prefix>
4632 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4633 ************************************************************************/
4634 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4636 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4637 /* based on rfapi_open */
4638 struct rfapi_descriptor
*rfd
;
4640 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4641 sizeof(struct rfapi_descriptor
));
4644 /* leave most fields empty as will get from (dynamic) config
4646 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4648 if (rfg
->vn_prefix
.family
4649 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4650 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4652 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4653 rfd
->vn_addr
.addr_family
= AF_INET
;
4654 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4656 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4658 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4660 rfapi_init_and_open(bgp
, rfd
, rfg
);
4664 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4665 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4666 const char *arg_prefix
,
4667 const char *arg_rd
, /* optional */
4668 const char *arg_label
, /* optional */
4669 const char *arg_pref
) /* optional */
4672 struct rfapi_nve_group_cfg
*rfg
;
4674 struct rfapi_ip_prefix rpfx
;
4676 struct rfapi_vn_option optary
[3];
4677 struct rfapi_vn_option
*opt
= NULL
;
4680 bgp
= bgp_get_default(); /* assume main instance for now */
4682 vty_out(vty
, "No BGP process is configured\n");
4683 return CMD_WARNING_CONFIG_FAILED
;
4685 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4686 vty_out(vty
, "VRF support not configured\n");
4687 return CMD_WARNING_CONFIG_FAILED
;
4690 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4693 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4695 return CMD_WARNING_CONFIG_FAILED
;
4697 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4699 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4701 return CMD_WARNING_CONFIG_FAILED
;
4703 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4705 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4707 return CMD_WARNING_CONFIG_FAILED
;
4709 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4711 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4713 return CMD_WARNING_CONFIG_FAILED
;
4715 if (!str2prefix(arg_prefix
, &pfx
)) {
4716 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4717 return CMD_WARNING_CONFIG_FAILED
;
4719 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4720 memset(optary
, 0, sizeof(optary
));
4723 opt
->next
= &optary
[cur_opt
];
4724 opt
= &optary
[cur_opt
++];
4725 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4726 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4727 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4728 return CMD_WARNING_CONFIG_FAILED
;
4731 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4732 struct rfapi_l2address_option
*l2o
;
4734 opt
->next
= &optary
[cur_opt
];
4735 opt
= &optary
[cur_opt
++];
4736 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4737 l2o
= &opt
->v
.l2addr
;
4740 label
= strtoul(arg_label
, NULL
, 10);
4743 l2o
->label
= rfg
->label
;
4746 char *endptr
= NULL
;
4747 pref
= strtoul(arg_pref
, &endptr
, 10);
4748 if (*endptr
!= '\0') {
4750 "%% Invalid local-preference value \"%s\"\n",
4752 return CMD_WARNING_CONFIG_FAILED
;
4755 rpfx
.cost
= 255 - (pref
& 255);
4756 vnc_add_vrf_opener(bgp
, rfg
);
4758 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4759 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4760 struct rfapi_next_hop_entry
*head
= NULL
;
4761 struct rfapi_next_hop_entry
*tail
= NULL
;
4762 struct rfapi_vn_option
*vn_opt_new
;
4764 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4767 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4768 struct rfapi_descriptor
*r
=
4769 (struct rfapi_descriptor
*)rfg
->rfd
;
4770 vn_opt_new
= rfapi_vn_options_dup(opt
);
4772 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4774 RFAPI_INFINITE_LIFETIME
,
4775 vn_opt_new
, &head
, &tail
);
4777 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4778 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4780 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4784 vnc_zlog_debug_verbose(
4785 "%s completed, count=%d/%d", __func__
,
4786 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4787 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4791 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4792 vty_out(vty
, "Add failed.\n");
4793 return CMD_WARNING_CONFIG_FAILED
;
4796 DEFUN (add_vrf_prefix_rd_label_pref
,
4797 add_vrf_prefix_rd_label_pref_cmd
,
4798 "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)}]",
4802 "Add/modify prefix related information\n"
4805 "Override configured VRF Route Distinguisher\n"
4806 "<as-number>:<number> or <ip-address>:<number>\n"
4807 "Override configured VRF label\n"
4808 "Label Value <0-1048575>\n"
4809 "Set advertised local preference\n"
4810 "local preference (higher=more preferred)\n")
4812 char *arg_vrf
= argv
[2]->arg
;
4813 char *arg_prefix
= argv
[4]->arg
;
4814 char *arg_rd
= NULL
; /* optional */
4815 char *arg_label
= NULL
; /* optional */
4816 char *arg_pref
= NULL
; /* optional */
4818 argc
--; /* don't parse argument */
4819 while (pargc
< argc
) {
4820 switch (argv
[pargc
++]->arg
[0]) {
4822 arg_rd
= argv
[pargc
]->arg
;
4825 arg_label
= argv
[pargc
]->arg
;
4828 arg_pref
= argv
[pargc
]->arg
;
4836 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4840 /************************************************************************
4841 * del prefix with vrf
4843 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4844 ************************************************************************/
4845 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4849 if (rfg
->rfapi_import_table
== NULL
)
4852 afi_t afi
= AFI_MAX
;
4854 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4859 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4861 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4866 /* check if IT is empty */
4868 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4872 if (afi
== AFI_MAX
) {
4873 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4878 vnc_zlog_debug_verbose(
4879 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4880 rfg
->rfapi_import_table
->local_count
[afi
]);
4884 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4885 const char *arg_prefix
, /* NULL = all */
4886 const char *arg_rd
) /* optional */
4888 struct rfapi_nve_group_cfg
*rfg
;
4889 struct rfapi_local_reg_delete_arg cda
;
4894 bgp
= bgp_get_default(); /* assume main instance for now */
4896 vty_out(vty
, "No BGP process is configured\n");
4899 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4900 vty_out(vty
, "VRF support not configured\n");
4903 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4906 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4910 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4912 if (rc
!= CMD_SUCCESS
) /* parse error */
4915 start_count
= rfapi_cfg_group_it_count(rfg
);
4916 clear_vnc_prefix(&cda
);
4917 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4922 DEFUN (clear_vrf_prefix_rd
,
4923 clear_vrf_prefix_rd_cmd
,
4924 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4925 "Clear stored data\n"
4928 "Prefix related information\n"
4931 "Specific VRF Route Distinguisher\n"
4932 "<as-number>:<number> or <ip-address>:<number>\n")
4934 char *arg_vrf
= argv
[2]->arg
;
4935 char *arg_prefix
= NULL
; /* optional */
4936 char *arg_rd
= NULL
; /* optional */
4938 argc
--; /* don't check parameter */
4939 while (pargc
< argc
) {
4940 switch (argv
[pargc
++]->arg
[0]) {
4942 arg_rd
= argv
[pargc
]->arg
;
4945 arg_prefix
= argv
[pargc
]->arg
;
4952 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4955 DEFUN (clear_vrf_all
,
4957 "clear vrf NAME all",
4958 "Clear stored data\n"
4963 char *arg_vrf
= argv
[2]->arg
;
4964 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4967 void rfapi_vty_init()
4969 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4982 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4983 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4984 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4985 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4986 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4987 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4988 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4990 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4996 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
5002 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5008 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5010 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5011 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5012 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5013 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5014 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5016 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5017 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5019 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5022 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5023 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5025 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5026 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5027 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5028 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5029 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);