mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 20:26:36 +00:00
Merge branch 'master' of https://github.com/frrouting/frr into pmsi-parse-display
This commit is contained in:
commit
783e95b8e8
3
.gitignore
vendored
3
.gitignore
vendored
@ -82,3 +82,6 @@ GPATH
|
|||||||
*.lo
|
*.lo
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.dirstamp
|
.dirstamp
|
||||||
|
|
||||||
|
# clippy generated source
|
||||||
|
*_clippy.c
|
||||||
|
36
alpine/APKBUILD.in
Normal file
36
alpine/APKBUILD.in
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Maintainer: Arthur Jones <arthur.jones@riverbed.com>
|
||||||
|
pkgname=frr
|
||||||
|
pkgver=@VERSION@
|
||||||
|
pkgrel=0
|
||||||
|
pkgdesc="Free Range Routing is a fork of quagga"
|
||||||
|
url="https://frrouting.org/"
|
||||||
|
arch="all"
|
||||||
|
license="GPL-2.0"
|
||||||
|
depends="iproute2 json-c c-ares ipsec-tools iproute2"
|
||||||
|
makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
|
||||||
|
acct autoconf automake bash
|
||||||
|
binutils binutils-libs bison bsd-compat-headers build-base
|
||||||
|
c-ares c-ares-dev ca-certificates cryptsetup-libs curl
|
||||||
|
device-mapper-libs expat fakeroot flex fortify-headers gdbm
|
||||||
|
git gmp isl json-c-dev kmod lddtree libacl libatomic libattr
|
||||||
|
libblkid libburn libbz2 libc-dev libcap libcurl libedit libffi libgcc
|
||||||
|
libgomp libisoburn libisofs libltdl libressl libssh2
|
||||||
|
libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1
|
||||||
|
mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base
|
||||||
|
patch pax-utils pcre perl pkgconf python2 python2-dev readline
|
||||||
|
readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs"
|
||||||
|
subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
|
||||||
|
source="$pkgname-$pkgver.tar.gz"
|
||||||
|
|
||||||
|
builddir="$srcdir"/$pkgname-$pkgver
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$builddir"
|
||||||
|
./configure --prefix=/usr || return 1
|
||||||
|
make || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$builddir"
|
||||||
|
make DESTDIR="$pkgdir" install || return 1
|
||||||
|
}
|
1
bgpd/.gitignore
vendored
1
bgpd/.gitignore
vendored
@ -16,4 +16,3 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
*clippy.c
|
|
||||||
|
181
bgpd/bgp_evpn.c
181
bgpd/bgp_evpn.c
@ -474,6 +474,17 @@ static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
bgp_evpn_derive_auto_rt_export(bgp, vpn);
|
bgp_evpn_derive_auto_rt_export(bgp, vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert nexthop (remote VTEP IP) into an IPv6 address.
|
||||||
|
*/
|
||||||
|
static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
|
||||||
|
{
|
||||||
|
if (BGP_ATTR_NEXTHOP_AFI_IP6(attr))
|
||||||
|
return;
|
||||||
|
ipv4_to_ipv4_mapped_ipv6(&attr->mp_nexthop_global, attr->nexthop);
|
||||||
|
attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add (update) or delete MACIP from zebra.
|
* Add (update) or delete MACIP from zebra.
|
||||||
*/
|
*/
|
||||||
@ -622,17 +633,17 @@ static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build extended communities for EVPN route. RT and ENCAP are
|
* Build extended communities for EVPN route.
|
||||||
* applicable to all routes.
|
* This function is applicable for type-2 and type-3 routes. The layer-2 RT
|
||||||
* TODO: currently kernel doesnt support ipv6 routes with ipv4 nexthops.
|
* and ENCAP extended communities are applicable for all routes.
|
||||||
* This means that we can't do symmetric routing for ipv6 hosts routes
|
* The default gateway extended community and MAC mobility (sticky) extended
|
||||||
* in the same way as ipv4 host routes.
|
* community are added as needed based on passed settings - only for type-2
|
||||||
* We wont attach l3-vni related RTs for ipv6 routes.
|
* routes. Likewise, the layer-3 RT and Router MAC extended communities are
|
||||||
* For now, We will only adevrtise ipv4 host routes
|
* added, if present, based on passed settings - only for non-link-local
|
||||||
* with L3-VNI related ext-comm.
|
* type-2 routes.
|
||||||
*/
|
*/
|
||||||
static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
||||||
afi_t afi)
|
int add_l3_ecomm)
|
||||||
{
|
{
|
||||||
struct ecommunity ecom_encap;
|
struct ecommunity ecom_encap;
|
||||||
struct ecommunity ecom_sticky;
|
struct ecommunity ecom_sticky;
|
||||||
@ -662,11 +673,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
|||||||
for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
|
for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom))
|
||||||
attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
|
attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
|
||||||
|
|
||||||
/*
|
/* Add the export RTs for L3VNI if told to - caller determines
|
||||||
* only attach l3-vni export rts for ipv4 address family and if we are
|
* when this should be done.
|
||||||
* advertising both the labels in type-2 routes
|
|
||||||
*/
|
*/
|
||||||
if (afi == AFI_IP && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
|
if (add_l3_ecomm) {
|
||||||
vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
|
vrf_export_rtl = bgpevpn_get_vrf_export_rtl(vpn);
|
||||||
if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
|
if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
|
||||||
for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
|
for (ALL_LIST_ELEMENTS(vrf_export_rtl, node, nnode,
|
||||||
@ -676,6 +686,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add MAC mobility (sticky) if needed. */
|
||||||
if (attr->sticky) {
|
if (attr->sticky) {
|
||||||
seqnum = 0;
|
seqnum = 0;
|
||||||
memset(&ecom_sticky, 0, sizeof(ecom_sticky));
|
memset(&ecom_sticky, 0, sizeof(ecom_sticky));
|
||||||
@ -686,12 +697,8 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
|||||||
ecommunity_merge(attr->ecommunity, &ecom_sticky);
|
ecommunity_merge(attr->ecommunity, &ecom_sticky);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Add RMAC, if told to. */
|
||||||
* only attach l3-vni rmac for ipv4 address family and if we are
|
if (add_l3_ecomm) {
|
||||||
* advertising both the labels in type-2 routes
|
|
||||||
*/
|
|
||||||
if (afi == AFI_IP && !is_zero_mac(&attr->rmac)
|
|
||||||
&& CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) {
|
|
||||||
memset(&ecom_rmac, 0, sizeof(ecom_rmac));
|
memset(&ecom_rmac, 0, sizeof(ecom_rmac));
|
||||||
encode_rmac_extcomm(&eval_rmac, &attr->rmac);
|
encode_rmac_extcomm(&eval_rmac, &attr->rmac);
|
||||||
ecom_rmac.size = 1;
|
ecom_rmac.size = 1;
|
||||||
@ -700,6 +707,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
|
|||||||
ecommunity_merge(attr->ecommunity, &ecom_rmac);
|
ecommunity_merge(attr->ecommunity, &ecom_rmac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add default gateway, if needed. */
|
||||||
if (attr->default_gw) {
|
if (attr->default_gw) {
|
||||||
memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
|
memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
|
||||||
encode_default_gw_extcomm(&eval_default_gw);
|
encode_default_gw_extcomm(&eval_default_gw);
|
||||||
@ -1260,6 +1268,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
|||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct attr *attr_new;
|
struct attr *attr_new;
|
||||||
|
int add_l3_ecomm = 0;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
afi_t afi = AFI_L2VPN;
|
afi_t afi = AFI_L2VPN;
|
||||||
safi_t safi = SAFI_EVPN;
|
safi_t safi = SAFI_EVPN;
|
||||||
@ -1279,14 +1288,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
|||||||
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
|
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE)
|
||||||
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
|
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
|
||||||
|
|
||||||
/* router mac is only needed for type-2 and type-5 routes */
|
/* router mac is only needed for type-2 routes here. */
|
||||||
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
|
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
|
||||||
bgpevpn_get_rmac(vpn, &attr.rmac);
|
bgpevpn_get_rmac(vpn, &attr.rmac);
|
||||||
vni2label(vpn->vni, &(attr.label));
|
vni2label(vpn->vni, &(attr.label));
|
||||||
|
|
||||||
/* Set up RT and ENCAP extended community. */
|
/* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
|
||||||
build_evpn_route_extcomm(
|
* IPv4 or IPv6 global addresses and we're advertising L3VNI with
|
||||||
vpn, &attr, IS_EVPN_PREFIX_IPADDR_V4(p) ? AFI_IP : AFI_IP6);
|
* these routes.
|
||||||
|
*/
|
||||||
|
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
|
||||||
|
(IS_EVPN_PREFIX_IPADDR_V4(p) ||
|
||||||
|
!IN6_IS_ADDR_LINKLOCAL(&p->prefix.ip.ipaddr_v6)) &&
|
||||||
|
CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
|
||||||
|
add_l3_ecomm = 1;
|
||||||
|
|
||||||
|
/* Set up extended community. */
|
||||||
|
build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
|
||||||
|
|
||||||
/* First, create (or fetch) route node within the VNI. */
|
/* First, create (or fetch) route node within the VNI. */
|
||||||
/* NOTE: There is no RD here. */
|
/* NOTE: There is no RD here. */
|
||||||
@ -1466,22 +1484,20 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
struct attr attr;
|
struct attr attr;
|
||||||
struct attr attr_sticky;
|
struct attr attr_sticky;
|
||||||
struct attr attr_def_gw;
|
struct attr attr_def_gw;
|
||||||
struct attr attr_ip6;
|
struct attr attr_ip6_ll;
|
||||||
struct attr attr_sticky_ip6;
|
|
||||||
struct attr attr_def_gw_ip6;
|
|
||||||
struct attr *attr_new;
|
struct attr *attr_new;
|
||||||
|
int add_l3_ecomm = 0;
|
||||||
|
|
||||||
afi = AFI_L2VPN;
|
afi = AFI_L2VPN;
|
||||||
safi = SAFI_EVPN;
|
safi = SAFI_EVPN;
|
||||||
memset(&attr, 0, sizeof(struct attr));
|
memset(&attr, 0, sizeof(struct attr));
|
||||||
memset(&attr_sticky, 0, sizeof(struct attr));
|
memset(&attr_sticky, 0, sizeof(struct attr));
|
||||||
memset(&attr_def_gw, 0, sizeof(struct attr));
|
memset(&attr_def_gw, 0, sizeof(struct attr));
|
||||||
memset(&attr_ip6, 0, sizeof(struct attr));
|
memset(&attr_ip6_ll, 0, sizeof(struct attr));
|
||||||
memset(&attr_sticky_ip6, 0, sizeof(struct attr));
|
|
||||||
memset(&attr_def_gw_ip6, 0, sizeof(struct attr));
|
|
||||||
|
|
||||||
/* Build path-attribute - all type-2 routes for this VNI will share the
|
/* Build path-attribute - multiple type-2 routes for this VNI will share
|
||||||
* same path attribute.
|
* the same path attribute, but we need separate structures for sticky
|
||||||
|
* MACs, default gateway and IPv6 link-local addresses (no L3 RT/RMAC).
|
||||||
*/
|
*/
|
||||||
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
|
||||||
bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
|
bgp_attr_default_set(&attr_sticky, BGP_ORIGIN_IGP);
|
||||||
@ -1500,31 +1516,21 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
attr_def_gw.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
||||||
attr_def_gw.default_gw = 1;
|
attr_def_gw.default_gw = 1;
|
||||||
bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
|
bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
|
||||||
bgp_attr_default_set(&attr_ip6, BGP_ORIGIN_IGP);
|
bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
|
||||||
bgp_attr_default_set(&attr_sticky_ip6, BGP_ORIGIN_IGP);
|
attr_ip6_ll.nexthop = vpn->originator_ip;
|
||||||
bgp_attr_default_set(&attr_def_gw_ip6, BGP_ORIGIN_IGP);
|
attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
|
||||||
attr_ip6.nexthop = vpn->originator_ip;
|
attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
||||||
attr_ip6.mp_nexthop_global_in = vpn->originator_ip;
|
|
||||||
attr_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
|
||||||
bgpevpn_get_rmac(vpn, &attr_ip6.rmac);
|
|
||||||
attr_sticky_ip6.nexthop = vpn->originator_ip;
|
|
||||||
attr_sticky_ip6.mp_nexthop_global_in = vpn->originator_ip;
|
|
||||||
attr_sticky_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
|
||||||
attr_sticky_ip6.sticky = 1;
|
|
||||||
bgpevpn_get_rmac(vpn, &attr_sticky_ip6.rmac);
|
|
||||||
attr_def_gw_ip6.nexthop = vpn->originator_ip;
|
|
||||||
attr_def_gw_ip6.mp_nexthop_global_in = vpn->originator_ip;
|
|
||||||
attr_def_gw_ip6.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
|
|
||||||
attr_def_gw_ip6.default_gw = 1;
|
|
||||||
bgpevpn_get_rmac(vpn, &attr_def_gw_ip6.rmac);
|
|
||||||
|
|
||||||
/* Set up RT, ENCAP and sticky MAC extended community. */
|
/* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
|
||||||
build_evpn_route_extcomm(vpn, &attr, AFI_IP);
|
* using L3 VNI for type-2 routes also.
|
||||||
build_evpn_route_extcomm(vpn, &attr_sticky, AFI_IP);
|
*/
|
||||||
build_evpn_route_extcomm(vpn, &attr_def_gw, AFI_IP);
|
if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
|
||||||
build_evpn_route_extcomm(vpn, &attr_ip6, AFI_IP6);
|
add_l3_ecomm = 1;
|
||||||
build_evpn_route_extcomm(vpn, &attr_sticky_ip6, AFI_IP6);
|
|
||||||
build_evpn_route_extcomm(vpn, &attr_def_gw_ip6, AFI_IP);
|
build_evpn_route_extcomm(vpn, &attr, add_l3_ecomm);
|
||||||
|
build_evpn_route_extcomm(vpn, &attr_sticky, add_l3_ecomm);
|
||||||
|
build_evpn_route_extcomm(vpn, &attr_def_gw, add_l3_ecomm);
|
||||||
|
build_evpn_route_extcomm(vpn, &attr_ip6_ll, 0);
|
||||||
|
|
||||||
/* Walk this VNI's route table and update local type-2 routes. For any
|
/* Walk this VNI's route table and update local type-2 routes. For any
|
||||||
* routes updated, update corresponding entry in the global table too.
|
* routes updated, update corresponding entry in the global table too.
|
||||||
@ -1538,7 +1544,11 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
|
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IS_EVPN_PREFIX_IPADDR_V4(evp)) {
|
if (IS_EVPN_PREFIX_IPADDR_V6(evp) &&
|
||||||
|
IN6_IS_ADDR_LINKLOCAL(&evp->prefix.ip.ipaddr_v6))
|
||||||
|
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
||||||
|
&attr_ip6_ll, 0, 1, &ri, 0);
|
||||||
|
else {
|
||||||
if (evpn_route_is_sticky(bgp, rn))
|
if (evpn_route_is_sticky(bgp, rn))
|
||||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
||||||
&attr_sticky, 0, 1, &ri,
|
&attr_sticky, 0, 1, &ri,
|
||||||
@ -1550,19 +1560,6 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
else
|
else
|
||||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
||||||
&attr, 0, 1, &ri, 0);
|
&attr, 0, 1, &ri, 0);
|
||||||
} else {
|
|
||||||
if (evpn_route_is_sticky(bgp, rn))
|
|
||||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
|
||||||
&attr_sticky_ip6, 0, 1,
|
|
||||||
&ri, 0);
|
|
||||||
else if (evpn_route_is_def_gw(bgp, rn))
|
|
||||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
|
||||||
&attr_def_gw_ip6, 0, 1,
|
|
||||||
&ri, 0);
|
|
||||||
else
|
|
||||||
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
|
|
||||||
&attr_ip6, 0, 1, &ri,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a local route exists for this prefix, we need to update
|
/* If a local route exists for this prefix, we need to update
|
||||||
@ -1593,11 +1590,9 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
|
|||||||
|
|
||||||
/* Unintern temporary. */
|
/* Unintern temporary. */
|
||||||
aspath_unintern(&attr.aspath);
|
aspath_unintern(&attr.aspath);
|
||||||
aspath_unintern(&attr_ip6.aspath);
|
|
||||||
aspath_unintern(&attr_sticky.aspath);
|
aspath_unintern(&attr_sticky.aspath);
|
||||||
aspath_unintern(&attr_sticky_ip6.aspath);
|
|
||||||
aspath_unintern(&attr_def_gw.aspath);
|
aspath_unintern(&attr_def_gw.aspath);
|
||||||
aspath_unintern(&attr_def_gw_ip6.aspath);
|
aspath_unintern(&attr_ip6_ll.aspath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1791,6 +1786,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
|
struct attr attr;
|
||||||
struct attr *attr_new;
|
struct attr *attr_new;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
@ -1827,6 +1823,15 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* EVPN routes currently only support a IPv4 next hop which corresponds
|
||||||
|
* to the remote VTEP. When importing into a VRF, if it is IPv6 host
|
||||||
|
* route, we have to convert the next hop to an IPv4-mapped address
|
||||||
|
* for the rest of the code to flow through.
|
||||||
|
*/
|
||||||
|
bgp_attr_dup(&attr, parent_ri->attr);
|
||||||
|
if (afi == AFI_IP6)
|
||||||
|
evpn_convert_nexthop_to_ipv6(&attr);
|
||||||
|
|
||||||
/* Check if route entry is already present. */
|
/* Check if route entry is already present. */
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
if (ri->extra
|
if (ri->extra
|
||||||
@ -1835,7 +1840,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
|
|
||||||
if (!ri) {
|
if (!ri) {
|
||||||
/* Add (or update) attribute to hash. */
|
/* Add (or update) attribute to hash. */
|
||||||
attr_new = bgp_attr_intern(parent_ri->attr);
|
attr_new = bgp_attr_intern(&attr);
|
||||||
|
|
||||||
/* Create new route with its attribute. */
|
/* Create new route with its attribute. */
|
||||||
ri = info_make(parent_ri->type, parent_ri->sub_type, 0,
|
ri = info_make(parent_ri->type, parent_ri->sub_type, 0,
|
||||||
@ -1850,21 +1855,25 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
|
|||||||
}
|
}
|
||||||
bgp_info_add(rn, ri);
|
bgp_info_add(rn, ri);
|
||||||
} else {
|
} else {
|
||||||
if (attrhash_cmp(ri->attr, parent_ri->attr)
|
if (attrhash_cmp(ri->attr, &attr)
|
||||||
&& !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
|
&& !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
|
||||||
bgp_unlock_node(rn);
|
bgp_unlock_node(rn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* The attribute has changed. */
|
/* The attribute has changed. */
|
||||||
/* Add (or update) attribute to hash. */
|
/* Add (or update) attribute to hash. */
|
||||||
attr_new = bgp_attr_intern(parent_ri->attr);
|
attr_new = bgp_attr_intern(&attr);
|
||||||
|
|
||||||
/* Restore route, if needed. */
|
/* Restore route, if needed. */
|
||||||
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
|
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
|
||||||
bgp_info_restore(rn, ri);
|
bgp_info_restore(rn, ri);
|
||||||
|
|
||||||
/* Mark if nexthop has changed. */
|
/* Mark if nexthop has changed. */
|
||||||
if (!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop))
|
if ((afi == AFI_IP &&
|
||||||
|
!IPV4_ADDR_SAME(&ri->attr->nexthop, &attr_new->nexthop)) ||
|
||||||
|
(afi == AFI_IP6 &&
|
||||||
|
!IPV6_ADDR_SAME(&ri->attr->mp_nexthop_global,
|
||||||
|
&attr_new->mp_nexthop_global)))
|
||||||
SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
|
SET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
|
||||||
|
|
||||||
/* Unintern existing, set to new. */
|
/* Unintern existing, set to new. */
|
||||||
@ -2577,9 +2586,11 @@ static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
|||||||
static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
|
static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
|
||||||
{
|
{
|
||||||
/* delete all ipv4 routes and withdraw from peers */
|
/* delete all ipv4 routes and withdraw from peers */
|
||||||
|
if (advertise_type5_routes(bgp_vrf, AFI_IP))
|
||||||
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
|
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
|
||||||
|
|
||||||
/* delete all ipv6 routes and withdraw from peers */
|
/* delete all ipv6 routes and withdraw from peers */
|
||||||
|
if (advertise_type5_routes(bgp_vrf, AFI_IP6))
|
||||||
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
|
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2588,9 +2599,11 @@ static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
|
|||||||
static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
|
static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
|
||||||
{
|
{
|
||||||
/* update all ipv4 routes */
|
/* update all ipv4 routes */
|
||||||
|
if (advertise_type5_routes(bgp_vrf, AFI_IP))
|
||||||
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
|
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
|
||||||
|
|
||||||
/* update all ipv6 routes */
|
/* update all ipv6 routes */
|
||||||
|
if (advertise_type5_routes(bgp_vrf, AFI_IP6))
|
||||||
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
|
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3227,10 +3240,6 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, struct prefix *p,
|
|||||||
struct prefix_evpn evp;
|
struct prefix_evpn evp;
|
||||||
char buf[PREFIX_STRLEN];
|
char buf[PREFIX_STRLEN];
|
||||||
|
|
||||||
/* NOTE: Check needed as this is called per-route also. */
|
|
||||||
if (!advertise_type5_routes(bgp_vrf, afi))
|
|
||||||
return;
|
|
||||||
|
|
||||||
build_type5_prefix_from_ip_prefix(&evp, p);
|
build_type5_prefix_from_ip_prefix(&evp, p);
|
||||||
ret = delete_evpn_type5_route(bgp_vrf, &evp);
|
ret = delete_evpn_type5_route(bgp_vrf, &evp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -3248,10 +3257,6 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
|
|||||||
struct bgp_node *rn = NULL;
|
struct bgp_node *rn = NULL;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
|
|
||||||
/* Bail out early if we don't have to advertise type-5 routes. */
|
|
||||||
if (!advertise_type5_routes(bgp_vrf, afi))
|
|
||||||
return;
|
|
||||||
|
|
||||||
table = bgp_vrf->rib[afi][safi];
|
table = bgp_vrf->rib[afi][safi];
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
/* Only care about "selected" routes - non-imported. */
|
/* Only care about "selected" routes - non-imported. */
|
||||||
@ -3281,10 +3286,6 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
|
|||||||
struct prefix_evpn evp;
|
struct prefix_evpn evp;
|
||||||
char buf[PREFIX_STRLEN];
|
char buf[PREFIX_STRLEN];
|
||||||
|
|
||||||
/* NOTE: Check needed as this is called per-route also. */
|
|
||||||
if (!advertise_type5_routes(bgp_vrf, afi))
|
|
||||||
return;
|
|
||||||
|
|
||||||
build_type5_prefix_from_ip_prefix(&evp, p);
|
build_type5_prefix_from_ip_prefix(&evp, p);
|
||||||
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
|
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -3303,10 +3304,6 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
|
|||||||
struct bgp_node *rn = NULL;
|
struct bgp_node *rn = NULL;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
|
|
||||||
/* Bail out early if we don't have to advertise type-5 routes. */
|
|
||||||
if (!advertise_type5_routes(bgp_vrf, afi))
|
|
||||||
return;
|
|
||||||
|
|
||||||
table = bgp_vrf->rib[afi][safi];
|
table = bgp_vrf->rib[afi][safi];
|
||||||
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
|
||||||
/* Need to identify the "selected" route entry to use its
|
/* Need to identify the "selected" route entry to use its
|
||||||
|
@ -55,6 +55,25 @@ static inline vni_t label2vni(mpls_label_t *label)
|
|||||||
return vni;
|
return vni;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int advertise_type5_routes(struct bgp *bgp_vrf,
|
||||||
|
afi_t afi)
|
||||||
|
{
|
||||||
|
if (!bgp_vrf->l3vni)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (afi == AFI_IP &&
|
||||||
|
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (afi == AFI_IP6 &&
|
||||||
|
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
|
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
|
||||||
struct prefix *p,
|
struct prefix *p,
|
||||||
struct attr *src_attr, afi_t afi,
|
struct attr *src_attr, afi_t afi,
|
||||||
|
@ -285,6 +285,14 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int is_evpn_prefix_default(struct prefix *evp)
|
||||||
|
{
|
||||||
|
if (evp->family != AF_EVPN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ((evp->u.prefix_evpn.ip_prefix_length == 0) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
|
static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
|
||||||
struct prefix *ip)
|
struct prefix *ip)
|
||||||
{
|
{
|
||||||
@ -352,19 +360,17 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
|
|||||||
p->prefix.ip.ipaddr_v4 = originator_ip;
|
p->prefix.ip.ipaddr_v4 = originator_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi)
|
static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
|
||||||
|
safi_t safi)
|
||||||
{
|
{
|
||||||
if (!bgp_vrf->l3vni)
|
if (afi == AFI_IP &&
|
||||||
return 0;
|
CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
|
||||||
if (afi == AFI_IP
|
|
||||||
&& CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
else if (afi == AFI_IP6 &&
|
||||||
if (afi == AFI_IP6
|
CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
&& CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2419,7 +2419,50 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
|
|||||||
/*
|
/*
|
||||||
* evpn - enable advertisement of default g/w
|
* evpn - enable advertisement of default g/w
|
||||||
*/
|
*/
|
||||||
static void evpn_set_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)
|
static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf,
|
||||||
|
afi_t afi, int add)
|
||||||
|
{
|
||||||
|
struct prefix ip_prefix;
|
||||||
|
safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */
|
||||||
|
|
||||||
|
/* form the default prefix 0.0.0.0/0 */
|
||||||
|
memset(&ip_prefix, 0, sizeof(struct prefix));
|
||||||
|
ip_prefix.family = afi2family(afi);
|
||||||
|
ip_prefix.prefixlen = 0;
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
/* bail if we are already advertising default route */
|
||||||
|
if (evpn_default_originate_set(bgp_vrf, afi, safi))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (afi == AFI_IP)
|
||||||
|
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
|
||||||
|
else if (afi == AFI_IP6)
|
||||||
|
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
|
||||||
|
bgp_evpn_advertise_type5_route(bgp_vrf, &ip_prefix,
|
||||||
|
NULL, afi, safi);
|
||||||
|
} else {
|
||||||
|
/* bail out if we havent advertised the default route */
|
||||||
|
if (!evpn_default_originate_set(bgp_vrf, afi, safi))
|
||||||
|
return;
|
||||||
|
if (afi == AFI_IP)
|
||||||
|
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
|
||||||
|
else if (afi == AFI_IP6)
|
||||||
|
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
|
||||||
|
bgp_evpn_withdraw_type5_route(bgp_vrf, &ip_prefix,
|
||||||
|
afi, safi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* evpn - enable advertisement of default g/w
|
||||||
|
*/
|
||||||
|
static void evpn_set_advertise_subnet(struct bgp *bgp,
|
||||||
|
struct bgpevpn *vpn)
|
||||||
{
|
{
|
||||||
if (vpn->advertise_subnet)
|
if (vpn->advertise_subnet)
|
||||||
return;
|
return;
|
||||||
@ -2612,6 +2655,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_evpn_default_originate,
|
||||||
|
bgp_evpn_default_originate_cmd,
|
||||||
|
"default-originate <ipv4 | ipv6>",
|
||||||
|
"originate a default route\n"
|
||||||
|
"ipv4 address family\n"
|
||||||
|
"ipv6 address family\n")
|
||||||
|
{
|
||||||
|
afi_t afi = 0;
|
||||||
|
int idx_afi = 0;
|
||||||
|
struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
|
||||||
|
|
||||||
|
if (!bgp_vrf)
|
||||||
|
return CMD_WARNING;
|
||||||
|
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
|
||||||
|
evpn_process_default_originate_cmd(bgp_vrf, afi, 1);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_bgp_evpn_default_originate,
|
||||||
|
no_bgp_evpn_default_originate_cmd,
|
||||||
|
"no default-originate <ipv4 | ipv6>",
|
||||||
|
NO_STR
|
||||||
|
"withdraw a default route\n"
|
||||||
|
"ipv4 address family\n"
|
||||||
|
"ipv6 address family\n")
|
||||||
|
{
|
||||||
|
afi_t afi = 0;
|
||||||
|
int idx_afi = 0;
|
||||||
|
struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
|
||||||
|
|
||||||
|
if (!bgp_vrf)
|
||||||
|
return CMD_WARNING;
|
||||||
|
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
|
||||||
|
evpn_process_default_originate_cmd(bgp_vrf, afi, 0);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (bgp_evpn_advertise_vni_subnet,
|
DEFUN (bgp_evpn_advertise_vni_subnet,
|
||||||
bgp_evpn_advertise_vni_subnet_cmd,
|
bgp_evpn_advertise_vni_subnet_cmd,
|
||||||
"advertise-subnet",
|
"advertise-subnet",
|
||||||
@ -2631,14 +2711,6 @@ DEFUN (bgp_evpn_advertise_vni_subnet,
|
|||||||
if (!bgp_vrf)
|
if (!bgp_vrf)
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
||||||
if (!(advertise_type5_routes(bgp_vrf, AFI_IP)
|
|
||||||
|| advertise_type5_routes(bgp_vrf, AFI_IP6))) {
|
|
||||||
vty_out(vty,
|
|
||||||
"%%Please enable ip prefix advertisement under l2vpn evpn in %s",
|
|
||||||
vrf_id_to_name(bgp_vrf->vrf_id));
|
|
||||||
return CMD_WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
evpn_set_advertise_subnet(bgp, vpn);
|
evpn_set_advertise_subnet(bgp, vpn);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2711,19 +2783,23 @@ DEFUN (bgp_evpn_advertise_type5,
|
|||||||
/* if we are already advertising ipv4 prefix as type-5
|
/* if we are already advertising ipv4 prefix as type-5
|
||||||
* nothing to do
|
* nothing to do
|
||||||
*/
|
*/
|
||||||
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
|
if (!rmap_changed &&
|
||||||
BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
|
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
|
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* if we are already advertising ipv6 prefix as type-5
|
/* if we are already advertising ipv6 prefix as type-5
|
||||||
* nothing to do
|
* nothing to do
|
||||||
*/
|
*/
|
||||||
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
|
if (!rmap_changed &&
|
||||||
BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
|
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
|
SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmap_changed) {
|
if (rmap_changed) {
|
||||||
@ -2766,7 +2842,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
|
|||||||
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
|
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
|
||||||
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
|
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
|
||||||
|
|
||||||
if (!(afi == AFI_IP) || (afi == AFI_IP6)) {
|
if (!(afi == AFI_IP || afi == AFI_IP6)) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"%%only ipv4 or ipv6 address families are supported");
|
"%%only ipv4 or ipv6 address families are supported");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
@ -2780,25 +2856,25 @@ DEFUN (no_bgp_evpn_advertise_type5,
|
|||||||
|
|
||||||
if (afi == AFI_IP) {
|
if (afi == AFI_IP) {
|
||||||
|
|
||||||
/* if we are already advertising ipv4 prefix as type-5
|
/* if we are not advertising ipv4 prefix as type-5
|
||||||
* nothing to do
|
* nothing to do
|
||||||
*/
|
*/
|
||||||
if (CHECK_FLAG(bgp_vrf->vrf_flags,
|
if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
|
||||||
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
|
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
|
||||||
UNSET_FLAG(bgp_vrf->vrf_flags,
|
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* if we are already advertising ipv6 prefix as type-5
|
/* if we are not advertising ipv6 prefix as type-5
|
||||||
* nothing to do
|
* nothing to do
|
||||||
*/
|
*/
|
||||||
if (CHECK_FLAG(bgp_vrf->vrf_flags,
|
if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
|
||||||
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
|
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
|
||||||
UNSET_FLAG(bgp_vrf->vrf_flags,
|
UNSET_FLAG(bgp_vrf->vrf_flags,
|
||||||
BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4305,12 +4381,22 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
if (bgp->advertise_gw_macip)
|
if (bgp->advertise_gw_macip)
|
||||||
vty_out(vty, " advertise-default-gw\n");
|
vty_out(vty, " advertise-default-gw\n");
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
|
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
|
||||||
vty_out(vty, " advertise ipv4 unicast\n");
|
vty_out(vty, " advertise ipv4 unicast\n");
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
|
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
|
||||||
vty_out(vty, " advertise ipv6 unicast\n");
|
vty_out(vty, " advertise ipv6 unicast\n");
|
||||||
|
|
||||||
|
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
|
||||||
|
vty_out(vty, " default-originate ipv4\n");
|
||||||
|
|
||||||
|
if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
|
||||||
|
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
|
||||||
|
vty_out(vty, " default-originate ipv6\n");
|
||||||
|
|
||||||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
|
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
|
||||||
vty_out(vty, " rd %s\n",
|
vty_out(vty, " rd %s\n",
|
||||||
prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
|
prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
|
||||||
@ -4373,6 +4459,8 @@ void bgp_ethernetvpn_init(void)
|
|||||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
|
install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
|
||||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
|
||||||
|
install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
|
||||||
|
install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
|
||||||
|
|
||||||
/* "show bgp l2vpn evpn" commands. */
|
/* "show bgp l2vpn evpn" commands. */
|
||||||
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
|
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
|
||||||
|
@ -2227,12 +2227,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
|||||||
|
|
||||||
/* advertise/withdraw type-5 routes */
|
/* advertise/withdraw type-5 routes */
|
||||||
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
|
||||||
if (new_select
|
if (advertise_type5_routes(bgp, afi) && new_select &&
|
||||||
&& (!new_select->extra || !new_select->extra->parent))
|
(!new_select->extra || !new_select->extra->parent))
|
||||||
bgp_evpn_advertise_type5_route(
|
bgp_evpn_advertise_type5_route(bgp, &rn->p,
|
||||||
bgp, &rn->p, new_select->attr, afi, safi);
|
new_select->attr,
|
||||||
else if (old_select
|
afi, safi);
|
||||||
&& (!old_select->extra || !old_select->extra->parent))
|
else if (advertise_type5_routes(bgp, afi) && old_select &&
|
||||||
|
(!old_select->extra || !old_select->extra->parent))
|
||||||
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
|
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,6 +594,24 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
|
|||||||
route_match_ip_route_source_prefix_list_compile,
|
route_match_ip_route_source_prefix_list_compile,
|
||||||
route_match_ip_route_source_prefix_list_free};
|
route_match_ip_route_source_prefix_list_free};
|
||||||
|
|
||||||
|
/* `match evpn default-route' */
|
||||||
|
|
||||||
|
/* Match function should return 1 if match is success else 0 */
|
||||||
|
static route_map_result_t route_match_evpn_default_route(void *rule,
|
||||||
|
struct prefix *p,
|
||||||
|
route_map_object_t
|
||||||
|
type, void *object)
|
||||||
|
{
|
||||||
|
if (type == RMAP_BGP && is_evpn_prefix_default(p))
|
||||||
|
return RMAP_MATCH;
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route map commands for default-route matching. */
|
||||||
|
struct route_map_rule_cmd route_match_evpn_default_route_cmd = {
|
||||||
|
"evpn default-route", route_match_evpn_default_route, NULL, NULL};
|
||||||
|
|
||||||
/* `match mac address MAC_ACCESS_LIST' */
|
/* `match mac address MAC_ACCESS_LIST' */
|
||||||
|
|
||||||
/* Match function should return 1 if match is success else return
|
/* Match function should return 1 if match is success else return
|
||||||
@ -3249,6 +3267,29 @@ DEFUN (no_match_evpn_vni,
|
|||||||
RMAP_EVENT_MATCH_DELETED);
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (match_evpn_default_route,
|
||||||
|
match_evpn_default_route_cmd,
|
||||||
|
"match evpn default-route",
|
||||||
|
MATCH_STR
|
||||||
|
EVPN_HELP_STR
|
||||||
|
"default EVPN type-5 route\n")
|
||||||
|
{
|
||||||
|
return bgp_route_match_add(vty, "evpn default-route", NULL,
|
||||||
|
RMAP_EVENT_MATCH_ADDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_match_evpn_default_route,
|
||||||
|
no_match_evpn_default_route_cmd,
|
||||||
|
"no match evpn default-route",
|
||||||
|
NO_STR
|
||||||
|
MATCH_STR
|
||||||
|
EVPN_HELP_STR
|
||||||
|
"default EVPN type-5 route\n")
|
||||||
|
{
|
||||||
|
return bgp_route_match_delete(vty, "evpn default-route", NULL,
|
||||||
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (match_peer,
|
DEFUN (match_peer,
|
||||||
match_peer_cmd,
|
match_peer_cmd,
|
||||||
"match peer <A.B.C.D|X:X::X:X|WORD>",
|
"match peer <A.B.C.D|X:X::X:X|WORD>",
|
||||||
@ -4628,6 +4669,7 @@ void bgp_route_map_init(void)
|
|||||||
route_map_install_match(&route_match_mac_address_cmd);
|
route_map_install_match(&route_match_mac_address_cmd);
|
||||||
route_map_install_match(&route_match_evpn_vni_cmd);
|
route_map_install_match(&route_match_evpn_vni_cmd);
|
||||||
route_map_install_match(&route_match_evpn_route_type_cmd);
|
route_map_install_match(&route_match_evpn_route_type_cmd);
|
||||||
|
route_map_install_match(&route_match_evpn_default_route_cmd);
|
||||||
|
|
||||||
route_map_install_set(&route_set_ip_nexthop_cmd);
|
route_map_install_set(&route_set_ip_nexthop_cmd);
|
||||||
route_map_install_set(&route_set_local_pref_cmd);
|
route_map_install_set(&route_set_local_pref_cmd);
|
||||||
@ -4664,6 +4706,8 @@ void bgp_route_map_init(void)
|
|||||||
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
|
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
|
||||||
install_element(RMAP_NODE, &match_evpn_route_type_cmd);
|
install_element(RMAP_NODE, &match_evpn_route_type_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
|
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
|
||||||
|
install_element(RMAP_NODE, &match_evpn_default_route_cmd);
|
||||||
|
install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
|
||||||
|
|
||||||
install_element(RMAP_NODE, &match_aspath_cmd);
|
install_element(RMAP_NODE, &match_aspath_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
install_element(RMAP_NODE, &no_match_aspath_cmd);
|
||||||
|
18
bgpd/bgpd.h
18
bgpd/bgpd.h
@ -312,6 +312,13 @@ struct bgp {
|
|||||||
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
|
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
|
||||||
#define BGP_CONFIG_DAMPENING (1 << 0)
|
#define BGP_CONFIG_DAMPENING (1 << 0)
|
||||||
|
|
||||||
|
/* l2vpn evpn flags - 1 << 0 is used for DAMPENNG */
|
||||||
|
#define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST (1 << 1)
|
||||||
|
#define BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST (1 << 2)
|
||||||
|
#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4 (1 << 3)
|
||||||
|
#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6 (1 << 4)
|
||||||
|
|
||||||
|
|
||||||
/* Route table for next-hop lookup cache. */
|
/* Route table for next-hop lookup cache. */
|
||||||
struct bgp_table *nexthop_cache_table[AFI_MAX];
|
struct bgp_table *nexthop_cache_table[AFI_MAX];
|
||||||
|
|
||||||
@ -423,12 +430,11 @@ struct bgp {
|
|||||||
/* vrf flags */
|
/* vrf flags */
|
||||||
uint32_t vrf_flags;
|
uint32_t vrf_flags;
|
||||||
#define BGP_VRF_AUTO (1 << 0)
|
#define BGP_VRF_AUTO (1 << 0)
|
||||||
#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN (1 << 1)
|
#define BGP_VRF_IMPORT_RT_CFGD (1 << 1)
|
||||||
#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN (1 << 2)
|
#define BGP_VRF_EXPORT_RT_CFGD (1 << 2)
|
||||||
#define BGP_VRF_IMPORT_RT_CFGD (1 << 3)
|
#define BGP_VRF_RD_CFGD (1 << 3)
|
||||||
#define BGP_VRF_EXPORT_RT_CFGD (1 << 4)
|
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 4)
|
||||||
#define BGP_VRF_RD_CFGD (1 << 5)
|
|
||||||
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 6)
|
|
||||||
|
|
||||||
/* unique ID for auto derivation of RD for this vrf */
|
/* unique ID for auto derivation of RD for this vrf */
|
||||||
uint16_t vrf_rd_id;
|
uint16_t vrf_rd_id;
|
||||||
|
11
configure.ac
11
configure.ac
@ -396,6 +396,8 @@ AC_ARG_ENABLE(rpki,
|
|||||||
AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support]))
|
AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support]))
|
||||||
AC_ARG_ENABLE([clippy-only],
|
AC_ARG_ENABLE([clippy-only],
|
||||||
AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
|
AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
|
||||||
|
AC_ARG_ENABLE([numeric_version],
|
||||||
|
AS_HELP_STRING([--enable-numeric-version], [Only numeric digits allowed in version (for Alpine)]))
|
||||||
|
|
||||||
AS_IF([test "${enable_clippy_only}" != "yes"], [
|
AS_IF([test "${enable_clippy_only}" != "yes"], [
|
||||||
AC_CHECK_HEADERS(json-c/json.h)
|
AC_CHECK_HEADERS(json-c/json.h)
|
||||||
@ -647,6 +649,14 @@ AC_DEFINE_UNQUOTED(MULTIPATH_NUM, $MPATH_NUM, Maximum number of paths for a rout
|
|||||||
|
|
||||||
AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use])
|
AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use])
|
||||||
|
|
||||||
|
dnl ------------------------------------
|
||||||
|
dnl Alpine only accepts numeric versions
|
||||||
|
dnl ------------------------------------
|
||||||
|
if test "x${enable_numeric_version}" != "x" ; then
|
||||||
|
VERSION="`echo ${VERSION} | tr -c -d '[[.0-9]]'`"
|
||||||
|
PACKAGE_VERSION="`echo ${PACKAGE_VERSION} | tr -c -d '[[.0-9]]'`"
|
||||||
|
fi
|
||||||
|
|
||||||
dnl -----------------------------------
|
dnl -----------------------------------
|
||||||
dnl Add extra version string to package
|
dnl Add extra version string to package
|
||||||
dnl name, string and version fields.
|
dnl name, string and version fields.
|
||||||
@ -1872,6 +1882,7 @@ AC_CONFIG_FILES([Makefile
|
|||||||
redhat/frr.spec
|
redhat/frr.spec
|
||||||
debianpkg/Makefile
|
debianpkg/Makefile
|
||||||
debianpkg/changelog
|
debianpkg/changelog
|
||||||
|
alpine/APKBUILD
|
||||||
snapcraft/snapcraft.yaml
|
snapcraft/snapcraft.yaml
|
||||||
lib/version.h
|
lib/version.h
|
||||||
tests/lib/cli/test_cli.refout
|
tests/lib/cli/test_cli.refout
|
||||||
|
@ -109,6 +109,10 @@ of grammar sandbox.
|
|||||||
Turn on some compile options to allow you to run fuzzing tools
|
Turn on some compile options to allow you to run fuzzing tools
|
||||||
against the system. This tools is intended as a developer
|
against the system. This tools is intended as a developer
|
||||||
only tool and should not be used for normal operations
|
only tool and should not be used for normal operations
|
||||||
|
@item --enable-numeric-version
|
||||||
|
Alpine Linux does not allow non-numeric characters in the version
|
||||||
|
string. With this option, we provide a way to strip out these
|
||||||
|
characters for apk dev package builds.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
You may specify any combination of the above options to the configure
|
You may specify any combination of the above options to the configure
|
||||||
|
1
ldpd/.gitignore
vendored
1
ldpd/.gitignore
vendored
@ -15,4 +15,3 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
ldp_vty_cmds_clippy.c
|
|
||||||
|
1
lib/.gitignore
vendored
1
lib/.gitignore
vendored
@ -24,4 +24,3 @@ refix
|
|||||||
grammar_sandbox
|
grammar_sandbox
|
||||||
clippy
|
clippy
|
||||||
defun_lex.c
|
defun_lex.c
|
||||||
plist_clippy.c
|
|
||||||
|
92
lib/debug.h
92
lib/debug.h
@ -104,76 +104,77 @@ struct debug_callbacks {
|
|||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_MODE_CHECK(name, type) \
|
#define DEBUG_MODE_CHECK(name, mode) \
|
||||||
CHECK_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
|
CHECK_FLAG_ATOMIC(&(name)->flags, (mode)&DEBUG_MODE_ALL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if an option bit is set for a debug.
|
* Check if an option bit is set for a debug.
|
||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_OPT_CHECK(name, type) \
|
#define DEBUG_OPT_CHECK(name, opt) \
|
||||||
CHECK_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
|
CHECK_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if bits are set for a debug.
|
* Check if bits are set for a debug.
|
||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_FLAGS_CHECK(name, type) CHECK_FLAG_ATOMIC(&(name)->flags, (type))
|
#define DEBUG_FLAGS_CHECK(name, fl) CHECK_FLAG_ATOMIC(&(name)->flags, (fl))
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if any mode is on for a debug.
|
|
||||||
*
|
|
||||||
* MT-Safe
|
|
||||||
*/
|
|
||||||
#define DEBUG(name) DEBUG_MODE_CHECK((name), DEBUG_MODE_ALL)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set modes on a debug.
|
* Set modes on a debug.
|
||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_MODE_SET(name, type) \
|
#define DEBUG_MODE_SET(name, mode, onoff) \
|
||||||
SET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
|
do { \
|
||||||
|
if (onoff) \
|
||||||
|
SET_FLAG_ATOMIC(&(name)->flags, \
|
||||||
|
(mode)&DEBUG_MODE_ALL); \
|
||||||
|
else \
|
||||||
|
UNSET_FLAG_ATOMIC(&(name)->flags, \
|
||||||
|
(mode)&DEBUG_MODE_ALL); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/* Convenience macros for specific set operations. */
|
||||||
* Unset modes on a debug.
|
#define DEBUG_MODE_ON(name, mode) DEBUG_MODE_SET(name, mode, true)
|
||||||
*
|
#define DEBUG_MODE_OFF(name, mode) DEBUG_MODE_SET(name, mode, false)
|
||||||
* MT-Safe
|
|
||||||
*/
|
|
||||||
#define DEBUG_MODE_UNSET(name, type) \
|
|
||||||
UNSET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set options on a debug.
|
* Set options on a debug.
|
||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_OPT_SET(name, type) \
|
#define DEBUG_OPT_SET(name, opt, onoff) \
|
||||||
SET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
|
do { \
|
||||||
|
if (onoff) \
|
||||||
|
SET_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL); \
|
||||||
|
else \
|
||||||
|
UNSET_FLAG_ATOMIC(&(name)->flags, \
|
||||||
|
(opt)&DEBUG_OPT_ALL); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/* Convenience macros for specific set operations. */
|
||||||
* Unset options on a debug.
|
#define DEBUG_OPT_ON(name, opt) DEBUG_OPT_SET(name, opt, true)
|
||||||
*
|
#define DEBUG_OPT_OFF(name, opt) DEBUG_OPT_SET(name, opt, true)
|
||||||
* MT-Safe
|
|
||||||
*/
|
|
||||||
#define DEBUG_OPT_UNSET(name, type) \
|
|
||||||
UNSET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set bits on a debug.
|
* Set bits on a debug.
|
||||||
*
|
*
|
||||||
* MT-Safe
|
* MT-Safe
|
||||||
*/
|
*/
|
||||||
#define DEBUG_FLAGS_SET(name, type) SET_FLAG_ATOMIC(&(name)->flags, (type))
|
#define DEBUG_FLAGS_SET(name, fl, onoff) \
|
||||||
|
do { \
|
||||||
|
if (onoff) \
|
||||||
|
SET_FLAG_ATOMIC(&(name)->flags, (fl)); \
|
||||||
|
else \
|
||||||
|
UNSET_FLAG_ATOMIC(&(name)->flags, (fl)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*
|
/* Convenience macros for specific set operations. */
|
||||||
* Unset bits on a debug.
|
#define DEBUG_FLAGS_ON(name, fl) DEBUG_FLAGS_SET(&(name)->flags, (type), true)
|
||||||
*
|
#define DEBUG_FLAGS_OFF(name, fl) DEBUG_FLAGS_SET(&(name)->flags, (type), false)
|
||||||
* MT-Safe
|
|
||||||
*/
|
|
||||||
#define DEBUG_FLAGS_UNSET(name, type) UNSET_FLAG_ATOMIC(&(name)->flags, (type))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unset all modes and options on a debug.
|
* Unset all modes and options on a debug.
|
||||||
@ -201,6 +202,23 @@ struct debug_callbacks {
|
|||||||
#define DEBUG_NODE2MODE(vtynode) \
|
#define DEBUG_NODE2MODE(vtynode) \
|
||||||
(((vtynode) == CONFIG_NODE) ? DEBUG_MODE_ALL : DEBUG_MODE_TERM)
|
(((vtynode) == CONFIG_NODE) ? DEBUG_MODE_ALL : DEBUG_MODE_TERM)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug at the given level to the default logging destination.
|
||||||
|
*
|
||||||
|
* MT-Safe
|
||||||
|
*/
|
||||||
|
#define DEBUG(level, name, fmt, ...) \
|
||||||
|
do { \
|
||||||
|
if (DEBUG_MODE_CHECK(name, DEBUG_MODE_ALL)) \
|
||||||
|
zlog_##level(fmt, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Convenience macros for the various levels. */
|
||||||
|
#define DEBUGE(name, fmt, ...) DEBUG(err, name, fmt, ##__VA_ARGS__)
|
||||||
|
#define DEBUGW(name, fmt, ...) DEBUG(warn, name, fmt, ##__VA_ARGS__)
|
||||||
|
#define DEBUGI(name, fmt, ...) DEBUG(info, name, fmt, ##__VA_ARGS__)
|
||||||
|
#define DEBUGN(name, fmt, ...) DEBUG(notice, name, fmt, ##__VA_ARGS__)
|
||||||
|
#define DEBUGD(name, fmt, ...) DEBUG(debug, name, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optional initializer for debugging. Highly recommended.
|
* Optional initializer for debugging. Highly recommended.
|
||||||
|
17
lib/ipaddr.h
17
lib/ipaddr.h
@ -85,4 +85,21 @@ static inline char *ipaddr2str(struct ipaddr *ip, char *buf, int size)
|
|||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert IPv4 address to IPv4-mapped IPv6 address which is of the
|
||||||
|
* form ::FFFF:<IPv4 address> (RFC 4291). This IPv6 address can then
|
||||||
|
* be used to represent the IPv4 address, wherever only an IPv6 address
|
||||||
|
* is required.
|
||||||
|
*/
|
||||||
|
static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6,
|
||||||
|
struct in_addr in)
|
||||||
|
{
|
||||||
|
u_int32_t addr_type = htonl(0xFFFF);
|
||||||
|
|
||||||
|
memset(in6, 0, sizeof(struct in6_addr));
|
||||||
|
memcpy((char *)in6 + 8, &addr_type, sizeof(addr_type));
|
||||||
|
memcpy((char *)in6 + 12, &in, sizeof(struct in_addr));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __IPADDR_H__ */
|
#endif /* __IPADDR_H__ */
|
||||||
|
43
lib/log.c
43
lib/log.c
@ -1092,41 +1092,52 @@ void zlog_hexdump(const void *mem, unsigned int len)
|
|||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
unsigned int columns = 8;
|
unsigned int columns = 8;
|
||||||
char buf[(len * 4) + ((len / 4) * 20) + 30];
|
/*
|
||||||
|
* 19 bytes for 0xADDRESS:
|
||||||
|
* 24 bytes for data; 2 chars plus a space per data byte
|
||||||
|
* 1 byte for space
|
||||||
|
* 8 bytes for ASCII representation
|
||||||
|
* 1 byte for a newline
|
||||||
|
* =====================
|
||||||
|
* 53 bytes per 8 bytes of data
|
||||||
|
* 1 byte for null term
|
||||||
|
*/
|
||||||
|
size_t bs = ((len / 8) + 1) * 53 + 1;
|
||||||
|
char buf[bs];
|
||||||
char *s = buf;
|
char *s = buf;
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0);
|
for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0);
|
||||||
i++) {
|
i++) {
|
||||||
/* print offset */
|
/* print offset */
|
||||||
if (i % columns == 0)
|
if (i % columns == 0)
|
||||||
s += sprintf(s, "0x%016lx: ", (unsigned long)mem + i);
|
s += snprintf(s, bs - (s - buf),
|
||||||
|
"0x%016lx: ", (unsigned long)mem + i);
|
||||||
|
|
||||||
/* print hex data */
|
/* print hex data */
|
||||||
if (i < len)
|
if (i < len)
|
||||||
s += sprintf(s, "%02x ", 0xFF & ((const char *)mem)[i]);
|
s += snprintf(s, bs - (s - buf), "%02x ",
|
||||||
|
0xFF & ((const char *)mem)[i]);
|
||||||
|
|
||||||
/* end of block, just aligning for ASCII dump */
|
/* end of block, just aligning for ASCII dump */
|
||||||
else
|
else
|
||||||
s += sprintf(s, " ");
|
s += snprintf(s, bs - (s - buf), " ");
|
||||||
|
|
||||||
/* print ASCII dump */
|
/* print ASCII dump */
|
||||||
if (i % columns == (columns - 1)) {
|
if (i % columns == (columns - 1)) {
|
||||||
for (j = i - (columns - 1); j <= i; j++) {
|
for (j = i - (columns - 1); j <= i; j++) {
|
||||||
if (j >= len) /* end of block, not really
|
/* end of block not really printing */
|
||||||
printing */
|
if (j >= len)
|
||||||
s += sprintf(s, " ");
|
s += snprintf(s, bs - (s - buf), " ");
|
||||||
|
else if (isprint((int)((const char *)mem)[j]))
|
||||||
else if (isprint((int)((const char *)mem)
|
s += snprintf(
|
||||||
[j])) /* printable char
|
s, bs - (s - buf), "%c",
|
||||||
*/
|
|
||||||
s += sprintf(
|
|
||||||
s, "%c",
|
|
||||||
0xFF & ((const char *)mem)[j]);
|
0xFF & ((const char *)mem)[j]);
|
||||||
|
|
||||||
else /* other char */
|
else /* other char */
|
||||||
s += sprintf(s, ".");
|
s += snprintf(s, bs - (s - buf), ".");
|
||||||
}
|
}
|
||||||
s += sprintf(s, "\n");
|
s += snprintf(s, bs - (s - buf), "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zlog_debug("\n%s", buf);
|
zlog_debug("\n%s", buf);
|
||||||
|
@ -322,6 +322,18 @@ stream_failure:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
|
||||||
|
{
|
||||||
|
STREAM_GETW(zmsg, hdr->length);
|
||||||
|
STREAM_GETC(zmsg, hdr->marker);
|
||||||
|
STREAM_GETC(zmsg, hdr->version);
|
||||||
|
STREAM_GETL(zmsg, hdr->vrf_id);
|
||||||
|
STREAM_GETW(zmsg, hdr->command);
|
||||||
|
return true;
|
||||||
|
stream_failure:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send simple Zebra message. */
|
/* Send simple Zebra message. */
|
||||||
static int zebra_message_send(struct zclient *zclient, int command,
|
static int zebra_message_send(struct zclient *zclient, int command,
|
||||||
vrf_id_t vrf_id)
|
vrf_id_t vrf_id)
|
||||||
|
@ -237,14 +237,13 @@ struct zclient {
|
|||||||
*/
|
*/
|
||||||
#define ZAPI_MESSAGE_TABLEID 0x80
|
#define ZAPI_MESSAGE_TABLEID 0x80
|
||||||
|
|
||||||
/* Zserv protocol message header */
|
|
||||||
struct zserv_header {
|
|
||||||
uint16_t length;
|
|
||||||
uint8_t marker; /* corresponds to command field in old zserv
|
|
||||||
* always set to 255 in new zserv.
|
|
||||||
*/
|
|
||||||
uint8_t version;
|
|
||||||
#define ZSERV_VERSION 5
|
#define ZSERV_VERSION 5
|
||||||
|
/* Zserv protocol message header */
|
||||||
|
struct zmsghdr {
|
||||||
|
uint16_t length;
|
||||||
|
/* Always set to 255 in new zserv */
|
||||||
|
uint8_t marker;
|
||||||
|
uint8_t version;
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
uint16_t command;
|
uint16_t command;
|
||||||
};
|
};
|
||||||
@ -380,9 +379,11 @@ struct zclient_options {
|
|||||||
/* Prototypes of zebra client service functions. */
|
/* Prototypes of zebra client service functions. */
|
||||||
extern struct zclient *zclient_new(struct thread_master *);
|
extern struct zclient *zclient_new(struct thread_master *);
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
#if CONFDATE > 20181101
|
#if CONFDATE > 20181101
|
||||||
CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
|
CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
|
||||||
#endif
|
#endif
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
extern struct zclient_options zclient_options_default;
|
extern struct zclient_options zclient_options_default;
|
||||||
|
|
||||||
@ -449,9 +450,58 @@ extern int zclient_send_message(struct zclient *);
|
|||||||
|
|
||||||
/* create header for command, length to be filled in by user later */
|
/* create header for command, length to be filled in by user later */
|
||||||
extern void zclient_create_header(struct stream *, uint16_t, vrf_id_t);
|
extern void zclient_create_header(struct stream *, uint16_t, vrf_id_t);
|
||||||
|
/*
|
||||||
|
* Read sizeof(struct zmsghdr) bytes from the provided socket and parse the
|
||||||
|
* received data into the specified fields. If this is successful, read the
|
||||||
|
* rest of the packet into the provided stream.
|
||||||
|
*
|
||||||
|
* s
|
||||||
|
* The stream to read into
|
||||||
|
*
|
||||||
|
* sock
|
||||||
|
* The socket to read from
|
||||||
|
*
|
||||||
|
* size
|
||||||
|
* Parsed message size will be placed in the pointed-at integer
|
||||||
|
*
|
||||||
|
* marker
|
||||||
|
* Parsed marker will be placed in the pointed-at byte
|
||||||
|
*
|
||||||
|
* version
|
||||||
|
* Parsed version will be placed in the pointed-at byte
|
||||||
|
*
|
||||||
|
* vrf_id
|
||||||
|
* Parsed VRF ID will be placed in the pointed-at vrf_id_t
|
||||||
|
*
|
||||||
|
* cmd
|
||||||
|
* Parsed command number will be placed in the pointed-at integer
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* -1 if:
|
||||||
|
* - insufficient data for header was read
|
||||||
|
* - a version mismatch was detected
|
||||||
|
* - a marker mismatch was detected
|
||||||
|
* - header size field specified more data than could be read
|
||||||
|
*/
|
||||||
extern int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
|
extern int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
|
||||||
u_char *marker, u_char *version,
|
u_char *marker, u_char *version,
|
||||||
vrf_id_t *vrf_id, u_int16_t *cmd);
|
vrf_id_t *vrf_id, u_int16_t *cmd);
|
||||||
|
/*
|
||||||
|
* Parse header from ZAPI message stream into struct zmsghdr.
|
||||||
|
* This function assumes the stream getp points at the first byte of the header.
|
||||||
|
* If the function is successful then the stream getp will point to the byte
|
||||||
|
* immediately after the last byte of the header.
|
||||||
|
*
|
||||||
|
* zmsg
|
||||||
|
* The stream containing the header
|
||||||
|
*
|
||||||
|
* hdr
|
||||||
|
* The header struct to parse into.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* true if parsing succeeded, false otherwise
|
||||||
|
*/
|
||||||
|
extern bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr);
|
||||||
|
|
||||||
extern void zclient_interface_set_master(struct zclient *client,
|
extern void zclient_interface_set_master(struct zclient *client,
|
||||||
struct interface *master,
|
struct interface *master,
|
||||||
@ -468,10 +518,11 @@ extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
|
|||||||
extern void zebra_interface_if_set_value(struct stream *, struct interface *);
|
extern void zebra_interface_if_set_value(struct stream *, struct interface *);
|
||||||
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
|
extern void zebra_router_id_update_read(struct stream *s, struct prefix *rid);
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
#if CONFDATE > 20180823
|
#if CONFDATE > 20180823
|
||||||
CPP_NOTICE(
|
CPP_NOTICE("zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now");
|
||||||
"zapi_ipv4_route, zapi_ipv6_route, zapi_ipv4_route_ipv6_nexthop as well as the zapi_ipv4 and zapi_ipv6 data structures should be removed now");
|
|
||||||
#endif
|
#endif
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *,
|
extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *,
|
||||||
struct zapi_ipv4 *) __attribute__((deprecated));
|
struct zapi_ipv4 *) __attribute__((deprecated));
|
||||||
|
1
ospfd/.gitignore
vendored
1
ospfd/.gitignore
vendored
@ -15,4 +15,3 @@ TAGS
|
|||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
*.a
|
*.a
|
||||||
*clippy.c
|
|
||||||
|
@ -604,11 +604,18 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
|
|||||||
json_object_object_add(json, ifp->name,
|
json_object_object_add(json, ifp->name,
|
||||||
json_row);
|
json_row);
|
||||||
|
|
||||||
|
if (igmp->mtrace_only) {
|
||||||
|
json_object_boolean_true_add(
|
||||||
|
json_row, "mtraceOnly");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"%-9s %5s %15s %d %7s %11s %8s\n",
|
"%-9s %5s %15s %d %7s %11s %8s\n",
|
||||||
ifp->name,
|
ifp->name,
|
||||||
if_is_up(ifp) ? "up" : "down",
|
if_is_up(ifp)
|
||||||
|
? (igmp->mtrace_only ? "mtrc"
|
||||||
|
: "up")
|
||||||
|
: "down",
|
||||||
inet_ntoa(igmp->ifaddr),
|
inet_ntoa(igmp->ifaddr),
|
||||||
pim_ifp->igmp_version,
|
pim_ifp->igmp_version,
|
||||||
igmp->t_igmp_query_timer ? "local"
|
igmp->t_igmp_query_timer ? "local"
|
||||||
@ -758,10 +765,17 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
|
|||||||
json_object_object_add(json, ifp->name,
|
json_object_object_add(json, ifp->name,
|
||||||
json_row);
|
json_row);
|
||||||
|
|
||||||
|
if (igmp->mtrace_only) {
|
||||||
|
json_object_boolean_true_add(
|
||||||
|
json_row, "mtraceOnly");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty, "Interface : %s\n", ifp->name);
|
vty_out(vty, "Interface : %s\n", ifp->name);
|
||||||
vty_out(vty, "State : %s\n",
|
vty_out(vty, "State : %s\n",
|
||||||
if_is_up(ifp) ? "up" : "down");
|
if_is_up(ifp)
|
||||||
|
? (igmp->mtrace_only ? "mtrace"
|
||||||
|
: "up")
|
||||||
|
: "down");
|
||||||
vty_out(vty, "Address : %s\n",
|
vty_out(vty, "Address : %s\n",
|
||||||
inet_ntoa(pim_ifp->primary_address));
|
inet_ntoa(pim_ifp->primary_address));
|
||||||
vty_out(vty, "Uptime : %s\n", uptime);
|
vty_out(vty, "Uptime : %s\n", uptime);
|
||||||
|
@ -574,7 +574,11 @@ void pim_if_addr_add(struct connected *ifc)
|
|||||||
/* if addr new, add IGMP socket */
|
/* if addr new, add IGMP socket */
|
||||||
if (ifc->address->family == AF_INET)
|
if (ifc->address->family == AF_INET)
|
||||||
pim_igmp_sock_add(pim_ifp->igmp_socket_list,
|
pim_igmp_sock_add(pim_ifp->igmp_socket_list,
|
||||||
ifaddr, ifp);
|
ifaddr, ifp, false);
|
||||||
|
} else if (igmp->mtrace_only) {
|
||||||
|
igmp_sock_delete(igmp);
|
||||||
|
pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr,
|
||||||
|
ifp, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replay Static IGMP groups */
|
/* Replay Static IGMP groups */
|
||||||
@ -611,6 +615,20 @@ void pim_if_addr_add(struct connected *ifc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* igmp */
|
} /* igmp */
|
||||||
|
else {
|
||||||
|
struct igmp_sock *igmp;
|
||||||
|
|
||||||
|
/* lookup IGMP socket */
|
||||||
|
igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
|
||||||
|
ifaddr);
|
||||||
|
if (ifc->address->family == AF_INET) {
|
||||||
|
if (igmp)
|
||||||
|
igmp_sock_delete(igmp);
|
||||||
|
/* if addr new, add IGMP socket */
|
||||||
|
pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr,
|
||||||
|
ifp, true);
|
||||||
|
}
|
||||||
|
} /* igmp mtrace only */
|
||||||
|
|
||||||
if (PIM_IF_TEST_PIM(pim_ifp->options)) {
|
if (PIM_IF_TEST_PIM(pim_ifp->options)) {
|
||||||
|
|
||||||
|
@ -281,6 +281,9 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
|
|||||||
uint16_t recv_checksum;
|
uint16_t recv_checksum;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
|
||||||
|
if (igmp->mtrace_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
|
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
|
||||||
|
|
||||||
ifp = igmp->interface;
|
ifp = igmp->interface;
|
||||||
@ -387,6 +390,9 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from,
|
|||||||
|
|
||||||
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
||||||
|
|
||||||
|
if (igmp->mtrace_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"Recv IGMP report v1 from %s on %s: size=%d other than correct=%d",
|
"Recv IGMP report v1 from %s on %s: size=%d other than correct=%d",
|
||||||
@ -510,7 +516,6 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
|
|||||||
return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src,
|
return igmp_mtrace_recv_response(igmp, ip_hdr, ip_hdr->ip_src,
|
||||||
from_str, igmp_msg,
|
from_str, igmp_msg,
|
||||||
igmp_msg_len);
|
igmp_msg_len);
|
||||||
break;
|
|
||||||
case PIM_IGMP_MTRACE_QUERY_REQUEST:
|
case PIM_IGMP_MTRACE_QUERY_REQUEST:
|
||||||
return igmp_mtrace_recv_qry_req(igmp, ip_hdr, ip_hdr->ip_src,
|
return igmp_mtrace_recv_qry_req(igmp, ip_hdr, ip_hdr->ip_src,
|
||||||
from_str, igmp_msg,
|
from_str, igmp_msg,
|
||||||
@ -819,7 +824,7 @@ static int igmp_group_hash_equal(const void *arg1, const void *arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
|
static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
|
||||||
struct interface *ifp)
|
struct interface *ifp, int mtrace_only)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
struct igmp_sock *igmp;
|
struct igmp_sock *igmp;
|
||||||
@ -862,6 +867,13 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
|
|||||||
pim_ifp->igmp_default_robustness_variable;
|
pim_ifp->igmp_default_robustness_variable;
|
||||||
igmp->sock_creation = pim_time_monotonic_sec();
|
igmp->sock_creation = pim_time_monotonic_sec();
|
||||||
|
|
||||||
|
if (mtrace_only) {
|
||||||
|
igmp->mtrace_only = mtrace_only;
|
||||||
|
return igmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
igmp->mtrace_only = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
igmp_startup_mode_on() will reset QQI:
|
igmp_startup_mode_on() will reset QQI:
|
||||||
|
|
||||||
@ -919,7 +931,8 @@ static void igmp_read_on(struct igmp_sock *igmp)
|
|||||||
|
|
||||||
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
|
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
|
||||||
struct in_addr ifaddr,
|
struct in_addr ifaddr,
|
||||||
struct interface *ifp)
|
struct interface *ifp,
|
||||||
|
bool mtrace_only)
|
||||||
{
|
{
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
struct igmp_sock *igmp;
|
struct igmp_sock *igmp;
|
||||||
@ -934,7 +947,7 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
igmp = igmp_sock_new(fd, ifaddr, ifp);
|
igmp = igmp_sock_new(fd, ifaddr, ifp, mtrace_only);
|
||||||
if (!igmp) {
|
if (!igmp) {
|
||||||
zlog_err("%s %s: igmp_sock_new() failure", __FILE__,
|
zlog_err("%s %s: igmp_sock_new() failure", __FILE__,
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
|
@ -90,6 +90,8 @@ struct igmp_sock {
|
|||||||
int querier_robustness_variable; /* QRV */
|
int querier_robustness_variable; /* QRV */
|
||||||
int startup_query_count;
|
int startup_query_count;
|
||||||
|
|
||||||
|
bool mtrace_only;
|
||||||
|
|
||||||
struct list *igmp_group_list; /* list of struct igmp_group */
|
struct list *igmp_group_list; /* list of struct igmp_group */
|
||||||
struct hash *igmp_group_hash;
|
struct hash *igmp_group_hash;
|
||||||
};
|
};
|
||||||
@ -99,7 +101,8 @@ struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
|
|||||||
struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd);
|
struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd);
|
||||||
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
|
struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
|
||||||
struct in_addr ifaddr,
|
struct in_addr ifaddr,
|
||||||
struct interface *ifp);
|
struct interface *ifp,
|
||||||
|
bool mtrace_only);
|
||||||
void igmp_sock_delete(struct igmp_sock *igmp);
|
void igmp_sock_delete(struct igmp_sock *igmp);
|
||||||
void igmp_sock_free(struct igmp_sock *igmp);
|
void igmp_sock_free(struct igmp_sock *igmp);
|
||||||
void igmp_sock_delete_all(struct interface *ifp);
|
void igmp_sock_delete_all(struct interface *ifp);
|
||||||
|
@ -111,6 +111,9 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
|
|||||||
|
|
||||||
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
||||||
|
|
||||||
|
if (igmp->mtrace_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d",
|
"Recv IGMPv2 REPORT from %s on %s: size=%d other than correct=%d",
|
||||||
@ -154,6 +157,9 @@ int igmp_v2_recv_leave(struct igmp_sock *igmp, struct in_addr from,
|
|||||||
|
|
||||||
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
|
||||||
|
|
||||||
|
if (igmp->mtrace_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",
|
"Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",
|
||||||
|
@ -1874,6 +1874,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
|
|||||||
int local_ncb = 0;
|
int local_ncb = 0;
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
|
|
||||||
|
if (igmp->mtrace_only)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pim_ifp = igmp->interface->info;
|
pim_ifp = igmp->interface->info;
|
||||||
|
|
||||||
if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
|
if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
|
||||||
|
1
sharpd/.gitignore
vendored
1
sharpd/.gitignore
vendored
@ -13,6 +13,5 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
*clippy.c
|
|
||||||
sharpd
|
sharpd
|
||||||
sharpd.conf
|
sharpd.conf
|
||||||
|
@ -73,6 +73,7 @@ check_PROGRAMS = \
|
|||||||
lib/test_timer_correctness \
|
lib/test_timer_correctness \
|
||||||
lib/test_timer_performance \
|
lib/test_timer_performance \
|
||||||
lib/test_ttable \
|
lib/test_ttable \
|
||||||
|
lib/test_zlog \
|
||||||
lib/cli/test_cli \
|
lib/cli/test_cli \
|
||||||
lib/cli/test_commands \
|
lib/cli/test_commands \
|
||||||
$(TESTS_BGPD) \
|
$(TESTS_BGPD) \
|
||||||
@ -115,9 +116,9 @@ lib_test_heavy_SOURCES = lib/test_heavy.c helpers/c/main.c
|
|||||||
lib_test_memory_SOURCES = lib/test_memory.c
|
lib_test_memory_SOURCES = lib/test_memory.c
|
||||||
lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c
|
lib_test_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.c
|
||||||
lib_test_privs_SOURCES = lib/test_privs.c
|
lib_test_privs_SOURCES = lib/test_privs.c
|
||||||
|
lib_test_ringbuf_SOURCES = lib/test_ringbuf.c
|
||||||
lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \
|
lib_test_srcdest_table_SOURCES = lib/test_srcdest_table.c \
|
||||||
helpers/c/prng.c
|
helpers/c/prng.c
|
||||||
lib_test_ringbuf_SOURCES = lib/test_ringbuf.c
|
|
||||||
lib_test_segv_SOURCES = lib/test_segv.c
|
lib_test_segv_SOURCES = lib/test_segv.c
|
||||||
lib_test_sig_SOURCES = lib/test_sig.c
|
lib_test_sig_SOURCES = lib/test_sig.c
|
||||||
lib_test_stream_SOURCES = lib/test_stream.c
|
lib_test_stream_SOURCES = lib/test_stream.c
|
||||||
@ -127,6 +128,7 @@ lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \
|
|||||||
lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \
|
lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \
|
||||||
helpers/c/prng.c
|
helpers/c/prng.c
|
||||||
lib_test_ttable_SOURCES = lib/test_ttable.c
|
lib_test_ttable_SOURCES = lib/test_ttable.c
|
||||||
|
lib_test_zlog_SOURCES = lib/test_zlog.c
|
||||||
lib_test_zmq_SOURCES = lib/test_zmq.c
|
lib_test_zmq_SOURCES = lib/test_zmq.c
|
||||||
lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS)
|
lib_test_zmq_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS)
|
||||||
lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c
|
lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c
|
||||||
@ -167,6 +169,7 @@ lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm
|
|||||||
lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
|
lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD)
|
||||||
lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
|
lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD)
|
||||||
lib_test_ttable_LDADD = $(ALL_TESTS_LDADD)
|
lib_test_ttable_LDADD = $(ALL_TESTS_LDADD)
|
||||||
|
lib_test_zlog_LDADD = $(ALL_TESTS_LDADD)
|
||||||
lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS)
|
lib_test_zmq_LDADD = ../lib/libfrrzmq.la $(ALL_TESTS_LDADD) $(ZEROMQ_LIBS)
|
||||||
lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
|
lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD)
|
||||||
lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
|
lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD)
|
||||||
@ -207,6 +210,7 @@ EXTRA_DIST = \
|
|||||||
lib/test_timer_correctness.py \
|
lib/test_timer_correctness.py \
|
||||||
lib/test_ttable.py \
|
lib/test_ttable.py \
|
||||||
lib/test_ttable.refout \
|
lib/test_ttable.refout \
|
||||||
|
lib/test_zlog.py \
|
||||||
ospf6d/test_lsdb.py \
|
ospf6d/test_lsdb.py \
|
||||||
ospf6d/test_lsdb.in \
|
ospf6d/test_lsdb.in \
|
||||||
ospf6d/test_lsdb.refout \
|
ospf6d/test_lsdb.refout \
|
||||||
|
61
tests/lib/test_zlog.c
Normal file
61
tests/lib/test_zlog.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Zlog tests.
|
||||||
|
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||||
|
* Quentin Young
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; see the file COPYING; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
#include <zebra.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/* maximum amount of data to hexdump */
|
||||||
|
#define MAXDATA 16384
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test hexdump functionality.
|
||||||
|
*
|
||||||
|
* At the moment, not crashing is considered success.
|
||||||
|
*/
|
||||||
|
static bool test_zlog_hexdump(void)
|
||||||
|
{
|
||||||
|
unsigned int nl = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
long d[nl];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < nl; i++)
|
||||||
|
d[i] = random();
|
||||||
|
zlog_hexdump(d, nl * sizeof(long));
|
||||||
|
} while (++nl * sizeof(long) <= MAXDATA);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool (*tests[])(void) = {
|
||||||
|
test_zlog_hexdump,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
openzlog("testzlog", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID,
|
||||||
|
LOG_ERR);
|
||||||
|
zlog_set_file("test_zlog.log", LOG_DEBUG);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < array_size(tests); i++)
|
||||||
|
if (!tests[i]())
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
4
tests/lib/test_zlog.py
Normal file
4
tests/lib/test_zlog.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import frrtest
|
||||||
|
|
||||||
|
class TestZlog(frrtest.TestMultiOut):
|
||||||
|
program = './test_zlog'
|
1
zebra/.gitignore
vendored
1
zebra/.gitignore
vendored
@ -13,4 +13,3 @@ TAGS
|
|||||||
.arch-ids
|
.arch-ids
|
||||||
*~
|
*~
|
||||||
*.loT
|
*.loT
|
||||||
zebra_vty_clippy.c
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
#define _LINUX_IN6_H
|
#define _LINUX_IN6_H
|
||||||
|
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
#include <linux/if_bridge.h>
|
#include <linux/if_bridge.h>
|
||||||
#include <linux/if_link.h>
|
#include <linux/if_link.h>
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
@ -362,7 +363,7 @@ static int get_iflink_speed(struct interface *interface)
|
|||||||
/* initialize ethtool interface */
|
/* initialize ethtool interface */
|
||||||
memset(&ecmd, 0, sizeof(ecmd));
|
memset(&ecmd, 0, sizeof(ecmd));
|
||||||
ecmd.cmd = ETHTOOL_GSET; /* ETHTOOL_GLINK */
|
ecmd.cmd = ETHTOOL_GSET; /* ETHTOOL_GLINK */
|
||||||
ifdata.ifr_data = (__caddr_t)&ecmd;
|
ifdata.ifr_data = (caddr_t)&ecmd;
|
||||||
|
|
||||||
/* use ioctl to get IP address of an interface */
|
/* use ioctl to get IP address of an interface */
|
||||||
if (zserv_privs.change(ZPRIVS_RAISE))
|
if (zserv_privs.change(ZPRIVS_RAISE))
|
||||||
|
@ -50,6 +50,8 @@ DEFINE_MTYPE_STATIC(LBL_MGR, LM_CHUNK, "Label Manager Chunk");
|
|||||||
* it will be a proxy to relay messages to external label manager
|
* it will be a proxy to relay messages to external label manager
|
||||||
* This zclient thus is to connect to it
|
* This zclient thus is to connect to it
|
||||||
*/
|
*/
|
||||||
|
static struct stream *ibuf;
|
||||||
|
static struct stream *obuf;
|
||||||
static struct zclient *zclient;
|
static struct zclient *zclient;
|
||||||
bool lm_is_external;
|
bool lm_is_external;
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ static int relay_response_back(struct zserv *zserv)
|
|||||||
u_int16_t resp_cmd;
|
u_int16_t resp_cmd;
|
||||||
|
|
||||||
src = zclient->ibuf;
|
src = zclient->ibuf;
|
||||||
dst = zserv->obuf;
|
dst = obuf;
|
||||||
|
|
||||||
stream_reset(src);
|
stream_reset(src);
|
||||||
|
|
||||||
@ -87,7 +89,7 @@ static int relay_response_back(struct zserv *zserv)
|
|||||||
|
|
||||||
/* send response back */
|
/* send response back */
|
||||||
stream_copy(dst, src);
|
stream_copy(dst, src);
|
||||||
ret = writen(zserv->sock, dst->data, stream_get_endp(dst));
|
ret = writen(zserv->sock, src->data, stream_get_endp(src));
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
zlog_err("%s: Error sending Label Manager response back: %s",
|
zlog_err("%s: Error sending Label Manager response back: %s",
|
||||||
__func__, strerror(errno));
|
__func__, strerror(errno));
|
||||||
@ -116,10 +118,10 @@ static int lm_zclient_read(struct thread *t)
|
|||||||
|
|
||||||
static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
|
static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
|
|
||||||
s = zserv->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, vrf_id);
|
zclient_create_header(s, cmd, vrf_id);
|
||||||
|
|
||||||
@ -129,7 +131,10 @@ static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id)
|
|||||||
/* Write packet size. */
|
/* Write packet size. */
|
||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
return writen(zserv->sock, s->data, stream_get_endp(s));
|
ret = writen(zserv->sock, s->data, stream_get_endp(s));
|
||||||
|
|
||||||
|
stream_free(s);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Receive a request to get or release a label chunk and forward it to external
|
* Receive a request to get or release a label chunk and forward it to external
|
||||||
@ -161,7 +166,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv,
|
|||||||
ret = relay_response_back(zserv);
|
ret = relay_response_back(zserv);
|
||||||
|
|
||||||
/* Send request to external label manager */
|
/* Send request to external label manager */
|
||||||
src = zserv->ibuf;
|
src = ibuf;
|
||||||
dst = zclient->obuf;
|
dst = zclient->obuf;
|
||||||
|
|
||||||
stream_copy(dst, src);
|
stream_copy(dst, src);
|
||||||
@ -247,6 +252,9 @@ void label_manager_init(char *lm_zserv_path)
|
|||||||
lm_is_external = true;
|
lm_is_external = true;
|
||||||
lm_zclient_init(lm_zserv_path);
|
lm_zclient_init(lm_zserv_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
|
obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -379,4 +387,6 @@ int release_daemon_chunks(u_char proto, u_short instance)
|
|||||||
void label_manager_close()
|
void label_manager_close()
|
||||||
{
|
{
|
||||||
list_delete_and_null(&lbl_mgr.lc_list);
|
list_delete_and_null(&lbl_mgr.lc_list);
|
||||||
|
stream_free(ibuf);
|
||||||
|
stream_free(obuf);
|
||||||
}
|
}
|
||||||
|
@ -243,16 +243,15 @@ void redistribute_delete(struct prefix *p, struct prefix *src_p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_redistribute_add(int command, struct zserv *client, int length,
|
void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
afi_t afi = 0;
|
afi_t afi = 0;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
u_short instance;
|
u_short instance;
|
||||||
|
|
||||||
STREAM_GETC(client->ibuf, afi);
|
STREAM_GETC(msg, afi);
|
||||||
STREAM_GETC(client->ibuf, type);
|
STREAM_GETC(msg, type);
|
||||||
STREAM_GETW(client->ibuf, instance);
|
STREAM_GETW(msg, instance);
|
||||||
|
|
||||||
if (afi == 0 || afi > AFI_MAX) {
|
if (afi == 0 || afi > AFI_MAX) {
|
||||||
zlog_warn("%s: Specified afi %d does not exist",
|
zlog_warn("%s: Specified afi %d does not exist",
|
||||||
@ -287,16 +286,15 @@ stream_failure:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_redistribute_delete(int command, struct zserv *client, int length,
|
void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
afi_t afi = 0;
|
afi_t afi = 0;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
u_short instance;
|
u_short instance;
|
||||||
|
|
||||||
STREAM_GETC(client->ibuf, afi);
|
STREAM_GETC(msg, afi);
|
||||||
STREAM_GETC(client->ibuf, type);
|
STREAM_GETC(msg, type);
|
||||||
STREAM_GETW(client->ibuf, instance);
|
STREAM_GETW(msg, instance);
|
||||||
|
|
||||||
if (afi == 0 || afi > AFI_MAX) {
|
if (afi == 0 || afi > AFI_MAX) {
|
||||||
zlog_warn("%s: Specified afi %d does not exist",
|
zlog_warn("%s: Specified afi %d does not exist",
|
||||||
@ -325,15 +323,13 @@ stream_failure:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_redistribute_default_add(int command, struct zserv *client,
|
void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
|
||||||
int length, struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
|
vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
|
||||||
zebra_redistribute_default(client, zvrf_id(zvrf));
|
zebra_redistribute_default(client, zvrf_id(zvrf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_redistribute_default_delete(int command, struct zserv *client,
|
void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
|
||||||
int length, struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
|
vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,12 @@
|
|||||||
#include "vty.h"
|
#include "vty.h"
|
||||||
#include "vrf.h"
|
#include "vrf.h"
|
||||||
|
|
||||||
extern void zebra_redistribute_add(int, struct zserv *, int,
|
/* ZAPI command handlers */
|
||||||
struct zebra_vrf *zvrf);
|
extern void zebra_redistribute_add(ZAPI_HANDLER_ARGS);
|
||||||
extern void zebra_redistribute_delete(int, struct zserv *, int,
|
extern void zebra_redistribute_delete(ZAPI_HANDLER_ARGS);
|
||||||
struct zebra_vrf *zvrf);
|
extern void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS);
|
||||||
extern void zebra_redistribute_default_add(int, struct zserv *, int,
|
/* ----------------- */
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern void zebra_redistribute_default_delete(int, struct zserv *, int,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
|
|
||||||
extern void redistribute_update(struct prefix *, struct prefix *,
|
extern void redistribute_update(struct prefix *, struct prefix *,
|
||||||
struct route_entry *, struct route_entry *);
|
struct route_entry *, struct route_entry *);
|
||||||
|
@ -801,8 +801,7 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
|
|||||||
* if the operator has explicitly enabled RA. The enable request can also
|
* if the operator has explicitly enabled RA. The enable request can also
|
||||||
* specify a RA interval (in seconds).
|
* specify a RA interval (in seconds).
|
||||||
*/
|
*/
|
||||||
void zebra_interface_radv_set(struct zserv *client, u_short length,
|
static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
|
||||||
struct zebra_vrf *zvrf, int enable)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
@ -810,7 +809,7 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
|
|||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
int ra_interval;
|
int ra_interval;
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
/* Get interface index and RA interval. */
|
/* Get interface index and RA interval. */
|
||||||
STREAM_GETL(s, ifindex);
|
STREAM_GETL(s, ifindex);
|
||||||
@ -859,6 +858,15 @@ stream_failure:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
zebra_interface_radv_set(client, hdr, msg, zvrf, 0);
|
||||||
|
}
|
||||||
|
void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS)
|
||||||
|
{
|
||||||
|
zebra_interface_radv_set(client, hdr, msg, zvrf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (ipv6_nd_suppress_ra,
|
DEFUN (ipv6_nd_suppress_ra,
|
||||||
ipv6_nd_suppress_ra_cmd,
|
ipv6_nd_suppress_ra_cmd,
|
||||||
"ipv6 nd suppress-ra",
|
"ipv6 nd suppress-ra",
|
||||||
|
@ -103,7 +103,8 @@ typedef enum {
|
|||||||
extern void rtadv_init(struct zebra_ns *);
|
extern void rtadv_init(struct zebra_ns *);
|
||||||
extern void rtadv_terminate(struct zebra_ns *);
|
extern void rtadv_terminate(struct zebra_ns *);
|
||||||
extern void rtadv_cmd_init(void);
|
extern void rtadv_cmd_init(void);
|
||||||
extern void zebra_interface_radv_set(struct zserv *client, u_short length,
|
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
|
||||||
struct zebra_vrf *zvrf, int enable);
|
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _ZEBRA_RTADV_H */
|
#endif /* _ZEBRA_RTADV_H */
|
||||||
|
@ -455,8 +455,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
|
|||||||
rn = fec->rn;
|
rn = fec->rn;
|
||||||
|
|
||||||
/* Get output stream. */
|
/* Get output stream. */
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
|
zclient_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
|
||||||
|
|
||||||
@ -464,7 +463,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
|
|||||||
stream_put_prefix(s, &rn->p);
|
stream_put_prefix(s, &rn->p);
|
||||||
stream_putl(s, fec->label);
|
stream_putl(s, fec->label);
|
||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -32,17 +32,16 @@
|
|||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
|
|
||||||
int zebra_ipmr_route_stats(struct zserv *client, u_short length,
|
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct mcast_route_data mroute;
|
struct mcast_route_data mroute;
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int suc = -1;
|
int suc = -1;
|
||||||
|
|
||||||
memset(&mroute, 0, sizeof(mroute));
|
memset(&mroute, 0, sizeof(mroute));
|
||||||
STREAM_GET(&mroute.sg.src, client->ibuf, 4);
|
STREAM_GET(&mroute.sg.src, msg, 4);
|
||||||
STREAM_GET(&mroute.sg.grp, client->ibuf, 4);
|
STREAM_GET(&mroute.sg.grp, msg, 4);
|
||||||
STREAM_GETL(client->ibuf, mroute.ifindex);
|
STREAM_GETL(msg, mroute.ifindex);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) {
|
if (IS_ZEBRA_DEBUG_KERNEL) {
|
||||||
char sbuf[40];
|
char sbuf[40];
|
||||||
@ -57,7 +56,7 @@ int zebra_ipmr_route_stats(struct zserv *client, u_short length,
|
|||||||
suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);
|
suc = kernel_get_ipmr_sg_stats(zvrf, &mroute);
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
|
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
|
|
||||||
@ -68,6 +67,5 @@ stream_failure:
|
|||||||
stream_putl(s, suc);
|
stream_putl(s, suc);
|
||||||
|
|
||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
zebra_server_send_message(client);
|
zebra_server_send_message(client, s);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,14 @@
|
|||||||
#ifndef __ZEBRA_MROUTE_H__
|
#ifndef __ZEBRA_MROUTE_H__
|
||||||
#define __ZEBRA_MROUTE_H__
|
#define __ZEBRA_MROUTE_H__
|
||||||
|
|
||||||
|
#include "zebra/zserv.h"
|
||||||
|
|
||||||
struct mcast_route_data {
|
struct mcast_route_data {
|
||||||
struct prefix_sg sg;
|
struct prefix_sg sg;
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
unsigned long long lastused;
|
unsigned long long lastused;
|
||||||
};
|
};
|
||||||
|
|
||||||
int zebra_ipmr_route_stats(struct zserv *client, u_short length,
|
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS);
|
||||||
struct zebra_vrf *zvf);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -661,8 +661,7 @@ int zebra_ptm_sock_read(struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* BFD peer/dst register/update */
|
/* BFD peer/dst register/update */
|
||||||
int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
|
void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS)
|
||||||
int command, struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct prefix src_p;
|
struct prefix src_p;
|
||||||
@ -680,20 +679,20 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
|
|||||||
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
|
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
|
||||||
unsigned int pid;
|
unsigned int pid;
|
||||||
|
|
||||||
if (command == ZEBRA_BFD_DEST_UPDATE)
|
if (hdr->command == ZEBRA_BFD_DEST_UPDATE)
|
||||||
client->bfd_peer_upd8_cnt++;
|
client->bfd_peer_upd8_cnt++;
|
||||||
else
|
else
|
||||||
client->bfd_peer_add_cnt++;
|
client->bfd_peer_add_cnt++;
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
zlog_debug("bfd_dst_register msg from client %s: length=%d",
|
zlog_debug("bfd_dst_register msg from client %s: length=%d",
|
||||||
zebra_route_string(client->proto), length);
|
zebra_route_string(client->proto), hdr->length);
|
||||||
|
|
||||||
if (ptm_cb.ptm_sock == -1) {
|
if (ptm_cb.ptm_sock == -1) {
|
||||||
ptm_cb.t_timer = NULL;
|
ptm_cb.t_timer = NULL;
|
||||||
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
||||||
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
||||||
@ -703,7 +702,7 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
|
|||||||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
|
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
|
||||||
tmp_buf);
|
tmp_buf);
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
STREAM_GETL(s, pid);
|
STREAM_GETL(s, pid);
|
||||||
sprintf(tmp_buf, "%d", pid);
|
sprintf(tmp_buf, "%d", pid);
|
||||||
@ -816,16 +815,14 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
|
|||||||
ptm_cb.out_data);
|
ptm_cb.out_data);
|
||||||
zebra_ptm_send_message(ptm_cb.out_data, data_len);
|
zebra_ptm_send_message(ptm_cb.out_data, data_len);
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BFD peer/dst deregister */
|
/* BFD peer/dst deregister */
|
||||||
int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
|
void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct prefix src_p;
|
struct prefix src_p;
|
||||||
@ -843,13 +840,13 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
zlog_debug("bfd_dst_deregister msg from client %s: length=%d",
|
zlog_debug("bfd_dst_deregister msg from client %s: length=%d",
|
||||||
zebra_route_string(client->proto), length);
|
zebra_route_string(client->proto), hdr->length);
|
||||||
|
|
||||||
if (ptm_cb.ptm_sock == -1) {
|
if (ptm_cb.ptm_sock == -1) {
|
||||||
ptm_cb.t_timer = NULL;
|
ptm_cb.t_timer = NULL;
|
||||||
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
||||||
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
||||||
@ -861,7 +858,7 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
|
|||||||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
|
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
|
||||||
tmp_buf);
|
tmp_buf);
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
STREAM_GETL(s, pid);
|
STREAM_GETL(s, pid);
|
||||||
sprintf(tmp_buf, "%d", pid);
|
sprintf(tmp_buf, "%d", pid);
|
||||||
@ -948,15 +945,14 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
|
|||||||
|
|
||||||
zebra_ptm_send_message(ptm_cb.out_data, data_len);
|
zebra_ptm_send_message(ptm_cb.out_data, data_len);
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BFD client register */
|
/* BFD client register */
|
||||||
int zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
|
void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
unsigned int pid;
|
unsigned int pid;
|
||||||
@ -968,16 +964,16 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_EVENT)
|
if (IS_ZEBRA_DEBUG_EVENT)
|
||||||
zlog_debug("bfd_client_register msg from client %s: length=%d",
|
zlog_debug("bfd_client_register msg from client %s: length=%d",
|
||||||
zebra_route_string(client->proto), length);
|
zebra_route_string(client->proto), hdr->length);
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
STREAM_GETL(s, pid);
|
STREAM_GETL(s, pid);
|
||||||
|
|
||||||
if (ptm_cb.ptm_sock == -1) {
|
if (ptm_cb.ptm_sock == -1) {
|
||||||
ptm_cb.t_timer = NULL;
|
ptm_cb.t_timer = NULL;
|
||||||
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
|
||||||
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
ptm_cb.reconnect_time, &ptm_cb.t_timer);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
|
||||||
@ -1003,7 +999,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
|
|||||||
SET_FLAG(ptm_cb.client_flags[client->proto],
|
SET_FLAG(ptm_cb.client_flags[client->proto],
|
||||||
ZEBRA_PTM_BFD_CLIENT_FLAG_REG);
|
ZEBRA_PTM_BFD_CLIENT_FLAG_REG);
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
/*
|
/*
|
||||||
@ -1013,7 +1009,7 @@ stream_failure:
|
|||||||
* if (out_ctxt)
|
* if (out_ctxt)
|
||||||
* ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
* ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
|
||||||
*/
|
*/
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BFD client deregister */
|
/* BFD client deregister */
|
||||||
|
@ -28,6 +28,8 @@ extern const char ZEBRA_PTM_SOCK_NAME[];
|
|||||||
|
|
||||||
#define ZEBRA_PTM_BFD_CLIENT_FLAG_REG (1 << 1) /* client registered with BFD */
|
#define ZEBRA_PTM_BFD_CLIENT_FLAG_REG (1 << 1) /* client registered with BFD */
|
||||||
|
|
||||||
|
#include "zebra/zserv.h"
|
||||||
|
|
||||||
/* Zebra ptm context block */
|
/* Zebra ptm context block */
|
||||||
struct zebra_ptm_cb {
|
struct zebra_ptm_cb {
|
||||||
int ptm_sock; /* ptm file descriptor. */
|
int ptm_sock; /* ptm file descriptor. */
|
||||||
@ -62,12 +64,12 @@ int zebra_ptm_connect(struct thread *t);
|
|||||||
void zebra_ptm_write(struct vty *vty);
|
void zebra_ptm_write(struct vty *vty);
|
||||||
int zebra_ptm_get_enable_state(void);
|
int zebra_ptm_get_enable_state(void);
|
||||||
|
|
||||||
int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
|
/* ZAPI message handlers */
|
||||||
int command, struct zebra_vrf *zvrf);
|
void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS);
|
||||||
int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
|
void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS);
|
||||||
struct zebra_vrf *zvrf);
|
void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS);
|
||||||
|
|
||||||
void zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
|
void zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
|
||||||
int zebra_ptm_bfd_client_register(struct zserv *client, u_short length);
|
|
||||||
void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
|
void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
|
||||||
void zebra_ptm_if_set_ptm_state(struct interface *ifp,
|
void zebra_ptm_if_set_ptm_state(struct interface *ifp,
|
||||||
struct zebra_if *zebra_ifp);
|
struct zebra_if *zebra_ifp);
|
||||||
|
@ -38,8 +38,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client,
|
|||||||
if (!client->ifinfo)
|
if (!client->ifinfo)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, vrf_id);
|
zclient_create_header(s, cmd, vrf_id);
|
||||||
if (ifp)
|
if (ifp)
|
||||||
@ -66,7 +65,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client,
|
|||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
client->if_bfd_cnt++;
|
client->if_bfd_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp,
|
void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp,
|
||||||
@ -93,8 +92,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client)
|
|||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||||
|
|
||||||
@ -102,7 +100,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client)
|
|||||||
stream_putw_at(s, 0, stream_get_endp(s));
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
client->bfd_peer_replay_cnt++;
|
client->bfd_peer_replay_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_bfd_peer_replay_req(void)
|
void zebra_bfd_peer_replay_req(void)
|
||||||
|
@ -305,6 +305,8 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
|
|||||||
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
nexthop->gate.ipv6 = *ipv6;
|
nexthop->gate.ipv6 = *ipv6;
|
||||||
nexthop->ifindex = ifindex;
|
nexthop->ifindex = ifindex;
|
||||||
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
|
||||||
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
|
||||||
|
|
||||||
route_entry_nexthop_add(re, nexthop);
|
route_entry_nexthop_add(re, nexthop);
|
||||||
|
|
||||||
@ -421,6 +423,10 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
re->nexthop_mtu = 0;
|
re->nexthop_mtu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Next hops (remote VTEPs) for EVPN routes are fully resolved. */
|
||||||
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP))
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Skip nexthops that have been filtered out due to route-map */
|
/* Skip nexthops that have been filtered out due to route-map */
|
||||||
/* The nexthops are specific to this route and so the same */
|
/* The nexthops are specific to this route and so the same */
|
||||||
/* nexthop for a different route may not have this flag set */
|
/* nexthop for a different route may not have this flag set */
|
||||||
@ -859,9 +865,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
case NEXTHOP_TYPE_IPV4:
|
case NEXTHOP_TYPE_IPV4:
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
family = AFI_IP;
|
family = AFI_IP;
|
||||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP))
|
if (nexthop_active(AFI_IP, re, nexthop, set, rn))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
|
||||||
else if (nexthop_active(AFI_IP, re, nexthop, set, rn))
|
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -2554,10 +2558,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
|||||||
struct ipaddr vtep_ip;
|
struct ipaddr vtep_ip;
|
||||||
|
|
||||||
memset(&vtep_ip, 0, sizeof(struct ipaddr));
|
memset(&vtep_ip, 0, sizeof(struct ipaddr));
|
||||||
|
if (afi == AFI_IP) {
|
||||||
vtep_ip.ipa_type = IPADDR_V4;
|
vtep_ip.ipa_type = IPADDR_V4;
|
||||||
memcpy(&(vtep_ip.ipaddr_v4),
|
memcpy(&(vtep_ip.ipaddr_v4),
|
||||||
&(tmp_nh->gate.ipv4),
|
&(tmp_nh->gate.ipv4),
|
||||||
sizeof(struct in_addr));
|
sizeof(struct in_addr));
|
||||||
|
} else {
|
||||||
|
vtep_ip.ipa_type = IPADDR_V6;
|
||||||
|
memcpy(&(vtep_ip.ipaddr_v6),
|
||||||
|
&(tmp_nh->gate.ipv6),
|
||||||
|
sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
zebra_vxlan_evpn_vrf_route_del(re->vrf_id, rmac,
|
zebra_vxlan_evpn_vrf_route_del(re->vrf_id, rmac,
|
||||||
&vtep_ip, p);
|
&vtep_ip, p);
|
||||||
}
|
}
|
||||||
|
@ -995,8 +995,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
|
|||||||
re = rnh->state;
|
re = rnh->state;
|
||||||
|
|
||||||
/* Get output stream. */
|
/* Get output stream. */
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, vrf_id);
|
zclient_create_header(s, cmd, vrf_id);
|
||||||
|
|
||||||
@ -1063,7 +1062,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
|
|||||||
|
|
||||||
client->nh_last_upd_time = monotime(NULL);
|
client->nh_last_upd_time = monotime(NULL);
|
||||||
client->last_write_cmd = cmd;
|
client->last_write_cmd = cmd;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_nh(struct nexthop *nexthop, struct vty *vty)
|
static void print_nh(struct nexthop *nexthop, struct vty *vty)
|
||||||
|
@ -1157,8 +1157,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
|
|||||||
if (!client)
|
if (!client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||||
stream_putl(s, vni);
|
stream_putl(s, vni);
|
||||||
@ -1195,7 +1194,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
|
|||||||
else
|
else
|
||||||
client->macipdel_cnt++;
|
client->macipdel_cnt++;
|
||||||
|
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2565,8 +2564,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
|
|||||||
if (!client)
|
if (!client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
|
zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
|
||||||
stream_putl(s, zvni->vni);
|
stream_putl(s, zvni->vni);
|
||||||
@ -2583,7 +2581,7 @@ static int zvni_send_add_to_client(zebra_vni_t *zvni)
|
|||||||
zebra_route_string(client->proto));
|
zebra_route_string(client->proto));
|
||||||
|
|
||||||
client->vniadd_cnt++;
|
client->vniadd_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2599,7 +2597,7 @@ static int zvni_send_del_to_client(vni_t vni)
|
|||||||
if (!client)
|
if (!client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
|
|
||||||
zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
|
zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
|
||||||
@ -2613,7 +2611,7 @@ static int zvni_send_del_to_client(vni_t vni)
|
|||||||
zebra_route_string(client->proto));
|
zebra_route_string(client->proto));
|
||||||
|
|
||||||
client->vnidel_cnt++;
|
client->vnidel_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3550,8 +3548,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
|
|||||||
memset(&rmac, 0, sizeof(struct ethaddr));
|
memset(&rmac, 0, sizeof(struct ethaddr));
|
||||||
zl3vni_get_rmac(zl3vni, &rmac);
|
zl3vni_get_rmac(zl3vni, &rmac);
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
|
zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
|
||||||
stream_putl(s, zl3vni->vni);
|
stream_putl(s, zl3vni->vni);
|
||||||
@ -3574,7 +3571,7 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
|
|||||||
zebra_route_string(client->proto));
|
zebra_route_string(client->proto));
|
||||||
|
|
||||||
client->l3vniadd_cnt++;
|
client->l3vniadd_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3590,8 +3587,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
|
|||||||
if (!client)
|
if (!client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
|
zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
|
||||||
stream_putl(s, zl3vni->vni);
|
stream_putl(s, zl3vni->vni);
|
||||||
@ -3605,7 +3601,7 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
|
|||||||
zebra_route_string(client->proto));
|
zebra_route_string(client->proto));
|
||||||
|
|
||||||
client->l3vnidel_cnt++;
|
client->l3vnidel_cnt++;
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
|
static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
|
||||||
@ -3723,8 +3719,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
|
|||||||
if (!client)
|
if (!client)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = client->obuf;
|
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
||||||
stream_reset(s);
|
|
||||||
|
|
||||||
zclient_create_header(s, cmd, vrf_id);
|
zclient_create_header(s, cmd, vrf_id);
|
||||||
stream_put(s, p, sizeof(struct prefix));
|
stream_put(s, p, sizeof(struct prefix));
|
||||||
@ -3743,7 +3738,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
|
|||||||
else
|
else
|
||||||
client->prefixdel_cnt++;
|
client->prefixdel_cnt++;
|
||||||
|
|
||||||
return zebra_server_send_message(client);
|
return zebra_server_send_message(client, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-add remote rmac if needed */
|
/* re-add remote rmac if needed */
|
||||||
@ -4863,8 +4858,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
|
|||||||
/*
|
/*
|
||||||
* Handle message from client to delete a remote MACIP for a VNI.
|
* Handle message from client to delete a remote MACIP for a VNI.
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
|
void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
vni_t vni;
|
vni_t vni;
|
||||||
@ -4884,9 +4878,9 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
|
|||||||
memset(&ip, 0, sizeof(struct ipaddr));
|
memset(&ip, 0, sizeof(struct ipaddr));
|
||||||
memset(&vtep_ip, 0, sizeof(struct in_addr));
|
memset(&vtep_ip, 0, sizeof(struct in_addr));
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
while (l < length) {
|
while (l < hdr->length) {
|
||||||
/* Obtain each remote MACIP and process. */
|
/* Obtain each remote MACIP and process. */
|
||||||
/* Message contains VNI, followed by MAC followed by IP (if any)
|
/* Message contains VNI, followed by MAC followed by IP (if any)
|
||||||
* followed by remote VTEP IP.
|
* followed by remote VTEP IP.
|
||||||
@ -5008,7 +5002,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5016,8 +5010,7 @@ stream_failure:
|
|||||||
* could be just the add of a MAC address or the add of a neighbor
|
* could be just the add of a MAC address or the add of a neighbor
|
||||||
* (IP+MAC).
|
* (IP+MAC).
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
vni_t vni;
|
vni_t vni;
|
||||||
@ -5045,12 +5038,12 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
|||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
|
"%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
while (l < length) {
|
while (l < hdr->length) {
|
||||||
/* Obtain each remote MACIP and process. */
|
/* Obtain each remote MACIP and process. */
|
||||||
/* Message contains VNI, followed by MAC followed by IP (if any)
|
/* Message contains VNI, followed by MAC followed by IP (if any)
|
||||||
* followed by remote VTEP IP.
|
* followed by remote VTEP IP.
|
||||||
@ -5159,7 +5152,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
|||||||
prefix_mac2str(&macaddr, buf,
|
prefix_mac2str(&macaddr, buf,
|
||||||
sizeof(buf)),
|
sizeof(buf)),
|
||||||
vni, inet_ntoa(vtep_ip));
|
vni, inet_ntoa(vtep_ip));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this MAC created for a MACIP? */
|
/* Is this MAC created for a MACIP? */
|
||||||
@ -5212,7 +5205,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
|||||||
prefix_mac2str(&macaddr, buf,
|
prefix_mac2str(&macaddr, buf,
|
||||||
sizeof(buf)),
|
sizeof(buf)),
|
||||||
vni, inet_ntoa(vtep_ip));
|
vni, inet_ntoa(vtep_ip));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
|
} else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
|
||||||
@ -5240,7 +5233,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5543,8 +5536,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
|||||||
/*
|
/*
|
||||||
* Handle message from client to delete a remote VTEP for a VNI.
|
* Handle message from client to delete a remote VTEP for a VNI.
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
|
void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
u_short l = 0;
|
u_short l = 0;
|
||||||
@ -5559,18 +5551,18 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
|
|||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: EVPN is not enabled yet we have received a vtep del command",
|
"%s: EVPN is not enabled yet we have received a vtep del command",
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
||||||
zlog_err("Recv MACIP DEL for non-default VRF %u",
|
zlog_err("Recv MACIP DEL for non-default VRF %u",
|
||||||
zvrf_id(zvrf));
|
zvrf_id(zvrf));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
while (l < length) {
|
while (l < hdr->length) {
|
||||||
/* Obtain each remote VTEP and process. */
|
/* Obtain each remote VTEP and process. */
|
||||||
STREAM_GETL(s, vni);
|
STREAM_GETL(s, vni);
|
||||||
l += 4;
|
l += 4;
|
||||||
@ -5623,14 +5615,13 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle message from client to add a remote VTEP for a VNI.
|
* Handle message from client to add a remote VTEP for a VNI.
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
|
void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
u_short l = 0;
|
u_short l = 0;
|
||||||
@ -5644,18 +5635,18 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
|
|||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: EVPN not enabled yet we received a vtep_add zapi call",
|
"%s: EVPN not enabled yet we received a vtep_add zapi call",
|
||||||
__PRETTY_FUNCTION__);
|
__PRETTY_FUNCTION__);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
||||||
zlog_err("Recv MACIP ADD for non-default VRF %u",
|
zlog_err("Recv MACIP ADD for non-default VRF %u",
|
||||||
zvrf_id(zvrf));
|
zvrf_id(zvrf));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
|
|
||||||
while (l < length) {
|
while (l < hdr->length) {
|
||||||
/* Obtain each remote VTEP and process. */
|
/* Obtain each remote VTEP and process. */
|
||||||
STREAM_GETL(s, vni);
|
STREAM_GETL(s, vni);
|
||||||
l += 4;
|
l += 4;
|
||||||
@ -5705,7 +5696,7 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6512,8 +6503,7 @@ int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
|
|||||||
* Handle message from client to enable/disable advertisement of g/w macip
|
* Handle message from client to enable/disable advertisement of g/w macip
|
||||||
* routes
|
* routes
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
|
void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int advertise;
|
int advertise;
|
||||||
@ -6527,19 +6517,19 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
|
|||||||
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
||||||
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
|
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
|
||||||
zvrf_id(zvrf));
|
zvrf_id(zvrf));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
advertise = stream_getc(s);
|
advertise = stream_getc(s);
|
||||||
vni = stream_get3(s);
|
vni = stream_get3(s);
|
||||||
|
|
||||||
zvni = zvni_lookup(vni);
|
zvni = zvni_lookup(vni);
|
||||||
if (!zvni)
|
if (!zvni)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (zvni->advertise_subnet == advertise)
|
if (zvni->advertise_subnet == advertise)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
|
zlog_debug("EVPN subnet Adv %s on VNI %d , currently %s",
|
||||||
@ -6551,35 +6541,32 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
|
|||||||
|
|
||||||
ifp = zvni->vxlan_if;
|
ifp = zvni->vxlan_if;
|
||||||
if (!ifp)
|
if (!ifp)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
|
||||||
/* If down or not mapped to a bridge, we're done. */
|
/* If down or not mapped to a bridge, we're done. */
|
||||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zl2_info = zif->l2info.vxl;
|
zl2_info = zif->l2info.vxl;
|
||||||
|
|
||||||
vlan_if =
|
vlan_if =
|
||||||
zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
|
zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
|
||||||
if (!vlan_if)
|
if (!vlan_if)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (zvni->advertise_subnet)
|
if (zvni->advertise_subnet)
|
||||||
zvni_advertise_subnet(zvni, vlan_if, 1);
|
zvni_advertise_subnet(zvni, vlan_if, 1);
|
||||||
else
|
else
|
||||||
zvni_advertise_subnet(zvni, vlan_if, 0);
|
zvni_advertise_subnet(zvni, vlan_if, 0);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle message from client to enable/disable advertisement of g/w macip
|
* Handle message from client to enable/disable advertisement of g/w macip
|
||||||
* routes
|
* routes
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int advertise;
|
int advertise;
|
||||||
@ -6590,10 +6577,10 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|||||||
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
||||||
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
|
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
|
||||||
zvrf_id(zvrf));
|
zvrf_id(zvrf));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
STREAM_GETC(s, advertise);
|
STREAM_GETC(s, advertise);
|
||||||
STREAM_GET(&vni, s, 3);
|
STREAM_GET(&vni, s, 3);
|
||||||
|
|
||||||
@ -6606,7 +6593,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|||||||
: "disabled");
|
: "disabled");
|
||||||
|
|
||||||
if (zvrf->advertise_gw_macip == advertise)
|
if (zvrf->advertise_gw_macip == advertise)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zvrf->advertise_gw_macip = advertise;
|
zvrf->advertise_gw_macip = advertise;
|
||||||
|
|
||||||
@ -6625,7 +6612,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|||||||
|
|
||||||
zvni = zvni_lookup(vni);
|
zvni = zvni_lookup(vni);
|
||||||
if (!zvni)
|
if (!zvni)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -6635,26 +6622,26 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|||||||
: "disabled");
|
: "disabled");
|
||||||
|
|
||||||
if (zvni->advertise_gw_macip == advertise)
|
if (zvni->advertise_gw_macip == advertise)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zvni->advertise_gw_macip = advertise;
|
zvni->advertise_gw_macip = advertise;
|
||||||
|
|
||||||
ifp = zvni->vxlan_if;
|
ifp = zvni->vxlan_if;
|
||||||
if (!ifp)
|
if (!ifp)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
|
||||||
/* If down or not mapped to a bridge, we're done. */
|
/* If down or not mapped to a bridge, we're done. */
|
||||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zl2_info = zif->l2info.vxl;
|
zl2_info = zif->l2info.vxl;
|
||||||
|
|
||||||
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
|
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
|
||||||
zif->brslave_info.br_if);
|
zif->brslave_info.br_if);
|
||||||
if (!vlan_if)
|
if (!vlan_if)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (advertise_gw_macip_enabled(zvni)) {
|
if (advertise_gw_macip_enabled(zvni)) {
|
||||||
/* Add primary SVI MAC-IP */
|
/* Add primary SVI MAC-IP */
|
||||||
@ -6676,7 +6663,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6686,8 +6673,7 @@ stream_failure:
|
|||||||
* when disabled, the entries should be deleted and remote VTEPs and MACs
|
* when disabled, the entries should be deleted and remote VTEPs and MACs
|
||||||
* uninstalled from the kernel.
|
* uninstalled from the kernel.
|
||||||
*/
|
*/
|
||||||
int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
|
void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
|
||||||
struct zebra_vrf *zvrf)
|
|
||||||
{
|
{
|
||||||
struct stream *s = NULL;
|
struct stream *s = NULL;
|
||||||
int advertise = 0;
|
int advertise = 0;
|
||||||
@ -6695,10 +6681,10 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
|
|||||||
|
|
||||||
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
if (zvrf_id(zvrf) != VRF_DEFAULT) {
|
||||||
zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf));
|
zlog_err("EVPN VNI Adv for non-default VRF %u", zvrf_id(zvrf));
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = client->ibuf;
|
s = msg;
|
||||||
STREAM_GETC(s, advertise);
|
STREAM_GETC(s, advertise);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
@ -6707,7 +6693,7 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
|
|||||||
is_evpn_enabled() ? "enabled" : "disabled");
|
is_evpn_enabled() ? "enabled" : "disabled");
|
||||||
|
|
||||||
if (zvrf->advertise_all_vni == advertise)
|
if (zvrf->advertise_all_vni == advertise)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
zvrf->advertise_all_vni = advertise;
|
zvrf->advertise_all_vni = advertise;
|
||||||
if (is_evpn_enabled()) {
|
if (is_evpn_enabled()) {
|
||||||
@ -6732,13 +6718,13 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
|
|||||||
/* cleanup all l3vnis */
|
/* cleanup all l3vnis */
|
||||||
zns = zebra_ns_lookup(NS_DEFAULT);
|
zns = zebra_ns_lookup(NS_DEFAULT);
|
||||||
if (!zns)
|
if (!zns)
|
||||||
return -1;
|
return;
|
||||||
|
|
||||||
hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL);
|
hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "lib/json.h"
|
#include "lib/json.h"
|
||||||
#include "zebra/zebra_vrf.h"
|
#include "zebra/zebra_vrf.h"
|
||||||
|
#include "zebra/zserv.h"
|
||||||
|
|
||||||
/* Is EVPN enabled? */
|
/* Is EVPN enabled? */
|
||||||
#define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni
|
#define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni
|
||||||
@ -51,6 +52,15 @@ static inline int is_evpn_enabled()
|
|||||||
|
|
||||||
#define VNI_STR_LEN 32
|
#define VNI_STR_LEN 32
|
||||||
|
|
||||||
|
/* ZAPI message handlers */
|
||||||
|
extern void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS);
|
||||||
|
extern void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS);
|
||||||
|
|
||||||
extern int is_l3vni_for_prefix_routes_only(vni_t vni);
|
extern int is_l3vni_for_prefix_routes_only(vni_t vni);
|
||||||
extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);
|
extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);
|
||||||
extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf);
|
extern int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf);
|
||||||
@ -117,10 +127,6 @@ extern int zebra_vxlan_local_neigh_add_update(
|
|||||||
extern int zebra_vxlan_local_neigh_del(struct interface *ifp,
|
extern int zebra_vxlan_local_neigh_del(struct interface *ifp,
|
||||||
struct interface *link_if,
|
struct interface *link_if,
|
||||||
struct ipaddr *ip);
|
struct ipaddr *ip);
|
||||||
extern int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
extern int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
||||||
struct interface *br_if,
|
struct interface *br_if,
|
||||||
struct ethaddr *mac, vlanid_t vid,
|
struct ethaddr *mac, vlanid_t vid,
|
||||||
@ -140,16 +146,6 @@ extern int zebra_vxlan_if_down(struct interface *ifp);
|
|||||||
extern int zebra_vxlan_if_add(struct interface *ifp);
|
extern int zebra_vxlan_if_add(struct interface *ifp);
|
||||||
extern int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags);
|
extern int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags);
|
||||||
extern int zebra_vxlan_if_del(struct interface *ifp);
|
extern int zebra_vxlan_if_del(struct interface *ifp);
|
||||||
extern int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
|
|
||||||
struct zebra_vrf *zvrf);
|
|
||||||
extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
|
extern int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
|
||||||
char *err, int err_str_sz,
|
char *err, int err_str_sz,
|
||||||
int filter, int add);
|
int filter, int add);
|
||||||
|
1925
zebra/zserv.c
1925
zebra/zserv.c
File diff suppressed because it is too large
Load Diff
@ -47,8 +47,12 @@ struct zserv {
|
|||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
/* Input/output buffer to the client. */
|
/* Input/output buffer to the client. */
|
||||||
struct stream *ibuf;
|
struct stream_fifo *ibuf_fifo;
|
||||||
struct stream *obuf;
|
struct stream_fifo *obuf_fifo;
|
||||||
|
|
||||||
|
/* Private I/O buffers */
|
||||||
|
struct stream *ibuf_work;
|
||||||
|
struct stream *obuf_work;
|
||||||
|
|
||||||
/* Buffer of data waiting to be written to client. */
|
/* Buffer of data waiting to be written to client. */
|
||||||
struct buffer *wb;
|
struct buffer *wb;
|
||||||
@ -129,6 +133,10 @@ struct zserv {
|
|||||||
int last_write_cmd;
|
int last_write_cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ZAPI_HANDLER_ARGS \
|
||||||
|
struct zserv *client, struct zmsghdr *hdr, struct stream *msg, \
|
||||||
|
struct zebra_vrf *zvrf
|
||||||
|
|
||||||
/* Zebra instance */
|
/* Zebra instance */
|
||||||
struct zebra_t {
|
struct zebra_t {
|
||||||
/* Thread master */
|
/* Thread master */
|
||||||
@ -185,7 +193,7 @@ extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
|
|||||||
|
|
||||||
extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
|
extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
|
||||||
const unsigned int);
|
const unsigned int);
|
||||||
extern int zebra_server_send_message(struct zserv *client);
|
extern int zebra_server_send_message(struct zserv *client, struct stream *msg);
|
||||||
|
|
||||||
extern struct zserv *zebra_find_client(u_char proto, u_short instance);
|
extern struct zserv *zebra_find_client(u_char proto, u_short instance);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user