3 * Copyright 2009-2016, LabN Consulting, L.L.C.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "lib/zebra.h"
25 #include "lib/prefix.h"
26 #include "lib/table.h"
28 #include "lib/memory.h"
29 #include "lib/routemap.h"
31 #include "lib/log_int.h"
32 #include "lib/linklist.h"
33 #include "lib/command.h"
35 #include "bgpd/bgpd.h"
36 #include "bgpd/bgp_ecommunity.h"
37 #include "bgpd/bgp_attr.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_mplsvpn.h"
41 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
42 #include "bgpd/rfapi/rfapi.h"
43 #include "bgpd/rfapi/rfapi_backend.h"
45 #include "bgpd/bgp_route.h"
46 #include "bgpd/bgp_aspath.h"
47 #include "bgpd/bgp_community.h"
48 #include "bgpd/bgp_vnc_types.h"
49 #include "bgpd/bgp_label.h"
51 #include "bgpd/rfapi/rfapi_import.h"
52 #include "bgpd/rfapi/rfapi_private.h"
53 #include "bgpd/rfapi/rfapi_monitor.h"
54 #include "bgpd/rfapi/rfapi_rib.h"
55 #include "bgpd/rfapi/rfapi_vty.h"
56 #include "bgpd/rfapi/rfapi_ap.h"
57 #include "bgpd/rfapi/rfapi_encap_tlv.h"
58 #include "bgpd/rfapi/vnc_debug.h"
60 #define DEBUG_L2_EXTRA 0
61 #define DEBUG_SHOW_EXTRA 0
63 #define VNC_SHOW_STR "VNC information\n"
65 /* format related utilies */
68 #define FMT_MIN 60 /* seconds */
69 #define FMT_HOUR (60 * FMT_MIN)
70 #define FMT_DAY (24 * FMT_HOUR)
71 #define FMT_YEAR (365 * FMT_DAY)
73 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
75 int year
, day
, hour
, min
;
77 if (seconds
>= FMT_YEAR
) {
78 year
= seconds
/ FMT_YEAR
;
79 seconds
-= year
* FMT_YEAR
;
83 if (seconds
>= FMT_DAY
) {
84 day
= seconds
/ FMT_DAY
;
85 seconds
-= day
* FMT_DAY
;
89 if (seconds
>= FMT_HOUR
) {
90 hour
= seconds
/ FMT_HOUR
;
91 seconds
-= hour
* FMT_HOUR
;
95 if (seconds
>= FMT_MIN
) {
96 min
= seconds
/ FMT_MIN
;
97 seconds
-= min
* FMT_MIN
;
102 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
103 } else if (day
> 0) {
104 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
106 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
112 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
114 time_t now
, age_adjusted
;
116 now
= rfapi_time(NULL
);
117 age_adjusted
= now
- age
;
119 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
124 * Reimplementation of quagga/lib/prefix.c function, but
125 * for RFAPI-style prefixes
127 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
133 static uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
134 0xf8, 0xfc, 0xfe, 0xff};
136 switch (rprefix
->prefix
.addr_family
) {
138 index
= rprefix
->length
/ 8;
140 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
141 offset
= rprefix
->length
% 8;
142 pnt
[index
] &= maskbit
[offset
];
150 index
= rprefix
->length
/ 8;
152 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
153 offset
= rprefix
->length
% 8;
154 pnt
[index
] &= maskbit
[offset
];
167 * translate a quagga prefix into a rfapi IP address. The
168 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
175 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
177 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
178 raddr
->addr_family
= qprefix
->family
;
179 switch (qprefix
->family
) {
181 if (qprefix
->prefixlen
!= 32)
183 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
186 if (qprefix
->prefixlen
!= 128)
188 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
197 * Translate Quagga prefix to RFAPI prefix
199 /* rprefix->cost set to 0 */
200 void rfapiQprefix2Rprefix(struct prefix
*qprefix
,
201 struct rfapi_ip_prefix
*rprefix
)
203 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
204 rprefix
->length
= qprefix
->prefixlen
;
205 rprefix
->prefix
.addr_family
= qprefix
->family
;
206 switch (qprefix
->family
) {
208 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
211 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
218 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
219 struct prefix
*qprefix
)
221 memset(qprefix
, 0, sizeof(struct prefix
));
222 qprefix
->prefixlen
= rprefix
->length
;
223 qprefix
->family
= rprefix
->prefix
.addr_family
;
225 switch (rprefix
->prefix
.addr_family
) {
227 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
230 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
239 * returns 1 if prefixes have same addr family, prefix len, and address
240 * Note that host bits matter in this comparison!
242 * For paralellism with quagga/lib/prefix.c. if we need a comparison
243 * where host bits are ignored, call that function rfapiRprefixCmp.
245 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
247 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
249 if (hp1
->length
!= hp2
->length
)
251 if (hp1
->prefix
.addr_family
== AF_INET
)
252 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
254 if (hp1
->prefix
.addr_family
== AF_INET6
)
255 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
260 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
262 memset(pfx
, 0, sizeof(struct prefix
));
263 pfx
->family
= hia
->addr_family
;
265 switch (hia
->addr_family
) {
268 pfx
->u
.prefix4
= hia
->addr
.v4
;
271 pfx
->prefixlen
= 128;
272 pfx
->u
.prefix6
= hia
->addr
.v6
;
280 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
282 memset(pfx
, 0, sizeof(struct prefix
));
283 pfx
->family
= AF_ETHERNET
;
285 pfx
->u
.prefix_eth
= l2o
->macaddr
;
288 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
290 return prefix_mac2str(ea
, buf
, bufsize
);
293 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
298 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
305 for (i
= 0; i
< 6; ++i
)
306 ea
->octet
[i
] = a
[i
] & 0xff;
311 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
313 if (af
== AF_ETHERNET
) {
314 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
317 return inet_ntop(af
, src
, buf
, size
);
320 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
323 va_start(args
, format
);
324 vzlog(LOG_DEBUG
, format
, args
);
329 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
334 va_start(args
, format
);
336 switch ((uintptr_t)stream
) {
347 vfprintf(file
, format
, args
);
352 /* Fake out for debug logging */
353 static struct vty vty_dummy_zlog
;
354 static struct vty vty_dummy_stdio
;
355 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
357 static const char *str_vty_newline(struct vty
*vty
)
359 if (vty
== &vty_dummy_zlog
)
364 int rfapiStream2Vty(void *stream
, /* input */
365 int (**fp
)(void *, const char *, ...), /* output */
366 struct vty
**vty
, /* output */
367 void **outstream
, /* output */
368 const char **vty_newline
) /* output */
372 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
373 *vty
= &vty_dummy_zlog
;
374 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
376 *vty_newline
= str_vty_newline(*vty
);
377 return (vzlog_test(LOG_DEBUG
));
380 if (((uintptr_t)stream
== (uintptr_t)1)
381 || ((uintptr_t)stream
== (uintptr_t)2)) {
383 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
384 *vty
= &vty_dummy_stdio
;
385 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
387 *vty_newline
= str_vty_newline(*vty
);
391 *vty
= stream
; /* VTYNL requires vty to be legit */
392 *fp
= (int (*)(void *, const char *, ...))vty_out
;
394 *vty_newline
= str_vty_newline(*vty
);
398 /* called from bgpd/bgp_vty.c'route_vty_out() */
399 void rfapi_vty_out_vncinfo(struct vty
*vty
, struct prefix
*p
,
400 struct bgp_info
*bi
, safi_t safi
)
406 * Print, on an indented line:
407 * UN address [if VPN route and VNC UN addr subtlv]
413 if (safi
== SAFI_MPLS_VPN
) {
414 struct prefix pfx_un
;
416 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
418 vty_out(vty
, "UN=%s",
419 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
424 if (bi
->attr
&& bi
->attr
->ecommunity
) {
425 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
426 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
427 vty_out(vty
, " EC{%s}", s
);
428 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
431 if (bi
->extra
!= NULL
) {
432 if (bi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
433 vty_out(vty
, " label=VRF2VRF");
435 vty_out(vty
, " label=%u",
436 decode_label(&bi
->extra
->label
[0]));
439 if (!rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
440 vty_out(vty
, " life=%d", lifetime
);
443 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bi
->type
),
446 vty_out(vty
, "%s", HVTYNL
);
449 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
451 int (*fp
)(void *, const char *, ...);
454 const char *vty_newline
;
458 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
461 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
466 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
467 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
469 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
470 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
471 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
472 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
474 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
475 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
476 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
477 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
478 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
479 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
483 * Print BI in an Import Table
485 void rfapiPrintBi(void *stream
, struct bgp_info
*bi
)
490 int (*fp
)(void *, const char *, ...);
493 const char *vty_newline
;
499 struct ethaddr macaddr
= {{0}};
500 struct rfapi_l2address_option l2o_buf
;
501 uint8_t l2hid
= 0; /* valid if has_macaddr */
503 #define REMAIN (BUFSIZ - (p-line))
504 #define INCP {p += (r > REMAIN)? REMAIN: r;}
506 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
512 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
513 && bi
->extra
->vnc
.import
.timer
) {
514 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
515 r
= snprintf(p
, REMAIN
, " [%4lu] ",
516 thread_timer_remain_second(t
));
520 r
= snprintf(p
, REMAIN
, " ");
525 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
526 if (decode_rd_type(bi
->extra
->vnc
.import
.rd
.val
)
527 == RD_TYPE_VNC_ETH
) {
529 memcpy(macaddr
.octet
, bi
->extra
->vnc
.import
.rd
.val
+ 2,
531 l2hid
= bi
->extra
->vnc
.import
.rd
.val
[1];
540 * RFP option sizes (they are opaque values)
541 * extended communities (RTs)
545 int printed_1st_gol
= 0;
546 struct bgp_attr_encap_subtlv
*pEncap
;
547 struct prefix pfx_un
;
548 int af
= BGP_MP_NEXTHOP_FAMILY(bi
->attr
->mp_nexthop_len
);
552 r
= snprintf(p
, REMAIN
, "%s",
554 &bi
->attr
->mp_nexthop_global_in
,
557 } else if (af
== AF_INET6
) {
558 r
= snprintf(p
, REMAIN
, "%s",
560 &bi
->attr
->mp_nexthop_global
,
564 r
= snprintf(p
, REMAIN
, "?");
569 * VNC tunnel subtlv, if present, contains UN address
571 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
572 r
= snprintf(p
, REMAIN
, " un=%s",
573 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
579 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
580 r
= snprintf(p
, REMAIN
, " nolife");
583 if (lifetime
== 0xffffffff)
584 r
= snprintf(p
, REMAIN
, " %6s", "infini");
586 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
590 /* RFP option lengths */
591 for (pEncap
= bi
->attr
->vnc_subtlvs
; pEncap
;
592 pEncap
= pEncap
->next
) {
594 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
595 if (printed_1st_gol
) {
596 r
= snprintf(p
, REMAIN
, ",");
599 r
= snprintf(p
, REMAIN
,
600 " "); /* leading space */
603 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
610 if (bi
->attr
->ecommunity
) {
611 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
612 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
613 r
= snprintf(p
, REMAIN
, " %s", s
);
615 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
619 r
= snprintf(p
, REMAIN
, " bi@%p", bi
);
622 r
= snprintf(p
, REMAIN
, " p@%p", bi
->peer
);
625 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
626 r
= snprintf(p
, REMAIN
, " HD=yes");
629 r
= snprintf(p
, REMAIN
, " HD=no");
635 if (bi
->attr
->weight
) {
636 r
= snprintf(p
, REMAIN
, " W=%d", bi
->attr
->weight
);
640 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
641 r
= snprintf(p
, REMAIN
, " LP=%d", bi
->attr
->local_pref
);
644 r
= snprintf(p
, REMAIN
, " LP=unset");
649 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bi
->type
),
653 fp(out
, "%s%s", line
, HVTYNL
);
656 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
657 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
658 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
662 if (!rfapiGetL2o(bi
->attr
, &l2o_buf
)) {
664 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
665 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
666 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
667 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
668 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
671 if (bi
->extra
&& bi
->extra
->vnc
.import
.aux_prefix
.family
) {
675 sp
= rfapi_ntop(bi
->extra
->vnc
.import
.aux_prefix
.family
,
676 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
, buf
,
680 fp(out
, " IP: %s%s", sp
, HVTYNL
);
684 struct rfapi_un_option
*uo
=
685 rfapi_encap_tlv_to_un_option(bi
->attr
);
687 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
688 rfapi_un_options_free(uo
);
693 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
695 char buf_pfx
[BUFSIZ
];
700 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
701 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
703 rc
= snprintf(buf
, size
,
704 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
705 m
->next
, m
->rfd
, buf_vn
, buf_un
,
706 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
707 m
->p
.prefixlen
, m
->node
);
714 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
718 int (*fp
)(void *, const char *, ...);
721 const char *vty_newline
;
723 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
726 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
727 fp(out
, " Mon %s%s", buf
, HVTYNL
);
730 static void rfapiDebugPrintMonitorEncap(void *stream
,
731 struct rfapi_monitor_encap
*m
)
733 int (*fp
)(void *, const char *, ...);
736 const char *vty_newline
;
738 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
741 fp(out
, " Mon m=%p, next=%p, node=%p, bi=%p%s", m
, m
->next
, m
->node
,
745 void rfapiShowItNode(void *stream
, struct route_node
*rn
)
750 int (*fp
)(void *, const char *, ...);
753 const char *vty_newline
;
755 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
758 fp(out
, "%s/%d @%p #%d%s",
759 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
),
760 rn
->p
.prefixlen
, rn
, rn
->lock
, HVTYNL
);
762 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
763 rfapiPrintBi(stream
, bi
);
766 /* doesn't show montors */
769 void rfapiShowImportTable(void *stream
, const char *label
,
770 struct route_table
*rt
, int isvpn
)
772 struct route_node
*rn
;
775 int (*fp
)(void *, const char *, ...);
778 const char *vty_newline
;
780 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
783 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
785 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
788 if (rn
->p
.family
== AF_ETHERNET
) {
789 rfapiEthAddr2Str(&rn
->p
.u
.prefix_eth
, buf
, BUFSIZ
);
791 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
);
794 fp(out
, "%s/%d @%p #%d%s", buf
, rn
->p
.prefixlen
, rn
,
795 rn
->lock
- 1, /* account for loop iterator locking */
798 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
799 rfapiPrintBi(stream
, bi
);
803 struct rfapi_monitor_vpn
*m
;
804 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
805 rfapiDebugPrintMonitorVpn(stream
, m
);
808 struct rfapi_monitor_encap
*m
;
809 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
810 rfapiDebugPrintMonitorEncap(stream
, m
);
816 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
820 struct listnode
*node
;
821 struct rfapi_descriptor
*rfd
;
823 int (*fp
)(void *, const char *, ...);
826 const char *vty_newline
;
828 int printedheader
= 0;
831 int nves_with_queries
= 0;
832 int nves_displayed
= 0;
834 int queries_total
= 0;
835 int queries_displayed
= 0;
837 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
840 bgp
= bgp_get_default(); /* assume 1 instance for now */
842 vty_out(vty
, "No BGP instance\n");
848 vty_out(vty
, "No RFAPI instance\n");
852 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
854 struct route_node
*rn
;
855 int printedquerier
= 0;
861 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
871 for (rn
= route_top(rfd
->mon
); rn
;
872 rn
= route_next(rn
)) {
873 struct rfapi_monitor_vpn
*m
;
874 char buf_remain
[BUFSIZ
];
875 char buf_pfx
[BUFSIZ
];
885 && !prefix_match(pfx_match
, &rn
->p
)
886 && !prefix_match(&rn
->p
, pfx_match
))
891 if (!printedheader
) {
894 fp(out
, "%-15s %-15s %-15s %-10s\n",
895 "VN Address", "UN Address", "Target",
899 if (!printedquerier
) {
903 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
905 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
908 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
913 fp(out
, "%-15s %-15s", "", "");
917 thread_timer_remain_second(
921 fp(out
, " %-15s %-10s\n",
922 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
931 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
935 struct rfapi_monitor_eth
*mon_eth
;
938 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
939 (void **)&mon_eth
, &cursor
);
941 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
942 (void **)&mon_eth
, &cursor
)) {
944 char buf_remain
[BUFSIZ
];
945 char buf_pfx
[BUFSIZ
];
946 struct prefix pfx_mac
;
950 vnc_zlog_debug_verbose(
951 "%s: checking rfd=%p mon_eth=%p",
952 __func__
, rfd
, mon_eth
);
954 memset((void *)&pfx_mac
, 0,
955 sizeof(struct prefix
));
956 pfx_mac
.family
= AF_ETHERNET
;
957 pfx_mac
.prefixlen
= 48;
958 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
961 && !prefix_match(pfx_match
, &pfx_mac
)
962 && !prefix_match(&pfx_mac
, pfx_match
))
967 if (!printedheader
) {
971 "%-15s %-15s %-17s %10s %-10s\n",
972 "VN Address", "UN Address", "Target",
976 if (!printedquerier
) {
980 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
982 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
985 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
990 fp(out
, "%-15s %-15s", "", "");
992 if (mon_eth
->timer
) {
994 thread_timer_remain_second(
998 fp(out
, " %-17s %10d %-10s\n",
999 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
1001 mon_eth
->logical_net_id
, buf_remain
);
1006 if (queries_total
) {
1008 fp(out
, "Displayed %d out of %d total queries\n",
1009 queries_displayed
, queries_total
);
1014 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1015 struct route_node
*rn
, struct bgp_info
*bi
)
1017 int (*fp
)(void *, const char *, ...);
1020 const char *vty_newline
;
1021 struct prefix pfx_un
;
1022 struct prefix pfx_vn
;
1025 bgp_encap_types tun_type
;
1027 char buf_pfx
[BUFSIZ
];
1028 char buf_ntop
[BUFSIZ
];
1029 char buf_un
[BUFSIZ
];
1030 char buf_vn
[BUFSIZ
];
1031 char buf_lifetime
[BUFSIZ
];
1035 return 0; /* for debug log, print into buf & call output once */
1037 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1044 snprintf(buf_pfx
, BUFSIZ
, "%s/%d",
1045 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf_ntop
, BUFSIZ
),
1047 buf_pfx
[BUFSIZ
- 1] = 0;
1054 if (!rfapiGetUnAddrOfVpnBi(bi
, &pfx_un
)) {
1055 snprintf(buf_un
, BUFSIZ
, "%s",
1056 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1060 rfapiGetTunnelType(bi
->attr
, &tun_type
);
1065 rfapiNexthop2Prefix(bi
->attr
, &pfx_vn
);
1066 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1067 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1069 snprintf(buf_un
, BUFSIZ
, "%s",
1070 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1073 uint32_t l
= decode_label(&bi
->extra
->label
[0]);
1074 snprintf(buf_vn
, BUFSIZ
, "Label: %d", l
);
1075 } else /* should never happen */
1077 snprintf(buf_vn
, BUFSIZ
, "Label: N/A");
1080 snprintf(buf_vn
, BUFSIZ
, "%s",
1081 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1084 buf_vn
[BUFSIZ
- 1] = 0;
1085 buf_un
[BUFSIZ
- 1] = 0;
1088 * Cost is encoded in local_pref as (255-cost)
1089 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1093 uint32_t local_pref
;
1094 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1095 local_pref
= bi
->attr
->local_pref
;
1098 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1103 fp(out
, "%-20s ", buf_pfx
);
1104 fp(out
, "%-15s ", buf_vn
);
1105 fp(out
, "%-15s ", buf_un
);
1106 fp(out
, "%-4d ", cost
);
1109 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1110 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)
1111 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1113 fp(out
, "%-10s ", "infinite");
1115 time_t t_lifetime
= lifetime
;
1116 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1117 fp(out
, "%-10s ", buf_lifetime
);
1120 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
1121 && bi
->extra
->vnc
.import
.timer
) {
1125 char buf_age
[BUFSIZ
];
1127 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
1128 remaining
= thread_timer_remain_second(t
);
1130 #if RFAPI_REGISTRATIONS_REPORT_AGE
1132 * Calculate when the timer started. Doing so here saves
1133 * us a timestamp field in "struct bgp_info".
1135 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1136 * original calculation.
1138 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1140 #else /* report remaining time */
1143 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1145 fp(out
, "%-10s ", buf_age
);
1147 } else if (RFAPI_LOCAL_BI(bi
)) {
1149 char buf_age
[BUFSIZ
];
1151 if (bi
->extra
&& bi
->extra
->vnc
.import
.create_time
) {
1152 rfapiFormatAge(bi
->extra
->vnc
.import
.create_time
,
1158 fp(out
, "%-10s ", buf_age
);
1160 fp(out
, "%s", HVTYNL
);
1162 if (rn
->p
.family
== AF_ETHERNET
) {
1164 * If there is a corresponding IP address && != VN address,
1165 * print that on the next line
1168 if (bi
->extra
&& bi
->extra
->vnc
.import
.aux_prefix
.family
) {
1172 bi
->extra
->vnc
.import
.aux_prefix
.family
,
1173 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1175 buf_ntop
[BUFSIZ
- 1] = 0;
1177 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1178 fp(out
, " IP: %s", sp
);
1184 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bi
->extra
) {
1185 uint32_t l
= decode_label(&bi
->extra
->label
[0]);
1186 if (!MPLS_LABEL_IS_NULL(l
)) {
1187 fp(out
, " Label: %d", l
);
1193 fp(out
, "%s", HVTYNL
);
1198 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1199 struct rfapi_import_table
*it
,
1200 struct prefix
*prefix_only
,
1201 int show_expiring
, /* either/or */
1202 int show_local
, int show_remote
,
1203 int show_imported
, /* either/or */
1204 uint32_t *pLni
) /* AFI_L2VPN only */
1207 int printed_rtlist_hdr
= 0;
1209 int (*fp
)(void *, const char *, ...);
1212 const char *vty_newline
;
1216 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1219 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1221 struct route_node
*rn
;
1223 if (!it
->imported_vpn
[afi
])
1226 for (rn
= route_top(it
->imported_vpn
[afi
]); rn
;
1227 rn
= route_next(rn
)) {
1229 struct bgp_info
*bi
;
1232 /* allow for wider or more narrow mask from user */
1233 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1234 && !prefix_match(&rn
->p
, prefix_only
))
1239 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
1241 if (!show_local
&& RFAPI_LOCAL_BI(bi
)) {
1243 /* local route from RFP */
1247 if (!show_remote
&& !RFAPI_LOCAL_BI(bi
)) {
1254 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1258 && CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1261 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1262 || bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1271 if (count_only
== 1)
1273 if (!printed_rtlist_hdr
) {
1274 const char *agetype
= "";
1276 const char *type
= "";
1277 if (show_imported
) {
1280 if (show_expiring
) {
1292 s
= ecommunity_ecom2str(
1294 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1298 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1299 HVTYNL
, type
, *pLni
,
1300 (*pLni
& 0xfff), s
);
1302 fp(out
, "%s[%s] Prefix RT={%s}",
1305 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1307 if (it
->rfg
&& it
->rfg
->name
) {
1308 fp(out
, " %s \"%s\"",
1309 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1314 fp(out
, "%s", HVTYNL
);
1315 if (show_expiring
) {
1316 #if RFAPI_REGISTRATIONS_REPORT_AGE
1319 agetype
= "Remaining";
1321 } else if (show_local
) {
1325 printed_rtlist_hdr
= 1;
1328 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1329 (pLni
? "L2 Address/IP" : "Prefix"),
1330 "VN Address", "UN Address", "Cost",
1331 "Lifetime", agetype
, HVTYNL
);
1333 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1341 const char *type
= "prefixes";
1343 if (show_imported
) {
1344 type
= "imported prefixes";
1346 if (show_expiring
) {
1347 type
= "prefixes in holddown";
1349 if (show_local
&& !show_remote
) {
1350 type
= "locally registered prefixes";
1351 } else if (!show_local
&& show_remote
) {
1352 type
= "remotely registered prefixes";
1357 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1359 #if DEBUG_SHOW_EXTRA
1360 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1368 * rfapiShowRemoteRegistrations
1370 * Similar to rfapiShowImportTable() above. This function
1371 * is mean to produce the "remote" portion of the output
1372 * of "show vnc registrations".
1374 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1375 int show_expiring
, int show_local
,
1376 int show_remote
, int show_imported
)
1380 struct rfapi_import_table
*it
;
1383 bgp
= bgp_get_default();
1393 for (it
= h
->imports
; it
; it
= it
->next
) {
1394 printed
+= rfapiShowRemoteRegistrationsIt(
1395 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1396 show_remote
, show_imported
, NULL
);
1399 if (h
->import_mac
) {
1400 void *cursor
= NULL
;
1402 uintptr_t lni_as_ptr
;
1406 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1407 (void **)&it
, &cursor
);
1409 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1410 (void **)&it
, &cursor
)) {
1412 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1413 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1417 printed
+= rfapiShowRemoteRegistrationsIt(
1418 bgp
, stream
, it
, prefix_only
, show_expiring
,
1419 show_local
, show_remote
, show_imported
, pLni
);
1426 /*------------------------------------------
1427 * rfapiRfapiIpAddr2Str
1429 * UI helper: generate string from rfapi_ip_addr
1432 * a IP v4/v6 address
1435 * buf put string here
1436 * bufsize max space to write
1439 * NULL conversion failed
1440 * non-NULL pointer to buf
1441 --------------------------------------------*/
1442 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1445 const char *rc
= NULL
;
1447 switch (a
->addr_family
) {
1449 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1452 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1458 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1461 const char *rc
= NULL
;
1463 int (*fp
)(void *, const char *, ...);
1466 const char *vty_newline
;
1468 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1471 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1477 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1480 struct rfapi_ip_addr
*a
= &p
->prefix
;
1481 const char *rc
= NULL
;
1483 switch (a
->addr_family
) {
1485 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1488 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1493 int alen
= strlen(buf
);
1494 int remaining
= bufsize
- alen
- 1;
1497 if (remaining
> 0) {
1498 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1500 if (slen
< remaining
) /* see man page for snprintf(3) */
1508 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1513 int (*fp
)(void *, const char *, ...);
1516 const char *vty_newline
;
1518 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1521 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1524 fp(out
, "%s:%u", buf
, p
->cost
);
1529 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1531 char buf
[RD_ADDRSTRLEN
];
1533 prefix_rd2str(prd
, buf
, sizeof(buf
));
1534 vty_out(vty
, "%s", buf
);
1537 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1538 safi_t safi
, struct prefix
*p
)
1540 afi_t afi
; /* of the VN address */
1541 struct bgp_node
*bn
;
1542 struct bgp_info
*bi
;
1543 uint8_t type
= ZEBRA_ROUTE_BGP
;
1546 struct prefix_rd prd0
;
1547 struct prefix_rd
*prd
;
1550 * Find the bgp_info in the RIB corresponding to this
1554 afi
= family2afi(p
->family
);
1555 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1557 bgp
= bgp_get_default(); /* assume 1 instance for now */
1560 if (safi
== SAFI_ENCAP
) {
1561 memset(&prd0
, 0, sizeof(prd0
));
1562 prd0
.family
= AF_UNSPEC
;
1563 prd0
.prefixlen
= 64;
1568 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1570 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1572 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1573 if (bi
->peer
== rfd
->peer
&& bi
->type
== type
1574 && bi
->sub_type
== BGP_ROUTE_RFP
&& bi
->extra
1575 && bi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1577 rfapiPrintBi(vty
, bi
);
1583 vty_out(vty
, " --?--%s", HVTYNL
);
1588 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1590 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1591 /* RT export list */
1592 /* RT import list */
1593 /* list of advertised prefixes */
1594 /* dump import table */
1600 struct rfapi_adb
*adb
;
1601 char buf
[PREFIX_STRLEN
];
1603 vty_out(vty
, "%-10p ", rfd
);
1604 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1606 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1607 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1608 rfapiPrintRd(vty
, &rfd
->rd
);
1609 vty_out(vty
, " %d", rfd
->response_lifetime
);
1610 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1611 vty_out(vty
, "%s", HVTYNL
);
1613 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1615 /* export RT list */
1616 if (rfd
->rt_export_list
) {
1617 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1618 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1619 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1620 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1622 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1625 /* import RT list */
1626 if (rfd
->import_table
) {
1627 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1628 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1629 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1630 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1632 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1635 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1638 family
= afi2family(afi
);
1643 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1644 (void **)&adb
, &cursor
);
1646 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1647 (void **)&adb
, &cursor
)) {
1649 /* group like family prefixes together in output */
1650 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1653 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1655 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1656 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1657 &adb
->u
.s
.prefix_ip
);
1660 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1661 (void **)&adb
, &cursor
);
1662 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1663 (void **)&adb
, &cursor
)) {
1665 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1667 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1669 /* TBD update the following function to print ethernet info */
1670 /* Also need to pass/use rd */
1671 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1672 &adb
->u
.s
.prefix_ip
);
1674 vty_out(vty
, "%s", HVTYNL
);
1678 * test scripts rely on first line for each nve starting in 1st column,
1679 * leading whitespace for additional detail of that nve
1681 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1682 struct prefix
*un_prefix
)
1686 struct listnode
*ln
;
1687 struct rfapi_descriptor
*rfd
;
1690 bgp
= bgp_get_default(); /* assume 1 instance for now */
1697 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1698 rfd
= listgetdata(ln
);
1703 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1704 if (!prefix_match(vn_prefix
, &pfx
))
1709 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1710 if (!prefix_match(un_prefix
, &pfx
))
1715 /* print column header */
1716 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1717 "un-addr", "vn-addr", "callback", "cookie",
1718 "RD", "lifetime", "group", HVTYNL
);
1720 rfapiPrintDescriptor(vty
, rfd
);
1727 * Parse an address and put into a struct prefix
1729 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1731 if (!str2prefix(str
, p
)) {
1732 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1736 switch (p
->family
) {
1738 if (p
->prefixlen
!= 32) {
1739 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1745 if (p
->prefixlen
!= 128) {
1746 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1752 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1758 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1759 struct rfapi_ip_addr
*hai
)
1764 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1768 hai
->addr_family
= pfx
.family
;
1769 if (pfx
.family
== AF_INET
)
1770 hai
->addr
.v4
= pfx
.u
.prefix4
;
1772 hai
->addr
.v6
= pfx
.u
.prefix6
;
1778 * Note: this function does not flush vty output, so if it is called
1779 * with a stream pointing to a vty, the user will have to type something
1780 * before the callback output shows up
1782 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1784 struct rfapi_next_hop_entry
*nh
;
1787 int (*fp
)(void *, const char *, ...);
1790 const char *vty_newline
;
1792 #define REMAIN (BUFSIZ - (p-line))
1793 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1795 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1798 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1804 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1807 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1808 /* it fit, so count length */
1816 r
= snprintf(p
, REMAIN
, ", un=");
1819 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1820 /* it fit, so count length */
1828 r
= snprintf(p
, REMAIN
, ", vn=");
1831 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1832 /* it fit, so count length */
1841 line
[BUFSIZ
- 1] = 0;
1842 fp(out
, "%s%s", line
, HVTYNL
);
1847 if (nh
->vn_options
) {
1848 struct rfapi_vn_option
*vo
;
1849 char offset
[] = " ";
1851 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1855 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1856 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1857 pbuf
, sizeof(pbuf
));
1859 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1861 (vo
->v
.l2addr
.label
& 0x00ffffff),
1862 (vo
->v
.l2addr
.logical_net_id
1864 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1867 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1868 prefix2str(&vo
->v
.local_nexthop
.addr
,
1869 pbuf
, sizeof(pbuf
));
1870 fp(out
, "%sLNH %s cost=%d%s", offset
,
1871 pbuf
, vo
->v
.local_nexthop
.cost
,
1877 "%svn option type %d (unknown)%s",
1878 offset
, vo
->type
, HVTYNL
);
1883 if (nh
->un_options
) {
1884 struct rfapi_un_option
*uo
;
1885 char offset
[] = " ";
1887 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1889 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1890 rfapi_print_tunneltype_option(
1891 stream
, 8, &uo
->v
.tunnel
);
1894 fp(out
, "%sUN Option type %d%s", offset
,
1895 uo
->type
, vty_newline
);
1903 /***********************************************************************
1905 ***********************************************************************/
1908 * Add another nexthop to the NHL
1910 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1911 struct rfapi_ip_addr
*vn_addr
,
1912 struct rfapi_ip_prefix
*rprefix
,
1914 uint32_t lifetime
, /* add only */
1915 struct rfapi_vn_option
*vn_options
,
1916 struct rfapi_next_hop_entry
**head
,
1917 struct rfapi_next_hop_entry
**tail
)
1919 struct rfapi_next_hop_entry
*new;
1925 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1926 new->prefix
= *rprefix
;
1927 new->un_address
= *un_addr
;
1928 new->vn_address
= *vn_addr
;
1930 new->vn_options
= vn_options
;
1932 new->lifetime
= lifetime
;
1934 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1938 (*tail
)->next
= new;
1947 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1948 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1949 struct cmd_token
*carg_cost
, /* optional */
1950 struct cmd_token
*carg_lifetime
, /* optional */
1951 struct cmd_token
*carg_macaddr
, /* optional */
1953 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1954 int argc
, struct cmd_token
**argv
)
1956 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1957 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1958 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1959 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1960 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1961 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1962 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1963 struct rfapi_ip_addr vn_address
;
1964 struct rfapi_ip_addr un_address
;
1966 struct rfapi_ip_prefix rpfx
;
1971 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1972 struct rfapi_vn_option
*opt
= NULL
;
1975 int rc
= CMD_WARNING_CONFIG_FAILED
;
1979 struct rfapi_cfg
*rfapi_cfg
;
1981 const char *arg_lnh
= NULL
;
1982 const char *arg_lnh_cost
= NULL
;
1984 bgp
= bgp_get_default(); /* assume 1 instance for now */
1987 vty_out(vty
, "BGP not configured\n");
1988 return CMD_WARNING_CONFIG_FAILED
;
1992 rfapi_cfg
= bgp
->rfapi_cfg
;
1993 if (!h
|| !rfapi_cfg
) {
1995 vty_out(vty
, "RFAPI not configured\n");
1996 return CMD_WARNING_CONFIG_FAILED
;
1999 for (; argc
; --argc
, ++argv
) {
2000 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2003 "local-next-hop specified more than once\n");
2004 return CMD_WARNING_CONFIG_FAILED
;
2008 "Missing parameter for local-next-hop\n");
2009 return CMD_WARNING_CONFIG_FAILED
;
2012 arg_lnh
= argv
[0]->arg
;
2014 if (strmatch(argv
[0]->text
, "local-cost")) {
2017 "local-cost specified more than once\n");
2018 return CMD_WARNING_CONFIG_FAILED
;
2022 "Missing parameter for local-cost\n");
2023 return CMD_WARNING_CONFIG_FAILED
;
2026 arg_lnh_cost
= argv
[0]->arg
;
2030 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2032 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2035 /* arg_prefix is optional if mac address is given */
2036 if (arg_macaddr
&& !arg_prefix
) {
2038 * fake up a 0/32 or 0/128 prefix
2040 switch (vn_address
.addr_family
) {
2042 arg_prefix
= "0.0.0.0/32";
2045 arg_prefix
= "0::0/128";
2049 "Internal error, unknown VN address family\n");
2050 return CMD_WARNING_CONFIG_FAILED
;
2054 if (!str2prefix(arg_prefix
, &pfx
)) {
2055 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2058 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2059 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2065 memset(optary
, 0, sizeof(optary
));
2069 cost
= strtoul(arg_cost
, &endptr
, 10);
2070 if (*endptr
!= '\0' || cost
> 255) {
2071 vty_out(vty
, "%% Invalid %s value\n", "cost");
2079 if (!strcmp(arg_lifetime
, "infinite")) {
2080 lifetime
= RFAPI_INFINITE_LIFETIME
;
2083 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2084 if (*endptr
!= '\0') {
2085 vty_out(vty
, "%% Invalid %s value\n",
2091 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2097 "%% %s may only be specified with local-next-hop\n",
2102 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2103 if (*endptr
!= '\0' || lnh_cost
> 255) {
2104 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2114 "%% %s may only be specified with prefix\n",
2118 if ((rc
= rfapiCliGetPrefixAddr(
2120 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2125 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2126 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2129 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2136 if (arg_vni
&& !arg_macaddr
) {
2137 vty_out(vty
, "%% %s may only be specified with mac address\n",
2138 "virtual-network-identifier");
2145 "Missing \"vni\" parameter (mandatory with mac)\n");
2146 return CMD_WARNING_CONFIG_FAILED
;
2148 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2149 strtoul(arg_vni
, NULL
, 10);
2151 if ((rc
= rfapiStr2EthAddr(
2153 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2154 vty_out(vty
, "Invalid %s value\n", "mac address");
2157 /* TBD label, NVE ID */
2159 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2162 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2169 vnc_zlog_debug_verbose(
2170 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2171 __func__
, arg_vn
, arg_un
, arg_prefix
,
2172 (arg_cost
? arg_cost
: "NULL"),
2173 (arg_lifetime
? arg_lifetime
: "NULL"),
2174 (arg_lnh
? arg_lnh
: "NULL"));
2176 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2178 rpfx
.cost
= cost
& 255;
2180 /* look up rf descriptor, call open if it doesn't exist */
2181 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2182 (struct rfapi_descriptor
**)&rfd
);
2185 struct rfapi_un_option uo
;
2188 * flag descriptor as provisionally opened for static
2190 * registration so that we can fix up the other
2192 * when the real open comes along
2194 memset(&uo
, 0, sizeof(uo
));
2195 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2197 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2198 &vn_address
, &un_address
,
2200 NULL
, NULL
, /* no userdata */
2204 "Can't open session for this NVE: %s\n",
2205 rfapi_error_str(rc
));
2206 rc
= CMD_WARNING_CONFIG_FAILED
;
2210 vty_out(vty
, "Can't find session for this NVE: %s\n",
2211 rfapi_error_str(rc
));
2216 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2217 RFAPI_REGISTER_ADD
);
2219 struct rfapi_next_hop_entry
*head
= NULL
;
2220 struct rfapi_next_hop_entry
*tail
= NULL
;
2221 struct rfapi_vn_option
*vn_opt_new
;
2223 vnc_zlog_debug_verbose(
2224 "%s: rfapi_register succeeded, returning 0", __func__
);
2226 if (h
->rfp_methods
.local_cb
) {
2227 struct rfapi_descriptor
*r
=
2228 (struct rfapi_descriptor
*)rfd
;
2229 vn_opt_new
= rfapi_vn_options_dup(opt
);
2231 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2233 vn_opt_new
, &head
, &tail
);
2235 h
->flags
|= RFAPI_INCALLBACK
;
2236 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2237 h
->flags
&= ~RFAPI_INCALLBACK
;
2244 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2246 vty_out(vty
, "Registration failed.\n");
2248 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2249 return CMD_WARNING_CONFIG_FAILED
;
2252 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2256 /************************************************************************
2257 * Add prefix With LNH_OPTIONS...
2258 ************************************************************************/
2259 DEFUN (add_vnc_prefix_cost_life_lnh
,
2260 add_vnc_prefix_cost_life_lnh_cmd
,
2261 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295) LNH_OPTIONS...",
2262 "Add registration\n"
2264 "Add/modify prefix related information\n"
2267 "VN address of NVE\n"
2268 "VN IPv4 interface address\n"
2269 "VN IPv6 interface address\n"
2270 "UN address of NVE\n"
2271 "UN IPv4 interface address\n"
2272 "UN IPv6 interface address\n"
2273 "Administrative cost [default: 255]\n"
2274 "Administrative cost\n"
2275 "Registration lifetime [default: infinite]\n"
2276 "Lifetime value in seconds\n"
2277 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2279 /* pfx vn un cost life */
2280 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2282 NULL
, NULL
, argc
- 12, argv
+ 12);
2285 DEFUN (add_vnc_prefix_life_cost_lnh
,
2286 add_vnc_prefix_life_cost_lnh_cmd
,
2287 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255) LNH_OPTIONS...",
2288 "Add registration\n"
2290 "Add/modify prefix related information\n"
2293 "VN address of NVE\n"
2294 "VN IPv4 interface address\n"
2295 "VN IPv6 interface address\n"
2296 "UN address of NVE\n"
2297 "UN IPv4 interface address\n"
2298 "UN IPv6 interface address\n"
2299 "Registration lifetime [default: infinite]\n"
2300 "Lifetime value in seconds\n"
2301 "Administrative cost [default: 255]\n"
2302 "Administrative cost\n"
2303 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2305 /* pfx vn un cost life */
2306 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2308 NULL
, NULL
, argc
- 12, argv
+ 12);
2311 DEFUN (add_vnc_prefix_cost_lnh
,
2312 add_vnc_prefix_cost_lnh_cmd
,
2313 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) LNH_OPTIONS...",
2314 "Add registration\n"
2316 "Add/modify prefix related information\n"
2319 "VN address of NVE\n"
2320 "VN IPv4 interface address\n"
2321 "VN IPv6 interface address\n"
2322 "UN address of NVE\n"
2323 "UN IPv4 interface address\n"
2324 "UN IPv6 interface address\n"
2325 "Administrative cost [default: 255]\n"
2326 "Administrative cost\n"
2327 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2329 /* pfx vn un cost life */
2330 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2332 NULL
, NULL
, argc
- 10, argv
+ 10);
2335 DEFUN (add_vnc_prefix_life_lnh
,
2336 add_vnc_prefix_life_lnh_cmd
,
2337 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) LNH_OPTIONS...",
2338 "Add registration\n"
2340 "Add/modify prefix related information\n"
2343 "VN address of NVE\n"
2344 "VN IPv4 interface address\n"
2345 "VN IPv6 interface address\n"
2346 "UN address of NVE\n"
2347 "UN IPv4 interface address\n"
2348 "UN IPv6 interface address\n"
2349 "Registration lifetime [default: infinite]\n"
2350 "Lifetime value in seconds\n"
2351 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2353 /* pfx vn un cost life */
2354 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2356 NULL
, NULL
, argc
- 10, argv
+ 10);
2359 DEFUN (add_vnc_prefix_lnh
,
2360 add_vnc_prefix_lnh_cmd
,
2361 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> LNH_OPTIONS...",
2362 "Add registration\n"
2364 "Add/modify prefix related information\n"
2367 "VN address of NVE\n"
2368 "VN IPv4 interface address\n"
2369 "VN IPv6 interface address\n"
2370 "UN address of NVE\n"
2371 "UN IPv4 interface address\n"
2372 "UN IPv6 interface address\n"
2373 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2375 /* pfx vn un cost life */
2376 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2378 NULL
, NULL
, argc
- 8, argv
+ 8);
2381 /************************************************************************
2382 * Add prefix Without LNH_OPTIONS...
2383 ************************************************************************/
2384 DEFUN (add_vnc_prefix_cost_life
,
2385 add_vnc_prefix_cost_life_cmd
,
2386 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
2387 "Add registration\n"
2389 "Add/modify prefix related information\n"
2392 "VN address of NVE\n"
2393 "VN IPv4 interface address\n"
2394 "VN IPv6 interface address\n"
2395 "UN address of NVE\n"
2396 "UN IPv4 interface address\n"
2397 "UN IPv6 interface address\n"
2398 "Administrative cost [default: 255]\n"
2399 "Administrative cost\n"
2400 "Registration lifetime [default: infinite]\n"
2401 "Lifetime value in seconds\n")
2403 /* pfx vn un cost life */
2404 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2406 NULL
, NULL
, 0, NULL
);
2409 DEFUN (add_vnc_prefix_life_cost
,
2410 add_vnc_prefix_life_cost_cmd
,
2411 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295) cost (0-255)",
2412 "Add registration\n"
2414 "Add/modify prefix related information\n"
2417 "VN address of NVE\n"
2418 "VN IPv4 interface address\n"
2419 "VN IPv6 interface address\n"
2420 "UN address of NVE\n"
2421 "UN IPv4 interface address\n"
2422 "UN IPv6 interface address\n"
2423 "Registration lifetime [default: infinite]\n"
2424 "Lifetime value in seconds\n"
2425 "Administrative cost [default: 255]\n"
2426 "Administrative cost\n")
2428 /* pfx vn un cost life */
2429 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2431 NULL
, NULL
, 0, NULL
);
2434 DEFUN (add_vnc_prefix_cost
,
2435 add_vnc_prefix_cost_cmd
,
2436 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
2437 "Add registration\n"
2439 "Add/modify prefix related information\n"
2442 "VN address of NVE\n"
2443 "VN IPv4 interface address\n"
2444 "VN IPv6 interface address\n"
2445 "UN address of NVE\n"
2446 "UN IPv4 interface address\n"
2447 "UN IPv6 interface address\n"
2448 "Administrative cost [default: 255]\n"
2449 "Administrative cost\n")
2451 /* pfx vn un cost life */
2452 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2454 NULL
, NULL
, 0, NULL
);
2457 DEFUN (add_vnc_prefix_life
,
2458 add_vnc_prefix_life_cmd
,
2459 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
2460 "Add registration\n"
2462 "Add/modify prefix related information\n"
2465 "VN address of NVE\n"
2466 "VN IPv4 interface address\n"
2467 "VN IPv6 interface address\n"
2468 "UN address of NVE\n"
2469 "UN IPv4 interface address\n"
2470 "UN IPv6 interface address\n"
2471 "Registration lifetime [default: infinite]\n"
2472 "Lifetime value in seconds\n")
2474 /* pfx vn un cost life */
2475 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2477 NULL
, NULL
, 0, NULL
);
2480 DEFUN (add_vnc_prefix
,
2482 "add vnc prefix <A.B.C.D/M|X:X::X:X/M> vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2483 "Add registration\n"
2485 "Add/modify prefix related information\n"
2488 "VN address of NVE\n"
2489 "VN IPv4 interface address\n"
2490 "VN IPv6 interface address\n"
2491 "UN address of NVE\n"
2492 "UN IPv4 interface address\n"
2493 "UN IPv6 interface address\n")
2495 /* pfx vn un cost life */
2496 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2498 NULL
, NULL
, 0, NULL
);
2501 /************************************************************************
2502 * Mac address registrations
2503 ************************************************************************/
2504 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2505 add_vnc_mac_vni_prefix_cost_life_cmd
,
2506 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255) lifetime (1-4294967295)",
2507 "Add registration\n"
2509 "Add/modify mac address information\n"
2511 "Virtual Network Identifier follows\n"
2512 "Virtual Network Identifier\n"
2513 "VN address of NVE\n"
2514 "VN IPv4 interface address\n"
2515 "VN IPv6 interface address\n"
2516 "UN address of NVE\n"
2517 "UN IPv4 interface address\n"
2518 "UN IPv6 interface address\n"
2519 "Add/modify prefix related information\n"
2522 "Administrative cost [default: 255]\n"
2523 "Administrative cost\n"
2524 "Registration lifetime [default: infinite]\n"
2525 "Lifetime value in seconds\n")
2527 /* pfx vn un cost life */
2528 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2530 argv
[3], argv
[5], 0, NULL
);
2534 DEFUN (add_vnc_mac_vni_prefix_life
,
2535 add_vnc_mac_vni_prefix_life_cmd
,
2536 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> lifetime (1-4294967295)",
2537 "Add registration\n"
2539 "Add/modify mac address information\n"
2541 "Virtual Network Identifier follows\n"
2542 "Virtual Network Identifier\n"
2543 "VN address of NVE\n"
2544 "VN IPv4 interface address\n"
2545 "VN IPv6 interface address\n"
2546 "UN address of NVE\n"
2547 "UN IPv4 interface address\n"
2548 "UN IPv6 interface address\n"
2549 "Add/modify prefix related information\n"
2552 "Registration lifetime [default: infinite]\n"
2553 "Lifetime value in seconds\n")
2555 /* pfx vn un cost life */
2556 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2558 argv
[3], argv
[5], 0, NULL
);
2561 DEFUN (add_vnc_mac_vni_prefix_cost
,
2562 add_vnc_mac_vni_prefix_cost_cmd
,
2563 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M> cost (0-255)",
2564 "Add registration\n"
2566 "Add/modify mac address information\n"
2568 "Virtual Network Identifier follows\n"
2569 "Virtual Network Identifier\n"
2570 "VN address of NVE\n"
2571 "VN IPv4 interface address\n"
2572 "VN IPv6 interface address\n"
2573 "UN address of NVE\n"
2574 "UN IPv4 interface address\n"
2575 "UN IPv6 interface address\n"
2576 "Add/modify prefix related information\n"
2579 "Administrative cost [default: 255]\n" "Administrative cost\n")
2581 /* pfx vn un cost life */
2582 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2584 argv
[3], argv
[5], 0, NULL
);
2587 DEFUN (add_vnc_mac_vni_prefix
,
2588 add_vnc_mac_vni_prefix_cmd
,
2589 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> prefix <A.B.C.D/M|X:X::X:X/M>",
2590 "Add registration\n"
2592 "Add/modify mac address information\n"
2594 "Virtual Network Identifier follows\n"
2595 "Virtual Network Identifier\n"
2596 "VN address of NVE\n"
2597 "VN IPv4 interface address\n"
2598 "VN IPv6 interface address\n"
2599 "UN address of NVE\n"
2600 "UN IPv4 interface address\n"
2601 "UN IPv6 interface address\n"
2602 "Add/modify prefix related information\n"
2603 "IPv4 prefix\n" "IPv6 prefix\n")
2605 /* pfx vn un cost life */
2606 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2608 argv
[3], argv
[5], 0, NULL
);
2611 DEFUN (add_vnc_mac_vni_cost_life
,
2612 add_vnc_mac_vni_cost_life_cmd
,
2613 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255) lifetime (1-4294967295)",
2614 "Add registration\n"
2616 "Add/modify mac address information\n"
2618 "Virtual Network Identifier follows\n"
2619 "Virtual Network Identifier\n"
2620 "VN address of NVE\n"
2621 "VN IPv4 interface address\n"
2622 "VN IPv6 interface address\n"
2623 "UN address of NVE\n"
2624 "UN IPv4 interface address\n"
2625 "UN IPv6 interface address\n"
2626 "Administrative cost [default: 255]\n"
2627 "Administrative cost\n"
2628 "Registration lifetime [default: infinite]\n"
2629 "Lifetime value in seconds\n")
2631 /* pfx vn un cost life */
2632 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2634 argv
[3], argv
[5], 0, NULL
);
2638 DEFUN (add_vnc_mac_vni_cost
,
2639 add_vnc_mac_vni_cost_cmd
,
2640 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> cost (0-255)",
2641 "Add registration\n"
2643 "Add/modify mac address information\n"
2645 "Virtual Network Identifier follows\n"
2646 "Virtual Network Identifier\n"
2647 "VN address of NVE\n"
2648 "VN IPv4 interface address\n"
2649 "VN IPv6 interface address\n"
2650 "UN address of NVE\n"
2651 "UN IPv4 interface address\n"
2652 "UN IPv6 interface address\n"
2653 "Administrative cost [default: 255]\n" "Administrative cost\n")
2655 /* pfx vn un cost life */
2656 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2658 argv
[3], argv
[5], 0, NULL
);
2662 DEFUN (add_vnc_mac_vni_life
,
2663 add_vnc_mac_vni_life_cmd
,
2664 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X> lifetime (1-4294967295)",
2665 "Add registration\n"
2667 "Add/modify mac address information\n"
2669 "Virtual Network Identifier follows\n"
2670 "Virtual Network Identifier\n"
2671 "VN address of NVE\n"
2672 "VN IPv4 interface address\n"
2673 "VN IPv6 interface address\n"
2674 "UN address of NVE\n"
2675 "UN IPv4 interface address\n"
2676 "UN IPv6 interface address\n"
2677 "Registration lifetime [default: infinite]\n"
2678 "Lifetime value in seconds\n")
2680 /* pfx vn un cost life */
2681 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2683 argv
[3], argv
[5], 0, NULL
);
2687 DEFUN (add_vnc_mac_vni
,
2688 add_vnc_mac_vni_cmd
,
2689 "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn <A.B.C.D|X:X::X:X> un <A.B.C.D|X:X::X:X>",
2690 "Add registration\n"
2692 "Add/modify mac address information\n"
2694 "Virtual Network Identifier follows\n"
2695 "Virtual Network Identifier\n"
2696 "VN address of NVE\n"
2697 "VN IPv4 interface address\n"
2698 "VN IPv6 interface address\n"
2699 "UN address of NVE\n"
2700 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2702 /* pfx vn un cost life */
2703 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2705 argv
[3], argv
[5], 0, NULL
);
2708 /************************************************************************
2710 ************************************************************************/
2712 struct rfapi_local_reg_delete_arg
{
2717 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2718 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2719 struct prefix prefix
; /* AF==0: wildcard */
2720 struct prefix_rd rd
; /* plen!=64: wildcard */
2721 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2723 struct rfapi_l2address_option_match l2o
;
2731 uint32_t query_count
;
2733 uint32_t failed_pfx_count
;
2736 struct skiplist
*nves
;
2738 uint32_t remote_active_nve_count
;
2739 uint32_t remote_active_pfx_count
;
2740 uint32_t remote_holddown_nve_count
;
2741 uint32_t remote_holddown_pfx_count
;
2745 struct rfapi_ip_addr vn
;
2746 struct rfapi_ip_addr un
;
2747 struct rfapi_descriptor
*rfd
;
2748 struct rfapi_local_reg_delete_arg
*cda
;
2751 static void nve_addr_free(void *hap
)
2753 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2754 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2757 static int nve_addr_cmp(void *k1
, void *k2
)
2759 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2760 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2766 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2767 return (a
->un
.addr_family
- b
->un
.addr_family
);
2769 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2770 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2772 if (a
->un
.addr_family
== AF_INET
) {
2773 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2777 } else if (a
->un
.addr_family
== AF_INET6
) {
2778 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2785 if (a
->vn
.addr_family
== AF_INET
) {
2786 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2789 } else if (a
->vn
.addr_family
== AF_INET6
) {
2790 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2800 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2801 const char *arg_prefix
, const char *arg_vn
,
2802 const char *arg_un
, const char *arg_l2addr
,
2803 const char *arg_vni
, const char *arg_rd
,
2804 struct rfapi_nve_group_cfg
*arg_rfg
,
2805 struct rfapi_local_reg_delete_arg
*rcdarg
)
2807 int rc
= CMD_WARNING
;
2809 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2813 bgp
= bgp_get_default();
2815 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2817 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2818 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2819 &rcdarg
->vn_address
)))
2822 if (arg_un
&& strcmp(arg_un
, "*")) {
2823 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2824 &rcdarg
->un_address
)))
2827 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2829 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2830 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2837 vty_out(vty
, "Missing VNI\n");
2840 if (strcmp(arg_l2addr
, "*")) {
2841 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2842 &rcdarg
->l2o
.o
.macaddr
))) {
2843 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2847 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2849 if (strcmp(arg_vni
, "*")) {
2850 rcdarg
->l2o
.o
.logical_net_id
=
2851 strtoul(arg_vni
, NULL
, 10);
2852 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2856 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2857 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2866 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2867 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2868 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2869 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2870 struct rfapi_nve_group_cfg
*arg_rfg
,
2871 struct rfapi_local_reg_delete_arg
*rcdarg
)
2873 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2874 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2875 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2876 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2877 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2878 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2879 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2880 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2883 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2884 struct rfapi_ip_addr
*un_address
,
2885 struct rfapi_ip_addr
*vn_address
,
2886 struct rfapi_descriptor
*rfd
)
2889 struct nve_addr
*hap
;
2891 memset(&ha
, 0, sizeof(ha
));
2892 ha
.un
= *un_address
;
2893 ha
.vn
= *vn_address
;
2897 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2899 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2900 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2904 skiplist_insert(cda
->nves
, hap
, hap
);
2908 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2911 struct rfapi_descriptor
*rfd
;
2912 int query_count
= 0;
2913 struct listnode
*node
;
2914 struct bgp
*bgp_default
= bgp_get_default();
2916 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2920 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2921 &cda
->un_address
, &rfd
))
2925 rfapi_query_done_all(rfd
, &query_count
);
2926 cda
->query_count
+= query_count
;
2929 * Track unique nves seen
2931 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2942 h
= bgp_default
->rfapi
;
2947 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2949 * match un, vn addresses of NVEs
2951 if (cda
->un_address
.addr_family
2952 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2955 if (cda
->vn_address
.addr_family
2956 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2962 rfapi_query_done_all(rfd
, &query_count
);
2963 cda
->query_count
+= query_count
;
2966 * Track unique nves seen
2968 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2973 * TBD need to count deleted prefixes and nves?
2975 * ENXIO BGP or VNC not configured
2977 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2978 struct rfapi_descriptor
*rfd
)
2980 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2981 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2982 struct prefix
*pPrefix
; /* NULL = wildcard */
2983 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2985 struct rfapi_ip_prefix rprefix
;
2986 struct rfapi_next_hop_entry
*head
= NULL
;
2987 struct rfapi_next_hop_entry
*tail
= NULL
;
2990 vnc_zlog_debug_verbose("%s: entry", __func__
);
2993 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2994 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2995 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2996 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2999 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
3002 do /* to preserve old code structure */
3004 struct rfapi
*h
= cda
->bgp
->rfapi
;
3006 struct rfapi_adb
*adb
;
3008 int deleted_from_this_nve
;
3010 struct nve_addr
*hap
;
3013 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3017 * match un, vn addresses of NVEs
3019 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3021 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3025 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3032 deleted_from_this_nve
= 0;
3035 struct skiplist
*sl
;
3036 struct rfapi_ip_prefix rp
;
3038 struct list
*adb_delete_list
;
3041 * The advertisements are stored in a skiplist.
3043 * the registration deletes the advertisement from the
3044 * skiplist, which we can't do while iterating over that
3045 * same skiplist using the current skiplist API.
3047 * Strategy: iterate over the skiplist and build another
3048 * list containing only the matching ADBs. Then delete
3049 * _everything_ in that second list (which can be done
3050 * using either skiplists or quagga linklists).
3052 adb_delete_list
= list_new();
3055 * Advertised IP prefixes (not 0/32 or 0/128)
3057 sl
= rfd
->advertised
.ipN_by_prefix
;
3060 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3062 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3066 if (!prefix_same(pPrefix
,
3067 &adb
->u
.s
.prefix_ip
)) {
3069 vnc_zlog_debug_verbose(
3070 "%s: adb=%p, prefix doesn't match, skipping",
3077 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3081 vnc_zlog_debug_verbose(
3082 "%s: adb=%p, RD doesn't match, skipping",
3088 if (CHECK_FLAG(cda
->l2o
.flags
,
3089 RFAPI_L2O_MACADDR
)) {
3090 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3091 adb
->u
.s
.prefix_eth
.u
3095 vnc_zlog_debug_verbose(
3096 "%s: adb=%p, macaddr doesn't match, skipping",
3103 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3104 if (cda
->l2o
.o
.logical_net_id
3105 != adb
->l2o
.logical_net_id
) {
3107 vnc_zlog_debug_verbose(
3108 "%s: adb=%p, LNI doesn't match, skipping",
3116 vnc_zlog_debug_verbose(
3117 "%s: ipN adding adb %p to delete list",
3121 listnode_add(adb_delete_list
, adb
);
3124 struct listnode
*node
;
3126 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3127 int this_advertisement_prefix_count
;
3128 struct rfapi_vn_option optary
[3];
3129 struct rfapi_vn_option
*opt
= NULL
;
3132 this_advertisement_prefix_count
= 1;
3134 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3136 memset(optary
, 0, sizeof(optary
));
3138 /* if mac addr present in advert, make l2o vn
3140 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3142 opt
->next
= &optary
[cur_opt
];
3143 opt
= &optary
[cur_opt
++];
3144 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3145 opt
->v
.l2addr
.macaddr
=
3146 adb
->u
.s
.prefix_eth
.u
3148 ++this_advertisement_prefix_count
;
3151 * use saved RD value instead of trying to
3153 * complex RD computation in rfapi_register()
3156 opt
->next
= &optary
[cur_opt
];
3157 opt
= &optary
[cur_opt
++];
3158 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3159 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3162 vnc_zlog_debug_verbose(
3163 "%s: ipN killing reg from adb %p ",
3167 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3168 (cur_opt
? optary
: NULL
),
3169 RFAPI_REGISTER_KILL
);
3172 this_advertisement_prefix_count
;
3173 cda
->reg_count
+= 1;
3174 deleted_from_this_nve
= 1;
3176 if (h
->rfp_methods
.local_cb
) {
3177 rfapiAddDeleteLocalRfpPrefix(
3178 &rfd
->un_addr
, &rfd
->vn_addr
,
3179 &rp
, 0, 0, NULL
, &head
, &tail
);
3182 list_delete_all_node(adb_delete_list
);
3184 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3188 * Caller didn't specify a prefix, or specified
3193 * Advertised 0/32 and 0/128 (indexed by
3196 sl
= rfd
->advertised
.ip0_by_ether
;
3199 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3202 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3205 if (CHECK_FLAG(cda
->l2o
.flags
,
3206 RFAPI_L2O_MACADDR
)) {
3207 if (memcmp(cda
->l2o
.o
.macaddr
3209 adb
->u
.s
.prefix_eth
.u
3217 if (CHECK_FLAG(cda
->l2o
.flags
,
3219 if (cda
->l2o
.o
.logical_net_id
3220 != adb
->l2o
.logical_net_id
) {
3225 vnc_zlog_debug_verbose(
3226 "%s: ip0 adding adb %p to delete list",
3229 listnode_add(adb_delete_list
, adb
);
3233 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3236 struct rfapi_vn_option vn
;
3238 rfapiQprefix2Rprefix(
3239 &adb
->u
.s
.prefix_ip
, &rp
);
3241 memset(&vn
, 0, sizeof(vn
));
3242 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3243 vn
.v
.l2addr
= adb
->l2o
;
3246 vnc_zlog_debug_verbose(
3247 "%s: ip0 killing reg from adb %p ",
3251 rc
= rfapi_register(
3252 rfd
, &rp
, 0, NULL
, &vn
,
3253 RFAPI_REGISTER_KILL
);
3255 cda
->pfx_count
+= 1;
3256 cda
->reg_count
+= 1;
3257 deleted_from_this_nve
= 1;
3259 if (h
->rfp_methods
.local_cb
) {
3260 struct rfapi_vn_option
3264 rfapi_vn_options_dup(
3266 rfapiAddDeleteLocalRfpPrefix(
3268 &rfd
->vn_addr
, &rp
, 0,
3269 0, vn_opt_new
, &head
,
3273 list_delete_all_node(adb_delete_list
);
3275 list_delete_and_null(&adb_delete_list
);
3279 if (head
) { /* should not be set if (NULL ==
3280 rfapi_cfg->local_cb) */
3281 h
->flags
|= RFAPI_INCALLBACK
;
3282 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3283 h
->flags
&= ~RFAPI_INCALLBACK
;
3287 if (deleted_from_this_nve
) {
3289 * track unique NVEs seen
3291 memset(&ha
, 0, sizeof(ha
));
3292 ha
.un
= rfd
->un_addr
;
3293 ha
.vn
= rfd
->vn_addr
;
3296 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3298 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3299 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3300 sizeof(struct nve_addr
));
3304 skiplist_insert(cda
->nves
, hap
, hap
);
3307 } while (0); /* to preserve old code structure */
3312 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3317 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3318 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3320 struct bgp
*bgp
= cda
->bgp
;
3322 struct rfapi_cfg
*rfapi_cfg
;
3324 struct listnode
*node
;
3325 struct rfapi_descriptor
*rfd
;
3329 rfapi_cfg
= bgp
->rfapi_cfg
;
3330 if (!h
|| !rfapi_cfg
)
3332 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3334 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3335 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3344 * Deletes local and remote prefixes that match
3346 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3348 struct prefix pfx_un
;
3349 struct prefix pfx_vn
;
3351 struct prefix
*pUN
= NULL
;
3352 struct prefix
*pVN
= NULL
;
3353 struct prefix
*pPrefix
= NULL
;
3355 struct rfapi_import_table
*it
= NULL
;
3358 * Delete matching remote prefixes in holddown
3360 if (cda
->vn_address
.addr_family
) {
3361 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3364 if (cda
->un_address
.addr_family
) {
3365 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3368 if (cda
->prefix
.family
) {
3369 pPrefix
= &cda
->prefix
;
3372 it
= cda
->rfg
->rfapi_import_table
;
3374 rfapiDeleteRemotePrefixes(
3375 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3376 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3377 &cda
->remote_holddown_nve_count
);
3380 * Now do local prefixes
3382 rfapiDeleteLocalPrefixes(cda
);
3385 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3387 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3389 /* Our special element-deleting function counts nves */
3391 skiplist_free(cda
->nves
);
3394 if (cda
->failed_pfx_count
)
3395 vty_out(vty
, "Failed to delete %d prefixes\n",
3396 cda
->failed_pfx_count
);
3398 /* left as "prefixes" even in single case for ease of machine parsing */
3400 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3401 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3405 * We don't currently allow deletion of active remote prefixes from
3409 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3410 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3414 * Caller has already deleted registrations and queries for this/these
3415 * NVEs. Now we just have to close their descriptors.
3417 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3419 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3420 struct nve_addr
*pKey
;
3421 struct nve_addr
*pValue
;
3422 void *cursor
= NULL
;
3428 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3429 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3433 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3434 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3435 rfapi_close(pValue
->rfd
);
3440 DEFUN (clear_vnc_nve_all
,
3441 clear_vnc_nve_all_cmd
,
3445 "Clear per NVE information\n"
3449 struct rfapi_local_reg_delete_arg cda
;
3452 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3458 clear_vnc_responses(&cda
);
3459 clear_vnc_prefix(&cda
);
3460 clear_vnc_nve_closer(&cda
);
3462 print_cleared_stats(&cda
);
3467 DEFUN (clear_vnc_nve_vn_un
,
3468 clear_vnc_nve_vn_un_cmd
,
3469 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3472 "Clear prefix registration information\n"
3473 "VN address of NVE\n"
3475 "VN IPv4 interface address\n"
3476 "VN IPv6 interface address\n"
3477 "UN address of NVE\n"
3478 "For all UN addresses\n"
3479 "UN IPv4 interface address\n"
3480 "UN IPv6 interface address\n")
3482 struct rfapi_local_reg_delete_arg cda
;
3485 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3486 NULL
, NULL
, NULL
, &cda
)))
3491 clear_vnc_responses(&cda
);
3492 clear_vnc_prefix(&cda
);
3493 clear_vnc_nve_closer(&cda
);
3495 print_cleared_stats(&cda
);
3500 DEFUN (clear_vnc_nve_un_vn
,
3501 clear_vnc_nve_un_vn_cmd
,
3502 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3505 "Clear prefix registration information\n"
3506 "UN address of NVE\n"
3508 "UN IPv4 interface address\n"
3509 "UN IPv6 interface address\n"
3510 "VN address of NVE\n"
3512 "VN IPv4 interface address\n"
3513 "VN IPv6 interface address\n")
3515 struct rfapi_local_reg_delete_arg cda
;
3518 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3519 NULL
, NULL
, NULL
, &cda
)))
3524 clear_vnc_responses(&cda
);
3525 clear_vnc_prefix(&cda
);
3526 clear_vnc_nve_closer(&cda
);
3528 print_cleared_stats(&cda
);
3533 DEFUN (clear_vnc_nve_vn
,
3534 clear_vnc_nve_vn_cmd
,
3535 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3538 "Clear prefix registration information\n"
3539 "VN address of NVE\n"
3541 "VN IPv4 interface address\n"
3542 "VN IPv6 interface address\n")
3544 struct rfapi_local_reg_delete_arg cda
;
3547 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3548 NULL
, NULL
, NULL
, &cda
)))
3553 clear_vnc_responses(&cda
);
3554 clear_vnc_prefix(&cda
);
3555 clear_vnc_nve_closer(&cda
);
3557 print_cleared_stats(&cda
);
3561 DEFUN (clear_vnc_nve_un
,
3562 clear_vnc_nve_un_cmd
,
3563 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3566 "Clear prefix registration information\n"
3567 "UN address of NVE\n"
3569 "UN IPv4 interface address\n"
3570 "UN IPv6 interface address\n")
3572 struct rfapi_local_reg_delete_arg cda
;
3575 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3576 NULL
, NULL
, NULL
, &cda
)))
3581 clear_vnc_responses(&cda
);
3582 clear_vnc_prefix(&cda
);
3583 clear_vnc_nve_closer(&cda
);
3585 print_cleared_stats(&cda
);
3589 /*-------------------------------------------------
3591 *-------------------------------------------------*/
3594 * This function is defined in this file (rather than in rfp_registration.c)
3595 * because here we have access to all the task handles.
3597 DEFUN (clear_vnc_prefix_vn_un
,
3598 clear_vnc_prefix_vn_un_cmd
,
3599 "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>",
3602 "Clear prefix registration information\n"
3606 "VN address of NVE\n"
3607 "All VN addresses\n"
3608 "VN IPv4 interface address\n"
3609 "VN IPv6 interface address\n"
3610 "UN address of NVE\n"
3611 "All UN addresses\n"
3612 "UN IPv4 interface address\n"
3613 "UN IPv6 interface address\n")
3615 struct rfapi_local_reg_delete_arg cda
;
3618 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3619 NULL
, NULL
, NULL
, NULL
, &cda
)))
3622 clear_vnc_prefix(&cda
);
3623 print_cleared_stats(&cda
);
3627 DEFUN (clear_vnc_prefix_un_vn
,
3628 clear_vnc_prefix_un_vn_cmd
,
3629 "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>",
3632 "Clear prefix registration information\n"
3636 "UN address of NVE\n"
3637 "All UN addresses\n"
3638 "UN IPv4 interface address\n"
3639 "UN IPv6 interface address\n"
3640 "VN address of NVE\n"
3641 "All VN addresses\n"
3642 "VN IPv4 interface address\n"
3643 "VN IPv6 interface address\n")
3645 struct rfapi_local_reg_delete_arg cda
;
3648 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3649 NULL
, NULL
, NULL
, NULL
, &cda
)))
3652 clear_vnc_prefix(&cda
);
3653 print_cleared_stats(&cda
);
3657 DEFUN (clear_vnc_prefix_un
,
3658 clear_vnc_prefix_un_cmd
,
3659 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3662 "Clear prefix registration information\n"
3666 "UN address of NVE\n"
3667 "All UN addresses\n"
3668 "UN IPv4 interface address\n"
3669 "UN IPv6 interface address\n")
3671 struct rfapi_local_reg_delete_arg cda
;
3674 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3675 NULL
, NULL
, NULL
, &cda
)))
3678 clear_vnc_prefix(&cda
);
3679 print_cleared_stats(&cda
);
3683 DEFUN (clear_vnc_prefix_vn
,
3684 clear_vnc_prefix_vn_cmd
,
3685 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3688 "Clear prefix registration information\n"
3692 "UN address of NVE\n"
3693 "All VN addresses\n"
3694 "VN IPv4 interface address\n"
3695 "VN IPv6 interface address\n")
3697 struct rfapi_local_reg_delete_arg cda
;
3700 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3701 NULL
, NULL
, NULL
, &cda
)))
3704 clear_vnc_prefix(&cda
);
3705 print_cleared_stats(&cda
);
3709 DEFUN (clear_vnc_prefix_all
,
3710 clear_vnc_prefix_all_cmd
,
3711 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3714 "Clear prefix registration information\n"
3720 struct rfapi_local_reg_delete_arg cda
;
3723 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3724 NULL
, NULL
, NULL
, &cda
)))
3727 clear_vnc_prefix(&cda
);
3728 print_cleared_stats(&cda
);
3732 /*-------------------------------------------------
3734 *-------------------------------------------------*/
3737 * This function is defined in this file (rather than in rfp_registration.c)
3738 * because here we have access to all the task handles.
3740 DEFUN (clear_vnc_mac_vn_un
,
3741 clear_vnc_mac_vn_un_cmd
,
3742 "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>",
3745 "Clear mac registration information\n"
3749 "Any virtual network identifier\n"
3750 "Virtual network identifier\n"
3751 "VN address of NVE\n"
3752 "All VN addresses\n"
3753 "VN IPv4 interface address\n"
3754 "VN IPv6 interface address\n"
3755 "UN address of NVE\n"
3756 "All UN addresses\n"
3757 "UN IPv4 interface address\n"
3758 "UN IPv6 interface address\n")
3760 struct rfapi_local_reg_delete_arg cda
;
3763 /* pfx vn un L2 VNI */
3764 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3765 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3768 clear_vnc_prefix(&cda
);
3769 print_cleared_stats(&cda
);
3773 DEFUN (clear_vnc_mac_un_vn
,
3774 clear_vnc_mac_un_vn_cmd
,
3775 "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>",
3778 "Clear mac registration information\n"
3782 "Any virtual network identifier\n"
3783 "Virtual network identifier\n"
3784 "UN address of NVE\n"
3785 "All UN addresses\n"
3786 "UN IPv4 interface address\n"
3787 "UN IPv6 interface address\n"
3788 "VN address of NVE\n"
3789 "All VN addresses\n"
3790 "VN IPv4 interface address\n"
3791 "VN IPv6 interface address\n")
3793 struct rfapi_local_reg_delete_arg cda
;
3796 /* pfx vn un L2 VNI */
3797 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3798 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3801 clear_vnc_prefix(&cda
);
3802 print_cleared_stats(&cda
);
3806 DEFUN (clear_vnc_mac_un
,
3807 clear_vnc_mac_un_cmd
,
3808 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3811 "Clear mac registration information\n"
3815 "Any virtual network identifier\n"
3816 "Virtual network identifier\n"
3817 "UN address of NVE\n"
3818 "All UN addresses\n"
3819 "UN IPv4 interface address\n"
3820 "UN IPv6 interface address\n")
3822 struct rfapi_local_reg_delete_arg cda
;
3825 /* pfx vn un L2 VNI */
3826 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3827 argv
[5], NULL
, NULL
, &cda
)))
3830 clear_vnc_prefix(&cda
);
3831 print_cleared_stats(&cda
);
3835 DEFUN (clear_vnc_mac_vn
,
3836 clear_vnc_mac_vn_cmd
,
3837 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3840 "Clear mac registration information\n"
3844 "Any virtual network identifier\n"
3845 "Virtual network identifier\n"
3846 "UN address of NVE\n"
3847 "All VN addresses\n"
3848 "VN IPv4 interface address\n"
3849 "VN IPv6 interface address\n")
3851 struct rfapi_local_reg_delete_arg cda
;
3854 /* pfx vn un L2 VNI */
3855 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3856 argv
[5], NULL
, NULL
, &cda
)))
3859 clear_vnc_prefix(&cda
);
3860 print_cleared_stats(&cda
);
3864 DEFUN (clear_vnc_mac_all
,
3865 clear_vnc_mac_all_cmd
,
3866 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3869 "Clear mac registration information\n"
3873 "Any virtual network identifier\n"
3874 "Virtual network identifier\n"
3877 struct rfapi_local_reg_delete_arg cda
;
3880 /* pfx vn un L2 VNI */
3881 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3882 argv
[5], NULL
, NULL
, &cda
)))
3885 clear_vnc_prefix(&cda
);
3886 print_cleared_stats(&cda
);
3890 /*-------------------------------------------------
3891 * Clear VNC MAC PREFIX
3892 *-------------------------------------------------*/
3894 DEFUN (clear_vnc_mac_vn_un_prefix
,
3895 clear_vnc_mac_vn_un_prefix_cmd
,
3896 "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>",
3899 "Clear mac registration information\n"
3903 "Any virtual network identifier\n"
3904 "Virtual network identifier\n"
3905 "VN address of NVE\n"
3906 "All VN addresses\n"
3907 "VN IPv4 interface address\n"
3908 "VN IPv6 interface address\n"
3909 "UN address of NVE\n"
3910 "All UN addresses\n"
3911 "UN IPv4 interface address\n"
3912 "UN IPv6 interface address\n"
3913 "Clear prefix registration information\n"
3918 struct rfapi_local_reg_delete_arg cda
;
3921 /* pfx vn un L2 VNI */
3922 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3923 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3926 clear_vnc_prefix(&cda
);
3927 print_cleared_stats(&cda
);
3931 DEFUN (clear_vnc_mac_un_vn_prefix
,
3932 clear_vnc_mac_un_vn_prefix_cmd
,
3933 "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>",
3936 "Clear mac registration information\n"
3940 "Any virtual network identifier\n"
3941 "Virtual network identifier\n"
3942 "UN address of NVE\n"
3943 "All UN addresses\n"
3944 "UN IPv4 interface address\n"
3945 "UN IPv6 interface address\n"
3946 "VN address of NVE\n"
3947 "All VN addresses\n"
3948 "VN IPv4 interface address\n"
3949 "VN IPv6 interface address\n"
3950 "Clear prefix registration information\n"
3954 "Clear prefix registration information\n"
3959 struct rfapi_local_reg_delete_arg cda
;
3962 /* pfx vn un L2 VNI */
3963 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3964 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3967 clear_vnc_prefix(&cda
);
3968 print_cleared_stats(&cda
);
3972 DEFUN (clear_vnc_mac_un_prefix
,
3973 clear_vnc_mac_un_prefix_cmd
,
3974 "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>",
3977 "Clear mac registration information\n"
3981 "Any virtual network identifier\n"
3982 "Virtual network identifier\n"
3983 "UN address of NVE\n"
3984 "All UN addresses\n"
3985 "UN IPv4 interface address\n"
3986 "UN IPv6 interface address\n"
3987 "Clear prefix registration information\n"
3992 struct rfapi_local_reg_delete_arg cda
;
3995 /* pfx vn un L2 VNI */
3996 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3997 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4000 clear_vnc_prefix(&cda
);
4001 print_cleared_stats(&cda
);
4005 DEFUN (clear_vnc_mac_vn_prefix
,
4006 clear_vnc_mac_vn_prefix_cmd
,
4007 "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>",
4010 "Clear mac registration information\n"
4014 "Any virtual network identifier\n"
4015 "Virtual network identifier\n"
4016 "UN address of NVE\n"
4017 "All VN addresses\n"
4018 "VN IPv4 interface address\n"
4019 "VN IPv6 interface address\n"
4020 "Clear prefix registration information\n"
4025 struct rfapi_local_reg_delete_arg cda
;
4028 /* pfx vn un L2 VNI */
4029 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4030 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4033 clear_vnc_prefix(&cda
);
4034 print_cleared_stats(&cda
);
4038 DEFUN (clear_vnc_mac_all_prefix
,
4039 clear_vnc_mac_all_prefix_cmd
,
4040 "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>",
4043 "Clear mac registration information\n"
4047 "Any virtual network identifier\n"
4048 "Virtual network identifier\n"
4049 "UN address of NVE\n"
4050 "All VN addresses\n"
4051 "VN IPv4 interface address\n"
4052 "VN IPv6 interface address\n")
4054 struct rfapi_local_reg_delete_arg cda
;
4057 /* pfx vn un L2 VNI */
4058 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4059 argv
[5], NULL
, NULL
, &cda
)))
4062 clear_vnc_prefix(&cda
);
4063 print_cleared_stats(&cda
);
4067 /************************************************************************
4069 ************************************************************************/
4072 /* copied from rfp_vty.c */
4073 static int check_and_display_is_vnc_running(struct vty
*vty
)
4075 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4076 return 1; /* is running */
4079 vty_out(vty
, "VNC is not configured.\n");
4081 return 0; /* not running */
4084 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4085 show_nve_summary_t show_type
)
4087 struct bgp
*bgp_default
= bgp_get_default();
4089 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4091 int active_local_routes
;
4092 int active_remote_routes
;
4093 int holddown_remote_routes
;
4094 int imported_remote_routes
;
4099 h
= bgp_default
->rfapi
;
4104 /* don't show local info if not running RFP */
4105 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4107 switch (show_type
) {
4109 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4110 vty_out(vty
, "%-24s ", "NVEs:");
4111 vty_out(vty
, "%-8s %-8u ",
4112 "Active:", h
->descriptors
.count
);
4113 vty_out(vty
, "%-8s %-8u ",
4114 "Maximum:", h
->stat
.max_descriptors
);
4115 vty_out(vty
, "%-8s %-8u",
4116 "Unknown:", h
->stat
.count_unknown_nves
);
4119 case SHOW_NVE_SUMMARY_REGISTERED
:
4121 * NB: With the introduction of L2 route support, we no
4122 * longer have a one-to-one correspondence between
4123 * locally-originated route advertisements and routes in
4124 * the import tables that have local origin. This
4125 * discrepancy arises because a single advertisement
4126 * may contain both an IP prefix and a MAC address.
4127 * Such an advertisement results in two import table
4128 * entries: one indexed by IP prefix, the other indexed
4131 * TBD: update computation and display of registration
4132 * statistics to reflect the underlying semantics.
4134 if (is_vnc_running
) {
4135 vty_out(vty
, "%-24s ", "Registrations:");
4136 vty_out(vty
, "%-8s %-8u ", "Active:",
4137 rfapiApCountAll(bgp_default
));
4138 vty_out(vty
, "%-8s %-8u ", "Failed:",
4139 h
->stat
.count_registrations_failed
);
4140 vty_out(vty
, "%-8s %-8u",
4141 "Total:", h
->stat
.count_registrations
);
4144 vty_out(vty
, "%-24s ", "Prefixes registered:");
4147 rfapiCountAllItRoutes(&active_local_routes
,
4148 &active_remote_routes
,
4149 &holddown_remote_routes
,
4150 &imported_remote_routes
);
4153 if (is_vnc_running
) {
4154 vty_out(vty
, " %-20s ", "Locally:");
4155 vty_out(vty
, "%-8s %-8u ",
4156 "Active:", active_local_routes
);
4161 vty_out(vty
, " %-20s ", "Remotely:");
4162 vty_out(vty
, "%-8s %-8u",
4163 "Active:", active_remote_routes
);
4165 vty_out(vty
, " %-20s ", "In Holddown:");
4166 vty_out(vty
, "%-8s %-8u",
4167 "Active:", holddown_remote_routes
);
4169 vty_out(vty
, " %-20s ", "Imported:");
4170 vty_out(vty
, "%-8s %-8u",
4171 "Active:", imported_remote_routes
);
4174 case SHOW_NVE_SUMMARY_QUERIES
:
4175 vty_out(vty
, "%-24s ", "Queries:");
4176 vty_out(vty
, "%-8s %-8u ",
4177 "Active:", rfapi_monitor_count(NULL
));
4178 vty_out(vty
, "%-8s %-8u ",
4179 "Failed:", h
->stat
.count_queries_failed
);
4180 vty_out(vty
, "%-8s %-8u",
4181 "Total:", h
->stat
.count_queries
);
4184 case SHOW_NVE_SUMMARY_RESPONSES
:
4185 rfapiRibShowResponsesSummary(vty
);
4195 vty_out(vty
, "VNC is not configured.\n");
4199 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4200 struct prefix
*un_prefix
)
4202 // struct hash *rfds;
4203 // struct rfp_rfapi_descriptor_param param;
4205 struct bgp
*bgp_default
= bgp_get_default();
4207 struct listnode
*node
;
4208 struct rfapi_descriptor
*rfd
;
4217 h
= bgp_default
->rfapi
;
4222 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4226 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4228 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4231 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4239 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4240 if (!prefix_match(vn_prefix
, &pfx
))
4245 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4246 if (!prefix_match(un_prefix
, &pfx
))
4250 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4252 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4256 /* print out a header */
4258 " Active Next Hops\n");
4259 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4260 "VN Address", "UN Address", "Regis", "Resps",
4261 "Reach", "Remove", "Age");
4266 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4267 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4268 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4269 rfd
->stat_count_nh_removal
,
4270 rfapiFormatAge(rfd
->open_time
, age
, 10));
4273 if (printed
> 0 || vn_prefix
|| un_prefix
)
4274 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4280 vty_out(vty
, "VNC is not configured.\n");
4285 DEFUN (vnc_show_summary
,
4286 vnc_show_summary_cmd
,
4290 "Display VNC status summary\n")
4292 if (!check_and_display_is_vnc_running(vty
))
4294 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4296 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4297 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4298 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4299 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4303 DEFUN (vnc_show_nves
,
4308 "List known NVEs\n")
4310 rfapi_show_nves(vty
, NULL
, NULL
);
4314 DEFUN (vnc_show_nves_ptct
,
4315 vnc_show_nves_ptct_cmd
,
4316 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4320 "VN address of NVE\n"
4321 "UN address of NVE\n"
4322 "IPv4 interface address\n"
4323 "IPv6 interface address\n")
4327 if (!check_and_display_is_vnc_running(vty
))
4330 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4331 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4334 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4335 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4339 if (argv
[3]->arg
[0] == 'u') {
4340 rfapi_show_nves(vty
, NULL
, &pfx
);
4342 rfapi_show_nves(vty
, &pfx
, NULL
);
4348 /* adapted from rfp_registration_cache_log() */
4349 static void rfapi_show_registrations(struct vty
*vty
,
4350 struct prefix
*restrict_to
, int show_local
,
4351 int show_remote
, int show_holddown
,
4359 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4362 /* non-expiring, local */
4363 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4367 /* non-expiring, non-local */
4368 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4371 if (show_holddown
) {
4372 /* expiring, including local */
4373 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4376 if (show_imported
) {
4377 /* non-expiring, non-local */
4378 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4386 DEFUN (vnc_show_registrations_pfx
,
4387 vnc_show_registrations_pfx_cmd
,
4388 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4391 "List active prefix registrations\n"
4392 "Limit output to a particular IPv4 prefix\n"
4393 "Limit output to a particular IPv6 prefix\n"
4394 "Limit output to a particular IPv6 address\n")
4397 struct prefix
*p_addr
= NULL
;
4400 if (!str2prefix(argv
[3]->arg
, &p
)) {
4401 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4408 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4412 DEFUN (vnc_show_registrations_some_pfx
,
4413 vnc_show_registrations_some_pfx_cmd
,
4414 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4417 "List active prefix registrations\n"
4418 "show all registrations\n"
4419 "show only registrations in holddown\n"
4420 "show only imported prefixes\n"
4421 "show only local registrations\n"
4422 "show only remote registrations\n"
4423 "Limit output to a particular prefix or address\n"
4424 "Limit output to a particular prefix or address\n"
4425 "Limit output to a particular prefix or address\n")
4428 struct prefix
*p_addr
= NULL
;
4431 int show_remote
= 0;
4432 int show_holddown
= 0;
4433 int show_imported
= 0;
4436 if (!str2prefix(argv
[4]->arg
, &p
)) {
4437 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4443 switch (argv
[3]->arg
[0]) {
4468 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4469 show_holddown
, show_imported
);
4473 DEFUN (vnc_show_responses_pfx
,
4474 vnc_show_responses_pfx_cmd
,
4475 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4478 "List recent query responses\n"
4479 "Limit output to a particular IPv4 prefix\n"
4480 "Limit output to a particular IPv6 prefix\n"
4481 "Limit output to a particular IPv6 address\n" )
4484 struct prefix
*p_addr
= NULL
;
4487 if (!str2prefix(argv
[3]->arg
, &p
)) {
4488 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4494 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4496 rfapiRibShowResponsesSummary(vty
);
4498 rfapiRibShowResponses(vty
, p_addr
, 0);
4499 rfapiRibShowResponses(vty
, p_addr
, 1);
4504 DEFUN (vnc_show_responses_some_pfx
,
4505 vnc_show_responses_some_pfx_cmd
,
4506 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4509 "List recent query responses\n"
4510 "show only active query responses\n"
4511 "show only removed query responses\n"
4512 "Limit output to a particular IPv4 prefix\n"
4513 "Limit output to a particular IPv6 prefix\n"
4514 "Limit output to a particular IPV6 address\n")
4517 struct prefix
*p_addr
= NULL
;
4519 int show_active
= 0;
4520 int show_removed
= 0;
4522 if (!check_and_display_is_vnc_running(vty
))
4526 if (!str2prefix(argv
[4]->arg
, &p
)) {
4527 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4534 switch (argv
[3]->arg
[0]) {
4544 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4546 rfapiRibShowResponsesSummary(vty
);
4549 rfapiRibShowResponses(vty
, p_addr
, 0);
4551 rfapiRibShowResponses(vty
, p_addr
, 1);
4556 DEFUN (show_vnc_queries_pfx
,
4557 show_vnc_queries_pfx_cmd
,
4558 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4561 "List active queries\n"
4562 "Limit output to a particular IPv4 prefix or address\n"
4563 "Limit output to a particular IPv6 prefix\n"
4564 "Limit output to a particualr IPV6 address\n")
4567 struct prefix
*p
= NULL
;
4570 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4571 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4577 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4579 return rfapiShowVncQueries(vty
, p
);
4582 DEFUN (vnc_clear_counters
,
4583 vnc_clear_counters_cmd
,
4584 "clear vnc counters",
4587 "Reset VNC counters\n")
4589 struct bgp
*bgp_default
= bgp_get_default();
4591 struct listnode
*node
;
4592 struct rfapi_descriptor
*rfd
;
4597 h
= bgp_default
->rfapi
;
4603 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4604 rfd
->stat_count_nh_reachable
= 0;
4605 rfd
->stat_count_nh_removal
= 0;
4609 memset(&h
->stat
, 0, sizeof(h
->stat
));
4612 * 151122 per bug 103, set count_registrations = number active.
4613 * Do same for queries
4615 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4616 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4618 rfapiRibShowResponsesSummaryClear();
4623 vty_out(vty
, "VNC is not configured.\n");
4627 /************************************************************************
4628 * Add prefix with vrf
4630 * add [vrf <vrf-name>] prefix <prefix>
4631 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4632 ************************************************************************/
4633 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4635 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4636 /* based on rfapi_open */
4637 struct rfapi_descriptor
*rfd
;
4639 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4640 sizeof(struct rfapi_descriptor
));
4643 /* leave most fields empty as will get from (dynamic) config
4645 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4647 if (rfg
->vn_prefix
.family
4648 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4649 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4651 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4652 rfd
->vn_addr
.addr_family
= AF_INET
;
4653 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4655 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4657 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4659 rfapi_init_and_open(bgp
, rfd
, rfg
);
4663 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4664 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4665 const char *arg_prefix
,
4666 const char *arg_rd
, /* optional */
4667 const char *arg_label
, /* optional */
4668 const char *arg_pref
) /* optional */
4671 struct rfapi_nve_group_cfg
*rfg
;
4673 struct rfapi_ip_prefix rpfx
;
4675 struct rfapi_vn_option optary
[3];
4676 struct rfapi_vn_option
*opt
= NULL
;
4679 bgp
= bgp_get_default(); /* assume main instance for now */
4681 vty_out(vty
, "No BGP process is configured\n");
4682 return CMD_WARNING_CONFIG_FAILED
;
4684 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4685 vty_out(vty
, "VRF support not configured\n");
4686 return CMD_WARNING_CONFIG_FAILED
;
4689 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4692 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4694 return CMD_WARNING_CONFIG_FAILED
;
4696 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4698 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4700 return CMD_WARNING_CONFIG_FAILED
;
4702 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4704 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4706 return CMD_WARNING_CONFIG_FAILED
;
4708 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4710 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4712 return CMD_WARNING_CONFIG_FAILED
;
4714 if (!str2prefix(arg_prefix
, &pfx
)) {
4715 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4716 return CMD_WARNING_CONFIG_FAILED
;
4718 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4719 memset(optary
, 0, sizeof(optary
));
4722 opt
->next
= &optary
[cur_opt
];
4723 opt
= &optary
[cur_opt
++];
4724 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4725 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4726 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4727 return CMD_WARNING_CONFIG_FAILED
;
4730 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4731 struct rfapi_l2address_option
*l2o
;
4733 opt
->next
= &optary
[cur_opt
];
4734 opt
= &optary
[cur_opt
++];
4735 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4736 l2o
= &opt
->v
.l2addr
;
4739 label
= strtoul(arg_label
, NULL
, 10);
4742 l2o
->label
= rfg
->label
;
4745 char *endptr
= NULL
;
4746 pref
= strtoul(arg_pref
, &endptr
, 10);
4747 if (*endptr
!= '\0') {
4749 "%% Invalid local-preference value \"%s\"\n",
4751 return CMD_WARNING_CONFIG_FAILED
;
4754 rpfx
.cost
= 255 - (pref
& 255);
4755 vnc_add_vrf_opener(bgp
, rfg
);
4757 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4758 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4759 struct rfapi_next_hop_entry
*head
= NULL
;
4760 struct rfapi_next_hop_entry
*tail
= NULL
;
4761 struct rfapi_vn_option
*vn_opt_new
;
4763 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4766 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4767 struct rfapi_descriptor
*r
=
4768 (struct rfapi_descriptor
*)rfg
->rfd
;
4769 vn_opt_new
= rfapi_vn_options_dup(opt
);
4771 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4773 RFAPI_INFINITE_LIFETIME
,
4774 vn_opt_new
, &head
, &tail
);
4776 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4777 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4779 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4783 vnc_zlog_debug_verbose(
4784 "%s completed, count=%d/%d", __func__
,
4785 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4786 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4790 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4791 vty_out(vty
, "Add failed.\n");
4792 return CMD_WARNING_CONFIG_FAILED
;
4795 DEFUN (add_vrf_prefix_rd_label_pref
,
4796 add_vrf_prefix_rd_label_pref_cmd
,
4797 "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)}]",
4801 "Add/modify prefix related information\n"
4804 "Override configured VRF Route Distinguisher\n"
4805 "<as-number>:<number> or <ip-address>:<number>\n"
4806 "Override configured VRF label\n"
4807 "Label Value <0-1048575>\n"
4808 "Set advertised local preference\n"
4809 "local preference (higher=more preferred)\n")
4811 char *arg_vrf
= argv
[2]->arg
;
4812 char *arg_prefix
= argv
[4]->arg
;
4813 char *arg_rd
= NULL
; /* optional */
4814 char *arg_label
= NULL
; /* optional */
4815 char *arg_pref
= NULL
; /* optional */
4817 argc
--; /* don't parse argument */
4818 while (pargc
< argc
) {
4819 switch (argv
[pargc
++]->arg
[0]) {
4821 arg_rd
= argv
[pargc
]->arg
;
4824 arg_label
= argv
[pargc
]->arg
;
4827 arg_pref
= argv
[pargc
]->arg
;
4835 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4839 /************************************************************************
4840 * del prefix with vrf
4842 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4843 ************************************************************************/
4844 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4847 afi_t afi
= AFI_MAX
;
4849 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4854 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4856 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4861 /* check if IT is empty */
4863 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4867 if (afi
== AFI_MAX
) {
4868 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4873 vnc_zlog_debug_verbose(
4874 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4875 rfg
->rfapi_import_table
->local_count
[afi
]);
4879 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4880 const char *arg_prefix
, /* NULL = all */
4881 const char *arg_rd
) /* optional */
4883 struct rfapi_nve_group_cfg
*rfg
;
4884 struct rfapi_local_reg_delete_arg cda
;
4889 bgp
= bgp_get_default(); /* assume main instance for now */
4891 vty_out(vty
, "No BGP process is configured\n");
4894 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4895 vty_out(vty
, "VRF support not configured\n");
4898 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4901 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4905 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4907 if (rc
!= CMD_SUCCESS
) /* parse error */
4910 start_count
= rfapi_cfg_group_it_count(rfg
);
4911 clear_vnc_prefix(&cda
);
4912 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4917 DEFUN (clear_vrf_prefix_rd
,
4918 clear_vrf_prefix_rd_cmd
,
4919 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4920 "Clear stored data\n"
4923 "Prefix related information\n"
4926 "Specific VRF Route Distinguisher\n"
4927 "<as-number>:<number> or <ip-address>:<number>\n")
4929 char *arg_vrf
= argv
[2]->arg
;
4930 char *arg_prefix
= NULL
; /* optional */
4931 char *arg_rd
= NULL
; /* optional */
4933 argc
--; /* don't check parameter */
4934 while (pargc
< argc
) {
4935 switch (argv
[pargc
++]->arg
[0]) {
4937 arg_rd
= argv
[pargc
]->arg
;
4940 arg_prefix
= argv
[pargc
]->arg
;
4947 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4950 DEFUN (clear_vrf_all
,
4952 "clear vrf NAME all",
4953 "Clear stored data\n"
4958 char *arg_vrf
= argv
[2]->arg
;
4959 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4962 void rfapi_vty_init()
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4966 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4967 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4968 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4981 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4982 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4983 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4985 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4989 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4990 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4996 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
5002 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5007 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5008 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5009 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5011 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5012 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5014 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5016 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5017 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5018 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5021 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5022 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5023 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5024 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);