3 * Copyright 2009-2016, LabN Consulting, L.L.C.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "lib/zebra.h"
22 #include "lib/prefix.h"
23 #include "lib/agg_table.h"
25 #include "lib/memory.h"
26 #include "lib/routemap.h"
28 #include "lib/log_int.h"
29 #include "lib/linklist.h"
30 #include "lib/command.h"
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_ecommunity.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_mplsvpn.h"
38 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
39 #include "bgpd/rfapi/rfapi.h"
40 #include "bgpd/rfapi/rfapi_backend.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_aspath.h"
44 #include "bgpd/bgp_community.h"
45 #include "bgpd/bgp_vnc_types.h"
46 #include "bgpd/bgp_label.h"
48 #include "bgpd/rfapi/rfapi_import.h"
49 #include "bgpd/rfapi/rfapi_private.h"
50 #include "bgpd/rfapi/rfapi_monitor.h"
51 #include "bgpd/rfapi/rfapi_rib.h"
52 #include "bgpd/rfapi/rfapi_vty.h"
53 #include "bgpd/rfapi/rfapi_ap.h"
54 #include "bgpd/rfapi/rfapi_encap_tlv.h"
55 #include "bgpd/rfapi/vnc_debug.h"
57 #define DEBUG_L2_EXTRA 0
58 #define DEBUG_SHOW_EXTRA 0
60 #define VNC_SHOW_STR "VNC information\n"
62 /* format related utilies */
65 #define FMT_MIN 60 /* seconds */
66 #define FMT_HOUR (60 * FMT_MIN)
67 #define FMT_DAY (24 * FMT_HOUR)
68 #define FMT_YEAR (365 * FMT_DAY)
70 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
72 int year
, day
, hour
, min
;
74 if (seconds
>= FMT_YEAR
) {
75 year
= seconds
/ FMT_YEAR
;
76 seconds
-= year
* FMT_YEAR
;
80 if (seconds
>= FMT_DAY
) {
81 day
= seconds
/ FMT_DAY
;
82 seconds
-= day
* FMT_DAY
;
86 if (seconds
>= FMT_HOUR
) {
87 hour
= seconds
/ FMT_HOUR
;
88 seconds
-= hour
* FMT_HOUR
;
92 if (seconds
>= FMT_MIN
) {
93 min
= seconds
/ FMT_MIN
;
94 seconds
-= min
* FMT_MIN
;
99 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
100 } else if (day
> 0) {
101 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
103 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
109 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
111 time_t now
, age_adjusted
;
113 now
= rfapi_time(NULL
);
114 age_adjusted
= now
- age
;
116 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
121 * Reimplementation of quagga/lib/prefix.c function, but
122 * for RFAPI-style prefixes
124 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
130 static uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
131 0xf8, 0xfc, 0xfe, 0xff};
133 switch (rprefix
->prefix
.addr_family
) {
135 index
= rprefix
->length
/ 8;
137 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
138 offset
= rprefix
->length
% 8;
139 pnt
[index
] &= maskbit
[offset
];
147 index
= rprefix
->length
/ 8;
149 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
150 offset
= rprefix
->length
% 8;
151 pnt
[index
] &= maskbit
[offset
];
164 * translate a quagga prefix into a rfapi IP address. The
165 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
172 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
174 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
175 raddr
->addr_family
= qprefix
->family
;
176 switch (qprefix
->family
) {
178 if (qprefix
->prefixlen
!= 32)
180 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
183 if (qprefix
->prefixlen
!= 128)
185 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
194 * Translate Quagga prefix to RFAPI prefix
196 /* rprefix->cost set to 0 */
197 void rfapiQprefix2Rprefix(struct prefix
*qprefix
,
198 struct rfapi_ip_prefix
*rprefix
)
200 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
201 rprefix
->length
= qprefix
->prefixlen
;
202 rprefix
->prefix
.addr_family
= qprefix
->family
;
203 switch (qprefix
->family
) {
205 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
208 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
215 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
216 struct prefix
*qprefix
)
218 memset(qprefix
, 0, sizeof(struct prefix
));
219 qprefix
->prefixlen
= rprefix
->length
;
220 qprefix
->family
= rprefix
->prefix
.addr_family
;
222 switch (rprefix
->prefix
.addr_family
) {
224 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
227 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
236 * returns 1 if prefixes have same addr family, prefix len, and address
237 * Note that host bits matter in this comparison!
239 * For paralellism with quagga/lib/prefix.c. if we need a comparison
240 * where host bits are ignored, call that function rfapiRprefixCmp.
242 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
244 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
246 if (hp1
->length
!= hp2
->length
)
248 if (hp1
->prefix
.addr_family
== AF_INET
)
249 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
251 if (hp1
->prefix
.addr_family
== AF_INET6
)
252 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
257 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
259 memset(pfx
, 0, sizeof(struct prefix
));
260 pfx
->family
= hia
->addr_family
;
262 switch (hia
->addr_family
) {
265 pfx
->u
.prefix4
= hia
->addr
.v4
;
268 pfx
->prefixlen
= 128;
269 pfx
->u
.prefix6
= hia
->addr
.v6
;
277 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
279 memset(pfx
, 0, sizeof(struct prefix
));
280 pfx
->family
= AF_ETHERNET
;
282 pfx
->u
.prefix_eth
= l2o
->macaddr
;
285 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
287 return prefix_mac2str(ea
, buf
, bufsize
);
290 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
295 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
302 for (i
= 0; i
< 6; ++i
)
303 ea
->octet
[i
] = a
[i
] & 0xff;
308 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
310 if (af
== AF_ETHERNET
) {
311 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
314 return inet_ntop(af
, src
, buf
, size
);
317 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
320 va_start(args
, format
);
321 vzlog(LOG_DEBUG
, format
, args
);
326 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
331 va_start(args
, format
);
333 switch ((uintptr_t)stream
) {
344 vfprintf(file
, format
, args
);
349 /* Fake out for debug logging */
350 static struct vty vty_dummy_zlog
;
351 static struct vty vty_dummy_stdio
;
352 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
354 static const char *str_vty_newline(struct vty
*vty
)
356 if (vty
== &vty_dummy_zlog
)
361 int rfapiStream2Vty(void *stream
, /* input */
362 int (**fp
)(void *, const char *, ...), /* output */
363 struct vty
**vty
, /* output */
364 void **outstream
, /* output */
365 const char **vty_newline
) /* output */
369 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
370 *vty
= &vty_dummy_zlog
;
371 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
373 *vty_newline
= str_vty_newline(*vty
);
374 return (vzlog_test(LOG_DEBUG
));
377 if (((uintptr_t)stream
== (uintptr_t)1)
378 || ((uintptr_t)stream
== (uintptr_t)2)) {
380 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
381 *vty
= &vty_dummy_stdio
;
382 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
384 *vty_newline
= str_vty_newline(*vty
);
388 *vty
= stream
; /* VTYNL requires vty to be legit */
389 *fp
= (int (*)(void *, const char *, ...))vty_out
;
391 *vty_newline
= str_vty_newline(*vty
);
395 /* called from bgpd/bgp_vty.c'route_vty_out() */
396 void rfapi_vty_out_vncinfo(struct vty
*vty
, struct prefix
*p
,
397 struct bgp_info
*bi
, safi_t safi
)
403 * Print, on an indented line:
404 * UN address [if VPN route and VNC UN addr subtlv]
410 if (safi
== SAFI_MPLS_VPN
) {
411 struct prefix pfx_un
;
413 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
415 vty_out(vty
, "UN=%s",
416 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
421 if (bi
->attr
&& bi
->attr
->ecommunity
) {
422 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
423 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
424 vty_out(vty
, " EC{%s}", s
);
425 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
428 if (bi
->extra
!= NULL
) {
429 if (bi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
430 vty_out(vty
, " label=VRF2VRF");
432 vty_out(vty
, " label=%u",
433 decode_label(&bi
->extra
->label
[0]));
436 if (!rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
437 vty_out(vty
, " life=%d", lifetime
);
440 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bi
->type
),
443 vty_out(vty
, "%s", HVTYNL
);
446 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
448 int (*fp
)(void *, const char *, ...);
451 const char *vty_newline
;
455 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
458 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
463 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
464 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
466 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
467 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
468 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
469 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
471 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
472 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
473 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
474 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
475 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
476 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
480 * Print BI in an Import Table
482 void rfapiPrintBi(void *stream
, struct bgp_info
*bi
)
487 int (*fp
)(void *, const char *, ...);
490 const char *vty_newline
;
496 struct ethaddr macaddr
= {{0}};
497 struct rfapi_l2address_option l2o_buf
;
498 uint8_t l2hid
= 0; /* valid if has_macaddr */
500 #define REMAIN (BUFSIZ - (p-line))
501 #define INCP {p += (r > REMAIN)? REMAIN: r;}
503 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
509 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
510 && bi
->extra
->vnc
.import
.timer
) {
511 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
512 r
= snprintf(p
, REMAIN
, " [%4lu] ",
513 thread_timer_remain_second(t
));
517 r
= snprintf(p
, REMAIN
, " ");
522 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
523 if (decode_rd_type(bi
->extra
->vnc
.import
.rd
.val
)
524 == RD_TYPE_VNC_ETH
) {
526 memcpy(macaddr
.octet
, bi
->extra
->vnc
.import
.rd
.val
+ 2,
528 l2hid
= bi
->extra
->vnc
.import
.rd
.val
[1];
537 * RFP option sizes (they are opaque values)
538 * extended communities (RTs)
542 int printed_1st_gol
= 0;
543 struct bgp_attr_encap_subtlv
*pEncap
;
544 struct prefix pfx_un
;
545 int af
= BGP_MP_NEXTHOP_FAMILY(bi
->attr
->mp_nexthop_len
);
549 r
= snprintf(p
, REMAIN
, "%s",
551 &bi
->attr
->mp_nexthop_global_in
,
554 } else if (af
== AF_INET6
) {
555 r
= snprintf(p
, REMAIN
, "%s",
557 &bi
->attr
->mp_nexthop_global
,
561 r
= snprintf(p
, REMAIN
, "?");
566 * VNC tunnel subtlv, if present, contains UN address
568 if (!rfapiGetVncTunnelUnAddr(bi
->attr
, &pfx_un
)) {
569 r
= snprintf(p
, REMAIN
, " un=%s",
570 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
576 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)) {
577 r
= snprintf(p
, REMAIN
, " nolife");
580 if (lifetime
== 0xffffffff)
581 r
= snprintf(p
, REMAIN
, " %6s", "infini");
583 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
587 /* RFP option lengths */
588 for (pEncap
= bi
->attr
->vnc_subtlvs
; pEncap
;
589 pEncap
= pEncap
->next
) {
591 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
592 if (printed_1st_gol
) {
593 r
= snprintf(p
, REMAIN
, ",");
596 r
= snprintf(p
, REMAIN
,
597 " "); /* leading space */
600 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
607 if (bi
->attr
->ecommunity
) {
608 s
= ecommunity_ecom2str(bi
->attr
->ecommunity
,
609 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
610 r
= snprintf(p
, REMAIN
, " %s", s
);
612 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
616 r
= snprintf(p
, REMAIN
, " bi@%p", bi
);
619 r
= snprintf(p
, REMAIN
, " p@%p", bi
->peer
);
622 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
623 r
= snprintf(p
, REMAIN
, " HD=yes");
626 r
= snprintf(p
, REMAIN
, " HD=no");
632 if (bi
->attr
->weight
) {
633 r
= snprintf(p
, REMAIN
, " W=%d", bi
->attr
->weight
);
637 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
638 r
= snprintf(p
, REMAIN
, " LP=%d", bi
->attr
->local_pref
);
641 r
= snprintf(p
, REMAIN
, " LP=unset");
646 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bi
->type
),
650 fp(out
, "%s%s", line
, HVTYNL
);
653 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
654 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
655 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
659 if (!rfapiGetL2o(bi
->attr
, &l2o_buf
)) {
661 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
662 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
663 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
664 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
665 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
668 if (bi
->extra
&& bi
->extra
->vnc
.import
.aux_prefix
.family
) {
672 sp
= rfapi_ntop(bi
->extra
->vnc
.import
.aux_prefix
.family
,
673 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
, buf
,
677 fp(out
, " IP: %s%s", sp
, HVTYNL
);
681 struct rfapi_un_option
*uo
=
682 rfapi_encap_tlv_to_un_option(bi
->attr
);
684 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
685 rfapi_un_options_free(uo
);
690 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
692 char buf_pfx
[BUFSIZ
];
697 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
698 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
700 rc
= snprintf(buf
, size
,
701 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
702 m
->next
, m
->rfd
, buf_vn
, buf_un
,
703 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
704 m
->p
.prefixlen
, m
->node
);
711 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
715 int (*fp
)(void *, const char *, ...);
718 const char *vty_newline
;
720 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
723 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
724 fp(out
, " Mon %s%s", buf
, HVTYNL
);
727 static void rfapiDebugPrintMonitorEncap(void *stream
,
728 struct rfapi_monitor_encap
*m
)
730 int (*fp
)(void *, const char *, ...);
733 const char *vty_newline
;
735 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
738 fp(out
, " Mon m=%p, next=%p, node=%p, bi=%p%s", m
, m
->next
, m
->node
,
742 void rfapiShowItNode(void *stream
, struct agg_node
*rn
)
747 int (*fp
)(void *, const char *, ...);
750 const char *vty_newline
;
752 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
755 fp(out
, "%s/%d @%p #%d%s",
756 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
),
757 rn
->p
.prefixlen
, rn
, rn
->lock
, HVTYNL
);
759 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
760 rfapiPrintBi(stream
, bi
);
763 /* doesn't show montors */
766 void rfapiShowImportTable(void *stream
, const char *label
, struct agg_table
*rt
,
772 int (*fp
)(void *, const char *, ...);
775 const char *vty_newline
;
777 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
780 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
782 for (rn
= agg_route_top(rt
); rn
; rn
= agg_route_next(rn
)) {
785 if (rn
->p
.family
== AF_ETHERNET
) {
786 rfapiEthAddr2Str(&rn
->p
.u
.prefix_eth
, buf
, BUFSIZ
);
788 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
);
791 fp(out
, "%s/%d @%p #%d%s", buf
, rn
->p
.prefixlen
, rn
,
792 rn
->lock
- 1, /* account for loop iterator locking */
795 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
796 rfapiPrintBi(stream
, bi
);
800 struct rfapi_monitor_vpn
*m
;
801 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
802 rfapiDebugPrintMonitorVpn(stream
, m
);
805 struct rfapi_monitor_encap
*m
;
806 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
807 rfapiDebugPrintMonitorEncap(stream
, m
);
813 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
817 struct listnode
*node
;
818 struct rfapi_descriptor
*rfd
;
820 int (*fp
)(void *, const char *, ...);
823 const char *vty_newline
;
825 int printedheader
= 0;
828 int nves_with_queries
= 0;
829 int nves_displayed
= 0;
831 int queries_total
= 0;
832 int queries_displayed
= 0;
834 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
837 bgp
= bgp_get_default(); /* assume 1 instance for now */
839 vty_out(vty
, "No BGP instance\n");
845 vty_out(vty
, "No RFAPI instance\n");
849 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
852 int printedquerier
= 0;
858 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
868 for (rn
= agg_route_top(rfd
->mon
); rn
;
869 rn
= agg_route_next(rn
)) {
870 struct rfapi_monitor_vpn
*m
;
871 char buf_remain
[BUFSIZ
];
872 char buf_pfx
[BUFSIZ
];
882 && !prefix_match(pfx_match
, &rn
->p
)
883 && !prefix_match(&rn
->p
, pfx_match
))
888 if (!printedheader
) {
891 fp(out
, "%-15s %-15s %-15s %-10s\n",
892 "VN Address", "UN Address", "Target",
896 if (!printedquerier
) {
900 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
902 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
905 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
910 fp(out
, "%-15s %-15s", "", "");
914 thread_timer_remain_second(
918 fp(out
, " %-15s %-10s\n",
919 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
928 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
932 struct rfapi_monitor_eth
*mon_eth
;
935 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
936 (void **)&mon_eth
, &cursor
);
938 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
939 (void **)&mon_eth
, &cursor
)) {
941 char buf_remain
[BUFSIZ
];
942 char buf_pfx
[BUFSIZ
];
943 struct prefix pfx_mac
;
947 vnc_zlog_debug_verbose(
948 "%s: checking rfd=%p mon_eth=%p",
949 __func__
, rfd
, mon_eth
);
951 memset((void *)&pfx_mac
, 0,
952 sizeof(struct prefix
));
953 pfx_mac
.family
= AF_ETHERNET
;
954 pfx_mac
.prefixlen
= 48;
955 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
958 && !prefix_match(pfx_match
, &pfx_mac
)
959 && !prefix_match(&pfx_mac
, pfx_match
))
964 if (!printedheader
) {
968 "%-15s %-15s %-17s %10s %-10s\n",
969 "VN Address", "UN Address", "Target",
973 if (!printedquerier
) {
977 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
979 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
982 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
987 fp(out
, "%-15s %-15s", "", "");
989 if (mon_eth
->timer
) {
991 thread_timer_remain_second(
995 fp(out
, " %-17s %10d %-10s\n",
996 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
998 mon_eth
->logical_net_id
, buf_remain
);
1003 if (queries_total
) {
1005 fp(out
, "Displayed %d out of %d total queries\n",
1006 queries_displayed
, queries_total
);
1011 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1012 struct agg_node
*rn
, struct bgp_info
*bi
)
1014 int (*fp
)(void *, const char *, ...);
1017 const char *vty_newline
;
1018 struct prefix pfx_un
;
1019 struct prefix pfx_vn
;
1022 bgp_encap_types tun_type
;
1024 char buf_pfx
[BUFSIZ
];
1025 char buf_ntop
[BUFSIZ
];
1026 char buf_un
[BUFSIZ
];
1027 char buf_vn
[BUFSIZ
];
1028 char buf_lifetime
[BUFSIZ
];
1032 return 0; /* for debug log, print into buf & call output once */
1034 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1041 snprintf(buf_pfx
, BUFSIZ
, "%s/%d",
1042 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf_ntop
, BUFSIZ
),
1044 buf_pfx
[BUFSIZ
- 1] = 0;
1051 if (!rfapiGetUnAddrOfVpnBi(bi
, &pfx_un
)) {
1052 snprintf(buf_un
, BUFSIZ
, "%s",
1053 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1057 rfapiGetTunnelType(bi
->attr
, &tun_type
);
1062 rfapiNexthop2Prefix(bi
->attr
, &pfx_vn
);
1063 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1064 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1066 snprintf(buf_un
, BUFSIZ
, "%s",
1067 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1070 uint32_t l
= decode_label(&bi
->extra
->label
[0]);
1071 snprintf(buf_vn
, BUFSIZ
, "Label: %d", l
);
1072 } else /* should never happen */
1074 snprintf(buf_vn
, BUFSIZ
, "Label: N/A");
1077 snprintf(buf_vn
, BUFSIZ
, "%s",
1078 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1081 buf_vn
[BUFSIZ
- 1] = 0;
1082 buf_un
[BUFSIZ
- 1] = 0;
1085 * Cost is encoded in local_pref as (255-cost)
1086 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1090 uint32_t local_pref
;
1091 if (bi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1092 local_pref
= bi
->attr
->local_pref
;
1095 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1100 fp(out
, "%-20s ", buf_pfx
);
1101 fp(out
, "%-15s ", buf_vn
);
1102 fp(out
, "%-15s ", buf_un
);
1103 fp(out
, "%-4d ", cost
);
1106 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1107 if (rfapiGetVncLifetime(bi
->attr
, &lifetime
)
1108 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1110 fp(out
, "%-10s ", "infinite");
1112 time_t t_lifetime
= lifetime
;
1113 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1114 fp(out
, "%-10s ", buf_lifetime
);
1117 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
) && bi
->extra
1118 && bi
->extra
->vnc
.import
.timer
) {
1122 char buf_age
[BUFSIZ
];
1124 struct thread
*t
= (struct thread
*)bi
->extra
->vnc
.import
.timer
;
1125 remaining
= thread_timer_remain_second(t
);
1127 #if RFAPI_REGISTRATIONS_REPORT_AGE
1129 * Calculate when the timer started. Doing so here saves
1130 * us a timestamp field in "struct bgp_info".
1132 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1133 * original calculation.
1135 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1137 #else /* report remaining time */
1140 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1142 fp(out
, "%-10s ", buf_age
);
1144 } else if (RFAPI_LOCAL_BI(bi
)) {
1146 char buf_age
[BUFSIZ
];
1148 if (bi
->extra
&& bi
->extra
->vnc
.import
.create_time
) {
1149 rfapiFormatAge(bi
->extra
->vnc
.import
.create_time
,
1155 fp(out
, "%-10s ", buf_age
);
1157 fp(out
, "%s", HVTYNL
);
1159 if (rn
->p
.family
== AF_ETHERNET
) {
1161 * If there is a corresponding IP address && != VN address,
1162 * print that on the next line
1165 if (bi
->extra
&& bi
->extra
->vnc
.import
.aux_prefix
.family
) {
1169 bi
->extra
->vnc
.import
.aux_prefix
.family
,
1170 &bi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1172 buf_ntop
[BUFSIZ
- 1] = 0;
1174 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1175 fp(out
, " IP: %s", sp
);
1181 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bi
->extra
) {
1182 uint32_t l
= decode_label(&bi
->extra
->label
[0]);
1183 if (!MPLS_LABEL_IS_NULL(l
)) {
1184 fp(out
, " Label: %d", l
);
1190 fp(out
, "%s", HVTYNL
);
1195 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1196 struct rfapi_import_table
*it
,
1197 struct prefix
*prefix_only
,
1198 int show_expiring
, /* either/or */
1199 int show_local
, int show_remote
,
1200 int show_imported
, /* either/or */
1201 uint32_t *pLni
) /* AFI_L2VPN only */
1204 int printed_rtlist_hdr
= 0;
1206 int (*fp
)(void *, const char *, ...);
1209 const char *vty_newline
;
1213 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1216 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1218 struct agg_node
*rn
;
1220 if (!it
->imported_vpn
[afi
])
1223 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1224 rn
= agg_route_next(rn
)) {
1226 struct bgp_info
*bi
;
1229 /* allow for wider or more narrow mask from user */
1230 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1231 && !prefix_match(&rn
->p
, prefix_only
))
1236 for (bi
= rn
->info
; bi
; bi
= bi
->next
) {
1238 if (!show_local
&& RFAPI_LOCAL_BI(bi
)) {
1240 /* local route from RFP */
1244 if (!show_remote
&& !RFAPI_LOCAL_BI(bi
)) {
1251 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1255 && CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
1258 if (bi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1259 || bi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1268 if (count_only
== 1)
1270 if (!printed_rtlist_hdr
) {
1271 const char *agetype
= "";
1273 const char *type
= "";
1274 if (show_imported
) {
1277 if (show_expiring
) {
1289 s
= ecommunity_ecom2str(
1291 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1295 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1296 HVTYNL
, type
, *pLni
,
1297 (*pLni
& 0xfff), s
);
1299 fp(out
, "%s[%s] Prefix RT={%s}",
1302 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1304 if (it
->rfg
&& it
->rfg
->name
) {
1305 fp(out
, " %s \"%s\"",
1306 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1311 fp(out
, "%s", HVTYNL
);
1312 if (show_expiring
) {
1313 #if RFAPI_REGISTRATIONS_REPORT_AGE
1316 agetype
= "Remaining";
1318 } else if (show_local
) {
1322 printed_rtlist_hdr
= 1;
1325 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1326 (pLni
? "L2 Address/IP" : "Prefix"),
1327 "VN Address", "UN Address", "Cost",
1328 "Lifetime", agetype
, HVTYNL
);
1330 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1338 const char *type
= "prefixes";
1340 if (show_imported
) {
1341 type
= "imported prefixes";
1343 if (show_expiring
) {
1344 type
= "prefixes in holddown";
1346 if (show_local
&& !show_remote
) {
1347 type
= "locally registered prefixes";
1348 } else if (!show_local
&& show_remote
) {
1349 type
= "remotely registered prefixes";
1354 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1356 #if DEBUG_SHOW_EXTRA
1357 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1365 * rfapiShowRemoteRegistrations
1367 * Similar to rfapiShowImportTable() above. This function
1368 * is mean to produce the "remote" portion of the output
1369 * of "show vnc registrations".
1371 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1372 int show_expiring
, int show_local
,
1373 int show_remote
, int show_imported
)
1377 struct rfapi_import_table
*it
;
1380 bgp
= bgp_get_default();
1390 for (it
= h
->imports
; it
; it
= it
->next
) {
1391 printed
+= rfapiShowRemoteRegistrationsIt(
1392 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1393 show_remote
, show_imported
, NULL
);
1396 if (h
->import_mac
) {
1397 void *cursor
= NULL
;
1399 uintptr_t lni_as_ptr
;
1403 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1404 (void **)&it
, &cursor
);
1406 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1407 (void **)&it
, &cursor
)) {
1409 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1410 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1414 printed
+= rfapiShowRemoteRegistrationsIt(
1415 bgp
, stream
, it
, prefix_only
, show_expiring
,
1416 show_local
, show_remote
, show_imported
, pLni
);
1423 /*------------------------------------------
1424 * rfapiRfapiIpAddr2Str
1426 * UI helper: generate string from rfapi_ip_addr
1429 * a IP v4/v6 address
1432 * buf put string here
1433 * bufsize max space to write
1436 * NULL conversion failed
1437 * non-NULL pointer to buf
1438 --------------------------------------------*/
1439 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1442 const char *rc
= NULL
;
1444 switch (a
->addr_family
) {
1446 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1449 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1455 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1458 const char *rc
= NULL
;
1460 int (*fp
)(void *, const char *, ...);
1463 const char *vty_newline
;
1465 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1468 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1474 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1477 struct rfapi_ip_addr
*a
= &p
->prefix
;
1478 const char *rc
= NULL
;
1480 switch (a
->addr_family
) {
1482 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1485 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1490 int alen
= strlen(buf
);
1491 int remaining
= bufsize
- alen
- 1;
1494 if (remaining
> 0) {
1495 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1497 if (slen
< remaining
) /* see man page for snprintf(3) */
1505 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1510 int (*fp
)(void *, const char *, ...);
1513 const char *vty_newline
;
1515 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1518 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1521 fp(out
, "%s:%u", buf
, p
->cost
);
1526 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1528 char buf
[RD_ADDRSTRLEN
];
1530 prefix_rd2str(prd
, buf
, sizeof(buf
));
1531 vty_out(vty
, "%s", buf
);
1534 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1535 safi_t safi
, struct prefix
*p
)
1537 afi_t afi
; /* of the VN address */
1538 struct bgp_node
*bn
;
1539 struct bgp_info
*bi
;
1540 uint8_t type
= ZEBRA_ROUTE_BGP
;
1543 struct prefix_rd prd0
;
1544 struct prefix_rd
*prd
;
1547 * Find the bgp_info in the RIB corresponding to this
1551 afi
= family2afi(p
->family
);
1552 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1554 bgp
= bgp_get_default(); /* assume 1 instance for now */
1557 if (safi
== SAFI_ENCAP
) {
1558 memset(&prd0
, 0, sizeof(prd0
));
1559 prd0
.family
= AF_UNSPEC
;
1560 prd0
.prefixlen
= 64;
1565 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1567 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1569 for (bi
= bn
->info
; bi
; bi
= bi
->next
) {
1570 if (bi
->peer
== rfd
->peer
&& bi
->type
== type
1571 && bi
->sub_type
== BGP_ROUTE_RFP
&& bi
->extra
1572 && bi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1574 rfapiPrintBi(vty
, bi
);
1580 vty_out(vty
, " --?--%s", HVTYNL
);
1585 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1587 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1588 /* RT export list */
1589 /* RT import list */
1590 /* list of advertised prefixes */
1591 /* dump import table */
1597 struct rfapi_adb
*adb
;
1598 char buf
[PREFIX_STRLEN
];
1600 vty_out(vty
, "%-10p ", rfd
);
1601 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1603 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1604 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1605 rfapiPrintRd(vty
, &rfd
->rd
);
1606 vty_out(vty
, " %d", rfd
->response_lifetime
);
1607 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1608 vty_out(vty
, "%s", HVTYNL
);
1610 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1612 /* export RT list */
1613 if (rfd
->rt_export_list
) {
1614 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1615 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1616 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1617 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1619 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1622 /* import RT list */
1623 if (rfd
->import_table
) {
1624 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1625 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1626 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1627 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1629 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1632 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1635 family
= afi2family(afi
);
1640 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1641 (void **)&adb
, &cursor
);
1643 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1644 (void **)&adb
, &cursor
)) {
1646 /* group like family prefixes together in output */
1647 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1650 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1652 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1653 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1654 &adb
->u
.s
.prefix_ip
);
1657 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1658 (void **)&adb
, &cursor
);
1659 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1660 (void **)&adb
, &cursor
)) {
1662 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1664 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1666 /* TBD update the following function to print ethernet info */
1667 /* Also need to pass/use rd */
1668 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1669 &adb
->u
.s
.prefix_ip
);
1671 vty_out(vty
, "%s", HVTYNL
);
1675 * test scripts rely on first line for each nve starting in 1st column,
1676 * leading whitespace for additional detail of that nve
1678 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1679 struct prefix
*un_prefix
)
1683 struct listnode
*ln
;
1684 struct rfapi_descriptor
*rfd
;
1687 bgp
= bgp_get_default(); /* assume 1 instance for now */
1694 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1695 rfd
= listgetdata(ln
);
1700 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1701 if (!prefix_match(vn_prefix
, &pfx
))
1706 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1707 if (!prefix_match(un_prefix
, &pfx
))
1712 /* print column header */
1713 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1714 "un-addr", "vn-addr", "callback", "cookie",
1715 "RD", "lifetime", "group", HVTYNL
);
1717 rfapiPrintDescriptor(vty
, rfd
);
1724 * Parse an address and put into a struct prefix
1726 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1728 if (!str2prefix(str
, p
)) {
1729 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1733 switch (p
->family
) {
1735 if (p
->prefixlen
!= 32) {
1736 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1742 if (p
->prefixlen
!= 128) {
1743 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1749 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1755 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1756 struct rfapi_ip_addr
*hai
)
1761 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1765 hai
->addr_family
= pfx
.family
;
1766 if (pfx
.family
== AF_INET
)
1767 hai
->addr
.v4
= pfx
.u
.prefix4
;
1769 hai
->addr
.v6
= pfx
.u
.prefix6
;
1775 * Note: this function does not flush vty output, so if it is called
1776 * with a stream pointing to a vty, the user will have to type something
1777 * before the callback output shows up
1779 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1781 struct rfapi_next_hop_entry
*nh
;
1784 int (*fp
)(void *, const char *, ...);
1787 const char *vty_newline
;
1789 #define REMAIN (BUFSIZ - (p-line))
1790 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1792 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1795 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1801 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1804 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1805 /* it fit, so count length */
1813 r
= snprintf(p
, REMAIN
, ", un=");
1816 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1817 /* it fit, so count length */
1825 r
= snprintf(p
, REMAIN
, ", vn=");
1828 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1829 /* it fit, so count length */
1838 line
[BUFSIZ
- 1] = 0;
1839 fp(out
, "%s%s", line
, HVTYNL
);
1844 if (nh
->vn_options
) {
1845 struct rfapi_vn_option
*vo
;
1846 char offset
[] = " ";
1848 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1852 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1853 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1854 pbuf
, sizeof(pbuf
));
1856 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1858 (vo
->v
.l2addr
.label
& 0x00ffffff),
1859 (vo
->v
.l2addr
.logical_net_id
1861 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1864 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1865 prefix2str(&vo
->v
.local_nexthop
.addr
,
1866 pbuf
, sizeof(pbuf
));
1867 fp(out
, "%sLNH %s cost=%d%s", offset
,
1868 pbuf
, vo
->v
.local_nexthop
.cost
,
1874 "%svn option type %d (unknown)%s",
1875 offset
, vo
->type
, HVTYNL
);
1880 if (nh
->un_options
) {
1881 struct rfapi_un_option
*uo
;
1882 char offset
[] = " ";
1884 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1886 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1887 rfapi_print_tunneltype_option(
1888 stream
, 8, &uo
->v
.tunnel
);
1891 fp(out
, "%sUN Option type %d%s", offset
,
1892 uo
->type
, vty_newline
);
1900 /***********************************************************************
1902 ***********************************************************************/
1905 * Add another nexthop to the NHL
1907 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1908 struct rfapi_ip_addr
*vn_addr
,
1909 struct rfapi_ip_prefix
*rprefix
,
1911 uint32_t lifetime
, /* add only */
1912 struct rfapi_vn_option
*vn_options
,
1913 struct rfapi_next_hop_entry
**head
,
1914 struct rfapi_next_hop_entry
**tail
)
1916 struct rfapi_next_hop_entry
*new;
1922 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1923 new->prefix
= *rprefix
;
1924 new->un_address
= *un_addr
;
1925 new->vn_address
= *vn_addr
;
1927 new->vn_options
= vn_options
;
1929 new->lifetime
= lifetime
;
1931 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1935 (*tail
)->next
= new;
1944 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1945 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1946 struct cmd_token
*carg_cost
, /* optional */
1947 struct cmd_token
*carg_lifetime
, /* optional */
1948 struct cmd_token
*carg_macaddr
, /* optional */
1950 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1951 int argc
, struct cmd_token
**argv
)
1953 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1954 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1955 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1956 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1957 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1958 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1959 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1960 struct rfapi_ip_addr vn_address
;
1961 struct rfapi_ip_addr un_address
;
1963 struct rfapi_ip_prefix rpfx
;
1968 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1969 struct rfapi_vn_option
*opt
= NULL
;
1972 int rc
= CMD_WARNING_CONFIG_FAILED
;
1976 struct rfapi_cfg
*rfapi_cfg
;
1978 const char *arg_lnh
= NULL
;
1979 const char *arg_lnh_cost
= NULL
;
1981 bgp
= bgp_get_default(); /* assume 1 instance for now */
1984 vty_out(vty
, "BGP not configured\n");
1985 return CMD_WARNING_CONFIG_FAILED
;
1989 rfapi_cfg
= bgp
->rfapi_cfg
;
1990 if (!h
|| !rfapi_cfg
) {
1992 vty_out(vty
, "RFAPI not configured\n");
1993 return CMD_WARNING_CONFIG_FAILED
;
1996 for (; argc
; --argc
, ++argv
) {
1997 if (strmatch(argv
[0]->text
, "local-next-hop")) {
2000 "local-next-hop specified more than once\n");
2001 return CMD_WARNING_CONFIG_FAILED
;
2005 "Missing parameter for local-next-hop\n");
2006 return CMD_WARNING_CONFIG_FAILED
;
2009 arg_lnh
= argv
[0]->arg
;
2011 if (strmatch(argv
[0]->text
, "local-cost")) {
2014 "local-cost specified more than once\n");
2015 return CMD_WARNING_CONFIG_FAILED
;
2019 "Missing parameter for local-cost\n");
2020 return CMD_WARNING_CONFIG_FAILED
;
2023 arg_lnh_cost
= argv
[0]->arg
;
2027 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2029 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2032 /* arg_prefix is optional if mac address is given */
2033 if (arg_macaddr
&& !arg_prefix
) {
2035 * fake up a 0/32 or 0/128 prefix
2037 switch (vn_address
.addr_family
) {
2039 arg_prefix
= "0.0.0.0/32";
2042 arg_prefix
= "0::0/128";
2046 "Internal error, unknown VN address family\n");
2047 return CMD_WARNING_CONFIG_FAILED
;
2051 if (!str2prefix(arg_prefix
, &pfx
)) {
2052 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2055 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2056 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2062 memset(optary
, 0, sizeof(optary
));
2066 cost
= strtoul(arg_cost
, &endptr
, 10);
2067 if (*endptr
!= '\0' || cost
> 255) {
2068 vty_out(vty
, "%% Invalid %s value\n", "cost");
2076 if (!strcmp(arg_lifetime
, "infinite")) {
2077 lifetime
= RFAPI_INFINITE_LIFETIME
;
2080 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2081 if (*endptr
!= '\0') {
2082 vty_out(vty
, "%% Invalid %s value\n",
2088 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2094 "%% %s may only be specified with local-next-hop\n",
2099 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2100 if (*endptr
!= '\0' || lnh_cost
> 255) {
2101 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2111 "%% %s may only be specified with prefix\n",
2115 if ((rc
= rfapiCliGetPrefixAddr(
2117 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2122 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2123 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2126 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2133 if (arg_vni
&& !arg_macaddr
) {
2134 vty_out(vty
, "%% %s may only be specified with mac address\n",
2135 "virtual-network-identifier");
2142 "Missing \"vni\" parameter (mandatory with mac)\n");
2143 return CMD_WARNING_CONFIG_FAILED
;
2145 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2146 strtoul(arg_vni
, NULL
, 10);
2148 if ((rc
= rfapiStr2EthAddr(
2150 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2151 vty_out(vty
, "Invalid %s value\n", "mac address");
2154 /* TBD label, NVE ID */
2156 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2159 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2166 vnc_zlog_debug_verbose(
2167 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2168 __func__
, arg_vn
, arg_un
, arg_prefix
,
2169 (arg_cost
? arg_cost
: "NULL"),
2170 (arg_lifetime
? arg_lifetime
: "NULL"),
2171 (arg_lnh
? arg_lnh
: "NULL"));
2173 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2175 rpfx
.cost
= cost
& 255;
2177 /* look up rf descriptor, call open if it doesn't exist */
2178 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2179 (struct rfapi_descriptor
**)&rfd
);
2182 struct rfapi_un_option uo
;
2185 * flag descriptor as provisionally opened for static
2187 * registration so that we can fix up the other
2189 * when the real open comes along
2191 memset(&uo
, 0, sizeof(uo
));
2192 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2194 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2195 &vn_address
, &un_address
,
2197 NULL
, NULL
, /* no userdata */
2201 "Can't open session for this NVE: %s\n",
2202 rfapi_error_str(rc
));
2203 rc
= CMD_WARNING_CONFIG_FAILED
;
2207 vty_out(vty
, "Can't find session for this NVE: %s\n",
2208 rfapi_error_str(rc
));
2213 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2214 RFAPI_REGISTER_ADD
);
2216 struct rfapi_next_hop_entry
*head
= NULL
;
2217 struct rfapi_next_hop_entry
*tail
= NULL
;
2218 struct rfapi_vn_option
*vn_opt_new
;
2220 vnc_zlog_debug_verbose(
2221 "%s: rfapi_register succeeded, returning 0", __func__
);
2223 if (h
->rfp_methods
.local_cb
) {
2224 struct rfapi_descriptor
*r
=
2225 (struct rfapi_descriptor
*)rfd
;
2226 vn_opt_new
= rfapi_vn_options_dup(opt
);
2228 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2230 vn_opt_new
, &head
, &tail
);
2232 h
->flags
|= RFAPI_INCALLBACK
;
2233 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2234 h
->flags
&= ~RFAPI_INCALLBACK
;
2241 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2243 vty_out(vty
, "Registration failed.\n");
2245 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2246 return CMD_WARNING_CONFIG_FAILED
;
2249 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2253 /************************************************************************
2254 * Add prefix With LNH_OPTIONS...
2255 ************************************************************************/
2256 DEFUN (add_vnc_prefix_cost_life_lnh
,
2257 add_vnc_prefix_cost_life_lnh_cmd
,
2258 "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...",
2259 "Add registration\n"
2261 "Add/modify prefix related information\n"
2264 "VN address of NVE\n"
2265 "VN IPv4 interface address\n"
2266 "VN IPv6 interface address\n"
2267 "UN address of NVE\n"
2268 "UN IPv4 interface address\n"
2269 "UN IPv6 interface address\n"
2270 "Administrative cost [default: 255]\n"
2271 "Administrative cost\n"
2272 "Registration lifetime [default: infinite]\n"
2273 "Lifetime value in seconds\n"
2274 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2276 /* pfx vn un cost life */
2277 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2279 NULL
, NULL
, argc
- 12, argv
+ 12);
2282 DEFUN (add_vnc_prefix_life_cost_lnh
,
2283 add_vnc_prefix_life_cost_lnh_cmd
,
2284 "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...",
2285 "Add registration\n"
2287 "Add/modify prefix related information\n"
2290 "VN address of NVE\n"
2291 "VN IPv4 interface address\n"
2292 "VN IPv6 interface address\n"
2293 "UN address of NVE\n"
2294 "UN IPv4 interface address\n"
2295 "UN IPv6 interface address\n"
2296 "Registration lifetime [default: infinite]\n"
2297 "Lifetime value in seconds\n"
2298 "Administrative cost [default: 255]\n"
2299 "Administrative cost\n"
2300 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2302 /* pfx vn un cost life */
2303 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2305 NULL
, NULL
, argc
- 12, argv
+ 12);
2308 DEFUN (add_vnc_prefix_cost_lnh
,
2309 add_vnc_prefix_cost_lnh_cmd
,
2310 "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...",
2311 "Add registration\n"
2313 "Add/modify prefix related information\n"
2316 "VN address of NVE\n"
2317 "VN IPv4 interface address\n"
2318 "VN IPv6 interface address\n"
2319 "UN address of NVE\n"
2320 "UN IPv4 interface address\n"
2321 "UN IPv6 interface address\n"
2322 "Administrative cost [default: 255]\n"
2323 "Administrative cost\n"
2324 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2326 /* pfx vn un cost life */
2327 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2329 NULL
, NULL
, argc
- 10, argv
+ 10);
2332 DEFUN (add_vnc_prefix_life_lnh
,
2333 add_vnc_prefix_life_lnh_cmd
,
2334 "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...",
2335 "Add registration\n"
2337 "Add/modify prefix related information\n"
2340 "VN address of NVE\n"
2341 "VN IPv4 interface address\n"
2342 "VN IPv6 interface address\n"
2343 "UN address of NVE\n"
2344 "UN IPv4 interface address\n"
2345 "UN IPv6 interface address\n"
2346 "Registration lifetime [default: infinite]\n"
2347 "Lifetime value in seconds\n"
2348 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2350 /* pfx vn un cost life */
2351 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2353 NULL
, NULL
, argc
- 10, argv
+ 10);
2356 DEFUN (add_vnc_prefix_lnh
,
2357 add_vnc_prefix_lnh_cmd
,
2358 "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...",
2359 "Add registration\n"
2361 "Add/modify prefix related information\n"
2364 "VN address of NVE\n"
2365 "VN IPv4 interface address\n"
2366 "VN IPv6 interface address\n"
2367 "UN address of NVE\n"
2368 "UN IPv4 interface address\n"
2369 "UN IPv6 interface address\n"
2370 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2372 /* pfx vn un cost life */
2373 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2375 NULL
, NULL
, argc
- 8, argv
+ 8);
2378 /************************************************************************
2379 * Add prefix Without LNH_OPTIONS...
2380 ************************************************************************/
2381 DEFUN (add_vnc_prefix_cost_life
,
2382 add_vnc_prefix_cost_life_cmd
,
2383 "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)",
2384 "Add registration\n"
2386 "Add/modify prefix related information\n"
2389 "VN address of NVE\n"
2390 "VN IPv4 interface address\n"
2391 "VN IPv6 interface address\n"
2392 "UN address of NVE\n"
2393 "UN IPv4 interface address\n"
2394 "UN IPv6 interface address\n"
2395 "Administrative cost [default: 255]\n"
2396 "Administrative cost\n"
2397 "Registration lifetime [default: infinite]\n"
2398 "Lifetime value in seconds\n")
2400 /* pfx vn un cost life */
2401 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2403 NULL
, NULL
, 0, NULL
);
2406 DEFUN (add_vnc_prefix_life_cost
,
2407 add_vnc_prefix_life_cost_cmd
,
2408 "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)",
2409 "Add registration\n"
2411 "Add/modify prefix related information\n"
2414 "VN address of NVE\n"
2415 "VN IPv4 interface address\n"
2416 "VN IPv6 interface address\n"
2417 "UN address of NVE\n"
2418 "UN IPv4 interface address\n"
2419 "UN IPv6 interface address\n"
2420 "Registration lifetime [default: infinite]\n"
2421 "Lifetime value in seconds\n"
2422 "Administrative cost [default: 255]\n"
2423 "Administrative cost\n")
2425 /* pfx vn un cost life */
2426 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2428 NULL
, NULL
, 0, NULL
);
2431 DEFUN (add_vnc_prefix_cost
,
2432 add_vnc_prefix_cost_cmd
,
2433 "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)",
2434 "Add registration\n"
2436 "Add/modify prefix related information\n"
2439 "VN address of NVE\n"
2440 "VN IPv4 interface address\n"
2441 "VN IPv6 interface address\n"
2442 "UN address of NVE\n"
2443 "UN IPv4 interface address\n"
2444 "UN IPv6 interface address\n"
2445 "Administrative cost [default: 255]\n"
2446 "Administrative cost\n")
2448 /* pfx vn un cost life */
2449 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2451 NULL
, NULL
, 0, NULL
);
2454 DEFUN (add_vnc_prefix_life
,
2455 add_vnc_prefix_life_cmd
,
2456 "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)",
2457 "Add registration\n"
2459 "Add/modify prefix related information\n"
2462 "VN address of NVE\n"
2463 "VN IPv4 interface address\n"
2464 "VN IPv6 interface address\n"
2465 "UN address of NVE\n"
2466 "UN IPv4 interface address\n"
2467 "UN IPv6 interface address\n"
2468 "Registration lifetime [default: infinite]\n"
2469 "Lifetime value in seconds\n")
2471 /* pfx vn un cost life */
2472 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2474 NULL
, NULL
, 0, NULL
);
2477 DEFUN (add_vnc_prefix
,
2479 "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>",
2480 "Add registration\n"
2482 "Add/modify prefix related information\n"
2485 "VN address of NVE\n"
2486 "VN IPv4 interface address\n"
2487 "VN IPv6 interface address\n"
2488 "UN address of NVE\n"
2489 "UN IPv4 interface address\n"
2490 "UN IPv6 interface address\n")
2492 /* pfx vn un cost life */
2493 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2495 NULL
, NULL
, 0, NULL
);
2498 /************************************************************************
2499 * Mac address registrations
2500 ************************************************************************/
2501 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2502 add_vnc_mac_vni_prefix_cost_life_cmd
,
2503 "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)",
2504 "Add registration\n"
2506 "Add/modify mac address information\n"
2508 "Virtual Network Identifier follows\n"
2509 "Virtual Network Identifier\n"
2510 "VN address of NVE\n"
2511 "VN IPv4 interface address\n"
2512 "VN IPv6 interface address\n"
2513 "UN address of NVE\n"
2514 "UN IPv4 interface address\n"
2515 "UN IPv6 interface address\n"
2516 "Add/modify prefix related information\n"
2519 "Administrative cost [default: 255]\n"
2520 "Administrative cost\n"
2521 "Registration lifetime [default: infinite]\n"
2522 "Lifetime value in seconds\n")
2524 /* pfx vn un cost life */
2525 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2527 argv
[3], argv
[5], 0, NULL
);
2531 DEFUN (add_vnc_mac_vni_prefix_life
,
2532 add_vnc_mac_vni_prefix_life_cmd
,
2533 "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)",
2534 "Add registration\n"
2536 "Add/modify mac address information\n"
2538 "Virtual Network Identifier follows\n"
2539 "Virtual Network Identifier\n"
2540 "VN address of NVE\n"
2541 "VN IPv4 interface address\n"
2542 "VN IPv6 interface address\n"
2543 "UN address of NVE\n"
2544 "UN IPv4 interface address\n"
2545 "UN IPv6 interface address\n"
2546 "Add/modify prefix related information\n"
2549 "Registration lifetime [default: infinite]\n"
2550 "Lifetime value in seconds\n")
2552 /* pfx vn un cost life */
2553 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2555 argv
[3], argv
[5], 0, NULL
);
2558 DEFUN (add_vnc_mac_vni_prefix_cost
,
2559 add_vnc_mac_vni_prefix_cost_cmd
,
2560 "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)",
2561 "Add registration\n"
2563 "Add/modify mac address information\n"
2565 "Virtual Network Identifier follows\n"
2566 "Virtual Network Identifier\n"
2567 "VN address of NVE\n"
2568 "VN IPv4 interface address\n"
2569 "VN IPv6 interface address\n"
2570 "UN address of NVE\n"
2571 "UN IPv4 interface address\n"
2572 "UN IPv6 interface address\n"
2573 "Add/modify prefix related information\n"
2576 "Administrative cost [default: 255]\n" "Administrative cost\n")
2578 /* pfx vn un cost life */
2579 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2581 argv
[3], argv
[5], 0, NULL
);
2584 DEFUN (add_vnc_mac_vni_prefix
,
2585 add_vnc_mac_vni_prefix_cmd
,
2586 "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>",
2587 "Add registration\n"
2589 "Add/modify mac address information\n"
2591 "Virtual Network Identifier follows\n"
2592 "Virtual Network Identifier\n"
2593 "VN address of NVE\n"
2594 "VN IPv4 interface address\n"
2595 "VN IPv6 interface address\n"
2596 "UN address of NVE\n"
2597 "UN IPv4 interface address\n"
2598 "UN IPv6 interface address\n"
2599 "Add/modify prefix related information\n"
2600 "IPv4 prefix\n" "IPv6 prefix\n")
2602 /* pfx vn un cost life */
2603 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2605 argv
[3], argv
[5], 0, NULL
);
2608 DEFUN (add_vnc_mac_vni_cost_life
,
2609 add_vnc_mac_vni_cost_life_cmd
,
2610 "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)",
2611 "Add registration\n"
2613 "Add/modify mac address information\n"
2615 "Virtual Network Identifier follows\n"
2616 "Virtual Network Identifier\n"
2617 "VN address of NVE\n"
2618 "VN IPv4 interface address\n"
2619 "VN IPv6 interface address\n"
2620 "UN address of NVE\n"
2621 "UN IPv4 interface address\n"
2622 "UN IPv6 interface address\n"
2623 "Administrative cost [default: 255]\n"
2624 "Administrative cost\n"
2625 "Registration lifetime [default: infinite]\n"
2626 "Lifetime value in seconds\n")
2628 /* pfx vn un cost life */
2629 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2631 argv
[3], argv
[5], 0, NULL
);
2635 DEFUN (add_vnc_mac_vni_cost
,
2636 add_vnc_mac_vni_cost_cmd
,
2637 "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)",
2638 "Add registration\n"
2640 "Add/modify mac address information\n"
2642 "Virtual Network Identifier follows\n"
2643 "Virtual Network Identifier\n"
2644 "VN address of NVE\n"
2645 "VN IPv4 interface address\n"
2646 "VN IPv6 interface address\n"
2647 "UN address of NVE\n"
2648 "UN IPv4 interface address\n"
2649 "UN IPv6 interface address\n"
2650 "Administrative cost [default: 255]\n" "Administrative cost\n")
2652 /* pfx vn un cost life */
2653 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2655 argv
[3], argv
[5], 0, NULL
);
2659 DEFUN (add_vnc_mac_vni_life
,
2660 add_vnc_mac_vni_life_cmd
,
2661 "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)",
2662 "Add registration\n"
2664 "Add/modify mac address information\n"
2666 "Virtual Network Identifier follows\n"
2667 "Virtual Network Identifier\n"
2668 "VN address of NVE\n"
2669 "VN IPv4 interface address\n"
2670 "VN IPv6 interface address\n"
2671 "UN address of NVE\n"
2672 "UN IPv4 interface address\n"
2673 "UN IPv6 interface address\n"
2674 "Registration lifetime [default: infinite]\n"
2675 "Lifetime value in seconds\n")
2677 /* pfx vn un cost life */
2678 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2680 argv
[3], argv
[5], 0, NULL
);
2684 DEFUN (add_vnc_mac_vni
,
2685 add_vnc_mac_vni_cmd
,
2686 "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>",
2687 "Add registration\n"
2689 "Add/modify mac address information\n"
2691 "Virtual Network Identifier follows\n"
2692 "Virtual Network Identifier\n"
2693 "VN address of NVE\n"
2694 "VN IPv4 interface address\n"
2695 "VN IPv6 interface address\n"
2696 "UN address of NVE\n"
2697 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2699 /* pfx vn un cost life */
2700 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2702 argv
[3], argv
[5], 0, NULL
);
2705 /************************************************************************
2707 ************************************************************************/
2709 struct rfapi_local_reg_delete_arg
{
2714 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2715 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2716 struct prefix prefix
; /* AF==0: wildcard */
2717 struct prefix_rd rd
; /* plen!=64: wildcard */
2718 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2720 struct rfapi_l2address_option_match l2o
;
2728 uint32_t query_count
;
2730 uint32_t failed_pfx_count
;
2733 struct skiplist
*nves
;
2735 uint32_t remote_active_nve_count
;
2736 uint32_t remote_active_pfx_count
;
2737 uint32_t remote_holddown_nve_count
;
2738 uint32_t remote_holddown_pfx_count
;
2742 struct rfapi_ip_addr vn
;
2743 struct rfapi_ip_addr un
;
2744 struct rfapi_descriptor
*rfd
;
2745 struct rfapi_local_reg_delete_arg
*cda
;
2748 static void nve_addr_free(void *hap
)
2750 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2751 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2754 static int nve_addr_cmp(void *k1
, void *k2
)
2756 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2757 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2763 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2764 return (a
->un
.addr_family
- b
->un
.addr_family
);
2766 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2767 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2769 if (a
->un
.addr_family
== AF_INET
) {
2770 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2774 } else if (a
->un
.addr_family
== AF_INET6
) {
2775 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2782 if (a
->vn
.addr_family
== AF_INET
) {
2783 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2786 } else if (a
->vn
.addr_family
== AF_INET6
) {
2787 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2797 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2798 const char *arg_prefix
, const char *arg_vn
,
2799 const char *arg_un
, const char *arg_l2addr
,
2800 const char *arg_vni
, const char *arg_rd
,
2801 struct rfapi_nve_group_cfg
*arg_rfg
,
2802 struct rfapi_local_reg_delete_arg
*rcdarg
)
2804 int rc
= CMD_WARNING
;
2806 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2810 bgp
= bgp_get_default();
2812 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2814 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2815 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2816 &rcdarg
->vn_address
)))
2819 if (arg_un
&& strcmp(arg_un
, "*")) {
2820 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2821 &rcdarg
->un_address
)))
2824 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2826 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2827 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2834 vty_out(vty
, "Missing VNI\n");
2837 if (strcmp(arg_l2addr
, "*")) {
2838 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2839 &rcdarg
->l2o
.o
.macaddr
))) {
2840 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2844 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2846 if (strcmp(arg_vni
, "*")) {
2847 rcdarg
->l2o
.o
.logical_net_id
=
2848 strtoul(arg_vni
, NULL
, 10);
2849 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2853 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2854 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2863 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2864 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2865 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2866 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2867 struct rfapi_nve_group_cfg
*arg_rfg
,
2868 struct rfapi_local_reg_delete_arg
*rcdarg
)
2870 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2871 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2872 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2873 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2874 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2875 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2876 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2877 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2880 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2881 struct rfapi_ip_addr
*un_address
,
2882 struct rfapi_ip_addr
*vn_address
,
2883 struct rfapi_descriptor
*rfd
)
2886 struct nve_addr
*hap
;
2888 memset(&ha
, 0, sizeof(ha
));
2889 ha
.un
= *un_address
;
2890 ha
.vn
= *vn_address
;
2894 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2896 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2897 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2901 skiplist_insert(cda
->nves
, hap
, hap
);
2905 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2908 struct rfapi_descriptor
*rfd
;
2909 int query_count
= 0;
2910 struct listnode
*node
;
2911 struct bgp
*bgp_default
= bgp_get_default();
2913 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2917 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2918 &cda
->un_address
, &rfd
))
2922 rfapi_query_done_all(rfd
, &query_count
);
2923 cda
->query_count
+= query_count
;
2926 * Track unique nves seen
2928 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2939 h
= bgp_default
->rfapi
;
2944 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2946 * match un, vn addresses of NVEs
2948 if (cda
->un_address
.addr_family
2949 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2952 if (cda
->vn_address
.addr_family
2953 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2959 rfapi_query_done_all(rfd
, &query_count
);
2960 cda
->query_count
+= query_count
;
2963 * Track unique nves seen
2965 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2970 * TBD need to count deleted prefixes and nves?
2972 * ENXIO BGP or VNC not configured
2974 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2975 struct rfapi_descriptor
*rfd
)
2977 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2978 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2979 struct prefix
*pPrefix
; /* NULL = wildcard */
2980 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2982 struct rfapi_ip_prefix rprefix
;
2983 struct rfapi_next_hop_entry
*head
= NULL
;
2984 struct rfapi_next_hop_entry
*tail
= NULL
;
2987 vnc_zlog_debug_verbose("%s: entry", __func__
);
2990 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2991 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2992 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2993 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2996 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
2999 do /* to preserve old code structure */
3001 struct rfapi
*h
= cda
->bgp
->rfapi
;
3003 struct rfapi_adb
*adb
;
3005 int deleted_from_this_nve
;
3007 struct nve_addr
*hap
;
3010 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3014 * match un, vn addresses of NVEs
3016 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3018 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3022 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3029 deleted_from_this_nve
= 0;
3032 struct skiplist
*sl
;
3033 struct rfapi_ip_prefix rp
;
3035 struct list
*adb_delete_list
;
3038 * The advertisements are stored in a skiplist.
3040 * the registration deletes the advertisement from the
3041 * skiplist, which we can't do while iterating over that
3042 * same skiplist using the current skiplist API.
3044 * Strategy: iterate over the skiplist and build another
3045 * list containing only the matching ADBs. Then delete
3046 * _everything_ in that second list (which can be done
3047 * using either skiplists or quagga linklists).
3049 adb_delete_list
= list_new();
3052 * Advertised IP prefixes (not 0/32 or 0/128)
3054 sl
= rfd
->advertised
.ipN_by_prefix
;
3057 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3059 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3063 if (!prefix_same(pPrefix
,
3064 &adb
->u
.s
.prefix_ip
)) {
3066 vnc_zlog_debug_verbose(
3067 "%s: adb=%p, prefix doesn't match, skipping",
3074 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3078 vnc_zlog_debug_verbose(
3079 "%s: adb=%p, RD doesn't match, skipping",
3085 if (CHECK_FLAG(cda
->l2o
.flags
,
3086 RFAPI_L2O_MACADDR
)) {
3087 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3088 adb
->u
.s
.prefix_eth
.u
3092 vnc_zlog_debug_verbose(
3093 "%s: adb=%p, macaddr doesn't match, skipping",
3100 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3101 if (cda
->l2o
.o
.logical_net_id
3102 != adb
->l2o
.logical_net_id
) {
3104 vnc_zlog_debug_verbose(
3105 "%s: adb=%p, LNI doesn't match, skipping",
3113 vnc_zlog_debug_verbose(
3114 "%s: ipN adding adb %p to delete list",
3118 listnode_add(adb_delete_list
, adb
);
3121 struct listnode
*node
;
3123 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3124 int this_advertisement_prefix_count
;
3125 struct rfapi_vn_option optary
[3];
3126 struct rfapi_vn_option
*opt
= NULL
;
3129 this_advertisement_prefix_count
= 1;
3131 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3133 memset(optary
, 0, sizeof(optary
));
3135 /* if mac addr present in advert, make l2o vn
3137 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3139 opt
->next
= &optary
[cur_opt
];
3140 opt
= &optary
[cur_opt
++];
3141 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3142 opt
->v
.l2addr
.macaddr
=
3143 adb
->u
.s
.prefix_eth
.u
3145 ++this_advertisement_prefix_count
;
3148 * use saved RD value instead of trying to
3150 * complex RD computation in rfapi_register()
3153 opt
->next
= &optary
[cur_opt
];
3154 opt
= &optary
[cur_opt
++];
3155 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3156 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3159 vnc_zlog_debug_verbose(
3160 "%s: ipN killing reg from adb %p ",
3164 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3165 (cur_opt
? optary
: NULL
),
3166 RFAPI_REGISTER_KILL
);
3169 this_advertisement_prefix_count
;
3170 cda
->reg_count
+= 1;
3171 deleted_from_this_nve
= 1;
3173 if (h
->rfp_methods
.local_cb
) {
3174 rfapiAddDeleteLocalRfpPrefix(
3175 &rfd
->un_addr
, &rfd
->vn_addr
,
3176 &rp
, 0, 0, NULL
, &head
, &tail
);
3179 list_delete_all_node(adb_delete_list
);
3181 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3185 * Caller didn't specify a prefix, or specified
3190 * Advertised 0/32 and 0/128 (indexed by
3193 sl
= rfd
->advertised
.ip0_by_ether
;
3196 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3199 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3202 if (CHECK_FLAG(cda
->l2o
.flags
,
3203 RFAPI_L2O_MACADDR
)) {
3204 if (memcmp(cda
->l2o
.o
.macaddr
3206 adb
->u
.s
.prefix_eth
.u
3214 if (CHECK_FLAG(cda
->l2o
.flags
,
3216 if (cda
->l2o
.o
.logical_net_id
3217 != adb
->l2o
.logical_net_id
) {
3222 vnc_zlog_debug_verbose(
3223 "%s: ip0 adding adb %p to delete list",
3226 listnode_add(adb_delete_list
, adb
);
3230 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3233 struct rfapi_vn_option vn
;
3235 rfapiQprefix2Rprefix(
3236 &adb
->u
.s
.prefix_ip
, &rp
);
3238 memset(&vn
, 0, sizeof(vn
));
3239 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3240 vn
.v
.l2addr
= adb
->l2o
;
3243 vnc_zlog_debug_verbose(
3244 "%s: ip0 killing reg from adb %p ",
3248 rc
= rfapi_register(
3249 rfd
, &rp
, 0, NULL
, &vn
,
3250 RFAPI_REGISTER_KILL
);
3252 cda
->pfx_count
+= 1;
3253 cda
->reg_count
+= 1;
3254 deleted_from_this_nve
= 1;
3256 if (h
->rfp_methods
.local_cb
) {
3257 struct rfapi_vn_option
3261 rfapi_vn_options_dup(
3263 rfapiAddDeleteLocalRfpPrefix(
3265 &rfd
->vn_addr
, &rp
, 0,
3266 0, vn_opt_new
, &head
,
3270 list_delete_all_node(adb_delete_list
);
3272 list_delete_and_null(&adb_delete_list
);
3276 if (head
) { /* should not be set if (NULL ==
3277 rfapi_cfg->local_cb) */
3278 h
->flags
|= RFAPI_INCALLBACK
;
3279 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3280 h
->flags
&= ~RFAPI_INCALLBACK
;
3284 if (deleted_from_this_nve
) {
3286 * track unique NVEs seen
3288 memset(&ha
, 0, sizeof(ha
));
3289 ha
.un
= rfd
->un_addr
;
3290 ha
.vn
= rfd
->vn_addr
;
3293 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3295 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3296 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3297 sizeof(struct nve_addr
));
3301 skiplist_insert(cda
->nves
, hap
, hap
);
3304 } while (0); /* to preserve old code structure */
3309 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3314 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3315 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3317 struct bgp
*bgp
= cda
->bgp
;
3319 struct rfapi_cfg
*rfapi_cfg
;
3321 struct listnode
*node
;
3322 struct rfapi_descriptor
*rfd
;
3326 rfapi_cfg
= bgp
->rfapi_cfg
;
3327 if (!h
|| !rfapi_cfg
)
3329 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3331 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3332 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3341 * Deletes local and remote prefixes that match
3343 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3345 struct prefix pfx_un
;
3346 struct prefix pfx_vn
;
3348 struct prefix
*pUN
= NULL
;
3349 struct prefix
*pVN
= NULL
;
3350 struct prefix
*pPrefix
= NULL
;
3352 struct rfapi_import_table
*it
= NULL
;
3355 * Delete matching remote prefixes in holddown
3357 if (cda
->vn_address
.addr_family
) {
3358 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3361 if (cda
->un_address
.addr_family
) {
3362 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3365 if (cda
->prefix
.family
) {
3366 pPrefix
= &cda
->prefix
;
3369 it
= cda
->rfg
->rfapi_import_table
;
3371 rfapiDeleteRemotePrefixes(
3372 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3373 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3374 &cda
->remote_holddown_nve_count
);
3377 * Now do local prefixes
3379 rfapiDeleteLocalPrefixes(cda
);
3382 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3384 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3386 /* Our special element-deleting function counts nves */
3388 skiplist_free(cda
->nves
);
3391 if (cda
->failed_pfx_count
)
3392 vty_out(vty
, "Failed to delete %d prefixes\n",
3393 cda
->failed_pfx_count
);
3395 /* left as "prefixes" even in single case for ease of machine parsing */
3397 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3398 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3402 * We don't currently allow deletion of active remote prefixes from
3406 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3407 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3411 * Caller has already deleted registrations and queries for this/these
3412 * NVEs. Now we just have to close their descriptors.
3414 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3416 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3417 struct nve_addr
*pKey
;
3418 struct nve_addr
*pValue
;
3419 void *cursor
= NULL
;
3425 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3426 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3430 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3431 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3432 rfapi_close(pValue
->rfd
);
3437 DEFUN (clear_vnc_nve_all
,
3438 clear_vnc_nve_all_cmd
,
3442 "Clear per NVE information\n"
3446 struct rfapi_local_reg_delete_arg cda
;
3449 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3455 clear_vnc_responses(&cda
);
3456 clear_vnc_prefix(&cda
);
3457 clear_vnc_nve_closer(&cda
);
3459 print_cleared_stats(&cda
);
3464 DEFUN (clear_vnc_nve_vn_un
,
3465 clear_vnc_nve_vn_un_cmd
,
3466 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3469 "Clear prefix registration information\n"
3470 "VN address of NVE\n"
3472 "VN IPv4 interface address\n"
3473 "VN IPv6 interface address\n"
3474 "UN address of NVE\n"
3475 "For all UN addresses\n"
3476 "UN IPv4 interface address\n"
3477 "UN IPv6 interface address\n")
3479 struct rfapi_local_reg_delete_arg cda
;
3482 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3483 NULL
, NULL
, NULL
, &cda
)))
3488 clear_vnc_responses(&cda
);
3489 clear_vnc_prefix(&cda
);
3490 clear_vnc_nve_closer(&cda
);
3492 print_cleared_stats(&cda
);
3497 DEFUN (clear_vnc_nve_un_vn
,
3498 clear_vnc_nve_un_vn_cmd
,
3499 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3502 "Clear prefix registration information\n"
3503 "UN address of NVE\n"
3505 "UN IPv4 interface address\n"
3506 "UN IPv6 interface address\n"
3507 "VN address of NVE\n"
3509 "VN IPv4 interface address\n"
3510 "VN IPv6 interface address\n")
3512 struct rfapi_local_reg_delete_arg cda
;
3515 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3516 NULL
, NULL
, NULL
, &cda
)))
3521 clear_vnc_responses(&cda
);
3522 clear_vnc_prefix(&cda
);
3523 clear_vnc_nve_closer(&cda
);
3525 print_cleared_stats(&cda
);
3530 DEFUN (clear_vnc_nve_vn
,
3531 clear_vnc_nve_vn_cmd
,
3532 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3535 "Clear prefix registration information\n"
3536 "VN address of NVE\n"
3538 "VN IPv4 interface address\n"
3539 "VN IPv6 interface address\n")
3541 struct rfapi_local_reg_delete_arg cda
;
3544 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3545 NULL
, NULL
, NULL
, &cda
)))
3550 clear_vnc_responses(&cda
);
3551 clear_vnc_prefix(&cda
);
3552 clear_vnc_nve_closer(&cda
);
3554 print_cleared_stats(&cda
);
3558 DEFUN (clear_vnc_nve_un
,
3559 clear_vnc_nve_un_cmd
,
3560 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3563 "Clear prefix registration information\n"
3564 "UN address of NVE\n"
3566 "UN IPv4 interface address\n"
3567 "UN IPv6 interface address\n")
3569 struct rfapi_local_reg_delete_arg cda
;
3572 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3573 NULL
, NULL
, NULL
, &cda
)))
3578 clear_vnc_responses(&cda
);
3579 clear_vnc_prefix(&cda
);
3580 clear_vnc_nve_closer(&cda
);
3582 print_cleared_stats(&cda
);
3586 /*-------------------------------------------------
3588 *-------------------------------------------------*/
3591 * This function is defined in this file (rather than in rfp_registration.c)
3592 * because here we have access to all the task handles.
3594 DEFUN (clear_vnc_prefix_vn_un
,
3595 clear_vnc_prefix_vn_un_cmd
,
3596 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3599 "Clear prefix registration information\n"
3603 "VN address of NVE\n"
3604 "All VN addresses\n"
3605 "VN IPv4 interface address\n"
3606 "VN IPv6 interface address\n"
3607 "UN address of NVE\n"
3608 "All UN addresses\n"
3609 "UN IPv4 interface address\n"
3610 "UN IPv6 interface address\n")
3612 struct rfapi_local_reg_delete_arg cda
;
3615 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3616 NULL
, NULL
, NULL
, NULL
, &cda
)))
3619 clear_vnc_prefix(&cda
);
3620 print_cleared_stats(&cda
);
3624 DEFUN (clear_vnc_prefix_un_vn
,
3625 clear_vnc_prefix_un_vn_cmd
,
3626 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3629 "Clear prefix registration information\n"
3633 "UN address of NVE\n"
3634 "All UN addresses\n"
3635 "UN IPv4 interface address\n"
3636 "UN IPv6 interface address\n"
3637 "VN address of NVE\n"
3638 "All VN addresses\n"
3639 "VN IPv4 interface address\n"
3640 "VN IPv6 interface address\n")
3642 struct rfapi_local_reg_delete_arg cda
;
3645 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3646 NULL
, NULL
, NULL
, NULL
, &cda
)))
3649 clear_vnc_prefix(&cda
);
3650 print_cleared_stats(&cda
);
3654 DEFUN (clear_vnc_prefix_un
,
3655 clear_vnc_prefix_un_cmd
,
3656 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3659 "Clear prefix registration information\n"
3663 "UN address of NVE\n"
3664 "All UN addresses\n"
3665 "UN IPv4 interface address\n"
3666 "UN IPv6 interface address\n")
3668 struct rfapi_local_reg_delete_arg cda
;
3671 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3672 NULL
, NULL
, NULL
, &cda
)))
3675 clear_vnc_prefix(&cda
);
3676 print_cleared_stats(&cda
);
3680 DEFUN (clear_vnc_prefix_vn
,
3681 clear_vnc_prefix_vn_cmd
,
3682 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3685 "Clear prefix registration information\n"
3689 "UN address of NVE\n"
3690 "All VN addresses\n"
3691 "VN IPv4 interface address\n"
3692 "VN IPv6 interface address\n")
3694 struct rfapi_local_reg_delete_arg cda
;
3697 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3698 NULL
, NULL
, NULL
, &cda
)))
3701 clear_vnc_prefix(&cda
);
3702 print_cleared_stats(&cda
);
3706 DEFUN (clear_vnc_prefix_all
,
3707 clear_vnc_prefix_all_cmd
,
3708 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3711 "Clear prefix registration information\n"
3717 struct rfapi_local_reg_delete_arg cda
;
3720 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3721 NULL
, NULL
, NULL
, &cda
)))
3724 clear_vnc_prefix(&cda
);
3725 print_cleared_stats(&cda
);
3729 /*-------------------------------------------------
3731 *-------------------------------------------------*/
3734 * This function is defined in this file (rather than in rfp_registration.c)
3735 * because here we have access to all the task handles.
3737 DEFUN (clear_vnc_mac_vn_un
,
3738 clear_vnc_mac_vn_un_cmd
,
3739 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3742 "Clear mac registration information\n"
3746 "Any virtual network identifier\n"
3747 "Virtual network identifier\n"
3748 "VN address of NVE\n"
3749 "All VN addresses\n"
3750 "VN IPv4 interface address\n"
3751 "VN IPv6 interface address\n"
3752 "UN address of NVE\n"
3753 "All UN addresses\n"
3754 "UN IPv4 interface address\n"
3755 "UN IPv6 interface address\n")
3757 struct rfapi_local_reg_delete_arg cda
;
3760 /* pfx vn un L2 VNI */
3761 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3762 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3765 clear_vnc_prefix(&cda
);
3766 print_cleared_stats(&cda
);
3770 DEFUN (clear_vnc_mac_un_vn
,
3771 clear_vnc_mac_un_vn_cmd
,
3772 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3775 "Clear mac registration information\n"
3779 "Any virtual network identifier\n"
3780 "Virtual network identifier\n"
3781 "UN address of NVE\n"
3782 "All UN addresses\n"
3783 "UN IPv4 interface address\n"
3784 "UN IPv6 interface address\n"
3785 "VN address of NVE\n"
3786 "All VN addresses\n"
3787 "VN IPv4 interface address\n"
3788 "VN IPv6 interface address\n")
3790 struct rfapi_local_reg_delete_arg cda
;
3793 /* pfx vn un L2 VNI */
3794 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3795 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3798 clear_vnc_prefix(&cda
);
3799 print_cleared_stats(&cda
);
3803 DEFUN (clear_vnc_mac_un
,
3804 clear_vnc_mac_un_cmd
,
3805 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3808 "Clear mac registration information\n"
3812 "Any virtual network identifier\n"
3813 "Virtual network identifier\n"
3814 "UN address of NVE\n"
3815 "All UN addresses\n"
3816 "UN IPv4 interface address\n"
3817 "UN IPv6 interface address\n")
3819 struct rfapi_local_reg_delete_arg cda
;
3822 /* pfx vn un L2 VNI */
3823 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3824 argv
[5], NULL
, NULL
, &cda
)))
3827 clear_vnc_prefix(&cda
);
3828 print_cleared_stats(&cda
);
3832 DEFUN (clear_vnc_mac_vn
,
3833 clear_vnc_mac_vn_cmd
,
3834 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3837 "Clear mac registration information\n"
3841 "Any virtual network identifier\n"
3842 "Virtual network identifier\n"
3843 "UN address of NVE\n"
3844 "All VN addresses\n"
3845 "VN IPv4 interface address\n"
3846 "VN IPv6 interface address\n")
3848 struct rfapi_local_reg_delete_arg cda
;
3851 /* pfx vn un L2 VNI */
3852 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3853 argv
[5], NULL
, NULL
, &cda
)))
3856 clear_vnc_prefix(&cda
);
3857 print_cleared_stats(&cda
);
3861 DEFUN (clear_vnc_mac_all
,
3862 clear_vnc_mac_all_cmd
,
3863 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3866 "Clear mac registration information\n"
3870 "Any virtual network identifier\n"
3871 "Virtual network identifier\n"
3874 struct rfapi_local_reg_delete_arg cda
;
3877 /* pfx vn un L2 VNI */
3878 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3879 argv
[5], NULL
, NULL
, &cda
)))
3882 clear_vnc_prefix(&cda
);
3883 print_cleared_stats(&cda
);
3887 /*-------------------------------------------------
3888 * Clear VNC MAC PREFIX
3889 *-------------------------------------------------*/
3891 DEFUN (clear_vnc_mac_vn_un_prefix
,
3892 clear_vnc_mac_vn_un_prefix_cmd
,
3893 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3896 "Clear mac registration information\n"
3900 "Any virtual network identifier\n"
3901 "Virtual network identifier\n"
3902 "VN address of NVE\n"
3903 "All VN addresses\n"
3904 "VN IPv4 interface address\n"
3905 "VN IPv6 interface address\n"
3906 "UN address of NVE\n"
3907 "All UN addresses\n"
3908 "UN IPv4 interface address\n"
3909 "UN IPv6 interface address\n"
3910 "Clear prefix registration information\n"
3915 struct rfapi_local_reg_delete_arg cda
;
3918 /* pfx vn un L2 VNI */
3919 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3920 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3923 clear_vnc_prefix(&cda
);
3924 print_cleared_stats(&cda
);
3928 DEFUN (clear_vnc_mac_un_vn_prefix
,
3929 clear_vnc_mac_un_vn_prefix_cmd
,
3930 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3933 "Clear mac registration information\n"
3937 "Any virtual network identifier\n"
3938 "Virtual network identifier\n"
3939 "UN address of NVE\n"
3940 "All UN addresses\n"
3941 "UN IPv4 interface address\n"
3942 "UN IPv6 interface address\n"
3943 "VN address of NVE\n"
3944 "All VN addresses\n"
3945 "VN IPv4 interface address\n"
3946 "VN IPv6 interface address\n"
3947 "Clear prefix registration information\n"
3951 "Clear prefix registration information\n"
3956 struct rfapi_local_reg_delete_arg cda
;
3959 /* pfx vn un L2 VNI */
3960 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3961 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3964 clear_vnc_prefix(&cda
);
3965 print_cleared_stats(&cda
);
3969 DEFUN (clear_vnc_mac_un_prefix
,
3970 clear_vnc_mac_un_prefix_cmd
,
3971 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
3974 "Clear mac registration information\n"
3978 "Any virtual network identifier\n"
3979 "Virtual network identifier\n"
3980 "UN address of NVE\n"
3981 "All UN addresses\n"
3982 "UN IPv4 interface address\n"
3983 "UN IPv6 interface address\n"
3984 "Clear prefix registration information\n"
3989 struct rfapi_local_reg_delete_arg cda
;
3992 /* pfx vn un L2 VNI */
3993 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3994 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3997 clear_vnc_prefix(&cda
);
3998 print_cleared_stats(&cda
);
4002 DEFUN (clear_vnc_mac_vn_prefix
,
4003 clear_vnc_mac_vn_prefix_cmd
,
4004 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4007 "Clear mac registration information\n"
4011 "Any virtual network identifier\n"
4012 "Virtual network identifier\n"
4013 "UN address of NVE\n"
4014 "All VN addresses\n"
4015 "VN IPv4 interface address\n"
4016 "VN IPv6 interface address\n"
4017 "Clear prefix registration information\n"
4022 struct rfapi_local_reg_delete_arg cda
;
4025 /* pfx vn un L2 VNI */
4026 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4027 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4030 clear_vnc_prefix(&cda
);
4031 print_cleared_stats(&cda
);
4035 DEFUN (clear_vnc_mac_all_prefix
,
4036 clear_vnc_mac_all_prefix_cmd
,
4037 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>",
4040 "Clear mac registration information\n"
4044 "Any virtual network identifier\n"
4045 "Virtual network identifier\n"
4046 "UN address of NVE\n"
4047 "All VN addresses\n"
4048 "VN IPv4 interface address\n"
4049 "VN IPv6 interface address\n")
4051 struct rfapi_local_reg_delete_arg cda
;
4054 /* pfx vn un L2 VNI */
4055 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4056 argv
[5], NULL
, NULL
, &cda
)))
4059 clear_vnc_prefix(&cda
);
4060 print_cleared_stats(&cda
);
4064 /************************************************************************
4066 ************************************************************************/
4069 /* copied from rfp_vty.c */
4070 static int check_and_display_is_vnc_running(struct vty
*vty
)
4072 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4073 return 1; /* is running */
4076 vty_out(vty
, "VNC is not configured.\n");
4078 return 0; /* not running */
4081 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4082 show_nve_summary_t show_type
)
4084 struct bgp
*bgp_default
= bgp_get_default();
4086 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4088 int active_local_routes
;
4089 int active_remote_routes
;
4090 int holddown_remote_routes
;
4091 int imported_remote_routes
;
4096 h
= bgp_default
->rfapi
;
4101 /* don't show local info if not running RFP */
4102 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4104 switch (show_type
) {
4106 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4107 vty_out(vty
, "%-24s ", "NVEs:");
4108 vty_out(vty
, "%-8s %-8u ",
4109 "Active:", h
->descriptors
.count
);
4110 vty_out(vty
, "%-8s %-8u ",
4111 "Maximum:", h
->stat
.max_descriptors
);
4112 vty_out(vty
, "%-8s %-8u",
4113 "Unknown:", h
->stat
.count_unknown_nves
);
4116 case SHOW_NVE_SUMMARY_REGISTERED
:
4118 * NB: With the introduction of L2 route support, we no
4119 * longer have a one-to-one correspondence between
4120 * locally-originated route advertisements and routes in
4121 * the import tables that have local origin. This
4122 * discrepancy arises because a single advertisement
4123 * may contain both an IP prefix and a MAC address.
4124 * Such an advertisement results in two import table
4125 * entries: one indexed by IP prefix, the other indexed
4128 * TBD: update computation and display of registration
4129 * statistics to reflect the underlying semantics.
4131 if (is_vnc_running
) {
4132 vty_out(vty
, "%-24s ", "Registrations:");
4133 vty_out(vty
, "%-8s %-8u ", "Active:",
4134 rfapiApCountAll(bgp_default
));
4135 vty_out(vty
, "%-8s %-8u ", "Failed:",
4136 h
->stat
.count_registrations_failed
);
4137 vty_out(vty
, "%-8s %-8u",
4138 "Total:", h
->stat
.count_registrations
);
4141 vty_out(vty
, "%-24s ", "Prefixes registered:");
4144 rfapiCountAllItRoutes(&active_local_routes
,
4145 &active_remote_routes
,
4146 &holddown_remote_routes
,
4147 &imported_remote_routes
);
4150 if (is_vnc_running
) {
4151 vty_out(vty
, " %-20s ", "Locally:");
4152 vty_out(vty
, "%-8s %-8u ",
4153 "Active:", active_local_routes
);
4158 vty_out(vty
, " %-20s ", "Remotely:");
4159 vty_out(vty
, "%-8s %-8u",
4160 "Active:", active_remote_routes
);
4162 vty_out(vty
, " %-20s ", "In Holddown:");
4163 vty_out(vty
, "%-8s %-8u",
4164 "Active:", holddown_remote_routes
);
4166 vty_out(vty
, " %-20s ", "Imported:");
4167 vty_out(vty
, "%-8s %-8u",
4168 "Active:", imported_remote_routes
);
4171 case SHOW_NVE_SUMMARY_QUERIES
:
4172 vty_out(vty
, "%-24s ", "Queries:");
4173 vty_out(vty
, "%-8s %-8u ",
4174 "Active:", rfapi_monitor_count(NULL
));
4175 vty_out(vty
, "%-8s %-8u ",
4176 "Failed:", h
->stat
.count_queries_failed
);
4177 vty_out(vty
, "%-8s %-8u",
4178 "Total:", h
->stat
.count_queries
);
4181 case SHOW_NVE_SUMMARY_RESPONSES
:
4182 rfapiRibShowResponsesSummary(vty
);
4192 vty_out(vty
, "VNC is not configured.\n");
4196 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4197 struct prefix
*un_prefix
)
4199 // struct hash *rfds;
4200 // struct rfp_rfapi_descriptor_param param;
4202 struct bgp
*bgp_default
= bgp_get_default();
4204 struct listnode
*node
;
4205 struct rfapi_descriptor
*rfd
;
4214 h
= bgp_default
->rfapi
;
4219 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4223 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4225 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4228 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4236 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4237 if (!prefix_match(vn_prefix
, &pfx
))
4242 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4243 if (!prefix_match(un_prefix
, &pfx
))
4247 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4249 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4253 /* print out a header */
4255 " Active Next Hops\n");
4256 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4257 "VN Address", "UN Address", "Regis", "Resps",
4258 "Reach", "Remove", "Age");
4263 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4264 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4265 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4266 rfd
->stat_count_nh_removal
,
4267 rfapiFormatAge(rfd
->open_time
, age
, 10));
4270 if (printed
> 0 || vn_prefix
|| un_prefix
)
4271 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4277 vty_out(vty
, "VNC is not configured.\n");
4282 DEFUN (vnc_show_summary
,
4283 vnc_show_summary_cmd
,
4287 "Display VNC status summary\n")
4289 if (!check_and_display_is_vnc_running(vty
))
4291 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4293 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4294 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4295 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4296 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4300 DEFUN (vnc_show_nves
,
4305 "List known NVEs\n")
4307 rfapi_show_nves(vty
, NULL
, NULL
);
4311 DEFUN (vnc_show_nves_ptct
,
4312 vnc_show_nves_ptct_cmd
,
4313 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4317 "VN address of NVE\n"
4318 "UN address of NVE\n"
4319 "IPv4 interface address\n"
4320 "IPv6 interface address\n")
4324 if (!check_and_display_is_vnc_running(vty
))
4327 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4328 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4331 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4332 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4336 if (argv
[3]->arg
[0] == 'u') {
4337 rfapi_show_nves(vty
, NULL
, &pfx
);
4339 rfapi_show_nves(vty
, &pfx
, NULL
);
4345 /* adapted from rfp_registration_cache_log() */
4346 static void rfapi_show_registrations(struct vty
*vty
,
4347 struct prefix
*restrict_to
, int show_local
,
4348 int show_remote
, int show_holddown
,
4356 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4359 /* non-expiring, local */
4360 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4364 /* non-expiring, non-local */
4365 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4368 if (show_holddown
) {
4369 /* expiring, including local */
4370 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4373 if (show_imported
) {
4374 /* non-expiring, non-local */
4375 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4383 DEFUN (vnc_show_registrations_pfx
,
4384 vnc_show_registrations_pfx_cmd
,
4385 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4388 "List active prefix registrations\n"
4389 "Limit output to a particular IPv4 prefix\n"
4390 "Limit output to a particular IPv6 prefix\n"
4391 "Limit output to a particular IPv6 address\n")
4394 struct prefix
*p_addr
= NULL
;
4397 if (!str2prefix(argv
[3]->arg
, &p
)) {
4398 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4405 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4409 DEFUN (vnc_show_registrations_some_pfx
,
4410 vnc_show_registrations_some_pfx_cmd
,
4411 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4414 "List active prefix registrations\n"
4415 "show all registrations\n"
4416 "show only registrations in holddown\n"
4417 "show only imported prefixes\n"
4418 "show only local registrations\n"
4419 "show only remote registrations\n"
4420 "Limit output to a particular prefix or address\n"
4421 "Limit output to a particular prefix or address\n"
4422 "Limit output to a particular prefix or address\n")
4425 struct prefix
*p_addr
= NULL
;
4428 int show_remote
= 0;
4429 int show_holddown
= 0;
4430 int show_imported
= 0;
4433 if (!str2prefix(argv
[4]->arg
, &p
)) {
4434 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4440 switch (argv
[3]->arg
[0]) {
4465 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4466 show_holddown
, show_imported
);
4470 DEFUN (vnc_show_responses_pfx
,
4471 vnc_show_responses_pfx_cmd
,
4472 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4475 "List recent query responses\n"
4476 "Limit output to a particular IPv4 prefix\n"
4477 "Limit output to a particular IPv6 prefix\n"
4478 "Limit output to a particular IPv6 address\n" )
4481 struct prefix
*p_addr
= NULL
;
4484 if (!str2prefix(argv
[3]->arg
, &p
)) {
4485 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4491 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4493 rfapiRibShowResponsesSummary(vty
);
4495 rfapiRibShowResponses(vty
, p_addr
, 0);
4496 rfapiRibShowResponses(vty
, p_addr
, 1);
4501 DEFUN (vnc_show_responses_some_pfx
,
4502 vnc_show_responses_some_pfx_cmd
,
4503 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4506 "List recent query responses\n"
4507 "show only active query responses\n"
4508 "show only removed query responses\n"
4509 "Limit output to a particular IPv4 prefix\n"
4510 "Limit output to a particular IPv6 prefix\n"
4511 "Limit output to a particular IPV6 address\n")
4514 struct prefix
*p_addr
= NULL
;
4516 int show_active
= 0;
4517 int show_removed
= 0;
4519 if (!check_and_display_is_vnc_running(vty
))
4523 if (!str2prefix(argv
[4]->arg
, &p
)) {
4524 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4531 switch (argv
[3]->arg
[0]) {
4541 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4543 rfapiRibShowResponsesSummary(vty
);
4546 rfapiRibShowResponses(vty
, p_addr
, 0);
4548 rfapiRibShowResponses(vty
, p_addr
, 1);
4553 DEFUN (show_vnc_queries_pfx
,
4554 show_vnc_queries_pfx_cmd
,
4555 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4558 "List active queries\n"
4559 "Limit output to a particular IPv4 prefix or address\n"
4560 "Limit output to a particular IPv6 prefix\n"
4561 "Limit output to a particualr IPV6 address\n")
4564 struct prefix
*p
= NULL
;
4567 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4568 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4574 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4576 return rfapiShowVncQueries(vty
, p
);
4579 DEFUN (vnc_clear_counters
,
4580 vnc_clear_counters_cmd
,
4581 "clear vnc counters",
4584 "Reset VNC counters\n")
4586 struct bgp
*bgp_default
= bgp_get_default();
4588 struct listnode
*node
;
4589 struct rfapi_descriptor
*rfd
;
4594 h
= bgp_default
->rfapi
;
4600 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4601 rfd
->stat_count_nh_reachable
= 0;
4602 rfd
->stat_count_nh_removal
= 0;
4606 memset(&h
->stat
, 0, sizeof(h
->stat
));
4609 * 151122 per bug 103, set count_registrations = number active.
4610 * Do same for queries
4612 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4613 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4615 rfapiRibShowResponsesSummaryClear();
4620 vty_out(vty
, "VNC is not configured.\n");
4624 /************************************************************************
4625 * Add prefix with vrf
4627 * add [vrf <vrf-name>] prefix <prefix>
4628 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4629 ************************************************************************/
4630 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4632 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4633 /* based on rfapi_open */
4634 struct rfapi_descriptor
*rfd
;
4636 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4637 sizeof(struct rfapi_descriptor
));
4640 /* leave most fields empty as will get from (dynamic) config
4642 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4644 if (rfg
->vn_prefix
.family
4645 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4646 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4648 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4649 rfd
->vn_addr
.addr_family
= AF_INET
;
4650 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4652 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4654 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4656 rfapi_init_and_open(bgp
, rfd
, rfg
);
4660 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4661 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4662 const char *arg_prefix
,
4663 const char *arg_rd
, /* optional */
4664 const char *arg_label
, /* optional */
4665 const char *arg_pref
) /* optional */
4668 struct rfapi_nve_group_cfg
*rfg
;
4670 struct rfapi_ip_prefix rpfx
;
4672 struct rfapi_vn_option optary
[3];
4673 struct rfapi_vn_option
*opt
= NULL
;
4676 bgp
= bgp_get_default(); /* assume main instance for now */
4678 vty_out(vty
, "No BGP process is configured\n");
4679 return CMD_WARNING_CONFIG_FAILED
;
4681 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4682 vty_out(vty
, "VRF support not configured\n");
4683 return CMD_WARNING_CONFIG_FAILED
;
4686 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4689 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4691 return CMD_WARNING_CONFIG_FAILED
;
4693 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4695 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4697 return CMD_WARNING_CONFIG_FAILED
;
4699 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4701 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4703 return CMD_WARNING_CONFIG_FAILED
;
4705 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4707 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4709 return CMD_WARNING_CONFIG_FAILED
;
4711 if (!str2prefix(arg_prefix
, &pfx
)) {
4712 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4713 return CMD_WARNING_CONFIG_FAILED
;
4715 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4716 memset(optary
, 0, sizeof(optary
));
4719 opt
->next
= &optary
[cur_opt
];
4720 opt
= &optary
[cur_opt
++];
4721 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4722 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4723 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4724 return CMD_WARNING_CONFIG_FAILED
;
4727 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4728 struct rfapi_l2address_option
*l2o
;
4730 opt
->next
= &optary
[cur_opt
];
4731 opt
= &optary
[cur_opt
++];
4732 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4733 l2o
= &opt
->v
.l2addr
;
4736 label
= strtoul(arg_label
, NULL
, 10);
4739 l2o
->label
= rfg
->label
;
4742 char *endptr
= NULL
;
4743 pref
= strtoul(arg_pref
, &endptr
, 10);
4744 if (*endptr
!= '\0') {
4746 "%% Invalid local-preference value \"%s\"\n",
4748 return CMD_WARNING_CONFIG_FAILED
;
4751 rpfx
.cost
= 255 - (pref
& 255);
4752 vnc_add_vrf_opener(bgp
, rfg
);
4754 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4755 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4756 struct rfapi_next_hop_entry
*head
= NULL
;
4757 struct rfapi_next_hop_entry
*tail
= NULL
;
4758 struct rfapi_vn_option
*vn_opt_new
;
4760 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4763 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4764 struct rfapi_descriptor
*r
=
4765 (struct rfapi_descriptor
*)rfg
->rfd
;
4766 vn_opt_new
= rfapi_vn_options_dup(opt
);
4768 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4770 RFAPI_INFINITE_LIFETIME
,
4771 vn_opt_new
, &head
, &tail
);
4773 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4774 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4776 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4780 vnc_zlog_debug_verbose(
4781 "%s completed, count=%d/%d", __func__
,
4782 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4783 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4787 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4788 vty_out(vty
, "Add failed.\n");
4789 return CMD_WARNING_CONFIG_FAILED
;
4792 DEFUN (add_vrf_prefix_rd_label_pref
,
4793 add_vrf_prefix_rd_label_pref_cmd
,
4794 "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)}]",
4798 "Add/modify prefix related information\n"
4801 "Override configured VRF Route Distinguisher\n"
4802 "<as-number>:<number> or <ip-address>:<number>\n"
4803 "Override configured VRF label\n"
4804 "Label Value <0-1048575>\n"
4805 "Set advertised local preference\n"
4806 "local preference (higher=more preferred)\n")
4808 char *arg_vrf
= argv
[2]->arg
;
4809 char *arg_prefix
= argv
[4]->arg
;
4810 char *arg_rd
= NULL
; /* optional */
4811 char *arg_label
= NULL
; /* optional */
4812 char *arg_pref
= NULL
; /* optional */
4814 argc
--; /* don't parse argument */
4815 while (pargc
< argc
) {
4816 switch (argv
[pargc
++]->arg
[0]) {
4818 arg_rd
= argv
[pargc
]->arg
;
4821 arg_label
= argv
[pargc
]->arg
;
4824 arg_pref
= argv
[pargc
]->arg
;
4832 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4836 /************************************************************************
4837 * del prefix with vrf
4839 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4840 ************************************************************************/
4841 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4844 afi_t afi
= AFI_MAX
;
4846 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4851 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4853 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4858 /* check if IT is empty */
4860 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4864 if (afi
== AFI_MAX
) {
4865 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4870 vnc_zlog_debug_verbose(
4871 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4872 rfg
->rfapi_import_table
->local_count
[afi
]);
4876 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4877 const char *arg_prefix
, /* NULL = all */
4878 const char *arg_rd
) /* optional */
4880 struct rfapi_nve_group_cfg
*rfg
;
4881 struct rfapi_local_reg_delete_arg cda
;
4886 bgp
= bgp_get_default(); /* assume main instance for now */
4888 vty_out(vty
, "No BGP process is configured\n");
4891 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4892 vty_out(vty
, "VRF support not configured\n");
4895 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4898 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4902 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4904 if (rc
!= CMD_SUCCESS
) /* parse error */
4907 start_count
= rfapi_cfg_group_it_count(rfg
);
4908 clear_vnc_prefix(&cda
);
4909 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4914 DEFUN (clear_vrf_prefix_rd
,
4915 clear_vrf_prefix_rd_cmd
,
4916 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4917 "Clear stored data\n"
4920 "Prefix related information\n"
4923 "Specific VRF Route Distinguisher\n"
4924 "<as-number>:<number> or <ip-address>:<number>\n")
4926 char *arg_vrf
= argv
[2]->arg
;
4927 char *arg_prefix
= NULL
; /* optional */
4928 char *arg_rd
= NULL
; /* optional */
4930 argc
--; /* don't check parameter */
4931 while (pargc
< argc
) {
4932 switch (argv
[pargc
++]->arg
[0]) {
4934 arg_rd
= argv
[pargc
]->arg
;
4937 arg_prefix
= argv
[pargc
]->arg
;
4944 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4947 DEFUN (clear_vrf_all
,
4949 "clear vrf NAME all",
4950 "Clear stored data\n"
4955 char *arg_vrf
= argv
[2]->arg
;
4956 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4959 void rfapi_vty_init()
4961 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4962 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4963 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4967 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4968 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4969 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4976 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4977 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4978 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4979 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4980 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4982 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4984 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4985 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4986 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4990 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4996 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
5002 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5005 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5006 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5008 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5009 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5011 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5013 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5014 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5015 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5017 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5018 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5019 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5020 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5021 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);