3 * Copyright 2009-2016, LabN Consulting, L.L.C.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "lib/zebra.h"
22 #include "lib/prefix.h"
23 #include "lib/agg_table.h"
25 #include "lib/memory.h"
26 #include "lib/routemap.h"
28 #include "lib/log_int.h"
29 #include "lib/linklist.h"
30 #include "lib/command.h"
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_ecommunity.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_mplsvpn.h"
38 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
39 #include "bgpd/rfapi/rfapi.h"
40 #include "bgpd/rfapi/rfapi_backend.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_aspath.h"
44 #include "bgpd/bgp_community.h"
45 #include "bgpd/bgp_vnc_types.h"
46 #include "bgpd/bgp_label.h"
48 #include "bgpd/rfapi/rfapi_import.h"
49 #include "bgpd/rfapi/rfapi_private.h"
50 #include "bgpd/rfapi/rfapi_monitor.h"
51 #include "bgpd/rfapi/rfapi_rib.h"
52 #include "bgpd/rfapi/rfapi_vty.h"
53 #include "bgpd/rfapi/rfapi_ap.h"
54 #include "bgpd/rfapi/rfapi_encap_tlv.h"
55 #include "bgpd/rfapi/vnc_debug.h"
57 #define DEBUG_L2_EXTRA 0
58 #define DEBUG_SHOW_EXTRA 0
60 #define VNC_SHOW_STR "VNC information\n"
62 /* format related utilies */
65 #define FMT_MIN 60 /* seconds */
66 #define FMT_HOUR (60 * FMT_MIN)
67 #define FMT_DAY (24 * FMT_HOUR)
68 #define FMT_YEAR (365 * FMT_DAY)
70 char *rfapiFormatSeconds(uint32_t seconds
, char *buf
, size_t len
)
72 int year
, day
, hour
, min
;
74 if (seconds
>= FMT_YEAR
) {
75 year
= seconds
/ FMT_YEAR
;
76 seconds
-= year
* FMT_YEAR
;
80 if (seconds
>= FMT_DAY
) {
81 day
= seconds
/ FMT_DAY
;
82 seconds
-= day
* FMT_DAY
;
86 if (seconds
>= FMT_HOUR
) {
87 hour
= seconds
/ FMT_HOUR
;
88 seconds
-= hour
* FMT_HOUR
;
92 if (seconds
>= FMT_MIN
) {
93 min
= seconds
/ FMT_MIN
;
94 seconds
-= min
* FMT_MIN
;
99 snprintf(buf
, len
, "%dy%dd%dh", year
, day
, hour
);
100 } else if (day
> 0) {
101 snprintf(buf
, len
, "%dd%dh%dm", day
, hour
, min
);
103 snprintf(buf
, len
, "%02d:%02d:%02d", hour
, min
, seconds
);
109 char *rfapiFormatAge(time_t age
, char *buf
, size_t len
)
111 time_t now
, age_adjusted
;
113 now
= rfapi_time(NULL
);
114 age_adjusted
= now
- age
;
116 return rfapiFormatSeconds(age_adjusted
, buf
, len
);
121 * Reimplementation of quagga/lib/prefix.c function, but
122 * for RFAPI-style prefixes
124 void rfapiRprefixApplyMask(struct rfapi_ip_prefix
*rprefix
)
130 static const uint8_t maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
131 0xf8, 0xfc, 0xfe, 0xff};
133 switch (rprefix
->prefix
.addr_family
) {
135 index
= rprefix
->length
/ 8;
137 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v4
;
138 offset
= rprefix
->length
% 8;
139 pnt
[index
] &= maskbit
[offset
];
147 index
= rprefix
->length
/ 8;
149 pnt
= (uint8_t *)&rprefix
->prefix
.addr
.v6
;
150 offset
= rprefix
->length
% 8;
151 pnt
[index
] &= maskbit
[offset
];
164 * translate a quagga prefix into a rfapi IP address. The
165 * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6
172 int rfapiQprefix2Raddr(struct prefix
*qprefix
, struct rfapi_ip_addr
*raddr
)
174 memset(raddr
, 0, sizeof(struct rfapi_ip_addr
));
175 raddr
->addr_family
= qprefix
->family
;
176 switch (qprefix
->family
) {
178 if (qprefix
->prefixlen
!= 32)
180 raddr
->addr
.v4
= qprefix
->u
.prefix4
;
183 if (qprefix
->prefixlen
!= 128)
185 raddr
->addr
.v6
= qprefix
->u
.prefix6
;
194 * Translate Quagga prefix to RFAPI prefix
196 /* rprefix->cost set to 0 */
197 void rfapiQprefix2Rprefix(struct prefix
*qprefix
,
198 struct rfapi_ip_prefix
*rprefix
)
200 memset(rprefix
, 0, sizeof(struct rfapi_ip_prefix
));
201 rprefix
->length
= qprefix
->prefixlen
;
202 rprefix
->prefix
.addr_family
= qprefix
->family
;
203 switch (qprefix
->family
) {
205 rprefix
->prefix
.addr
.v4
= qprefix
->u
.prefix4
;
208 rprefix
->prefix
.addr
.v6
= qprefix
->u
.prefix6
;
215 int rfapiRprefix2Qprefix(struct rfapi_ip_prefix
*rprefix
,
216 struct prefix
*qprefix
)
218 memset(qprefix
, 0, sizeof(struct prefix
));
219 qprefix
->prefixlen
= rprefix
->length
;
220 qprefix
->family
= rprefix
->prefix
.addr_family
;
222 switch (rprefix
->prefix
.addr_family
) {
224 qprefix
->u
.prefix4
= rprefix
->prefix
.addr
.v4
;
227 qprefix
->u
.prefix6
= rprefix
->prefix
.addr
.v6
;
236 * returns 1 if prefixes have same addr family, prefix len, and address
237 * Note that host bits matter in this comparison!
239 * For paralellism with quagga/lib/prefix.c. if we need a comparison
240 * where host bits are ignored, call that function rfapiRprefixCmp.
242 int rfapiRprefixSame(struct rfapi_ip_prefix
*hp1
, struct rfapi_ip_prefix
*hp2
)
244 if (hp1
->prefix
.addr_family
!= hp2
->prefix
.addr_family
)
246 if (hp1
->length
!= hp2
->length
)
248 if (hp1
->prefix
.addr_family
== AF_INET
)
249 if (IPV4_ADDR_SAME(&hp1
->prefix
.addr
.v4
, &hp2
->prefix
.addr
.v4
))
251 if (hp1
->prefix
.addr_family
== AF_INET6
)
252 if (IPV6_ADDR_SAME(&hp1
->prefix
.addr
.v6
, &hp2
->prefix
.addr
.v6
))
257 int rfapiRaddr2Qprefix(struct rfapi_ip_addr
*hia
, struct prefix
*pfx
)
259 memset(pfx
, 0, sizeof(struct prefix
));
260 pfx
->family
= hia
->addr_family
;
262 switch (hia
->addr_family
) {
265 pfx
->u
.prefix4
= hia
->addr
.v4
;
268 pfx
->prefixlen
= 128;
269 pfx
->u
.prefix6
= hia
->addr
.v6
;
277 void rfapiL2o2Qprefix(struct rfapi_l2address_option
*l2o
, struct prefix
*pfx
)
279 memset(pfx
, 0, sizeof(struct prefix
));
280 pfx
->family
= AF_ETHERNET
;
282 pfx
->u
.prefix_eth
= l2o
->macaddr
;
285 char *rfapiEthAddr2Str(const struct ethaddr
*ea
, char *buf
, int bufsize
)
287 return prefix_mac2str(ea
, buf
, bufsize
);
290 int rfapiStr2EthAddr(const char *str
, struct ethaddr
*ea
)
295 if (sscanf(str
, "%2x:%2x:%2x:%2x:%2x:%2x", a
+ 0, a
+ 1, a
+ 2, a
+ 3,
302 for (i
= 0; i
< 6; ++i
)
303 ea
->octet
[i
] = a
[i
] & 0xff;
308 const char *rfapi_ntop(int af
, const void *src
, char *buf
, socklen_t size
)
310 if (af
== AF_ETHERNET
) {
311 return rfapiEthAddr2Str((const struct ethaddr
*)src
, buf
, size
);
314 return inet_ntop(af
, src
, buf
, size
);
317 int rfapiDebugPrintf(void *dummy
, const char *format
, ...)
320 va_start(args
, format
);
321 vzlog(LOG_DEBUG
, format
, args
);
326 static int rfapiStdioPrintf(void *stream
, const char *format
, ...)
331 va_start(args
, format
);
333 switch ((uintptr_t)stream
) {
344 vfprintf(file
, format
, args
);
349 /* Fake out for debug logging */
350 static struct vty vty_dummy_zlog
;
351 static struct vty vty_dummy_stdio
;
352 #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n")
354 static const char *str_vty_newline(struct vty
*vty
)
356 if (vty
== &vty_dummy_zlog
)
361 int rfapiStream2Vty(void *stream
, /* input */
362 int (**fp
)(void *, const char *, ...), /* output */
363 struct vty
**vty
, /* output */
364 void **outstream
, /* output */
365 const char **vty_newline
) /* output */
369 vty_dummy_zlog
.type
= VTY_SHELL
; /* for VTYNL */
370 *vty
= &vty_dummy_zlog
;
371 *fp
= (int (*)(void *, const char *, ...))rfapiDebugPrintf
;
373 *vty_newline
= str_vty_newline(*vty
);
374 return (vzlog_test(LOG_DEBUG
));
377 if (((uintptr_t)stream
== (uintptr_t)1)
378 || ((uintptr_t)stream
== (uintptr_t)2)) {
380 vty_dummy_stdio
.type
= VTY_SHELL
; /* for VTYNL */
381 *vty
= &vty_dummy_stdio
;
382 *fp
= (int (*)(void *, const char *, ...))rfapiStdioPrintf
;
384 *vty_newline
= str_vty_newline(*vty
);
388 *vty
= stream
; /* VTYNL requires vty to be legit */
389 *fp
= (int (*)(void *, const char *, ...))vty_out
;
391 *vty_newline
= str_vty_newline(*vty
);
395 /* called from bgpd/bgp_vty.c'route_vty_out() */
396 void rfapi_vty_out_vncinfo(struct vty
*vty
, struct prefix
*p
,
397 struct bgp_path_info
*bpi
, safi_t safi
)
403 * Print, on an indented line:
404 * UN address [if VPN route and VNC UN addr subtlv]
410 if (safi
== SAFI_MPLS_VPN
) {
411 struct prefix pfx_un
;
413 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
415 vty_out(vty
, "UN=%s",
416 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
,
421 if (bpi
->attr
->ecommunity
) {
422 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
423 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
424 vty_out(vty
, " EC{%s}", s
);
425 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
428 if (bpi
->extra
!= NULL
) {
429 if (bpi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
430 vty_out(vty
, " label=VRF2VRF");
432 vty_out(vty
, " label=%u",
433 decode_label(&bpi
->extra
->label
[0]));
436 if (!rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
437 vty_out(vty
, " life=%d", lifetime
);
440 vty_out(vty
, " type=%s, subtype=%d", zebra_route_string(bpi
->type
),
443 vty_out(vty
, "%s", HVTYNL
);
446 void rfapiPrintAttrPtrs(void *stream
, struct attr
*attr
)
448 int (*fp
)(void *, const char *, ...);
451 const char *vty_newline
;
455 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
458 fp(out
, "Attr[%p]:%s", attr
, HVTYNL
);
463 inet_ntop(AF_INET
, &attr
->nexthop
, buf
, BUFSIZ
);
464 fp(out
, " nexthop=%s%s", buf
, HVTYNL
);
466 fp(out
, " aspath=%p, refcnt=%d%s", attr
->aspath
,
467 (attr
->aspath
? attr
->aspath
->refcnt
: 0), HVTYNL
);
468 fp(out
, " community=%p, refcnt=%d%s", attr
->community
,
469 (attr
->community
? attr
->community
->refcnt
: 0), HVTYNL
);
471 fp(out
, " ecommunity=%p, refcnt=%d%s", attr
->ecommunity
,
472 (attr
->ecommunity
? attr
->ecommunity
->refcnt
: 0), HVTYNL
);
473 fp(out
, " cluster=%p, refcnt=%d%s", attr
->cluster
,
474 (attr
->cluster
? attr
->cluster
->refcnt
: 0), HVTYNL
);
475 fp(out
, " transit=%p, refcnt=%d%s", attr
->transit
,
476 (attr
->transit
? attr
->transit
->refcnt
: 0), HVTYNL
);
480 * Print BPI in an Import Table
482 void rfapiPrintBi(void *stream
, struct bgp_path_info
*bpi
)
487 int (*fp
)(void *, const char *, ...);
490 const char *vty_newline
;
496 struct ethaddr macaddr
= {{0}};
497 struct rfapi_l2address_option l2o_buf
;
498 uint8_t l2hid
= 0; /* valid if has_macaddr */
500 #define REMAIN (BUFSIZ - (p-line))
501 #define INCP {p += (r > REMAIN)? REMAIN: r;}
503 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
509 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
510 && bpi
->extra
->vnc
.import
.timer
) {
512 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
513 r
= snprintf(p
, REMAIN
, " [%4lu] ",
514 thread_timer_remain_second(t
));
518 r
= snprintf(p
, REMAIN
, " ");
523 /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */
524 if (decode_rd_type(bpi
->extra
->vnc
.import
.rd
.val
)
525 == RD_TYPE_VNC_ETH
) {
527 memcpy(macaddr
.octet
, bpi
->extra
->vnc
.import
.rd
.val
+ 2,
529 l2hid
= bpi
->extra
->vnc
.import
.rd
.val
[1];
538 * RFP option sizes (they are opaque values)
539 * extended communities (RTs)
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(bpi
->attr
->mp_nexthop_len
);
549 r
= snprintf(p
, REMAIN
, "%s",
551 &bpi
->attr
->mp_nexthop_global_in
, buf
,
554 } else if (af
== AF_INET6
) {
555 r
= snprintf(p
, REMAIN
, "%s",
556 inet_ntop(AF_INET6
, &bpi
->attr
->mp_nexthop_global
,
560 r
= snprintf(p
, REMAIN
, "?");
565 * VNC tunnel subtlv, if present, contains UN address
567 if (!rfapiGetVncTunnelUnAddr(bpi
->attr
, &pfx_un
)) {
570 inet_ntop(pfx_un
.family
, pfx_un
.u
.val
, buf
, BUFSIZ
));
575 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)) {
576 r
= snprintf(p
, REMAIN
, " nolife");
579 if (lifetime
== 0xffffffff)
580 r
= snprintf(p
, REMAIN
, " %6s", "infini");
582 r
= snprintf(p
, REMAIN
, " %6u", lifetime
);
586 /* RFP option lengths */
587 for (pEncap
= bpi
->attr
->vnc_subtlvs
; pEncap
; pEncap
= pEncap
->next
) {
589 if (pEncap
->type
== BGP_VNC_SUBTLV_TYPE_RFPOPTION
) {
590 if (printed_1st_gol
) {
591 r
= snprintf(p
, REMAIN
, ",");
594 r
= snprintf(p
, REMAIN
,
595 " "); /* leading space */
598 r
= snprintf(p
, REMAIN
, "%d", pEncap
->length
);
605 if (bpi
->attr
->ecommunity
) {
606 s
= ecommunity_ecom2str(bpi
->attr
->ecommunity
,
607 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
608 r
= snprintf(p
, REMAIN
, " %s", s
);
610 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
613 r
= snprintf(p
, REMAIN
, " bpi@%p", bpi
);
616 r
= snprintf(p
, REMAIN
, " p@%p", bpi
->peer
);
619 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
620 r
= snprintf(p
, REMAIN
, " HD=yes");
623 r
= snprintf(p
, REMAIN
, " HD=no");
627 if (bpi
->attr
->weight
) {
628 r
= snprintf(p
, REMAIN
, " W=%d", bpi
->attr
->weight
);
632 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
633 r
= snprintf(p
, REMAIN
, " LP=%d", bpi
->attr
->local_pref
);
636 r
= snprintf(p
, REMAIN
, " LP=unset");
640 r
= snprintf(p
, REMAIN
, " %c:%u", zebra_route_char(bpi
->type
),
644 fp(out
, "%s%s", line
, HVTYNL
);
647 fp(out
, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s",
648 l2hid
, macaddr
.octet
[0], macaddr
.octet
[1], macaddr
.octet
[2],
649 macaddr
.octet
[3], macaddr
.octet
[4], macaddr
.octet
[5],
653 if (!rfapiGetL2o(bpi
->attr
, &l2o_buf
)) {
655 " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s",
656 l2o_buf
.macaddr
.octet
[0], l2o_buf
.macaddr
.octet
[1],
657 l2o_buf
.macaddr
.octet
[2], l2o_buf
.macaddr
.octet
[3],
658 l2o_buf
.macaddr
.octet
[4], l2o_buf
.macaddr
.octet
[5],
659 l2o_buf
.label
, l2o_buf
.logical_net_id
, l2o_buf
.local_nve_id
,
662 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
665 sp
= rfapi_ntop(bpi
->extra
->vnc
.import
.aux_prefix
.family
,
666 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
670 fp(out
, " IP: %s%s", sp
, HVTYNL
);
674 struct rfapi_un_option
*uo
=
675 rfapi_encap_tlv_to_un_option(bpi
->attr
);
677 rfapi_print_tunneltype_option(stream
, 8, &uo
->v
.tunnel
);
678 rfapi_un_options_free(uo
);
683 char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn
*m
, char *buf
, int size
)
685 char buf_pfx
[BUFSIZ
];
690 rfapiRfapiIpAddr2Str(&m
->rfd
->un_addr
, buf_vn
, BUFSIZ
);
691 rfapiRfapiIpAddr2Str(&m
->rfd
->vn_addr
, buf_un
, BUFSIZ
);
693 rc
= snprintf(buf
, size
,
694 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m
,
695 m
->next
, m
->rfd
, buf_vn
, buf_un
,
696 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
, buf_pfx
, BUFSIZ
),
697 m
->p
.prefixlen
, m
->node
);
704 static void rfapiDebugPrintMonitorVpn(void *stream
, struct rfapi_monitor_vpn
*m
)
708 int (*fp
)(void *, const char *, ...);
711 const char *vty_newline
;
713 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
716 rfapiMonitorVpn2Str(m
, buf
, BUFSIZ
);
717 fp(out
, " Mon %s%s", buf
, HVTYNL
);
720 static void rfapiDebugPrintMonitorEncap(void *stream
,
721 struct rfapi_monitor_encap
*m
)
723 int (*fp
)(void *, const char *, ...);
726 const char *vty_newline
;
728 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
731 fp(out
, " Mon m=%p, next=%p, node=%p, bpi=%p%s", m
, m
->next
, m
->node
,
735 void rfapiShowItNode(void *stream
, struct agg_node
*rn
)
737 struct bgp_path_info
*bpi
;
740 int (*fp
)(void *, const char *, ...);
743 const char *vty_newline
;
745 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
748 fp(out
, "%s/%d @%p #%d%s",
749 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
),
750 rn
->p
.prefixlen
, rn
, rn
->lock
, HVTYNL
);
752 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
753 rfapiPrintBi(stream
, bpi
);
756 /* doesn't show montors */
759 void rfapiShowImportTable(void *stream
, const char *label
, struct agg_table
*rt
,
765 int (*fp
)(void *, const char *, ...);
768 const char *vty_newline
;
770 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
773 fp(out
, "Import Table [%s]%s", label
, HVTYNL
);
775 for (rn
= agg_route_top(rt
); rn
; rn
= agg_route_next(rn
)) {
776 struct bgp_path_info
*bpi
;
778 if (rn
->p
.family
== AF_ETHERNET
) {
779 rfapiEthAddr2Str(&rn
->p
.u
.prefix_eth
, buf
, BUFSIZ
);
781 inet_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf
, BUFSIZ
);
784 fp(out
, "%s/%d @%p #%d%s", buf
, rn
->p
.prefixlen
, rn
,
785 rn
->lock
- 1, /* account for loop iterator locking */
788 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
789 rfapiPrintBi(stream
, bpi
);
793 struct rfapi_monitor_vpn
*m
;
794 for (m
= RFAPI_MONITOR_VPN(rn
); m
; m
= m
->next
) {
795 rfapiDebugPrintMonitorVpn(stream
, m
);
798 struct rfapi_monitor_encap
*m
;
799 for (m
= RFAPI_MONITOR_ENCAP(rn
); m
; m
= m
->next
) {
800 rfapiDebugPrintMonitorEncap(stream
, m
);
806 int rfapiShowVncQueries(void *stream
, struct prefix
*pfx_match
)
810 struct listnode
*node
;
811 struct rfapi_descriptor
*rfd
;
813 int (*fp
)(void *, const char *, ...);
816 const char *vty_newline
;
818 int printedheader
= 0;
821 int nves_with_queries
= 0;
822 int nves_displayed
= 0;
824 int queries_total
= 0;
825 int queries_displayed
= 0;
827 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
830 bgp
= bgp_get_default(); /* assume 1 instance for now */
832 vty_out(vty
, "No BGP instance\n");
838 vty_out(vty
, "No RFAPI instance\n");
842 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
845 int printedquerier
= 0;
851 || (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
))) {
861 for (rn
= agg_route_top(rfd
->mon
); rn
;
862 rn
= agg_route_next(rn
)) {
863 struct rfapi_monitor_vpn
*m
;
864 char buf_remain
[BUFSIZ
];
865 char buf_pfx
[BUFSIZ
];
875 && !prefix_match(pfx_match
, &rn
->p
)
876 && !prefix_match(&rn
->p
, pfx_match
))
881 if (!printedheader
) {
884 fp(out
, "%-15s %-15s %-15s %-10s\n",
885 "VN Address", "UN Address", "Target",
889 if (!printedquerier
) {
893 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
895 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
898 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
903 fp(out
, "%-15s %-15s", "", "");
907 thread_timer_remain_second(
911 fp(out
, " %-15s %-10s\n",
912 inet_ntop(m
->p
.family
, &m
->p
.u
.prefix
,
921 if (rfd
->mon_eth
&& skiplist_count(rfd
->mon_eth
)) {
925 struct rfapi_monitor_eth
*mon_eth
;
928 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
929 (void **)&mon_eth
, &cursor
);
931 rc
= skiplist_next(rfd
->mon_eth
, NULL
,
932 (void **)&mon_eth
, &cursor
)) {
934 char buf_remain
[BUFSIZ
];
935 char buf_pfx
[BUFSIZ
];
936 struct prefix pfx_mac
;
940 vnc_zlog_debug_verbose(
941 "%s: checking rfd=%p mon_eth=%p",
942 __func__
, rfd
, mon_eth
);
944 memset((void *)&pfx_mac
, 0,
945 sizeof(struct prefix
));
946 pfx_mac
.family
= AF_ETHERNET
;
947 pfx_mac
.prefixlen
= 48;
948 pfx_mac
.u
.prefix_eth
= mon_eth
->macaddr
;
951 && !prefix_match(pfx_match
, &pfx_mac
)
952 && !prefix_match(&pfx_mac
, pfx_match
))
957 if (!printedheader
) {
961 "%-15s %-15s %-17s %10s %-10s\n",
962 "VN Address", "UN Address", "Target",
966 if (!printedquerier
) {
970 rfapiRfapiIpAddr2Str(&rfd
->un_addr
,
972 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
,
975 fp(out
, "%-15s %-15s", buf_vn
, buf_un
);
980 fp(out
, "%-15s %-15s", "", "");
982 if (mon_eth
->timer
) {
984 thread_timer_remain_second(
988 fp(out
, " %-17s %10d %-10s\n",
989 rfapi_ntop(pfx_mac
.family
, &pfx_mac
.u
.prefix
,
991 mon_eth
->logical_net_id
, buf_remain
);
998 fp(out
, "Displayed %d out of %d total queries\n",
999 queries_displayed
, queries_total
);
1004 static int rfapiPrintRemoteRegBi(struct bgp
*bgp
, void *stream
,
1005 struct agg_node
*rn
, struct bgp_path_info
*bpi
)
1007 int (*fp
)(void *, const char *, ...);
1010 const char *vty_newline
;
1011 struct prefix pfx_un
;
1012 struct prefix pfx_vn
;
1015 bgp_encap_types tun_type
= BGP_ENCAP_TYPE_MPLS
;/*Default tunnel type*/
1017 char buf_pfx
[BUFSIZ
];
1018 char buf_ntop
[BUFSIZ
];
1019 char buf_un
[BUFSIZ
];
1020 char buf_vn
[BUFSIZ
];
1021 char buf_lifetime
[BUFSIZ
];
1025 return 0; /* for debug log, print into buf & call output once */
1027 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1034 snprintf(buf_pfx
, BUFSIZ
, "%s/%d",
1035 rfapi_ntop(rn
->p
.family
, &rn
->p
.u
.prefix
, buf_ntop
, BUFSIZ
),
1037 buf_pfx
[BUFSIZ
- 1] = 0;
1044 if (!rfapiGetUnAddrOfVpnBi(bpi
, &pfx_un
)) {
1045 snprintf(buf_un
, BUFSIZ
, "%s",
1046 inet_ntop(pfx_un
.family
, &pfx_un
.u
.prefix
, buf_ntop
,
1050 bgp_attr_extcom_tunnel_type(bpi
->attr
, &tun_type
);
1055 rfapiNexthop2Prefix(bpi
->attr
, &pfx_vn
);
1056 if (tun_type
== BGP_ENCAP_TYPE_MPLS
) {
1057 /* MPLS carries un in nrli next hop (same as vn for IP tunnels)
1059 snprintf(buf_un
, BUFSIZ
, "%s",
1060 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1063 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1064 snprintf(buf_vn
, BUFSIZ
, "Label: %d", l
);
1065 } else /* should never happen */
1067 snprintf(buf_vn
, BUFSIZ
, "Label: N/A");
1070 snprintf(buf_vn
, BUFSIZ
, "%s",
1071 inet_ntop(pfx_vn
.family
, &pfx_vn
.u
.prefix
, buf_ntop
,
1074 buf_vn
[BUFSIZ
- 1] = 0;
1075 buf_un
[BUFSIZ
- 1] = 0;
1078 * Cost is encoded in local_pref as (255-cost)
1079 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion
1082 uint32_t local_pref
;
1084 if (bpi
->attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
1085 local_pref
= bpi
->attr
->local_pref
;
1088 cost
= (local_pref
> 255) ? 0 : 255 - local_pref
;
1090 fp(out
, "%-20s ", buf_pfx
);
1091 fp(out
, "%-15s ", buf_vn
);
1092 fp(out
, "%-15s ", buf_un
);
1093 fp(out
, "%-4d ", cost
);
1096 /* NB rfapiGetVncLifetime sets infinite value when returning !0 */
1097 if (rfapiGetVncLifetime(bpi
->attr
, &lifetime
)
1098 || (lifetime
== RFAPI_INFINITE_LIFETIME
)) {
1100 fp(out
, "%-10s ", "infinite");
1102 time_t t_lifetime
= lifetime
;
1103 rfapiFormatSeconds(t_lifetime
, buf_lifetime
, BUFSIZ
);
1104 fp(out
, "%-10s ", buf_lifetime
);
1107 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
) && bpi
->extra
1108 && bpi
->extra
->vnc
.import
.timer
) {
1112 char buf_age
[BUFSIZ
];
1115 (struct thread
*)bpi
->extra
->vnc
.import
.timer
;
1116 remaining
= thread_timer_remain_second(t
);
1118 #if RFAPI_REGISTRATIONS_REPORT_AGE
1120 * Calculate when the timer started. Doing so here saves
1121 * us a timestamp field in "struct bgp_path_info".
1123 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the
1124 * original calculation.
1126 age
= rfapiGetHolddownFromLifetime(lifetime
, factor
)
1128 #else /* report remaining time */
1131 rfapiFormatSeconds(age
, buf_age
, BUFSIZ
);
1133 fp(out
, "%-10s ", buf_age
);
1135 } else if (RFAPI_LOCAL_BI(bpi
)) {
1137 char buf_age
[BUFSIZ
];
1139 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.create_time
) {
1140 rfapiFormatAge(bpi
->extra
->vnc
.import
.create_time
,
1146 fp(out
, "%-10s ", buf_age
);
1148 fp(out
, "%s", HVTYNL
);
1150 if (rn
->p
.family
== AF_ETHERNET
) {
1152 * If there is a corresponding IP address && != VN address,
1153 * print that on the next line
1156 if (bpi
->extra
&& bpi
->extra
->vnc
.import
.aux_prefix
.family
) {
1160 bpi
->extra
->vnc
.import
.aux_prefix
.family
,
1161 &bpi
->extra
->vnc
.import
.aux_prefix
.u
.prefix
,
1163 buf_ntop
[BUFSIZ
- 1] = 0;
1165 if (sp
&& strcmp(buf_vn
, sp
) != 0) {
1166 fp(out
, " IP: %s", sp
);
1172 if (tun_type
!= BGP_ENCAP_TYPE_MPLS
&& bpi
->extra
) {
1173 uint32_t l
= decode_label(&bpi
->extra
->label
[0]);
1174 if (!MPLS_LABEL_IS_NULL(l
)) {
1175 fp(out
, " Label: %d", l
);
1181 fp(out
, "%s", HVTYNL
);
1186 static int rfapiShowRemoteRegistrationsIt(struct bgp
*bgp
, void *stream
,
1187 struct rfapi_import_table
*it
,
1188 struct prefix
*prefix_only
,
1189 int show_expiring
, /* either/or */
1190 int show_local
, int show_remote
,
1191 int show_imported
, /* either/or */
1192 uint32_t *pLni
) /* AFI_L2VPN only */
1195 int printed_rtlist_hdr
= 0;
1197 int (*fp
)(void *, const char *, ...);
1200 const char *vty_newline
;
1204 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1207 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1209 struct agg_node
*rn
;
1211 if (!it
->imported_vpn
[afi
])
1214 for (rn
= agg_route_top(it
->imported_vpn
[afi
]); rn
;
1215 rn
= agg_route_next(rn
)) {
1217 struct bgp_path_info
*bpi
;
1220 /* allow for wider or more narrow mask from user */
1221 if (prefix_only
&& !prefix_match(prefix_only
, &rn
->p
)
1222 && !prefix_match(&rn
->p
, prefix_only
))
1227 for (bpi
= rn
->info
; bpi
; bpi
= bpi
->next
) {
1229 if (!show_local
&& RFAPI_LOCAL_BI(bpi
)) {
1231 /* local route from RFP */
1235 if (!show_remote
&& !RFAPI_LOCAL_BI(bpi
)) {
1242 && !CHECK_FLAG(bpi
->flags
,
1247 && CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
1250 if (bpi
->type
== ZEBRA_ROUTE_BGP_DIRECT
1252 == ZEBRA_ROUTE_BGP_DIRECT_EXT
) {
1261 if (count_only
== 1)
1263 if (!printed_rtlist_hdr
) {
1264 const char *agetype
= "";
1266 const char *type
= "";
1267 if (show_imported
) {
1270 if (show_expiring
) {
1282 s
= ecommunity_ecom2str(
1284 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1288 "%s[%s] L2VPN Network 0x%x (%u) RT={%s}",
1289 HVTYNL
, type
, *pLni
,
1290 (*pLni
& 0xfff), s
);
1292 fp(out
, "%s[%s] Prefix RT={%s}",
1295 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1297 if (it
->rfg
&& it
->rfg
->name
) {
1298 fp(out
, " %s \"%s\"",
1299 (it
->rfg
->type
== RFAPI_GROUP_CFG_VRF
1304 fp(out
, "%s", HVTYNL
);
1305 if (show_expiring
) {
1306 #if RFAPI_REGISTRATIONS_REPORT_AGE
1309 agetype
= "Remaining";
1311 } else if (show_local
) {
1315 printed_rtlist_hdr
= 1;
1318 "%-20s %-15s %-15s %4s %-10s %-10s%s",
1319 (pLni
? "L2 Address/IP" : "Prefix"),
1320 "VN Address", "UN Address", "Cost",
1321 "Lifetime", agetype
, HVTYNL
);
1323 printed
+= rfapiPrintRemoteRegBi(bgp
, stream
,
1331 const char *type
= "prefixes";
1333 if (show_imported
) {
1334 type
= "imported prefixes";
1336 if (show_expiring
) {
1337 type
= "prefixes in holddown";
1339 if (show_local
&& !show_remote
) {
1340 type
= "locally registered prefixes";
1341 } else if (!show_local
&& show_remote
) {
1342 type
= "remotely registered prefixes";
1347 fp(out
, "Displayed %d out of %d %s%s", printed
, total
, type
,
1349 #if DEBUG_SHOW_EXTRA
1350 fp(out
, "IT table above: it=%p%s", it
, HVTYNL
);
1358 * rfapiShowRemoteRegistrations
1360 * Similar to rfapiShowImportTable() above. This function
1361 * is mean to produce the "remote" portion of the output
1362 * of "show vnc registrations".
1364 int rfapiShowRemoteRegistrations(void *stream
, struct prefix
*prefix_only
,
1365 int show_expiring
, int show_local
,
1366 int show_remote
, int show_imported
)
1370 struct rfapi_import_table
*it
;
1373 bgp
= bgp_get_default();
1383 for (it
= h
->imports
; it
; it
= it
->next
) {
1384 printed
+= rfapiShowRemoteRegistrationsIt(
1385 bgp
, stream
, it
, prefix_only
, show_expiring
, show_local
,
1386 show_remote
, show_imported
, NULL
);
1389 if (h
->import_mac
) {
1390 void *cursor
= NULL
;
1392 uintptr_t lni_as_ptr
;
1396 for (rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1397 (void **)&it
, &cursor
);
1399 rc
= skiplist_next(h
->import_mac
, (void **)&lni_as_ptr
,
1400 (void **)&it
, &cursor
)) {
1402 if ((lni_as_ptr
& 0xffffffff) == lni_as_ptr
) {
1403 lni
= (uint32_t)(lni_as_ptr
& 0xffffffff);
1407 printed
+= rfapiShowRemoteRegistrationsIt(
1408 bgp
, stream
, it
, prefix_only
, show_expiring
,
1409 show_local
, show_remote
, show_imported
, pLni
);
1416 /*------------------------------------------
1417 * rfapiRfapiIpAddr2Str
1419 * UI helper: generate string from rfapi_ip_addr
1422 * a IP v4/v6 address
1425 * buf put string here
1426 * bufsize max space to write
1429 * NULL conversion failed
1430 * non-NULL pointer to buf
1431 --------------------------------------------*/
1432 const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr
*a
, char *buf
,
1435 const char *rc
= NULL
;
1437 switch (a
->addr_family
) {
1439 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1442 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1448 void rfapiPrintRfapiIpAddr(void *stream
, struct rfapi_ip_addr
*a
)
1451 const char *rc
= NULL
;
1453 int (*fp
)(void *, const char *, ...);
1456 const char *vty_newline
;
1458 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1461 rc
= rfapiRfapiIpAddr2Str(a
, buf
, BUFSIZ
);
1467 const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix
*p
, char *buf
,
1470 struct rfapi_ip_addr
*a
= &p
->prefix
;
1471 const char *rc
= NULL
;
1473 switch (a
->addr_family
) {
1475 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v4
, buf
, bufsize
);
1478 rc
= inet_ntop(a
->addr_family
, &a
->addr
.v6
, buf
, bufsize
);
1483 int alen
= strlen(buf
);
1484 int remaining
= bufsize
- alen
- 1;
1487 if (remaining
> 0) {
1488 slen
= snprintf(buf
+ alen
, remaining
, "/%u",
1490 if (slen
< remaining
) /* see man page for snprintf(3) */
1498 void rfapiPrintRfapiIpPrefix(void *stream
, struct rfapi_ip_prefix
*p
)
1503 int (*fp
)(void *, const char *, ...);
1506 const char *vty_newline
;
1508 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1511 rc
= rfapiRfapiIpPrefix2Str(p
, buf
, BUFSIZ
);
1514 fp(out
, "%s:%u", buf
, p
->cost
);
1519 void rfapiPrintRd(struct vty
*vty
, struct prefix_rd
*prd
)
1521 char buf
[RD_ADDRSTRLEN
];
1523 prefix_rd2str(prd
, buf
, sizeof(buf
));
1524 vty_out(vty
, "%s", buf
);
1527 void rfapiPrintAdvertisedInfo(struct vty
*vty
, struct rfapi_descriptor
*rfd
,
1528 safi_t safi
, struct prefix
*p
)
1530 afi_t afi
; /* of the VN address */
1531 struct bgp_node
*bn
;
1532 struct bgp_path_info
*bpi
;
1533 uint8_t type
= ZEBRA_ROUTE_BGP
;
1536 struct prefix_rd prd0
;
1537 struct prefix_rd
*prd
;
1540 * Find the bgp_path in the RIB corresponding to this
1544 afi
= family2afi(p
->family
);
1545 assert(afi
== AFI_IP
|| afi
== AFI_IP6
);
1547 bgp
= bgp_get_default(); /* assume 1 instance for now */
1550 if (safi
== SAFI_ENCAP
) {
1551 memset(&prd0
, 0, sizeof(prd0
));
1552 prd0
.family
= AF_UNSPEC
;
1553 prd0
.prefixlen
= 64;
1558 bn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
1560 vty_out(vty
, " bn=%p%s", bn
, HVTYNL
);
1562 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
; bpi
= bpi
->next
) {
1563 if (bpi
->peer
== rfd
->peer
&& bpi
->type
== type
1564 && bpi
->sub_type
== BGP_ROUTE_RFP
&& bpi
->extra
1565 && bpi
->extra
->vnc
.export
.rfapi_handle
== (void *)rfd
) {
1567 rfapiPrintBi(vty
, bpi
);
1573 vty_out(vty
, " --?--%s", HVTYNL
);
1578 void rfapiPrintDescriptor(struct vty
*vty
, struct rfapi_descriptor
*rfd
)
1580 /* pHD un-addr vn-addr pCB cookie rd lifetime */
1581 /* RT export list */
1582 /* RT import list */
1583 /* list of advertised prefixes */
1584 /* dump import table */
1590 struct rfapi_adb
*adb
;
1591 char buf
[PREFIX_STRLEN
];
1593 vty_out(vty
, "%-10p ", rfd
);
1594 rfapiPrintRfapiIpAddr(vty
, &rfd
->un_addr
);
1596 rfapiPrintRfapiIpAddr(vty
, &rfd
->vn_addr
);
1597 vty_out(vty
, " %p %p ", rfd
->response_cb
, rfd
->cookie
);
1598 rfapiPrintRd(vty
, &rfd
->rd
);
1599 vty_out(vty
, " %d", rfd
->response_lifetime
);
1600 vty_out(vty
, " %s", (rfd
->rfg
? rfd
->rfg
->name
: "<orphaned>"));
1601 vty_out(vty
, "%s", HVTYNL
);
1603 vty_out(vty
, " Peer %p #%d%s", rfd
->peer
, rfd
->peer
->lock
, HVTYNL
);
1605 /* export RT list */
1606 if (rfd
->rt_export_list
) {
1607 s
= ecommunity_ecom2str(rfd
->rt_export_list
,
1608 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1609 vty_out(vty
, " Export %s%s", s
, HVTYNL
);
1610 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1612 vty_out(vty
, " Export (nil)%s", HVTYNL
);
1615 /* import RT list */
1616 if (rfd
->import_table
) {
1617 s
= ecommunity_ecom2str(rfd
->import_table
->rt_import_list
,
1618 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1619 vty_out(vty
, " Import %s%s", s
, HVTYNL
);
1620 XFREE(MTYPE_ECOMMUNITY_STR
, s
);
1622 vty_out(vty
, " Import (nil)%s", HVTYNL
);
1625 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
1628 family
= afi2family(afi
);
1633 for (rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1634 (void **)&adb
, &cursor
);
1636 rc
= skiplist_next(rfd
->advertised
.ipN_by_prefix
, NULL
,
1637 (void **)&adb
, &cursor
)) {
1639 /* group like family prefixes together in output */
1640 if (family
!= adb
->u
.s
.prefix_ip
.family
)
1643 prefix2str(&adb
->u
.s
.prefix_ip
, buf
, sizeof(buf
));
1645 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1646 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1647 &adb
->u
.s
.prefix_ip
);
1650 for (rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1651 (void **)&adb
, &cursor
);
1652 rc
== 0; rc
= skiplist_next(rfd
->advertised
.ip0_by_ether
, NULL
,
1653 (void **)&adb
, &cursor
)) {
1655 prefix2str(&adb
->u
.s
.prefix_eth
, buf
, sizeof(buf
));
1657 vty_out(vty
, " Adv Pfx: %s%s", buf
, HVTYNL
);
1659 /* TBD update the following function to print ethernet info */
1660 /* Also need to pass/use rd */
1661 rfapiPrintAdvertisedInfo(vty
, rfd
, SAFI_MPLS_VPN
,
1662 &adb
->u
.s
.prefix_ip
);
1664 vty_out(vty
, "%s", HVTYNL
);
1668 * test scripts rely on first line for each nve starting in 1st column,
1669 * leading whitespace for additional detail of that nve
1671 void rfapiPrintMatchingDescriptors(struct vty
*vty
, struct prefix
*vn_prefix
,
1672 struct prefix
*un_prefix
)
1676 struct listnode
*ln
;
1677 struct rfapi_descriptor
*rfd
;
1680 bgp
= bgp_get_default(); /* assume 1 instance for now */
1687 for (ln
= listhead(&h
->descriptors
); ln
; ln
= listnextnode(ln
)) {
1688 rfd
= listgetdata(ln
);
1693 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
1694 if (!prefix_match(vn_prefix
, &pfx
))
1699 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
1700 if (!prefix_match(un_prefix
, &pfx
))
1705 /* print column header */
1706 vty_out(vty
, "%s %s %s %s %s %s %s %s%s", "descriptor",
1707 "un-addr", "vn-addr", "callback", "cookie",
1708 "RD", "lifetime", "group", HVTYNL
);
1710 rfapiPrintDescriptor(vty
, rfd
);
1717 * Parse an address and put into a struct prefix
1719 int rfapiCliGetPrefixAddr(struct vty
*vty
, const char *str
, struct prefix
*p
)
1721 if (!str2prefix(str
, p
)) {
1722 vty_out(vty
, "Malformed address \"%s\"%s", str
? str
: "null",
1726 switch (p
->family
) {
1728 if (p
->prefixlen
!= 32) {
1729 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1735 if (p
->prefixlen
!= 128) {
1736 vty_out(vty
, "Not a host address: \"%s\"%s", str
,
1742 vty_out(vty
, "Invalid address \"%s\"%s", str
, HVTYNL
);
1748 int rfapiCliGetRfapiIpAddr(struct vty
*vty
, const char *str
,
1749 struct rfapi_ip_addr
*hai
)
1754 rc
= rfapiCliGetPrefixAddr(vty
, str
, &pfx
);
1758 hai
->addr_family
= pfx
.family
;
1759 if (pfx
.family
== AF_INET
)
1760 hai
->addr
.v4
= pfx
.u
.prefix4
;
1762 hai
->addr
.v6
= pfx
.u
.prefix6
;
1768 * Note: this function does not flush vty output, so if it is called
1769 * with a stream pointing to a vty, the user will have to type something
1770 * before the callback output shows up
1772 void rfapiPrintNhl(void *stream
, struct rfapi_next_hop_entry
*next_hops
)
1774 struct rfapi_next_hop_entry
*nh
;
1777 int (*fp
)(void *, const char *, ...);
1780 const char *vty_newline
;
1782 #define REMAIN (BUFSIZ - (p-line))
1783 #define INCP {p += (r > REMAIN)? REMAIN: r;}
1785 if (rfapiStream2Vty(stream
, &fp
, &vty
, &out
, &vty_newline
) == 0)
1788 for (nh
= next_hops
, count
= 1; nh
; nh
= nh
->next
, ++count
) {
1794 r
= snprintf(p
, REMAIN
, "%3d pfx=", count
);
1797 if (rfapiRfapiIpPrefix2Str(&nh
->prefix
, p
, REMAIN
)) {
1798 /* it fit, so count length */
1806 r
= snprintf(p
, REMAIN
, ", un=");
1809 if (rfapiRfapiIpAddr2Str(&nh
->un_address
, p
, REMAIN
)) {
1810 /* it fit, so count length */
1818 r
= snprintf(p
, REMAIN
, ", vn=");
1821 if (rfapiRfapiIpAddr2Str(&nh
->vn_address
, p
, REMAIN
)) {
1822 /* it fit, so count length */
1831 line
[BUFSIZ
- 1] = 0;
1832 fp(out
, "%s%s", line
, HVTYNL
);
1837 if (nh
->vn_options
) {
1838 struct rfapi_vn_option
*vo
;
1839 char offset
[] = " ";
1841 for (vo
= nh
->vn_options
; vo
; vo
= vo
->next
) {
1845 case RFAPI_VN_OPTION_TYPE_L2ADDR
:
1846 rfapiEthAddr2Str(&vo
->v
.l2addr
.macaddr
,
1847 pbuf
, sizeof(pbuf
));
1849 "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s",
1851 (vo
->v
.l2addr
.label
& 0x00ffffff),
1852 (vo
->v
.l2addr
.logical_net_id
1854 vo
->v
.l2addr
.local_nve_id
, HVTYNL
);
1857 case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
:
1858 prefix2str(&vo
->v
.local_nexthop
.addr
,
1859 pbuf
, sizeof(pbuf
));
1860 fp(out
, "%sLNH %s cost=%d%s", offset
,
1861 pbuf
, vo
->v
.local_nexthop
.cost
,
1867 "%svn option type %d (unknown)%s",
1868 offset
, vo
->type
, HVTYNL
);
1873 if (nh
->un_options
) {
1874 struct rfapi_un_option
*uo
;
1875 char offset
[] = " ";
1877 for (uo
= nh
->un_options
; uo
; uo
= uo
->next
) {
1879 case RFAPI_UN_OPTION_TYPE_TUNNELTYPE
:
1880 rfapi_print_tunneltype_option(
1881 stream
, 8, &uo
->v
.tunnel
);
1884 fp(out
, "%sUN Option type %d%s", offset
,
1885 uo
->type
, vty_newline
);
1893 /***********************************************************************
1895 ***********************************************************************/
1898 * Add another nexthop to the NHL
1900 static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr
*un_addr
,
1901 struct rfapi_ip_addr
*vn_addr
,
1902 struct rfapi_ip_prefix
*rprefix
,
1904 uint32_t lifetime
, /* add only */
1905 struct rfapi_vn_option
*vn_options
,
1906 struct rfapi_next_hop_entry
**head
,
1907 struct rfapi_next_hop_entry
**tail
)
1909 struct rfapi_next_hop_entry
*new;
1915 new = XCALLOC(MTYPE_RFAPI_NEXTHOP
, sizeof(struct rfapi_next_hop_entry
));
1916 new->prefix
= *rprefix
;
1917 new->un_address
= *un_addr
;
1918 new->vn_address
= *vn_addr
;
1920 new->vn_options
= vn_options
;
1922 new->lifetime
= lifetime
;
1924 new->lifetime
= RFAPI_REMOVE_RESPONSE_LIFETIME
;
1928 (*tail
)->next
= new;
1937 register_add(struct vty
*vty
, struct cmd_token
*carg_prefix
,
1938 struct cmd_token
*carg_vn
, struct cmd_token
*carg_un
,
1939 struct cmd_token
*carg_cost
, /* optional */
1940 struct cmd_token
*carg_lifetime
, /* optional */
1941 struct cmd_token
*carg_macaddr
, /* optional */
1943 *carg_vni
, /* mac present=>mandatory Virtual Network ID */
1944 int argc
, struct cmd_token
**argv
)
1946 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
1947 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
1948 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
1949 const char *arg_cost
= carg_cost
? carg_cost
->arg
: NULL
;
1950 const char *arg_lifetime
= carg_lifetime
? carg_lifetime
->arg
: NULL
;
1951 const char *arg_macaddr
= carg_macaddr
? carg_macaddr
->arg
: NULL
;
1952 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
1953 struct rfapi_ip_addr vn_address
;
1954 struct rfapi_ip_addr un_address
;
1956 struct rfapi_ip_prefix rpfx
;
1961 struct rfapi_vn_option optary
[10]; /* XXX must be big enough */
1962 struct rfapi_vn_option
*opt
= NULL
;
1965 int rc
= CMD_WARNING_CONFIG_FAILED
;
1969 struct rfapi_cfg
*rfapi_cfg
;
1971 const char *arg_lnh
= NULL
;
1972 const char *arg_lnh_cost
= NULL
;
1974 bgp
= bgp_get_default(); /* assume 1 instance for now */
1977 vty_out(vty
, "BGP not configured\n");
1978 return CMD_WARNING_CONFIG_FAILED
;
1982 rfapi_cfg
= bgp
->rfapi_cfg
;
1983 if (!h
|| !rfapi_cfg
) {
1985 vty_out(vty
, "RFAPI not configured\n");
1986 return CMD_WARNING_CONFIG_FAILED
;
1989 for (; argc
; --argc
, ++argv
) {
1990 if (strmatch(argv
[0]->text
, "local-next-hop")) {
1993 "local-next-hop specified more than once\n");
1994 return CMD_WARNING_CONFIG_FAILED
;
1998 "Missing parameter for local-next-hop\n");
1999 return CMD_WARNING_CONFIG_FAILED
;
2003 arg_lnh
= argv
[0]->arg
;
2005 if (strmatch(argv
[0]->text
, "local-cost")) {
2008 "local-cost specified more than once\n");
2009 return CMD_WARNING_CONFIG_FAILED
;
2013 "Missing parameter for local-cost\n");
2014 return CMD_WARNING_CONFIG_FAILED
;
2018 arg_lnh_cost
= argv
[0]->arg
;
2022 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
, &vn_address
)))
2024 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
, &un_address
)))
2027 /* arg_prefix is optional if mac address is given */
2028 if (arg_macaddr
&& !arg_prefix
) {
2030 * fake up a 0/32 or 0/128 prefix
2032 switch (vn_address
.addr_family
) {
2034 arg_prefix
= "0.0.0.0/32";
2037 arg_prefix
= "0::0/128";
2041 "Internal error, unknown VN address family\n");
2042 return CMD_WARNING_CONFIG_FAILED
;
2046 if (!str2prefix(arg_prefix
, &pfx
)) {
2047 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2050 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
2051 vty_out(vty
, "prefix \"%s\" has invalid address family\n",
2057 memset(optary
, 0, sizeof(optary
));
2061 cost
= strtoul(arg_cost
, &endptr
, 10);
2062 if (*endptr
!= '\0' || cost
> 255) {
2063 vty_out(vty
, "%% Invalid %s value\n", "cost");
2071 if (!strcmp(arg_lifetime
, "infinite")) {
2072 lifetime
= RFAPI_INFINITE_LIFETIME
;
2075 lifetime
= strtoul(arg_lifetime
, &endptr
, 10);
2076 if (*endptr
!= '\0') {
2077 vty_out(vty
, "%% Invalid %s value\n",
2083 lifetime
= RFAPI_INFINITE_LIFETIME
; /* default infinite */
2089 "%% %s may only be specified with local-next-hop\n",
2094 lnh_cost
= strtoul(arg_lnh_cost
, &endptr
, 10);
2095 if (*endptr
!= '\0' || lnh_cost
> 255) {
2096 vty_out(vty
, "%% Invalid %s value\n", "local-cost");
2106 "%% %s may only be specified with prefix\n",
2110 if ((rc
= rfapiCliGetPrefixAddr(
2112 &optary
[opt_next
].v
.local_nexthop
.addr
))) {
2117 optary
[opt_next
].v
.local_nexthop
.cost
= lnh_cost
;
2118 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP
;
2121 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2128 if (arg_vni
&& !arg_macaddr
) {
2129 vty_out(vty
, "%% %s may only be specified with mac address\n",
2130 "virtual-network-identifier");
2137 "Missing \"vni\" parameter (mandatory with mac)\n");
2138 return CMD_WARNING_CONFIG_FAILED
;
2140 optary
[opt_next
].v
.l2addr
.logical_net_id
=
2141 strtoul(arg_vni
, NULL
, 10);
2143 if ((rc
= rfapiStr2EthAddr(
2145 &optary
[opt_next
].v
.l2addr
.macaddr
))) {
2146 vty_out(vty
, "Invalid %s value\n", "mac address");
2149 /* TBD label, NVE ID */
2151 optary
[opt_next
].type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
2154 optary
[opt_next
- 1].next
= optary
+ opt_next
;
2161 vnc_zlog_debug_verbose(
2162 "%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s",
2163 __func__
, arg_vn
, arg_un
, arg_prefix
,
2164 (arg_cost
? arg_cost
: "NULL"),
2165 (arg_lifetime
? arg_lifetime
: "NULL"),
2166 (arg_lnh
? arg_lnh
: "NULL"));
2168 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
2170 rpfx
.cost
= cost
& 255;
2172 /* look up rf descriptor, call open if it doesn't exist */
2173 rc
= rfapi_find_rfd(bgp
, &vn_address
, &un_address
,
2174 (struct rfapi_descriptor
**)&rfd
);
2177 struct rfapi_un_option uo
;
2180 * flag descriptor as provisionally opened for static
2182 * registration so that we can fix up the other
2184 * when the real open comes along
2186 memset(&uo
, 0, sizeof(uo
));
2187 uo
.type
= RFAPI_UN_OPTION_TYPE_PROVISIONAL
;
2189 rc
= rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp
),
2190 &vn_address
, &un_address
,
2192 NULL
, NULL
, /* no userdata */
2196 "Can't open session for this NVE: %s\n",
2197 rfapi_error_str(rc
));
2198 rc
= CMD_WARNING_CONFIG_FAILED
;
2202 vty_out(vty
, "Can't find session for this NVE: %s\n",
2203 rfapi_error_str(rc
));
2208 rc
= rfapi_register(rfd
, &rpfx
, lifetime
, NULL
, opt
,
2209 RFAPI_REGISTER_ADD
);
2211 struct rfapi_next_hop_entry
*head
= NULL
;
2212 struct rfapi_next_hop_entry
*tail
= NULL
;
2213 struct rfapi_vn_option
*vn_opt_new
;
2215 vnc_zlog_debug_verbose(
2216 "%s: rfapi_register succeeded, returning 0", __func__
);
2218 if (h
->rfp_methods
.local_cb
) {
2219 struct rfapi_descriptor
*r
=
2220 (struct rfapi_descriptor
*)rfd
;
2221 vn_opt_new
= rfapi_vn_options_dup(opt
);
2223 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
2225 vn_opt_new
, &head
, &tail
);
2227 h
->flags
|= RFAPI_INCALLBACK
;
2228 (*h
->rfp_methods
.local_cb
)(head
, r
->cookie
);
2229 h
->flags
&= ~RFAPI_INCALLBACK
;
2236 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
2238 vty_out(vty
, "Registration failed.\n");
2240 "Confirm that either the VN or UN address matches a configured NVE group.\n");
2241 return CMD_WARNING_CONFIG_FAILED
;
2244 vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__
, rc
);
2248 /************************************************************************
2249 * Add prefix With LNH_OPTIONS...
2250 ************************************************************************/
2251 DEFUN (add_vnc_prefix_cost_life_lnh
,
2252 add_vnc_prefix_cost_life_lnh_cmd
,
2253 "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...",
2254 "Add registration\n"
2256 "Add/modify prefix related information\n"
2259 "VN address of NVE\n"
2260 "VN IPv4 interface address\n"
2261 "VN IPv6 interface address\n"
2262 "UN address of NVE\n"
2263 "UN IPv4 interface address\n"
2264 "UN IPv6 interface address\n"
2265 "Administrative cost [default: 255]\n"
2266 "Administrative cost\n"
2267 "Registration lifetime [default: infinite]\n"
2268 "Lifetime value in seconds\n"
2269 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2271 /* pfx vn un cost life */
2272 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2274 NULL
, NULL
, argc
- 12, argv
+ 12);
2277 DEFUN (add_vnc_prefix_life_cost_lnh
,
2278 add_vnc_prefix_life_cost_lnh_cmd
,
2279 "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...",
2280 "Add registration\n"
2282 "Add/modify prefix related information\n"
2285 "VN address of NVE\n"
2286 "VN IPv4 interface address\n"
2287 "VN IPv6 interface address\n"
2288 "UN address of NVE\n"
2289 "UN IPv4 interface address\n"
2290 "UN IPv6 interface address\n"
2291 "Registration lifetime [default: infinite]\n"
2292 "Lifetime value in seconds\n"
2293 "Administrative cost [default: 255]\n"
2294 "Administrative cost\n"
2295 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2297 /* pfx vn un cost life */
2298 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2300 NULL
, NULL
, argc
- 12, argv
+ 12);
2303 DEFUN (add_vnc_prefix_cost_lnh
,
2304 add_vnc_prefix_cost_lnh_cmd
,
2305 "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...",
2306 "Add registration\n"
2308 "Add/modify prefix related information\n"
2311 "VN address of NVE\n"
2312 "VN IPv4 interface address\n"
2313 "VN IPv6 interface address\n"
2314 "UN address of NVE\n"
2315 "UN IPv4 interface address\n"
2316 "UN IPv6 interface address\n"
2317 "Administrative cost [default: 255]\n"
2318 "Administrative cost\n"
2319 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2321 /* pfx vn un cost life */
2322 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2324 NULL
, NULL
, argc
- 10, argv
+ 10);
2327 DEFUN (add_vnc_prefix_life_lnh
,
2328 add_vnc_prefix_life_lnh_cmd
,
2329 "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...",
2330 "Add registration\n"
2332 "Add/modify prefix related information\n"
2335 "VN address of NVE\n"
2336 "VN IPv4 interface address\n"
2337 "VN IPv6 interface address\n"
2338 "UN address of NVE\n"
2339 "UN IPv4 interface address\n"
2340 "UN IPv6 interface address\n"
2341 "Registration lifetime [default: infinite]\n"
2342 "Lifetime value in seconds\n"
2343 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2345 /* pfx vn un cost life */
2346 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2348 NULL
, NULL
, argc
- 10, argv
+ 10);
2351 DEFUN (add_vnc_prefix_lnh
,
2352 add_vnc_prefix_lnh_cmd
,
2353 "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...",
2354 "Add registration\n"
2356 "Add/modify prefix related information\n"
2359 "VN address of NVE\n"
2360 "VN IPv4 interface address\n"
2361 "VN IPv6 interface address\n"
2362 "UN address of NVE\n"
2363 "UN IPv4 interface address\n"
2364 "UN IPv6 interface address\n"
2365 "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")
2367 /* pfx vn un cost life */
2368 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2370 NULL
, NULL
, argc
- 8, argv
+ 8);
2373 /************************************************************************
2374 * Add prefix Without LNH_OPTIONS...
2375 ************************************************************************/
2376 DEFUN (add_vnc_prefix_cost_life
,
2377 add_vnc_prefix_cost_life_cmd
,
2378 "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)",
2379 "Add registration\n"
2381 "Add/modify prefix related information\n"
2384 "VN address of NVE\n"
2385 "VN IPv4 interface address\n"
2386 "VN IPv6 interface address\n"
2387 "UN address of NVE\n"
2388 "UN IPv4 interface address\n"
2389 "UN IPv6 interface address\n"
2390 "Administrative cost [default: 255]\n"
2391 "Administrative cost\n"
2392 "Registration lifetime [default: infinite]\n"
2393 "Lifetime value in seconds\n")
2395 /* pfx vn un cost life */
2396 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], argv
[11],
2398 NULL
, NULL
, 0, NULL
);
2401 DEFUN (add_vnc_prefix_life_cost
,
2402 add_vnc_prefix_life_cost_cmd
,
2403 "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)",
2404 "Add registration\n"
2406 "Add/modify prefix related information\n"
2409 "VN address of NVE\n"
2410 "VN IPv4 interface address\n"
2411 "VN IPv6 interface address\n"
2412 "UN address of NVE\n"
2413 "UN IPv4 interface address\n"
2414 "UN IPv6 interface address\n"
2415 "Registration lifetime [default: infinite]\n"
2416 "Lifetime value in seconds\n"
2417 "Administrative cost [default: 255]\n"
2418 "Administrative cost\n")
2420 /* pfx vn un cost life */
2421 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[11], argv
[9],
2423 NULL
, NULL
, 0, NULL
);
2426 DEFUN (add_vnc_prefix_cost
,
2427 add_vnc_prefix_cost_cmd
,
2428 "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)",
2429 "Add registration\n"
2431 "Add/modify prefix related information\n"
2434 "VN address of NVE\n"
2435 "VN IPv4 interface address\n"
2436 "VN IPv6 interface address\n"
2437 "UN address of NVE\n"
2438 "UN IPv4 interface address\n"
2439 "UN IPv6 interface address\n"
2440 "Administrative cost [default: 255]\n"
2441 "Administrative cost\n")
2443 /* pfx vn un cost life */
2444 return register_add(vty
, argv
[3], argv
[5], argv
[7], argv
[9], NULL
,
2446 NULL
, NULL
, 0, NULL
);
2449 DEFUN (add_vnc_prefix_life
,
2450 add_vnc_prefix_life_cmd
,
2451 "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)",
2452 "Add registration\n"
2454 "Add/modify prefix related information\n"
2457 "VN address of NVE\n"
2458 "VN IPv4 interface address\n"
2459 "VN IPv6 interface address\n"
2460 "UN address of NVE\n"
2461 "UN IPv4 interface address\n"
2462 "UN IPv6 interface address\n"
2463 "Registration lifetime [default: infinite]\n"
2464 "Lifetime value in seconds\n")
2466 /* pfx vn un cost life */
2467 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, argv
[9],
2469 NULL
, NULL
, 0, NULL
);
2472 DEFUN (add_vnc_prefix
,
2474 "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>",
2475 "Add registration\n"
2477 "Add/modify prefix related information\n"
2480 "VN address of NVE\n"
2481 "VN IPv4 interface address\n"
2482 "VN IPv6 interface address\n"
2483 "UN address of NVE\n"
2484 "UN IPv4 interface address\n"
2485 "UN IPv6 interface address\n")
2487 /* pfx vn un cost life */
2488 return register_add(vty
, argv
[3], argv
[5], argv
[7], NULL
, NULL
,
2490 NULL
, NULL
, 0, NULL
);
2493 /************************************************************************
2494 * Mac address registrations
2495 ************************************************************************/
2496 DEFUN (add_vnc_mac_vni_prefix_cost_life
,
2497 add_vnc_mac_vni_prefix_cost_life_cmd
,
2498 "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)",
2499 "Add registration\n"
2501 "Add/modify mac address information\n"
2503 "Virtual Network Identifier follows\n"
2504 "Virtual Network Identifier\n"
2505 "VN address of NVE\n"
2506 "VN IPv4 interface address\n"
2507 "VN IPv6 interface address\n"
2508 "UN address of NVE\n"
2509 "UN IPv4 interface address\n"
2510 "UN IPv6 interface address\n"
2511 "Add/modify prefix related information\n"
2514 "Administrative cost [default: 255]\n"
2515 "Administrative cost\n"
2516 "Registration lifetime [default: infinite]\n"
2517 "Lifetime value in seconds\n")
2519 /* pfx vn un cost life */
2520 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], argv
[15],
2522 argv
[3], argv
[5], 0, NULL
);
2526 DEFUN (add_vnc_mac_vni_prefix_life
,
2527 add_vnc_mac_vni_prefix_life_cmd
,
2528 "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)",
2529 "Add registration\n"
2531 "Add/modify mac address information\n"
2533 "Virtual Network Identifier follows\n"
2534 "Virtual Network Identifier\n"
2535 "VN address of NVE\n"
2536 "VN IPv4 interface address\n"
2537 "VN IPv6 interface address\n"
2538 "UN address of NVE\n"
2539 "UN IPv4 interface address\n"
2540 "UN IPv6 interface address\n"
2541 "Add/modify prefix related information\n"
2544 "Registration lifetime [default: infinite]\n"
2545 "Lifetime value in seconds\n")
2547 /* pfx vn un cost life */
2548 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, argv
[13],
2550 argv
[3], argv
[5], 0, NULL
);
2553 DEFUN (add_vnc_mac_vni_prefix_cost
,
2554 add_vnc_mac_vni_prefix_cost_cmd
,
2555 "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)",
2556 "Add registration\n"
2558 "Add/modify mac address information\n"
2560 "Virtual Network Identifier follows\n"
2561 "Virtual Network Identifier\n"
2562 "VN address of NVE\n"
2563 "VN IPv4 interface address\n"
2564 "VN IPv6 interface address\n"
2565 "UN address of NVE\n"
2566 "UN IPv4 interface address\n"
2567 "UN IPv6 interface address\n"
2568 "Add/modify prefix related information\n"
2571 "Administrative cost [default: 255]\n" "Administrative cost\n")
2573 /* pfx vn un cost life */
2574 return register_add(vty
, argv
[11], argv
[7], argv
[9], argv
[13], NULL
,
2576 argv
[3], argv
[5], 0, NULL
);
2579 DEFUN (add_vnc_mac_vni_prefix
,
2580 add_vnc_mac_vni_prefix_cmd
,
2581 "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>",
2582 "Add registration\n"
2584 "Add/modify mac address information\n"
2586 "Virtual Network Identifier follows\n"
2587 "Virtual Network Identifier\n"
2588 "VN address of NVE\n"
2589 "VN IPv4 interface address\n"
2590 "VN IPv6 interface address\n"
2591 "UN address of NVE\n"
2592 "UN IPv4 interface address\n"
2593 "UN IPv6 interface address\n"
2594 "Add/modify prefix related information\n"
2595 "IPv4 prefix\n" "IPv6 prefix\n")
2597 /* pfx vn un cost life */
2598 return register_add(vty
, argv
[11], argv
[7], argv
[9], NULL
, NULL
,
2600 argv
[3], argv
[5], 0, NULL
);
2603 DEFUN (add_vnc_mac_vni_cost_life
,
2604 add_vnc_mac_vni_cost_life_cmd
,
2605 "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)",
2606 "Add registration\n"
2608 "Add/modify mac address information\n"
2610 "Virtual Network Identifier follows\n"
2611 "Virtual Network Identifier\n"
2612 "VN address of NVE\n"
2613 "VN IPv4 interface address\n"
2614 "VN IPv6 interface address\n"
2615 "UN address of NVE\n"
2616 "UN IPv4 interface address\n"
2617 "UN IPv6 interface address\n"
2618 "Administrative cost [default: 255]\n"
2619 "Administrative cost\n"
2620 "Registration lifetime [default: infinite]\n"
2621 "Lifetime value in seconds\n")
2623 /* pfx vn un cost life */
2624 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], argv
[13],
2626 argv
[3], argv
[5], 0, NULL
);
2630 DEFUN (add_vnc_mac_vni_cost
,
2631 add_vnc_mac_vni_cost_cmd
,
2632 "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)",
2633 "Add registration\n"
2635 "Add/modify mac address information\n"
2637 "Virtual Network Identifier follows\n"
2638 "Virtual Network Identifier\n"
2639 "VN address of NVE\n"
2640 "VN IPv4 interface address\n"
2641 "VN IPv6 interface address\n"
2642 "UN address of NVE\n"
2643 "UN IPv4 interface address\n"
2644 "UN IPv6 interface address\n"
2645 "Administrative cost [default: 255]\n" "Administrative cost\n")
2647 /* pfx vn un cost life */
2648 return register_add(vty
, NULL
, argv
[7], argv
[9], argv
[11], NULL
,
2650 argv
[3], argv
[5], 0, NULL
);
2654 DEFUN (add_vnc_mac_vni_life
,
2655 add_vnc_mac_vni_life_cmd
,
2656 "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)",
2657 "Add registration\n"
2659 "Add/modify mac address information\n"
2661 "Virtual Network Identifier follows\n"
2662 "Virtual Network Identifier\n"
2663 "VN address of NVE\n"
2664 "VN IPv4 interface address\n"
2665 "VN IPv6 interface address\n"
2666 "UN address of NVE\n"
2667 "UN IPv4 interface address\n"
2668 "UN IPv6 interface address\n"
2669 "Registration lifetime [default: infinite]\n"
2670 "Lifetime value in seconds\n")
2672 /* pfx vn un cost life */
2673 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, argv
[11],
2675 argv
[3], argv
[5], 0, NULL
);
2679 DEFUN (add_vnc_mac_vni
,
2680 add_vnc_mac_vni_cmd
,
2681 "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>",
2682 "Add registration\n"
2684 "Add/modify mac address information\n"
2686 "Virtual Network Identifier follows\n"
2687 "Virtual Network Identifier\n"
2688 "VN address of NVE\n"
2689 "VN IPv4 interface address\n"
2690 "VN IPv6 interface address\n"
2691 "UN address of NVE\n"
2692 "UN IPv4 interface address\n" "UN IPv6 interface address\n")
2694 /* pfx vn un cost life */
2695 return register_add(vty
, NULL
, argv
[7], argv
[9], NULL
, NULL
,
2697 argv
[3], argv
[5], 0, NULL
);
2700 /************************************************************************
2702 ************************************************************************/
2704 struct rfapi_local_reg_delete_arg
{
2709 struct rfapi_ip_addr un_address
; /* AF==0: wildcard */
2710 struct rfapi_ip_addr vn_address
; /* AF==0: wildcard */
2711 struct prefix prefix
; /* AF==0: wildcard */
2712 struct prefix_rd rd
; /* plen!=64: wildcard */
2713 struct rfapi_nve_group_cfg
*rfg
; /* NULL: wildcard */
2715 struct rfapi_l2address_option_match l2o
;
2723 uint32_t query_count
;
2725 uint32_t failed_pfx_count
;
2728 struct skiplist
*nves
;
2730 uint32_t remote_active_nve_count
;
2731 uint32_t remote_active_pfx_count
;
2732 uint32_t remote_holddown_nve_count
;
2733 uint32_t remote_holddown_pfx_count
;
2737 struct rfapi_ip_addr vn
;
2738 struct rfapi_ip_addr un
;
2739 struct rfapi_descriptor
*rfd
;
2740 struct rfapi_local_reg_delete_arg
*cda
;
2743 static void nve_addr_free(void *hap
)
2745 ((struct nve_addr
*)hap
)->cda
->nve_count
+= 1;
2746 XFREE(MTYPE_RFAPI_NVE_ADDR
, hap
);
2749 static int nve_addr_cmp(void *k1
, void *k2
)
2751 struct nve_addr
*a
= (struct nve_addr
*)k1
;
2752 struct nve_addr
*b
= (struct nve_addr
*)k2
;
2758 if (a
->un
.addr_family
!= b
->un
.addr_family
) {
2759 return (a
->un
.addr_family
- b
->un
.addr_family
);
2761 if (a
->vn
.addr_family
!= b
->vn
.addr_family
) {
2762 return (a
->vn
.addr_family
- b
->vn
.addr_family
);
2764 if (a
->un
.addr_family
== AF_INET
) {
2765 ret
= IPV4_ADDR_CMP(&a
->un
.addr
.v4
, &b
->un
.addr
.v4
);
2769 } else if (a
->un
.addr_family
== AF_INET6
) {
2770 ret
= IPV6_ADDR_CMP(&a
->un
.addr
.v6
, &b
->un
.addr
.v6
);
2777 if (a
->vn
.addr_family
== AF_INET
) {
2778 ret
= IPV4_ADDR_CMP(&a
->vn
.addr
.v4
, &b
->vn
.addr
.v4
);
2781 } else if (a
->vn
.addr_family
== AF_INET6
) {
2782 ret
= IPV6_ADDR_CMP(&a
->vn
.addr
.v6
, &b
->vn
.addr
.v6
);
2792 static int parse_deleter_args(struct vty
*vty
, struct bgp
*bgp
,
2793 const char *arg_prefix
, const char *arg_vn
,
2794 const char *arg_un
, const char *arg_l2addr
,
2795 const char *arg_vni
, const char *arg_rd
,
2796 struct rfapi_nve_group_cfg
*arg_rfg
,
2797 struct rfapi_local_reg_delete_arg
*rcdarg
)
2799 int rc
= CMD_WARNING
;
2801 memset(rcdarg
, 0, sizeof(struct rfapi_local_reg_delete_arg
));
2805 bgp
= bgp_get_default();
2807 rcdarg
->rfg
= arg_rfg
; /* may be NULL */
2809 if (arg_vn
&& strcmp(arg_vn
, "*")) {
2810 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_vn
,
2811 &rcdarg
->vn_address
)))
2814 if (arg_un
&& strcmp(arg_un
, "*")) {
2815 if ((rc
= rfapiCliGetRfapiIpAddr(vty
, arg_un
,
2816 &rcdarg
->un_address
)))
2819 if (arg_prefix
&& strcmp(arg_prefix
, "*")) {
2821 if (!str2prefix(arg_prefix
, &rcdarg
->prefix
)) {
2822 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
2829 vty_out(vty
, "Missing VNI\n");
2832 if (strcmp(arg_l2addr
, "*")) {
2833 if ((rc
= rfapiStr2EthAddr(arg_l2addr
,
2834 &rcdarg
->l2o
.o
.macaddr
))) {
2835 vty_out(vty
, "Malformed L2 Address \"%s\"\n",
2839 rcdarg
->l2o
.flags
|= RFAPI_L2O_MACADDR
;
2841 if (strcmp(arg_vni
, "*")) {
2842 rcdarg
->l2o
.o
.logical_net_id
=
2843 strtoul(arg_vni
, NULL
, 10);
2844 rcdarg
->l2o
.flags
|= RFAPI_L2O_LNI
;
2848 if (!str2prefix_rd(arg_rd
, &rcdarg
->rd
)) {
2849 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
2858 parse_deleter_tokens(struct vty
*vty
, struct bgp
*bgp
,
2859 struct cmd_token
*carg_prefix
, struct cmd_token
*carg_vn
,
2860 struct cmd_token
*carg_un
, struct cmd_token
*carg_l2addr
,
2861 struct cmd_token
*carg_vni
, struct cmd_token
*carg_rd
,
2862 struct rfapi_nve_group_cfg
*arg_rfg
,
2863 struct rfapi_local_reg_delete_arg
*rcdarg
)
2865 const char *arg_prefix
= carg_prefix
? carg_prefix
->arg
: NULL
;
2866 const char *arg_vn
= carg_vn
? carg_vn
->arg
: NULL
;
2867 const char *arg_un
= carg_un
? carg_un
->arg
: NULL
;
2868 const char *arg_l2addr
= carg_l2addr
? carg_l2addr
->arg
: NULL
;
2869 const char *arg_vni
= carg_vni
? carg_vni
->arg
: NULL
;
2870 const char *arg_rd
= carg_rd
? carg_rd
->arg
: NULL
;
2871 return parse_deleter_args(vty
, bgp
, arg_prefix
, arg_vn
, arg_un
,
2872 arg_l2addr
, arg_vni
, arg_rd
, arg_rfg
, rcdarg
);
2875 static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg
*cda
,
2876 struct rfapi_ip_addr
*un_address
,
2877 struct rfapi_ip_addr
*vn_address
,
2878 struct rfapi_descriptor
*rfd
)
2881 struct nve_addr
*hap
;
2883 memset(&ha
, 0, sizeof(ha
));
2884 ha
.un
= *un_address
;
2885 ha
.vn
= *vn_address
;
2889 cda
->nves
= skiplist_new(0, nve_addr_cmp
, nve_addr_free
);
2891 if (skiplist_search(cda
->nves
, &ha
, (void *)&hap
)) {
2892 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
, sizeof(struct nve_addr
));
2896 skiplist_insert(cda
->nves
, hap
, hap
);
2900 static void clear_vnc_responses(struct rfapi_local_reg_delete_arg
*cda
)
2903 struct rfapi_descriptor
*rfd
;
2904 int query_count
= 0;
2905 struct listnode
*node
;
2906 struct bgp
*bgp_default
= bgp_get_default();
2908 if (cda
->vn_address
.addr_family
&& cda
->un_address
.addr_family
) {
2912 if (rfapi_find_rfd(bgp_default
, &cda
->vn_address
,
2913 &cda
->un_address
, &rfd
))
2917 rfapi_query_done_all(rfd
, &query_count
);
2918 cda
->query_count
+= query_count
;
2921 * Track unique nves seen
2923 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2934 h
= bgp_default
->rfapi
;
2939 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
2941 * match un, vn addresses of NVEs
2943 if (cda
->un_address
.addr_family
2944 && rfapi_ip_addr_cmp(&cda
->un_address
, &rfd
->un_addr
)) {
2947 if (cda
->vn_address
.addr_family
2948 && rfapi_ip_addr_cmp(&cda
->vn_address
, &rfd
->vn_addr
)) {
2954 rfapi_query_done_all(rfd
, &query_count
);
2955 cda
->query_count
+= query_count
;
2958 * Track unique nves seen
2960 record_nve_in_cda_list(cda
, &rfd
->un_addr
, &rfd
->vn_addr
, rfd
);
2965 * TBD need to count deleted prefixes and nves?
2967 * ENXIO BGP or VNC not configured
2969 static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg
*cda
,
2970 struct rfapi_descriptor
*rfd
)
2972 struct rfapi_ip_addr
*pUn
; /* NULL = wildcard */
2973 struct rfapi_ip_addr
*pVn
; /* NULL = wildcard */
2974 struct prefix
*pPrefix
; /* NULL = wildcard */
2975 struct prefix_rd
*pPrd
; /* NULL = wildcard */
2977 struct rfapi_ip_prefix rprefix
;
2978 struct rfapi_next_hop_entry
*head
= NULL
;
2979 struct rfapi_next_hop_entry
*tail
= NULL
;
2982 vnc_zlog_debug_verbose("%s: entry", __func__
);
2985 pUn
= (cda
->un_address
.addr_family
? &cda
->un_address
: NULL
);
2986 pVn
= (cda
->vn_address
.addr_family
? &cda
->vn_address
: NULL
);
2987 pPrefix
= (cda
->prefix
.family
? &cda
->prefix
: NULL
);
2988 pPrd
= (cda
->rd
.prefixlen
== 64 ? &cda
->rd
: NULL
);
2991 rfapiQprefix2Rprefix(pPrefix
, &rprefix
);
2994 do /* to preserve old code structure */
2996 struct rfapi
*h
= cda
->bgp
->rfapi
;
2998 struct rfapi_adb
*adb
;
3000 int deleted_from_this_nve
;
3002 struct nve_addr
*hap
;
3005 vnc_zlog_debug_verbose("%s: rfd=%p", __func__
, rfd
);
3009 * match un, vn addresses of NVEs
3011 if (pUn
&& (rfapi_ip_addr_cmp(pUn
, &rfd
->un_addr
)))
3013 if (pVn
&& (rfapi_ip_addr_cmp(pVn
, &rfd
->vn_addr
)))
3017 vnc_zlog_debug_verbose("%s: un, vn match", __func__
);
3024 deleted_from_this_nve
= 0;
3027 struct skiplist
*sl
;
3028 struct rfapi_ip_prefix rp
;
3030 struct list
*adb_delete_list
;
3033 * The advertisements are stored in a skiplist.
3035 * the registration deletes the advertisement from the
3036 * skiplist, which we can't do while iterating over that
3037 * same skiplist using the current skiplist API.
3039 * Strategy: iterate over the skiplist and build another
3040 * list containing only the matching ADBs. Then delete
3041 * _everything_ in that second list (which can be done
3042 * using either skiplists or quagga linklists).
3044 adb_delete_list
= list_new();
3047 * Advertised IP prefixes (not 0/32 or 0/128)
3049 sl
= rfd
->advertised
.ipN_by_prefix
;
3052 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3054 !rc
; rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3058 if (!prefix_same(pPrefix
,
3059 &adb
->u
.s
.prefix_ip
)) {
3061 vnc_zlog_debug_verbose(
3062 "%s: adb=%p, prefix doesn't match, skipping",
3069 if (memcmp(pPrd
->val
, adb
->u
.s
.prd
.val
,
3073 vnc_zlog_debug_verbose(
3074 "%s: adb=%p, RD doesn't match, skipping",
3080 if (CHECK_FLAG(cda
->l2o
.flags
,
3081 RFAPI_L2O_MACADDR
)) {
3082 if (memcmp(cda
->l2o
.o
.macaddr
.octet
,
3083 adb
->u
.s
.prefix_eth
.u
3087 vnc_zlog_debug_verbose(
3088 "%s: adb=%p, macaddr doesn't match, skipping",
3095 if (CHECK_FLAG(cda
->l2o
.flags
, RFAPI_L2O_LNI
)) {
3096 if (cda
->l2o
.o
.logical_net_id
3097 != adb
->l2o
.logical_net_id
) {
3099 vnc_zlog_debug_verbose(
3100 "%s: adb=%p, LNI doesn't match, skipping",
3108 vnc_zlog_debug_verbose(
3109 "%s: ipN adding adb %p to delete list",
3113 listnode_add(adb_delete_list
, adb
);
3116 struct listnode
*node
;
3118 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
, adb
)) {
3119 int this_advertisement_prefix_count
;
3120 struct rfapi_vn_option optary
[3];
3121 struct rfapi_vn_option
*opt
= NULL
;
3124 this_advertisement_prefix_count
= 1;
3126 rfapiQprefix2Rprefix(&adb
->u
.s
.prefix_ip
, &rp
);
3128 memset(optary
, 0, sizeof(optary
));
3130 /* if mac addr present in advert, make l2o vn
3132 if (adb
->u
.s
.prefix_eth
.family
== AF_ETHERNET
) {
3134 opt
->next
= &optary
[cur_opt
];
3135 opt
= &optary
[cur_opt
++];
3136 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3137 opt
->v
.l2addr
.macaddr
=
3138 adb
->u
.s
.prefix_eth
.u
3140 ++this_advertisement_prefix_count
;
3143 * use saved RD value instead of trying to
3145 * complex RD computation in rfapi_register()
3148 opt
->next
= &optary
[cur_opt
];
3149 opt
= &optary
[cur_opt
++];
3150 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
3151 opt
->v
.internal_rd
= adb
->u
.s
.prd
;
3154 vnc_zlog_debug_verbose(
3155 "%s: ipN killing reg from adb %p ",
3159 rc
= rfapi_register(rfd
, &rp
, 0, NULL
,
3160 (cur_opt
? optary
: NULL
),
3161 RFAPI_REGISTER_KILL
);
3164 this_advertisement_prefix_count
;
3165 cda
->reg_count
+= 1;
3166 deleted_from_this_nve
= 1;
3168 if (h
->rfp_methods
.local_cb
) {
3169 rfapiAddDeleteLocalRfpPrefix(
3170 &rfd
->un_addr
, &rfd
->vn_addr
,
3171 &rp
, 0, 0, NULL
, &head
, &tail
);
3174 list_delete_all_node(adb_delete_list
);
3176 if (!(pPrefix
&& !RFAPI_0_PREFIX(pPrefix
))) {
3178 * Caller didn't specify a prefix, or specified
3183 * Advertised 0/32 and 0/128 (indexed by
3186 sl
= rfd
->advertised
.ip0_by_ether
;
3189 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3192 rc
= skiplist_next(sl
, NULL
, (void **)&adb
,
3195 if (CHECK_FLAG(cda
->l2o
.flags
,
3196 RFAPI_L2O_MACADDR
)) {
3197 if (memcmp(cda
->l2o
.o
.macaddr
3199 adb
->u
.s
.prefix_eth
.u
3207 if (CHECK_FLAG(cda
->l2o
.flags
,
3209 if (cda
->l2o
.o
.logical_net_id
3210 != adb
->l2o
.logical_net_id
) {
3215 vnc_zlog_debug_verbose(
3216 "%s: ip0 adding adb %p to delete list",
3219 listnode_add(adb_delete_list
, adb
);
3223 for (ALL_LIST_ELEMENTS_RO(adb_delete_list
, node
,
3226 struct rfapi_vn_option vn
;
3228 rfapiQprefix2Rprefix(
3229 &adb
->u
.s
.prefix_ip
, &rp
);
3231 memset(&vn
, 0, sizeof(vn
));
3232 vn
.type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
3233 vn
.v
.l2addr
= adb
->l2o
;
3236 vnc_zlog_debug_verbose(
3237 "%s: ip0 killing reg from adb %p ",
3241 rc
= rfapi_register(
3242 rfd
, &rp
, 0, NULL
, &vn
,
3243 RFAPI_REGISTER_KILL
);
3245 cda
->pfx_count
+= 1;
3246 cda
->reg_count
+= 1;
3247 deleted_from_this_nve
= 1;
3249 if (h
->rfp_methods
.local_cb
) {
3250 struct rfapi_vn_option
3254 rfapi_vn_options_dup(
3256 rfapiAddDeleteLocalRfpPrefix(
3258 &rfd
->vn_addr
, &rp
, 0,
3259 0, vn_opt_new
, &head
,
3263 list_delete_all_node(adb_delete_list
);
3265 list_delete(&adb_delete_list
);
3269 if (head
) { /* should not be set if (NULL ==
3270 rfapi_cfg->local_cb) */
3271 h
->flags
|= RFAPI_INCALLBACK
;
3272 (*h
->rfp_methods
.local_cb
)(head
, rfd
->cookie
);
3273 h
->flags
&= ~RFAPI_INCALLBACK
;
3277 if (deleted_from_this_nve
) {
3279 * track unique NVEs seen
3281 memset(&ha
, 0, sizeof(ha
));
3282 ha
.un
= rfd
->un_addr
;
3283 ha
.vn
= rfd
->vn_addr
;
3286 cda
->nves
= skiplist_new(0, nve_addr_cmp
,
3288 if (skiplist_search(cda
->nves
, &ha
, (void **)&hap
)) {
3289 hap
= XCALLOC(MTYPE_RFAPI_NVE_ADDR
,
3290 sizeof(struct nve_addr
));
3294 skiplist_insert(cda
->nves
, hap
, hap
);
3297 } while (0); /* to preserve old code structure */
3302 static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg
*cda
)
3307 if (cda
->rfg
->rfd
) /* if not open, nothing to delete */
3308 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, cda
->rfg
->rfd
);
3310 struct bgp
*bgp
= cda
->bgp
;
3312 struct rfapi_cfg
*rfapi_cfg
;
3314 struct listnode
*node
;
3315 struct rfapi_descriptor
*rfd
;
3319 rfapi_cfg
= bgp
->rfapi_cfg
;
3320 if (!h
|| !rfapi_cfg
)
3322 vnc_zlog_debug_verbose("%s: starting descriptor loop",
3324 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
3325 rc
= rfapiDeleteLocalPrefixesByRFD(cda
, rfd
);
3334 * Deletes local and remote prefixes that match
3336 static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg
*cda
)
3338 struct prefix pfx_un
;
3339 struct prefix pfx_vn
;
3341 struct prefix
*pUN
= NULL
;
3342 struct prefix
*pVN
= NULL
;
3343 struct prefix
*pPrefix
= NULL
;
3345 struct rfapi_import_table
*it
= NULL
;
3348 * Delete matching remote prefixes in holddown
3350 if (cda
->vn_address
.addr_family
) {
3351 if (!rfapiRaddr2Qprefix(&cda
->vn_address
, &pfx_vn
))
3354 if (cda
->un_address
.addr_family
) {
3355 if (!rfapiRaddr2Qprefix(&cda
->un_address
, &pfx_un
))
3358 if (cda
->prefix
.family
) {
3359 pPrefix
= &cda
->prefix
;
3362 it
= cda
->rfg
->rfapi_import_table
;
3364 rfapiDeleteRemotePrefixes(
3365 pUN
, pVN
, pPrefix
, it
, 0, 1, &cda
->remote_active_pfx_count
,
3366 &cda
->remote_active_nve_count
, &cda
->remote_holddown_pfx_count
,
3367 &cda
->remote_holddown_nve_count
);
3370 * Now do local prefixes
3372 rfapiDeleteLocalPrefixes(cda
);
3375 static void print_cleared_stats(struct rfapi_local_reg_delete_arg
*cda
)
3377 struct vty
*vty
= cda
->vty
; /* for benefit of VTYNL */
3379 /* Our special element-deleting function counts nves */
3381 skiplist_free(cda
->nves
);
3384 if (cda
->failed_pfx_count
)
3385 vty_out(vty
, "Failed to delete %d prefixes\n",
3386 cda
->failed_pfx_count
);
3388 /* left as "prefixes" even in single case for ease of machine parsing */
3390 "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n",
3391 cda
->reg_count
, cda
->pfx_count
, cda
->query_count
,
3395 * We don't currently allow deletion of active remote prefixes from
3399 vty_out(vty
, "[Holddown] Cleared %u prefixes from %u NVEs\n",
3400 cda
->remote_holddown_pfx_count
, cda
->remote_holddown_nve_count
);
3404 * Caller has already deleted registrations and queries for this/these
3405 * NVEs. Now we just have to close their descriptors.
3407 static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg
*cda
)
3409 struct skiplist
*sl
= cda
->nves
; /* contains affected NVEs */
3410 struct nve_addr
*pKey
;
3411 struct nve_addr
*pValue
;
3412 void *cursor
= NULL
;
3418 for (rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
, &cursor
);
3419 !rc
; rc
= skiplist_next(sl
, (void **)&pKey
, (void **)&pValue
,
3423 ((struct rfapi_descriptor
*)pValue
->rfd
)->flags
|=
3424 RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY
;
3425 rfapi_close(pValue
->rfd
);
3430 DEFUN (clear_vnc_nve_all
,
3431 clear_vnc_nve_all_cmd
,
3435 "Clear per NVE information\n"
3439 struct rfapi_local_reg_delete_arg cda
;
3442 if ((rc
= parse_deleter_args(vty
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
3448 clear_vnc_responses(&cda
);
3449 clear_vnc_prefix(&cda
);
3450 clear_vnc_nve_closer(&cda
);
3452 print_cleared_stats(&cda
);
3457 DEFUN (clear_vnc_nve_vn_un
,
3458 clear_vnc_nve_vn_un_cmd
,
3459 "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>",
3462 "Clear prefix registration information\n"
3463 "VN address of NVE\n"
3465 "VN IPv4 interface address\n"
3466 "VN IPv6 interface address\n"
3467 "UN address of NVE\n"
3468 "For all UN addresses\n"
3469 "UN IPv4 interface address\n"
3470 "UN IPv6 interface address\n")
3472 struct rfapi_local_reg_delete_arg cda
;
3475 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], argv
[6], NULL
,
3476 NULL
, NULL
, NULL
, &cda
)))
3481 clear_vnc_responses(&cda
);
3482 clear_vnc_prefix(&cda
);
3483 clear_vnc_nve_closer(&cda
);
3485 print_cleared_stats(&cda
);
3490 DEFUN (clear_vnc_nve_un_vn
,
3491 clear_vnc_nve_un_vn_cmd
,
3492 "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>",
3495 "Clear prefix registration information\n"
3496 "UN address of NVE\n"
3498 "UN IPv4 interface address\n"
3499 "UN IPv6 interface address\n"
3500 "VN address of NVE\n"
3502 "VN IPv4 interface address\n"
3503 "VN IPv6 interface address\n")
3505 struct rfapi_local_reg_delete_arg cda
;
3508 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[6], argv
[4], NULL
,
3509 NULL
, NULL
, NULL
, &cda
)))
3514 clear_vnc_responses(&cda
);
3515 clear_vnc_prefix(&cda
);
3516 clear_vnc_nve_closer(&cda
);
3518 print_cleared_stats(&cda
);
3523 DEFUN (clear_vnc_nve_vn
,
3524 clear_vnc_nve_vn_cmd
,
3525 "clear vnc nve vn <*|A.B.C.D|X:X::X:X>",
3528 "Clear prefix registration information\n"
3529 "VN address of NVE\n"
3531 "VN IPv4 interface address\n"
3532 "VN IPv6 interface address\n")
3534 struct rfapi_local_reg_delete_arg cda
;
3537 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[4], NULL
, NULL
,
3538 NULL
, NULL
, NULL
, &cda
)))
3543 clear_vnc_responses(&cda
);
3544 clear_vnc_prefix(&cda
);
3545 clear_vnc_nve_closer(&cda
);
3547 print_cleared_stats(&cda
);
3551 DEFUN (clear_vnc_nve_un
,
3552 clear_vnc_nve_un_cmd
,
3553 "clear vnc nve un <*|A.B.C.D|X:X::X:X>",
3556 "Clear prefix registration information\n"
3557 "UN address of NVE\n"
3559 "UN IPv4 interface address\n"
3560 "UN IPv6 interface address\n")
3562 struct rfapi_local_reg_delete_arg cda
;
3565 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[4], NULL
,
3566 NULL
, NULL
, NULL
, &cda
)))
3571 clear_vnc_responses(&cda
);
3572 clear_vnc_prefix(&cda
);
3573 clear_vnc_nve_closer(&cda
);
3575 print_cleared_stats(&cda
);
3579 /*-------------------------------------------------
3581 *-------------------------------------------------*/
3584 * This function is defined in this file (rather than in rfp_registration.c)
3585 * because here we have access to all the task handles.
3587 DEFUN (clear_vnc_prefix_vn_un
,
3588 clear_vnc_prefix_vn_un_cmd
,
3589 "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>",
3592 "Clear prefix registration information\n"
3596 "VN address of NVE\n"
3597 "All VN addresses\n"
3598 "VN IPv4 interface address\n"
3599 "VN IPv6 interface address\n"
3600 "UN address of NVE\n"
3601 "All UN addresses\n"
3602 "UN IPv4 interface address\n"
3603 "UN IPv6 interface address\n")
3605 struct rfapi_local_reg_delete_arg cda
;
3608 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], argv
[7],
3609 NULL
, NULL
, NULL
, NULL
, &cda
)))
3612 clear_vnc_prefix(&cda
);
3613 print_cleared_stats(&cda
);
3617 DEFUN (clear_vnc_prefix_un_vn
,
3618 clear_vnc_prefix_un_vn_cmd
,
3619 "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>",
3622 "Clear prefix registration information\n"
3626 "UN address of NVE\n"
3627 "All UN addresses\n"
3628 "UN IPv4 interface address\n"
3629 "UN IPv6 interface address\n"
3630 "VN address of NVE\n"
3631 "All VN addresses\n"
3632 "VN IPv4 interface address\n"
3633 "VN IPv6 interface address\n")
3635 struct rfapi_local_reg_delete_arg cda
;
3638 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[7], argv
[5],
3639 NULL
, NULL
, NULL
, NULL
, &cda
)))
3642 clear_vnc_prefix(&cda
);
3643 print_cleared_stats(&cda
);
3647 DEFUN (clear_vnc_prefix_un
,
3648 clear_vnc_prefix_un_cmd
,
3649 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>",
3652 "Clear prefix registration information\n"
3656 "UN address of NVE\n"
3657 "All UN addresses\n"
3658 "UN IPv4 interface address\n"
3659 "UN IPv6 interface address\n")
3661 struct rfapi_local_reg_delete_arg cda
;
3664 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, argv
[5], NULL
,
3665 NULL
, NULL
, NULL
, &cda
)))
3668 clear_vnc_prefix(&cda
);
3669 print_cleared_stats(&cda
);
3673 DEFUN (clear_vnc_prefix_vn
,
3674 clear_vnc_prefix_vn_cmd
,
3675 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>",
3678 "Clear prefix registration information\n"
3682 "UN address of NVE\n"
3683 "All VN addresses\n"
3684 "VN IPv4 interface address\n"
3685 "VN IPv6 interface address\n")
3687 struct rfapi_local_reg_delete_arg cda
;
3690 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], argv
[5], NULL
, NULL
,
3691 NULL
, NULL
, NULL
, &cda
)))
3694 clear_vnc_prefix(&cda
);
3695 print_cleared_stats(&cda
);
3699 DEFUN (clear_vnc_prefix_all
,
3700 clear_vnc_prefix_all_cmd
,
3701 "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *",
3704 "Clear prefix registration information\n"
3710 struct rfapi_local_reg_delete_arg cda
;
3713 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[3], NULL
, NULL
, NULL
,
3714 NULL
, NULL
, NULL
, &cda
)))
3717 clear_vnc_prefix(&cda
);
3718 print_cleared_stats(&cda
);
3722 /*-------------------------------------------------
3724 *-------------------------------------------------*/
3727 * This function is defined in this file (rather than in rfp_registration.c)
3728 * because here we have access to all the task handles.
3730 DEFUN (clear_vnc_mac_vn_un
,
3731 clear_vnc_mac_vn_un_cmd
,
3732 "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>",
3735 "Clear mac registration information\n"
3739 "Any virtual network identifier\n"
3740 "Virtual network identifier\n"
3741 "VN address of NVE\n"
3742 "All VN addresses\n"
3743 "VN IPv4 interface address\n"
3744 "VN IPv6 interface address\n"
3745 "UN address of NVE\n"
3746 "All UN addresses\n"
3747 "UN IPv4 interface address\n"
3748 "UN IPv6 interface address\n")
3750 struct rfapi_local_reg_delete_arg cda
;
3753 /* pfx vn un L2 VNI */
3754 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], argv
[9],
3755 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3758 clear_vnc_prefix(&cda
);
3759 print_cleared_stats(&cda
);
3763 DEFUN (clear_vnc_mac_un_vn
,
3764 clear_vnc_mac_un_vn_cmd
,
3765 "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>",
3768 "Clear mac registration information\n"
3772 "Any virtual network identifier\n"
3773 "Virtual network identifier\n"
3774 "UN address of NVE\n"
3775 "All UN addresses\n"
3776 "UN IPv4 interface address\n"
3777 "UN IPv6 interface address\n"
3778 "VN address of NVE\n"
3779 "All VN addresses\n"
3780 "VN IPv4 interface address\n"
3781 "VN IPv6 interface address\n")
3783 struct rfapi_local_reg_delete_arg cda
;
3786 /* pfx vn un L2 VNI */
3787 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[9], argv
[7],
3788 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3791 clear_vnc_prefix(&cda
);
3792 print_cleared_stats(&cda
);
3796 DEFUN (clear_vnc_mac_un
,
3797 clear_vnc_mac_un_cmd
,
3798 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>",
3801 "Clear mac registration information\n"
3805 "Any virtual network identifier\n"
3806 "Virtual network identifier\n"
3807 "UN address of NVE\n"
3808 "All UN addresses\n"
3809 "UN IPv4 interface address\n"
3810 "UN IPv6 interface address\n")
3812 struct rfapi_local_reg_delete_arg cda
;
3815 /* pfx vn un L2 VNI */
3816 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, argv
[7], argv
[3],
3817 argv
[5], NULL
, NULL
, &cda
)))
3820 clear_vnc_prefix(&cda
);
3821 print_cleared_stats(&cda
);
3825 DEFUN (clear_vnc_mac_vn
,
3826 clear_vnc_mac_vn_cmd
,
3827 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>",
3830 "Clear mac registration information\n"
3834 "Any virtual network identifier\n"
3835 "Virtual network identifier\n"
3836 "UN address of NVE\n"
3837 "All VN addresses\n"
3838 "VN IPv4 interface address\n"
3839 "VN IPv6 interface address\n")
3841 struct rfapi_local_reg_delete_arg cda
;
3844 /* pfx vn un L2 VNI */
3845 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, argv
[7], NULL
, argv
[3],
3846 argv
[5], NULL
, NULL
, &cda
)))
3849 clear_vnc_prefix(&cda
);
3850 print_cleared_stats(&cda
);
3854 DEFUN (clear_vnc_mac_all
,
3855 clear_vnc_mac_all_cmd
,
3856 "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *",
3859 "Clear mac registration information\n"
3863 "Any virtual network identifier\n"
3864 "Virtual network identifier\n"
3867 struct rfapi_local_reg_delete_arg cda
;
3870 /* pfx vn un L2 VNI */
3871 if ((rc
= parse_deleter_tokens(vty
, NULL
, NULL
, NULL
, NULL
, argv
[3],
3872 argv
[5], NULL
, NULL
, &cda
)))
3875 clear_vnc_prefix(&cda
);
3876 print_cleared_stats(&cda
);
3880 /*-------------------------------------------------
3881 * Clear VNC MAC PREFIX
3882 *-------------------------------------------------*/
3884 DEFUN (clear_vnc_mac_vn_un_prefix
,
3885 clear_vnc_mac_vn_un_prefix_cmd
,
3886 "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>",
3889 "Clear mac registration information\n"
3893 "Any virtual network identifier\n"
3894 "Virtual network identifier\n"
3895 "VN address of NVE\n"
3896 "All VN addresses\n"
3897 "VN IPv4 interface address\n"
3898 "VN IPv6 interface address\n"
3899 "UN address of NVE\n"
3900 "All UN addresses\n"
3901 "UN IPv4 interface address\n"
3902 "UN IPv6 interface address\n"
3903 "Clear prefix registration information\n"
3908 struct rfapi_local_reg_delete_arg cda
;
3911 /* pfx vn un L2 VNI */
3912 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[7], argv
[9],
3913 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3916 clear_vnc_prefix(&cda
);
3917 print_cleared_stats(&cda
);
3921 DEFUN (clear_vnc_mac_un_vn_prefix
,
3922 clear_vnc_mac_un_vn_prefix_cmd
,
3923 "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>",
3926 "Clear mac registration information\n"
3930 "Any virtual network identifier\n"
3931 "Virtual network identifier\n"
3932 "UN address of NVE\n"
3933 "All UN addresses\n"
3934 "UN IPv4 interface address\n"
3935 "UN IPv6 interface address\n"
3936 "VN address of NVE\n"
3937 "All VN addresses\n"
3938 "VN IPv4 interface address\n"
3939 "VN IPv6 interface address\n"
3940 "Clear prefix registration information\n"
3944 "Clear prefix registration information\n"
3949 struct rfapi_local_reg_delete_arg cda
;
3952 /* pfx vn un L2 VNI */
3953 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[11], argv
[9], argv
[7],
3954 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3957 clear_vnc_prefix(&cda
);
3958 print_cleared_stats(&cda
);
3962 DEFUN (clear_vnc_mac_un_prefix
,
3963 clear_vnc_mac_un_prefix_cmd
,
3964 "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>",
3967 "Clear mac registration information\n"
3971 "Any virtual network identifier\n"
3972 "Virtual network identifier\n"
3973 "UN address of NVE\n"
3974 "All UN addresses\n"
3975 "UN IPv4 interface address\n"
3976 "UN IPv6 interface address\n"
3977 "Clear prefix registration information\n"
3982 struct rfapi_local_reg_delete_arg cda
;
3985 /* pfx vn un L2 VNI */
3986 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], NULL
, argv
[7],
3987 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
3990 clear_vnc_prefix(&cda
);
3991 print_cleared_stats(&cda
);
3995 DEFUN (clear_vnc_mac_vn_prefix
,
3996 clear_vnc_mac_vn_prefix_cmd
,
3997 "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>",
4000 "Clear mac registration information\n"
4004 "Any virtual network identifier\n"
4005 "Virtual network identifier\n"
4006 "UN address of NVE\n"
4007 "All VN addresses\n"
4008 "VN IPv4 interface address\n"
4009 "VN IPv6 interface address\n"
4010 "Clear prefix registration information\n"
4015 struct rfapi_local_reg_delete_arg cda
;
4018 /* pfx vn un L2 VNI */
4019 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[9], argv
[7], NULL
,
4020 argv
[3], argv
[5], NULL
, NULL
, &cda
)))
4023 clear_vnc_prefix(&cda
);
4024 print_cleared_stats(&cda
);
4028 DEFUN (clear_vnc_mac_all_prefix
,
4029 clear_vnc_mac_all_prefix_cmd
,
4030 "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>",
4033 "Clear mac registration information\n"
4037 "Any virtual network identifier\n"
4038 "Virtual network identifier\n"
4039 "UN address of NVE\n"
4040 "All VN addresses\n"
4041 "VN IPv4 interface address\n"
4042 "VN IPv6 interface address\n")
4044 struct rfapi_local_reg_delete_arg cda
;
4047 /* pfx vn un L2 VNI */
4048 if ((rc
= parse_deleter_tokens(vty
, NULL
, argv
[7], NULL
, NULL
, argv
[3],
4049 argv
[5], NULL
, NULL
, &cda
)))
4052 clear_vnc_prefix(&cda
);
4053 print_cleared_stats(&cda
);
4057 /************************************************************************
4059 ************************************************************************/
4062 /* copied from rfp_vty.c */
4063 static int check_and_display_is_vnc_running(struct vty
*vty
)
4065 if (bgp_rfapi_is_vnc_configured(NULL
) == 0)
4066 return 1; /* is running */
4069 vty_out(vty
, "VNC is not configured.\n");
4071 return 0; /* not running */
4074 static int rfapi_vty_show_nve_summary(struct vty
*vty
,
4075 show_nve_summary_t show_type
)
4077 struct bgp
*bgp_default
= bgp_get_default();
4079 int is_vnc_running
= (bgp_rfapi_is_vnc_configured(bgp_default
) == 0);
4081 int active_local_routes
;
4082 int active_remote_routes
;
4083 int holddown_remote_routes
;
4084 int imported_remote_routes
;
4089 h
= bgp_default
->rfapi
;
4094 /* don't show local info if not running RFP */
4095 if (is_vnc_running
|| show_type
== SHOW_NVE_SUMMARY_REGISTERED
) {
4097 switch (show_type
) {
4099 case SHOW_NVE_SUMMARY_ACTIVE_NVES
:
4100 vty_out(vty
, "%-24s ", "NVEs:");
4101 vty_out(vty
, "%-8s %-8u ",
4102 "Active:", h
->descriptors
.count
);
4103 vty_out(vty
, "%-8s %-8u ",
4104 "Maximum:", h
->stat
.max_descriptors
);
4105 vty_out(vty
, "%-8s %-8u",
4106 "Unknown:", h
->stat
.count_unknown_nves
);
4109 case SHOW_NVE_SUMMARY_REGISTERED
:
4111 * NB: With the introduction of L2 route support, we no
4112 * longer have a one-to-one correspondence between
4113 * locally-originated route advertisements and routes in
4114 * the import tables that have local origin. This
4115 * discrepancy arises because a single advertisement
4116 * may contain both an IP prefix and a MAC address.
4117 * Such an advertisement results in two import table
4118 * entries: one indexed by IP prefix, the other indexed
4121 * TBD: update computation and display of registration
4122 * statistics to reflect the underlying semantics.
4124 if (is_vnc_running
) {
4125 vty_out(vty
, "%-24s ", "Registrations:");
4126 vty_out(vty
, "%-8s %-8u ", "Active:",
4127 rfapiApCountAll(bgp_default
));
4128 vty_out(vty
, "%-8s %-8u ", "Failed:",
4129 h
->stat
.count_registrations_failed
);
4130 vty_out(vty
, "%-8s %-8u",
4131 "Total:", h
->stat
.count_registrations
);
4134 vty_out(vty
, "%-24s ", "Prefixes registered:");
4137 rfapiCountAllItRoutes(&active_local_routes
,
4138 &active_remote_routes
,
4139 &holddown_remote_routes
,
4140 &imported_remote_routes
);
4143 if (is_vnc_running
) {
4144 vty_out(vty
, " %-20s ", "Locally:");
4145 vty_out(vty
, "%-8s %-8u ",
4146 "Active:", active_local_routes
);
4151 vty_out(vty
, " %-20s ", "Remotely:");
4152 vty_out(vty
, "%-8s %-8u",
4153 "Active:", active_remote_routes
);
4155 vty_out(vty
, " %-20s ", "In Holddown:");
4156 vty_out(vty
, "%-8s %-8u",
4157 "Active:", holddown_remote_routes
);
4159 vty_out(vty
, " %-20s ", "Imported:");
4160 vty_out(vty
, "%-8s %-8u",
4161 "Active:", imported_remote_routes
);
4164 case SHOW_NVE_SUMMARY_QUERIES
:
4165 vty_out(vty
, "%-24s ", "Queries:");
4166 vty_out(vty
, "%-8s %-8u ",
4167 "Active:", rfapi_monitor_count(NULL
));
4168 vty_out(vty
, "%-8s %-8u ",
4169 "Failed:", h
->stat
.count_queries_failed
);
4170 vty_out(vty
, "%-8s %-8u",
4171 "Total:", h
->stat
.count_queries
);
4174 case SHOW_NVE_SUMMARY_RESPONSES
:
4175 rfapiRibShowResponsesSummary(vty
);
4185 vty_out(vty
, "VNC is not configured.\n");
4189 static int rfapi_show_nves(struct vty
*vty
, struct prefix
*vn_prefix
,
4190 struct prefix
*un_prefix
)
4192 // struct hash *rfds;
4193 // struct rfp_rfapi_descriptor_param param;
4195 struct bgp
*bgp_default
= bgp_get_default();
4197 struct listnode
*node
;
4198 struct rfapi_descriptor
*rfd
;
4207 h
= bgp_default
->rfapi
;
4212 rc
= rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4216 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4218 char vn_addr_buf
[INET6_ADDRSTRLEN
] = {
4221 char un_addr_buf
[INET6_ADDRSTRLEN
] = {
4229 assert(!rfapiRaddr2Qprefix(&rfd
->vn_addr
, &pfx
));
4230 if (!prefix_match(vn_prefix
, &pfx
))
4235 assert(!rfapiRaddr2Qprefix(&rfd
->un_addr
, &pfx
));
4236 if (!prefix_match(un_prefix
, &pfx
))
4240 rfapiRfapiIpAddr2Str(&rfd
->vn_addr
, vn_addr_buf
,
4242 rfapiRfapiIpAddr2Str(&rfd
->un_addr
, un_addr_buf
,
4246 /* print out a header */
4248 " Active Next Hops\n");
4249 vty_out(vty
, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n",
4250 "VN Address", "UN Address", "Regis", "Resps",
4251 "Reach", "Remove", "Age");
4256 vty_out(vty
, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n",
4257 vn_addr_buf
, un_addr_buf
, rfapiApCount(rfd
),
4258 rfapi_monitor_count(rfd
), rfd
->stat_count_nh_reachable
,
4259 rfd
->stat_count_nh_removal
,
4260 rfapiFormatAge(rfd
->open_time
, age
, 10));
4263 if (printed
> 0 || vn_prefix
|| un_prefix
)
4264 vty_out(vty
, "Displayed %d out of %d active NVEs\n", printed
,
4270 vty_out(vty
, "VNC is not configured.\n");
4275 DEFUN (vnc_show_summary
,
4276 vnc_show_summary_cmd
,
4280 "Display VNC status summary\n")
4282 if (!check_and_display_is_vnc_running(vty
))
4284 bgp_rfapi_show_summary(bgp_get_default(), vty
);
4286 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_ACTIVE_NVES
);
4287 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4288 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_RESPONSES
);
4289 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4293 DEFUN (vnc_show_nves
,
4298 "List known NVEs\n")
4300 rfapi_show_nves(vty
, NULL
, NULL
);
4304 DEFUN (vnc_show_nves_ptct
,
4305 vnc_show_nves_ptct_cmd
,
4306 "show vnc nves <vn|un> <A.B.C.D|X:X::X:X>",
4310 "VN address of NVE\n"
4311 "UN address of NVE\n"
4312 "IPv4 interface address\n"
4313 "IPv6 interface address\n")
4317 if (!check_and_display_is_vnc_running(vty
))
4320 if (!str2prefix(argv
[4]->arg
, &pfx
)) {
4321 vty_out(vty
, "Malformed address \"%s\"\n", argv
[4]->arg
);
4324 if (pfx
.family
!= AF_INET
&& pfx
.family
!= AF_INET6
) {
4325 vty_out(vty
, "Invalid address \"%s\"\n", argv
[4]->arg
);
4329 if (argv
[3]->arg
[0] == 'u') {
4330 rfapi_show_nves(vty
, NULL
, &pfx
);
4332 rfapi_show_nves(vty
, &pfx
, NULL
);
4338 /* adapted from rfp_registration_cache_log() */
4339 static void rfapi_show_registrations(struct vty
*vty
,
4340 struct prefix
*restrict_to
, int show_local
,
4341 int show_remote
, int show_holddown
,
4349 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_REGISTERED
);
4352 /* non-expiring, local */
4353 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 1,
4357 /* non-expiring, non-local */
4358 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4361 if (show_holddown
) {
4362 /* expiring, including local */
4363 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 1, 1,
4366 if (show_imported
) {
4367 /* non-expiring, non-local */
4368 printed
+= rfapiShowRemoteRegistrations(vty
, restrict_to
, 0, 0,
4376 DEFUN (vnc_show_registrations_pfx
,
4377 vnc_show_registrations_pfx_cmd
,
4378 "show vnc registrations [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4381 "List active prefix registrations\n"
4382 "Limit output to a particular IPv4 prefix\n"
4383 "Limit output to a particular IPv6 prefix\n"
4384 "Limit output to a particular IPv6 address\n")
4387 struct prefix
*p_addr
= NULL
;
4390 if (!str2prefix(argv
[3]->arg
, &p
)) {
4391 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4398 rfapi_show_registrations(vty
, p_addr
, 1, 1, 1, 1);
4402 DEFUN (vnc_show_registrations_some_pfx
,
4403 vnc_show_registrations_some_pfx_cmd
,
4404 "show vnc registrations <all|holddown|imported|local|remote> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4407 "List active prefix registrations\n"
4408 "show all registrations\n"
4409 "show only registrations in holddown\n"
4410 "show only imported prefixes\n"
4411 "show only local registrations\n"
4412 "show only remote registrations\n"
4413 "Limit output to a particular prefix or address\n"
4414 "Limit output to a particular prefix or address\n"
4415 "Limit output to a particular prefix or address\n")
4418 struct prefix
*p_addr
= NULL
;
4421 int show_remote
= 0;
4422 int show_holddown
= 0;
4423 int show_imported
= 0;
4426 if (!str2prefix(argv
[4]->arg
, &p
)) {
4427 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4433 switch (argv
[3]->arg
[0]) {
4458 rfapi_show_registrations(vty
, p_addr
, show_local
, show_remote
,
4459 show_holddown
, show_imported
);
4463 DEFUN (vnc_show_responses_pfx
,
4464 vnc_show_responses_pfx_cmd
,
4465 "show vnc responses [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4468 "List recent query responses\n"
4469 "Limit output to a particular IPv4 prefix\n"
4470 "Limit output to a particular IPv6 prefix\n"
4471 "Limit output to a particular IPv6 address\n" )
4474 struct prefix
*p_addr
= NULL
;
4477 if (!str2prefix(argv
[3]->arg
, &p
)) {
4478 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4484 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4486 rfapiRibShowResponsesSummary(vty
);
4488 rfapiRibShowResponses(vty
, p_addr
, 0);
4489 rfapiRibShowResponses(vty
, p_addr
, 1);
4494 DEFUN (vnc_show_responses_some_pfx
,
4495 vnc_show_responses_some_pfx_cmd
,
4496 "show vnc responses <active|removed> [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4499 "List recent query responses\n"
4500 "show only active query responses\n"
4501 "show only removed query responses\n"
4502 "Limit output to a particular IPv4 prefix\n"
4503 "Limit output to a particular IPv6 prefix\n"
4504 "Limit output to a particular IPV6 address\n")
4507 struct prefix
*p_addr
= NULL
;
4509 int show_active
= 0;
4510 int show_removed
= 0;
4512 if (!check_and_display_is_vnc_running(vty
))
4516 if (!str2prefix(argv
[4]->arg
, &p
)) {
4517 vty_out(vty
, "Invalid prefix: %s\n", argv
[4]->arg
);
4524 switch (argv
[3]->arg
[0]) {
4534 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4536 rfapiRibShowResponsesSummary(vty
);
4539 rfapiRibShowResponses(vty
, p_addr
, 0);
4541 rfapiRibShowResponses(vty
, p_addr
, 1);
4546 DEFUN (show_vnc_queries_pfx
,
4547 show_vnc_queries_pfx_cmd
,
4548 "show vnc queries [<A.B.C.D/M|X:X::X:X/M|YY:YY:YY:YY:YY:YY>]",
4551 "List active queries\n"
4552 "Limit output to a particular IPv4 prefix or address\n"
4553 "Limit output to a particular IPv6 prefix\n"
4554 "Limit output to a particualr IPV6 address\n")
4557 struct prefix
*p
= NULL
;
4560 if (!str2prefix(argv
[3]->arg
, &pfx
)) {
4561 vty_out(vty
, "Invalid prefix: %s\n", argv
[3]->arg
);
4567 rfapi_vty_show_nve_summary(vty
, SHOW_NVE_SUMMARY_QUERIES
);
4569 return rfapiShowVncQueries(vty
, p
);
4572 DEFUN (vnc_clear_counters
,
4573 vnc_clear_counters_cmd
,
4574 "clear vnc counters",
4577 "Reset VNC counters\n")
4579 struct bgp
*bgp_default
= bgp_get_default();
4581 struct listnode
*node
;
4582 struct rfapi_descriptor
*rfd
;
4587 h
= bgp_default
->rfapi
;
4593 for (ALL_LIST_ELEMENTS_RO(&h
->descriptors
, node
, rfd
)) {
4594 rfd
->stat_count_nh_reachable
= 0;
4595 rfd
->stat_count_nh_removal
= 0;
4599 memset(&h
->stat
, 0, sizeof(h
->stat
));
4602 * 151122 per bug 103, set count_registrations = number active.
4603 * Do same for queries
4605 h
->stat
.count_registrations
= rfapiApCountAll(bgp_default
);
4606 h
->stat
.count_queries
= rfapi_monitor_count(NULL
);
4608 rfapiRibShowResponsesSummaryClear();
4613 vty_out(vty
, "VNC is not configured.\n");
4617 /************************************************************************
4618 * Add prefix with vrf
4620 * add [vrf <vrf-name>] prefix <prefix>
4621 * [rd <value>] [label <value>] [local-preference <0-4294967295>]
4622 ************************************************************************/
4623 void vnc_add_vrf_opener(struct bgp
*bgp
, struct rfapi_nve_group_cfg
*rfg
)
4625 if (rfg
->rfd
== NULL
) { /* need new rfapi_handle */
4626 /* based on rfapi_open */
4627 struct rfapi_descriptor
*rfd
;
4629 rfd
= XCALLOC(MTYPE_RFAPI_DESC
,
4630 sizeof(struct rfapi_descriptor
));
4633 /* leave most fields empty as will get from (dynamic) config
4635 rfd
->default_tunneltype_option
.type
= BGP_ENCAP_TYPE_MPLS
;
4637 if (rfg
->vn_prefix
.family
4638 && !CHECK_FLAG(rfg
->flags
, RFAPI_RFG_VPN_NH_SELF
)) {
4639 rfapiQprefix2Raddr(&rfg
->vn_prefix
, &rfd
->vn_addr
);
4641 memset(&rfd
->vn_addr
, 0, sizeof(struct rfapi_ip_addr
));
4642 rfd
->vn_addr
.addr_family
= AF_INET
;
4643 rfd
->vn_addr
.addr
.v4
= bgp
->router_id
;
4645 rfd
->un_addr
= rfd
->vn_addr
; /* sigh, need something in UN for
4647 vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__
,
4649 rfapi_init_and_open(bgp
, rfd
, rfg
);
4653 /* NOTE: this functions parallels vnc_direct_add_rn_group_rd */
4654 static int vnc_add_vrf_prefix(struct vty
*vty
, const char *arg_vrf
,
4655 const char *arg_prefix
,
4656 const char *arg_rd
, /* optional */
4657 const char *arg_label
, /* optional */
4658 const char *arg_pref
) /* optional */
4661 struct rfapi_nve_group_cfg
*rfg
;
4663 struct rfapi_ip_prefix rpfx
;
4665 struct rfapi_vn_option optary
[3];
4666 struct rfapi_vn_option
*opt
= NULL
;
4669 bgp
= bgp_get_default(); /* assume main instance for now */
4671 vty_out(vty
, "No BGP process is configured\n");
4672 return CMD_WARNING_CONFIG_FAILED
;
4674 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4675 vty_out(vty
, "VRF support not configured\n");
4676 return CMD_WARNING_CONFIG_FAILED
;
4679 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4682 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4684 return CMD_WARNING_CONFIG_FAILED
;
4686 if (!rfg
->rt_export_list
|| !rfg
->rfapi_import_table
) {
4688 "VRF \"%s\" is missing RT import/export RT configuration.\n",
4690 return CMD_WARNING_CONFIG_FAILED
;
4692 if (!rfg
->rd
.prefixlen
&& !arg_rd
) {
4694 "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n",
4696 return CMD_WARNING_CONFIG_FAILED
;
4698 if (rfg
->label
> MPLS_LABEL_MAX
&& !arg_label
) {
4700 "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n",
4702 return CMD_WARNING_CONFIG_FAILED
;
4704 if (!str2prefix(arg_prefix
, &pfx
)) {
4705 vty_out(vty
, "Malformed prefix \"%s\"\n", arg_prefix
);
4706 return CMD_WARNING_CONFIG_FAILED
;
4708 rfapiQprefix2Rprefix(&pfx
, &rpfx
);
4709 memset(optary
, 0, sizeof(optary
));
4711 opt
= &optary
[cur_opt
++];
4712 opt
->type
= RFAPI_VN_OPTION_TYPE_INTERNAL_RD
;
4713 if (!str2prefix_rd(arg_rd
, &opt
->v
.internal_rd
)) {
4714 vty_out(vty
, "Malformed RD \"%s\"\n", arg_rd
);
4715 return CMD_WARNING_CONFIG_FAILED
;
4718 if (rfg
->label
<= MPLS_LABEL_MAX
|| arg_label
) {
4719 struct rfapi_l2address_option
*l2o
;
4721 opt
->next
= &optary
[cur_opt
];
4722 opt
= &optary
[cur_opt
++];
4723 opt
->type
= RFAPI_VN_OPTION_TYPE_L2ADDR
;
4724 l2o
= &opt
->v
.l2addr
;
4727 label
= strtoul(arg_label
, NULL
, 10);
4730 l2o
->label
= rfg
->label
;
4733 char *endptr
= NULL
;
4734 pref
= strtoul(arg_pref
, &endptr
, 10);
4735 if (*endptr
!= '\0') {
4737 "%% Invalid local-preference value \"%s\"\n",
4739 return CMD_WARNING_CONFIG_FAILED
;
4742 rpfx
.cost
= 255 - (pref
& 255);
4743 vnc_add_vrf_opener(bgp
, rfg
);
4745 if (!rfapi_register(rfg
->rfd
, &rpfx
, RFAPI_INFINITE_LIFETIME
, NULL
,
4746 (cur_opt
? optary
: NULL
), RFAPI_REGISTER_ADD
)) {
4747 struct rfapi_next_hop_entry
*head
= NULL
;
4748 struct rfapi_next_hop_entry
*tail
= NULL
;
4749 struct rfapi_vn_option
*vn_opt_new
;
4751 vnc_zlog_debug_verbose("%s: rfapi_register succeeded",
4754 if (bgp
->rfapi
->rfp_methods
.local_cb
) {
4755 struct rfapi_descriptor
*r
=
4756 (struct rfapi_descriptor
*)rfg
->rfd
;
4757 vn_opt_new
= rfapi_vn_options_dup(opt
);
4759 rfapiAddDeleteLocalRfpPrefix(&r
->un_addr
, &r
->vn_addr
,
4761 RFAPI_INFINITE_LIFETIME
,
4762 vn_opt_new
, &head
, &tail
);
4764 bgp
->rfapi
->flags
|= RFAPI_INCALLBACK
;
4765 (*bgp
->rfapi
->rfp_methods
.local_cb
)(head
,
4767 bgp
->rfapi
->flags
&= ~RFAPI_INCALLBACK
;
4771 vnc_zlog_debug_verbose(
4772 "%s completed, count=%d/%d", __func__
,
4773 rfg
->rfapi_import_table
->local_count
[AFI_IP
],
4774 rfg
->rfapi_import_table
->local_count
[AFI_IP6
]);
4778 vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__
);
4779 vty_out(vty
, "Add failed.\n");
4780 return CMD_WARNING_CONFIG_FAILED
;
4783 DEFUN (add_vrf_prefix_rd_label_pref
,
4784 add_vrf_prefix_rd_label_pref_cmd
,
4785 "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)}]",
4789 "Add/modify prefix related information\n"
4792 "Override configured VRF Route Distinguisher\n"
4793 "<as-number>:<number> or <ip-address>:<number>\n"
4794 "Override configured VRF label\n"
4795 "Label Value <0-1048575>\n"
4796 "Set advertised local preference\n"
4797 "local preference (higher=more preferred)\n")
4799 char *arg_vrf
= argv
[2]->arg
;
4800 char *arg_prefix
= argv
[4]->arg
;
4801 char *arg_rd
= NULL
; /* optional */
4802 char *arg_label
= NULL
; /* optional */
4803 char *arg_pref
= NULL
; /* optional */
4805 argc
--; /* don't parse argument */
4806 while (pargc
< argc
) {
4807 switch (argv
[pargc
++]->arg
[0]) {
4809 arg_rd
= argv
[pargc
]->arg
;
4812 arg_label
= argv
[pargc
]->arg
;
4815 arg_pref
= argv
[pargc
]->arg
;
4823 return vnc_add_vrf_prefix(vty
, arg_vrf
, arg_prefix
, arg_rd
, arg_label
,
4827 /************************************************************************
4828 * del prefix with vrf
4830 * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]
4831 ************************************************************************/
4832 static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg
*rfg
)
4836 if (rfg
->rfapi_import_table
== NULL
)
4839 afi_t afi
= AFI_MAX
;
4841 count
+= rfg
->rfapi_import_table
->local_count
[afi
];
4846 void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg
*rfg
)
4848 struct rfapi_descriptor
*rfd
= rfg
->rfd
;
4853 /* check if IT is empty */
4855 afi
< AFI_MAX
&& rfg
->rfapi_import_table
->local_count
[afi
] == 0;
4859 if (afi
== AFI_MAX
) {
4860 vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__
,
4865 vnc_zlog_debug_verbose(
4866 "%s: VRF %s afi=%d count=%d", __func__
, rfg
->name
, afi
,
4867 rfg
->rfapi_import_table
->local_count
[afi
]);
4871 static int vnc_clear_vrf(struct vty
*vty
, struct bgp
*bgp
, const char *arg_vrf
,
4872 const char *arg_prefix
, /* NULL = all */
4873 const char *arg_rd
) /* optional */
4875 struct rfapi_nve_group_cfg
*rfg
;
4876 struct rfapi_local_reg_delete_arg cda
;
4881 bgp
= bgp_get_default(); /* assume main instance for now */
4883 vty_out(vty
, "No BGP process is configured\n");
4886 if (!bgp
->rfapi
|| !bgp
->rfapi_cfg
) {
4887 vty_out(vty
, "VRF support not configured\n");
4890 rfg
= bgp_rfapi_cfg_match_byname(bgp
, arg_vrf
, RFAPI_GROUP_CFG_VRF
);
4893 vty_out(vty
, "VRF \"%s\" appears not to be configured.\n",
4897 rc
= parse_deleter_args(vty
, bgp
, arg_prefix
, NULL
, NULL
, NULL
, NULL
,
4899 if (rc
!= CMD_SUCCESS
) /* parse error */
4902 start_count
= rfapi_cfg_group_it_count(rfg
);
4903 clear_vnc_prefix(&cda
);
4904 vty_out(vty
, "Cleared %u out of %d prefixes.\n", cda
.pfx_count
,
4909 DEFUN (clear_vrf_prefix_rd
,
4910 clear_vrf_prefix_rd_cmd
,
4911 "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
4912 "Clear stored data\n"
4915 "Prefix related information\n"
4918 "Specific VRF Route Distinguisher\n"
4919 "<as-number>:<number> or <ip-address>:<number>\n")
4921 char *arg_vrf
= argv
[2]->arg
;
4922 char *arg_prefix
= NULL
; /* optional */
4923 char *arg_rd
= NULL
; /* optional */
4925 argc
--; /* don't check parameter */
4926 while (pargc
< argc
) {
4927 switch (argv
[pargc
++]->arg
[0]) {
4929 arg_rd
= argv
[pargc
]->arg
;
4932 arg_prefix
= argv
[pargc
]->arg
;
4939 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, arg_prefix
, arg_rd
);
4942 DEFUN (clear_vrf_all
,
4944 "clear vrf NAME all",
4945 "Clear stored data\n"
4950 char *arg_vrf
= argv
[2]->arg
;
4951 return vnc_clear_vrf(vty
, NULL
, arg_vrf
, NULL
, NULL
);
4954 void rfapi_vty_init(void)
4956 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_lnh_cmd
);
4957 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_lnh_cmd
);
4958 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_lnh_cmd
);
4959 install_element(ENABLE_NODE
, &add_vnc_prefix_life_lnh_cmd
);
4960 install_element(ENABLE_NODE
, &add_vnc_prefix_lnh_cmd
);
4962 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_life_cmd
);
4963 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cost_cmd
);
4964 install_element(ENABLE_NODE
, &add_vnc_prefix_cost_cmd
);
4965 install_element(ENABLE_NODE
, &add_vnc_prefix_life_cmd
);
4966 install_element(ENABLE_NODE
, &add_vnc_prefix_cmd
);
4968 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_life_cmd
);
4969 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_life_cmd
);
4970 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cost_cmd
);
4971 install_element(ENABLE_NODE
, &add_vnc_mac_vni_prefix_cmd
);
4972 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_life_cmd
);
4973 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cost_cmd
);
4974 install_element(ENABLE_NODE
, &add_vnc_mac_vni_life_cmd
);
4975 install_element(ENABLE_NODE
, &add_vnc_mac_vni_cmd
);
4977 install_element(ENABLE_NODE
, &add_vrf_prefix_rd_label_pref_cmd
);
4979 install_element(ENABLE_NODE
, &clear_vnc_nve_all_cmd
);
4980 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_un_cmd
);
4981 install_element(ENABLE_NODE
, &clear_vnc_nve_un_vn_cmd
);
4982 install_element(ENABLE_NODE
, &clear_vnc_nve_vn_cmd
);
4983 install_element(ENABLE_NODE
, &clear_vnc_nve_un_cmd
);
4985 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_un_cmd
);
4986 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_vn_cmd
);
4987 install_element(ENABLE_NODE
, &clear_vnc_prefix_un_cmd
);
4988 install_element(ENABLE_NODE
, &clear_vnc_prefix_vn_cmd
);
4989 install_element(ENABLE_NODE
, &clear_vnc_prefix_all_cmd
);
4991 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_cmd
);
4992 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_cmd
);
4993 install_element(ENABLE_NODE
, &clear_vnc_mac_un_cmd
);
4994 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_cmd
);
4995 install_element(ENABLE_NODE
, &clear_vnc_mac_all_cmd
);
4997 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_un_prefix_cmd
);
4998 install_element(ENABLE_NODE
, &clear_vnc_mac_un_vn_prefix_cmd
);
4999 install_element(ENABLE_NODE
, &clear_vnc_mac_un_prefix_cmd
);
5000 install_element(ENABLE_NODE
, &clear_vnc_mac_vn_prefix_cmd
);
5001 install_element(ENABLE_NODE
, &clear_vnc_mac_all_prefix_cmd
);
5003 install_element(ENABLE_NODE
, &clear_vrf_prefix_rd_cmd
);
5004 install_element(ENABLE_NODE
, &clear_vrf_all_cmd
);
5006 install_element(ENABLE_NODE
, &vnc_clear_counters_cmd
);
5008 install_element(VIEW_NODE
, &vnc_show_summary_cmd
);
5009 install_element(VIEW_NODE
, &vnc_show_nves_cmd
);
5010 install_element(VIEW_NODE
, &vnc_show_nves_ptct_cmd
);
5012 install_element(VIEW_NODE
, &vnc_show_registrations_pfx_cmd
);
5013 install_element(VIEW_NODE
, &vnc_show_registrations_some_pfx_cmd
);
5014 install_element(VIEW_NODE
, &vnc_show_responses_pfx_cmd
);
5015 install_element(VIEW_NODE
, &vnc_show_responses_some_pfx_cmd
);
5016 install_element(VIEW_NODE
, &show_vnc_queries_pfx_cmd
);