Merge branch 'master' of https://github.com/frrouting/frr into pmsi-parse-display

This commit is contained in:
vivek 2018-03-13 17:50:08 +00:00
commit 783e95b8e8
49 changed files with 1817 additions and 1373 deletions

3
.gitignore vendored
View File

@ -82,3 +82,6 @@ GPATH
*.lo
compile_commands.json
.dirstamp
# clippy generated source
*_clippy.c

36
alpine/APKBUILD.in Normal file
View 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
View File

@ -16,4 +16,3 @@ TAGS
.arch-ids
*~
*.loT
*clippy.c

View File

@ -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);
}
/*
* 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.
*/
@ -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
* applicable to all routes.
* TODO: currently kernel doesnt support ipv6 routes with ipv4 nexthops.
* This means that we can't do symmetric routing for ipv6 hosts routes
* in the same way as ipv4 host routes.
* We wont attach l3-vni related RTs for ipv6 routes.
* For now, We will only adevrtise ipv4 host routes
* with L3-VNI related ext-comm.
* Build extended communities for EVPN route.
* This function is applicable for type-2 and type-3 routes. The layer-2 RT
* and ENCAP extended communities are applicable for all routes.
* The default gateway extended community and MAC mobility (sticky) extended
* community are added as needed based on passed settings - only for type-2
* routes. Likewise, the layer-3 RT and Router MAC extended communities are
* added, if present, based on passed settings - only for non-link-local
* type-2 routes.
*/
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_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))
attr->ecommunity = ecommunity_merge(attr->ecommunity, ecom);
/*
* only attach l3-vni export rts for ipv4 address family and if we are
* advertising both the labels in type-2 routes
/* Add the export RTs for L3VNI if told to - caller determines
* when this should be done.
*/
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);
if (vrf_export_rtl && !list_isempty(vrf_export_rtl)) {
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) {
seqnum = 0;
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);
}
/*
* only attach l3-vni rmac for ipv4 address family and if we are
* 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)) {
/* Add RMAC, if told to. */
if (add_l3_ecomm) {
memset(&ecom_rmac, 0, sizeof(ecom_rmac));
encode_rmac_extcomm(&eval_rmac, &attr->rmac);
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);
}
/* Add default gateway, if needed. */
if (attr->default_gw) {
memset(&ecom_default_gw, 0, sizeof(ecom_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 attr attr;
struct attr *attr_new;
int add_l3_ecomm = 0;
struct bgp_info *ri;
afi_t afi = AFI_L2VPN;
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)
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)
bgpevpn_get_rmac(vpn, &attr.rmac);
vni2label(vpn->vni, &(attr.label));
/* Set up RT and ENCAP extended community. */
build_evpn_route_extcomm(
vpn, &attr, IS_EVPN_PREFIX_IPADDR_V4(p) ? AFI_IP : AFI_IP6);
/* Include L3 VNI related RTs and RMAC for type-2 routes, if they're
* IPv4 or IPv6 global addresses and we're advertising L3VNI with
* 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. */
/* 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_sticky;
struct attr attr_def_gw;
struct attr attr_ip6;
struct attr attr_sticky_ip6;
struct attr attr_def_gw_ip6;
struct attr attr_ip6_ll;
struct attr *attr_new;
int add_l3_ecomm = 0;
afi = AFI_L2VPN;
safi = SAFI_EVPN;
memset(&attr, 0, sizeof(struct attr));
memset(&attr_sticky, 0, sizeof(struct attr));
memset(&attr_def_gw, 0, sizeof(struct attr));
memset(&attr_ip6, 0, sizeof(struct attr));
memset(&attr_sticky_ip6, 0, sizeof(struct attr));
memset(&attr_def_gw_ip6, 0, sizeof(struct attr));
memset(&attr_ip6_ll, 0, sizeof(struct attr));
/* Build path-attribute - all type-2 routes for this VNI will share the
* same path attribute.
/* Build path-attribute - multiple type-2 routes for this VNI will share
* 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_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.default_gw = 1;
bgpevpn_get_rmac(vpn, &attr_def_gw.rmac);
bgp_attr_default_set(&attr_ip6, BGP_ORIGIN_IGP);
bgp_attr_default_set(&attr_sticky_ip6, BGP_ORIGIN_IGP);
bgp_attr_default_set(&attr_def_gw_ip6, BGP_ORIGIN_IGP);
attr_ip6.nexthop = vpn->originator_ip;
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);
bgp_attr_default_set(&attr_ip6_ll, BGP_ORIGIN_IGP);
attr_ip6_ll.nexthop = vpn->originator_ip;
attr_ip6_ll.mp_nexthop_global_in = vpn->originator_ip;
attr_ip6_ll.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
/* Set up RT, ENCAP and sticky MAC extended community. */
build_evpn_route_extcomm(vpn, &attr, AFI_IP);
build_evpn_route_extcomm(vpn, &attr_sticky, AFI_IP);
build_evpn_route_extcomm(vpn, &attr_def_gw, AFI_IP);
build_evpn_route_extcomm(vpn, &attr_ip6, AFI_IP6);
build_evpn_route_extcomm(vpn, &attr_sticky_ip6, AFI_IP6);
build_evpn_route_extcomm(vpn, &attr_def_gw_ip6, AFI_IP);
/* Add L3 VNI RTs and RMAC for non IPv6 link-local attributes if
* using L3 VNI for type-2 routes also.
*/
if (CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS))
add_l3_ecomm = 1;
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
* 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)
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))
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&attr_sticky, 0, 1, &ri,
@ -1550,19 +1560,6 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
else
update_evpn_route_entry(bgp, vpn, afi, safi, rn,
&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
@ -1593,11 +1590,9 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
/* Unintern temporary. */
aspath_unintern(&attr.aspath);
aspath_unintern(&attr_ip6.aspath);
aspath_unintern(&attr_sticky.aspath);
aspath_unintern(&attr_sticky_ip6.aspath);
aspath_unintern(&attr_def_gw.aspath);
aspath_unintern(&attr_def_gw_ip6.aspath);
aspath_unintern(&attr_ip6_ll.aspath);
return 0;
}
@ -1791,6 +1786,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
{
struct bgp_node *rn;
struct bgp_info *ri;
struct attr attr;
struct attr *attr_new;
int ret = 0;
struct prefix p;
@ -1827,6 +1823,15 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
} else
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. */
for (ri = rn->info; ri; ri = ri->next)
if (ri->extra
@ -1835,7 +1840,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
if (!ri) {
/* 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. */
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);
} else {
if (attrhash_cmp(ri->attr, parent_ri->attr)
if (attrhash_cmp(ri->attr, &attr)
&& !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
bgp_unlock_node(rn);
return 0;
}
/* The attribute has changed. */
/* Add (or update) attribute to hash. */
attr_new = bgp_attr_intern(parent_ri->attr);
attr_new = bgp_attr_intern(&attr);
/* Restore route, if needed. */
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
bgp_info_restore(rn, ri);
/* 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);
/* Unintern existing, set to new. */
@ -2577,10 +2586,12 @@ 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)
{
/* delete all ipv4 routes and withdraw from peers */
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
if (advertise_type5_routes(bgp_vrf, AFI_IP))
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
/* delete all ipv6 routes and withdraw from peers */
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
if (advertise_type5_routes(bgp_vrf, AFI_IP6))
bgp_evpn_withdraw_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
}
/* update and advertise all ipv4 and ipv6 routes in thr vrf table as type-5
@ -2588,10 +2599,12 @@ static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf)
static void update_advertise_vrf_routes(struct bgp *bgp_vrf)
{
/* update all ipv4 routes */
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
if (advertise_type5_routes(bgp_vrf, AFI_IP))
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP, SAFI_UNICAST);
/* update all ipv6 routes */
bgp_evpn_advertise_type5_routes(bgp_vrf, AFI_IP6, SAFI_UNICAST);
if (advertise_type5_routes(bgp_vrf, AFI_IP6))
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;
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);
ret = delete_evpn_type5_route(bgp_vrf, &evp);
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_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];
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
/* Only care about "selected" routes - non-imported. */
@ -3280,11 +3285,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
int ret = 0;
struct prefix_evpn evp;
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);
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
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_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];
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
/* Need to identify the "selected" route entry to use its

View File

@ -55,6 +55,25 @@ static inline vni_t label2vni(mpls_label_t *label)
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,
struct prefix *p,
struct attr *src_attr, afi_t afi,

View File

@ -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,
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;
}
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)
return 0;
if (afi == AFI_IP
&& CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
if (afi == AFI_IP &&
CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
return 1;
if (afi == AFI_IP6
&& CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
else if (afi == AFI_IP6 &&
CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
return 1;
return 0;
}

View File

@ -2419,7 +2419,50 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
/*
* 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)
return;
@ -2612,6 +2655,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
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,
bgp_evpn_advertise_vni_subnet_cmd,
"advertise-subnet",
@ -2631,14 +2711,6 @@ DEFUN (bgp_evpn_advertise_vni_subnet,
if (!bgp_vrf)
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);
return CMD_SUCCESS;
}
@ -2711,19 +2783,23 @@ DEFUN (bgp_evpn_advertise_type5,
/* if we are already advertising ipv4 prefix as type-5
* nothing to do
*/
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
if (!rmap_changed &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
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 {
/* if we are already advertising ipv6 prefix as type-5
* nothing to do
*/
if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
if (!rmap_changed &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
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) {
@ -2766,7 +2842,7 @@ DEFUN (no_bgp_evpn_advertise_type5,
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
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,
"%%only ipv4 or ipv6 address families are supported");
return CMD_WARNING;
@ -2780,25 +2856,25 @@ DEFUN (no_bgp_evpn_advertise_type5,
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
*/
if (CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
UNSET_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST);
}
} else {
/* if we are already advertising ipv6 prefix as type-5
/* if we are not advertising ipv6 prefix as type-5
* nothing to do
*/
if (CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
if (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST)) {
bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
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)
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");
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");
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))
vty_out(vty, " rd %s\n",
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, &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. */
install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);

View File

@ -2227,12 +2227,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
/* advertise/withdraw type-5 routes */
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
if (new_select
&& (!new_select->extra || !new_select->extra->parent))
bgp_evpn_advertise_type5_route(
bgp, &rn->p, new_select->attr, afi, safi);
else if (old_select
&& (!old_select->extra || !old_select->extra->parent))
if (advertise_type5_routes(bgp, afi) && new_select &&
(!new_select->extra || !new_select->extra->parent))
bgp_evpn_advertise_type5_route(bgp, &rn->p,
new_select->attr,
afi, safi);
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);
}

View File

@ -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_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 function should return 1 if match is success else return
@ -3249,6 +3267,29 @@ DEFUN (no_match_evpn_vni,
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,
match_peer_cmd,
"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_evpn_vni_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_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, &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, &no_match_aspath_cmd);

View File

@ -312,6 +312,13 @@ struct bgp {
u_int16_t af_flags[AFI_MAX][SAFI_MAX];
#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. */
struct bgp_table *nexthop_cache_table[AFI_MAX];
@ -423,12 +430,11 @@ struct bgp {
/* vrf flags */
uint32_t vrf_flags;
#define BGP_VRF_AUTO (1 << 0)
#define BGP_VRF_ADVERTISE_IPV4_IN_EVPN (1 << 1)
#define BGP_VRF_ADVERTISE_IPV6_IN_EVPN (1 << 2)
#define BGP_VRF_IMPORT_RT_CFGD (1 << 3)
#define BGP_VRF_EXPORT_RT_CFGD (1 << 4)
#define BGP_VRF_RD_CFGD (1 << 5)
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 6)
#define BGP_VRF_IMPORT_RT_CFGD (1 << 1)
#define BGP_VRF_EXPORT_RT_CFGD (1 << 2)
#define BGP_VRF_RD_CFGD (1 << 3)
#define BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY (1 << 4)
/* unique ID for auto derivation of RD for this vrf */
uint16_t vrf_rd_id;

View File

@ -396,6 +396,8 @@ AC_ARG_ENABLE(rpki,
AS_HELP_STRING([--enable-rpki], [enable RPKI prefix validation support]))
AC_ARG_ENABLE([clippy-only],
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"], [
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])
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 Add extra version string to package
dnl name, string and version fields.
@ -1872,6 +1882,7 @@ AC_CONFIG_FILES([Makefile
redhat/frr.spec
debianpkg/Makefile
debianpkg/changelog
alpine/APKBUILD
snapcraft/snapcraft.yaml
lib/version.h
tests/lib/cli/test_cli.refout

View File

@ -109,6 +109,10 @@ of grammar sandbox.
Turn on some compile options to allow you to run fuzzing tools
against the system. This tools is intended as a developer
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
You may specify any combination of the above options to the configure

1
ldpd/.gitignore vendored
View File

@ -15,4 +15,3 @@ TAGS
.arch-ids
*~
*.loT
ldp_vty_cmds_clippy.c

1
lib/.gitignore vendored
View File

@ -24,4 +24,3 @@ refix
grammar_sandbox
clippy
defun_lex.c
plist_clippy.c

View File

@ -104,76 +104,77 @@ struct debug_callbacks {
*
* MT-Safe
*/
#define DEBUG_MODE_CHECK(name, type) \
CHECK_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
#define DEBUG_MODE_CHECK(name, mode) \
CHECK_FLAG_ATOMIC(&(name)->flags, (mode)&DEBUG_MODE_ALL)
/*
* Check if an option bit is set for a debug.
*
* MT-Safe
*/
#define DEBUG_OPT_CHECK(name, type) \
CHECK_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
#define DEBUG_OPT_CHECK(name, opt) \
CHECK_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL)
/*
* Check if bits are set for a debug.
*
* MT-Safe
*/
#define DEBUG_FLAGS_CHECK(name, type) CHECK_FLAG_ATOMIC(&(name)->flags, (type))
/*
* Check if any mode is on for a debug.
*
* MT-Safe
*/
#define DEBUG(name) DEBUG_MODE_CHECK((name), DEBUG_MODE_ALL)
#define DEBUG_FLAGS_CHECK(name, fl) CHECK_FLAG_ATOMIC(&(name)->flags, (fl))
/*
* Set modes on a debug.
*
* MT-Safe
*/
#define DEBUG_MODE_SET(name, type) \
SET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
#define DEBUG_MODE_SET(name, mode, onoff) \
do { \
if (onoff) \
SET_FLAG_ATOMIC(&(name)->flags, \
(mode)&DEBUG_MODE_ALL); \
else \
UNSET_FLAG_ATOMIC(&(name)->flags, \
(mode)&DEBUG_MODE_ALL); \
} while (0)
/*
* Unset modes on a debug.
*
* MT-Safe
*/
#define DEBUG_MODE_UNSET(name, type) \
UNSET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_MODE_ALL)
/* Convenience macros for specific set operations. */
#define DEBUG_MODE_ON(name, mode) DEBUG_MODE_SET(name, mode, true)
#define DEBUG_MODE_OFF(name, mode) DEBUG_MODE_SET(name, mode, false)
/*
* Set options on a debug.
*
* MT-Safe
*/
#define DEBUG_OPT_SET(name, type) \
SET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
#define DEBUG_OPT_SET(name, opt, onoff) \
do { \
if (onoff) \
SET_FLAG_ATOMIC(&(name)->flags, (opt)&DEBUG_OPT_ALL); \
else \
UNSET_FLAG_ATOMIC(&(name)->flags, \
(opt)&DEBUG_OPT_ALL); \
} while (0)
/*
* Unset options on a debug.
*
* MT-Safe
*/
#define DEBUG_OPT_UNSET(name, type) \
UNSET_FLAG_ATOMIC(&(name)->flags, (type)&DEBUG_OPT_ALL)
/* Convenience macros for specific set operations. */
#define DEBUG_OPT_ON(name, opt) DEBUG_OPT_SET(name, opt, true)
#define DEBUG_OPT_OFF(name, opt) DEBUG_OPT_SET(name, opt, true)
/*
* Set bits on a debug.
*
* 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)
/*
* Unset bits on a debug.
*
* MT-Safe
*/
#define DEBUG_FLAGS_UNSET(name, type) UNSET_FLAG_ATOMIC(&(name)->flags, (type))
/* Convenience macros for specific set operations. */
#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)
/*
* Unset all modes and options on a debug.
@ -201,6 +202,23 @@ struct debug_callbacks {
#define DEBUG_NODE2MODE(vtynode) \
(((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.

View File

@ -85,4 +85,21 @@ static inline char *ipaddr2str(struct ipaddr *ip, char *buf, int size)
}
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__ */

View File

@ -1092,41 +1092,52 @@ void zlog_hexdump(const void *mem, unsigned int len)
unsigned long i = 0;
unsigned int j = 0;
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;
memset(buf, 0, sizeof(buf));
for (i = 0; i < len + ((len % columns) ? (columns - len % columns) : 0);
i++) {
/* print offset */
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 */
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 */
else
s += sprintf(s, " ");
s += snprintf(s, bs - (s - buf), " ");
/* print ASCII dump */
if (i % columns == (columns - 1)) {
for (j = i - (columns - 1); j <= i; j++) {
if (j >= len) /* end of block, not really
printing */
s += sprintf(s, " ");
else if (isprint((int)((const char *)mem)
[j])) /* printable char
*/
s += sprintf(
s, "%c",
/* end of block not really printing */
if (j >= len)
s += snprintf(s, bs - (s - buf), " ");
else if (isprint((int)((const char *)mem)[j]))
s += snprintf(
s, bs - (s - buf), "%c",
0xFF & ((const char *)mem)[j]);
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);

View File

@ -322,6 +322,18 @@ stream_failure:
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. */
static int zebra_message_send(struct zclient *zclient, int command,
vrf_id_t vrf_id)

View File

@ -237,14 +237,13 @@ struct zclient {
*/
#define ZAPI_MESSAGE_TABLEID 0x80
#define ZSERV_VERSION 5
/* Zserv protocol message header */
struct zserv_header {
struct zmsghdr {
uint16_t length;
uint8_t marker; /* corresponds to command field in old zserv
* always set to 255 in new zserv.
*/
/* Always set to 255 in new zserv */
uint8_t marker;
uint8_t version;
#define ZSERV_VERSION 5
vrf_id_t vrf_id;
uint16_t command;
};
@ -380,9 +379,11 @@ struct zclient_options {
/* Prototypes of zebra client service functions. */
extern struct zclient *zclient_new(struct thread_master *);
/* clang-format off */
#if CONFDATE > 20181101
CPP_NOTICE("zclient_new_notify can take over or zclient_new now");
#endif
/* clang-format on */
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 */
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,
u_char *marker, u_char *version,
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,
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_router_id_update_read(struct stream *s, struct prefix *rid);
/* clang-format off */
#if CONFDATE > 20180823
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");
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");
#endif
/* clang-format on */
extern int zapi_ipv4_route(u_char, struct zclient *, struct prefix_ipv4 *,
struct zapi_ipv4 *) __attribute__((deprecated));

1
ospfd/.gitignore vendored
View File

@ -15,4 +15,3 @@ TAGS
*~
*.loT
*.a
*clippy.c

View File

@ -604,11 +604,18 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
json_object_object_add(json, ifp->name,
json_row);
if (igmp->mtrace_only) {
json_object_boolean_true_add(
json_row, "mtraceOnly");
}
} else {
vty_out(vty,
"%-9s %5s %15s %d %7s %11s %8s\n",
ifp->name,
if_is_up(ifp) ? "up" : "down",
if_is_up(ifp)
? (igmp->mtrace_only ? "mtrc"
: "up")
: "down",
inet_ntoa(igmp->ifaddr),
pim_ifp->igmp_version,
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_row);
if (igmp->mtrace_only) {
json_object_boolean_true_add(
json_row, "mtraceOnly");
}
} else {
vty_out(vty, "Interface : %s\n", ifp->name);
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",
inet_ntoa(pim_ifp->primary_address));
vty_out(vty, "Uptime : %s\n", uptime);

View File

@ -574,7 +574,11 @@ void pim_if_addr_add(struct connected *ifc)
/* if addr new, add IGMP socket */
if (ifc->address->family == AF_INET)
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 */
@ -611,6 +615,20 @@ void pim_if_addr_add(struct connected *ifc)
}
}
} /* 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)) {

View File

@ -281,6 +281,9 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
uint16_t recv_checksum;
uint16_t checksum;
if (igmp->mtrace_only)
return 0;
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
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);
if (igmp->mtrace_only)
return 0;
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
zlog_warn(
"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,
from_str, igmp_msg,
igmp_msg_len);
break;
case PIM_IGMP_MTRACE_QUERY_REQUEST:
return igmp_mtrace_recv_qry_req(igmp, ip_hdr, ip_hdr->ip_src,
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,
struct interface *ifp)
struct interface *ifp, int mtrace_only)
{
struct pim_interface *pim_ifp;
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;
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:
@ -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 in_addr ifaddr,
struct interface *ifp)
struct interface *ifp,
bool mtrace_only)
{
struct pim_interface *pim_ifp;
struct igmp_sock *igmp;
@ -934,7 +947,7 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
return 0;
}
igmp = igmp_sock_new(fd, ifaddr, ifp);
igmp = igmp_sock_new(fd, ifaddr, ifp, mtrace_only);
if (!igmp) {
zlog_err("%s %s: igmp_sock_new() failure", __FILE__,
__PRETTY_FUNCTION__);

View File

@ -90,6 +90,8 @@ struct igmp_sock {
int querier_robustness_variable; /* QRV */
int startup_query_count;
bool mtrace_only;
struct list *igmp_group_list; /* list of struct igmp_group */
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 *pim_igmp_sock_add(struct list *igmp_sock_list,
struct in_addr ifaddr,
struct interface *ifp);
struct interface *ifp,
bool mtrace_only);
void igmp_sock_delete(struct igmp_sock *igmp);
void igmp_sock_free(struct igmp_sock *igmp);
void igmp_sock_delete_all(struct interface *ifp);

View File

@ -111,6 +111,9 @@ int igmp_v2_recv_report(struct igmp_sock *igmp, struct in_addr from,
on_trace(__PRETTY_FUNCTION__, igmp->interface, from);
if (igmp->mtrace_only)
return 0;
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
zlog_warn(
"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);
if (igmp->mtrace_only)
return 0;
if (igmp_msg_len != IGMP_V12_MSG_SIZE) {
zlog_warn(
"Recv IGMPv2 LEAVE from %s on %s: size=%d other than correct=%d",

View File

@ -1874,6 +1874,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
int local_ncb = 0;
struct pim_interface *pim_ifp;
if (igmp->mtrace_only)
return 0;
pim_ifp = igmp->interface->info;
if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {

1
sharpd/.gitignore vendored
View File

@ -13,6 +13,5 @@ TAGS
.arch-ids
*~
*.loT
*clippy.c
sharpd
sharpd.conf

View File

@ -73,6 +73,7 @@ check_PROGRAMS = \
lib/test_timer_correctness \
lib/test_timer_performance \
lib/test_ttable \
lib/test_zlog \
lib/cli/test_cli \
lib/cli/test_commands \
$(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_nexthop_iter_SOURCES = lib/test_nexthop_iter.c helpers/c/prng.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 \
helpers/c/prng.c
lib_test_ringbuf_SOURCES = lib/test_ringbuf.c
lib_test_segv_SOURCES = lib/test_segv.c
lib_test_sig_SOURCES = lib/test_sig.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 \
helpers/c/prng.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_CFLAGS = $(AM_CFLAGS) $(ZEROMQ_CFLAGS)
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_performance_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_cli_test_cli_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_ttable.py \
lib/test_ttable.refout \
lib/test_zlog.py \
ospf6d/test_lsdb.py \
ospf6d/test_lsdb.in \
ospf6d/test_lsdb.refout \

61
tests/lib/test_zlog.c Normal file
View 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
View File

@ -0,0 +1,4 @@
import frrtest
class TestZlog(frrtest.TestMultiOut):
program = './test_zlog'

1
zebra/.gitignore vendored
View File

@ -13,4 +13,3 @@ TAGS
.arch-ids
*~
*.loT
zebra_vty_clippy.c

View File

@ -30,6 +30,7 @@
*/
#define _LINUX_IN6_H
#include <netinet/if_ether.h>
#include <linux/if_bridge.h>
#include <linux/if_link.h>
#include <net/if_arp.h>
@ -362,7 +363,7 @@ static int get_iflink_speed(struct interface *interface)
/* initialize ethtool interface */
memset(&ecmd, 0, sizeof(ecmd));
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 */
if (zserv_privs.change(ZPRIVS_RAISE))

View File

@ -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
* This zclient thus is to connect to it
*/
static struct stream *ibuf;
static struct stream *obuf;
static struct zclient *zclient;
bool lm_is_external;
@ -69,7 +71,7 @@ static int relay_response_back(struct zserv *zserv)
u_int16_t resp_cmd;
src = zclient->ibuf;
dst = zserv->obuf;
dst = obuf;
stream_reset(src);
@ -87,7 +89,7 @@ static int relay_response_back(struct zserv *zserv)
/* send response back */
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) {
zlog_err("%s: Error sending Label Manager response back: %s",
__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)
{
int ret;
struct stream *s;
s = zserv->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
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. */
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
@ -161,7 +166,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv,
ret = relay_response_back(zserv);
/* Send request to external label manager */
src = zserv->ibuf;
src = ibuf;
dst = zclient->obuf;
stream_copy(dst, src);
@ -247,6 +252,9 @@ void label_manager_init(char *lm_zserv_path)
lm_is_external = true;
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()
{
list_delete_and_null(&lbl_mgr.lc_list);
stream_free(ibuf);
stream_free(obuf);
}

View File

@ -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,
struct zebra_vrf *zvrf)
void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
{
afi_t afi = 0;
int type = 0;
u_short instance;
STREAM_GETC(client->ibuf, afi);
STREAM_GETC(client->ibuf, type);
STREAM_GETW(client->ibuf, instance);
STREAM_GETC(msg, afi);
STREAM_GETC(msg, type);
STREAM_GETW(msg, instance);
if (afi == 0 || afi > AFI_MAX) {
zlog_warn("%s: Specified afi %d does not exist",
@ -287,16 +286,15 @@ stream_failure:
return;
}
void zebra_redistribute_delete(int command, struct zserv *client, int length,
struct zebra_vrf *zvrf)
void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
{
afi_t afi = 0;
int type = 0;
u_short instance;
STREAM_GETC(client->ibuf, afi);
STREAM_GETC(client->ibuf, type);
STREAM_GETW(client->ibuf, instance);
STREAM_GETC(msg, afi);
STREAM_GETC(msg, type);
STREAM_GETW(msg, instance);
if (afi == 0 || afi > AFI_MAX) {
zlog_warn("%s: Specified afi %d does not exist",
@ -325,15 +323,13 @@ stream_failure:
return;
}
void zebra_redistribute_default_add(int command, struct zserv *client,
int length, struct zebra_vrf *zvrf)
void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
{
vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
zebra_redistribute_default(client, zvrf_id(zvrf));
}
void zebra_redistribute_default_delete(int command, struct zserv *client,
int length, struct zebra_vrf *zvrf)
void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
{
vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
}

View File

@ -27,15 +27,12 @@
#include "vty.h"
#include "vrf.h"
extern void zebra_redistribute_add(int, struct zserv *, int,
struct zebra_vrf *zvrf);
extern void zebra_redistribute_delete(int, struct zserv *, int,
struct zebra_vrf *zvrf);
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);
/* ZAPI command handlers */
extern void zebra_redistribute_add(ZAPI_HANDLER_ARGS);
extern void zebra_redistribute_delete(ZAPI_HANDLER_ARGS);
extern void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS);
extern void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS);
/* ----------------- */
extern void redistribute_update(struct prefix *, struct prefix *,
struct route_entry *, struct route_entry *);

View File

@ -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
* specify a RA interval (in seconds).
*/
void zebra_interface_radv_set(struct zserv *client, u_short length,
struct zebra_vrf *zvrf, int enable)
static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
{
struct stream *s;
ifindex_t ifindex;
@ -810,7 +809,7 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
struct zebra_if *zif;
int ra_interval;
s = client->ibuf;
s = msg;
/* Get interface index and RA interval. */
STREAM_GETL(s, ifindex);
@ -859,6 +858,15 @@ stream_failure:
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,
ipv6_nd_suppress_ra_cmd,
"ipv6 nd suppress-ra",

View File

@ -103,7 +103,8 @@ typedef enum {
extern void rtadv_init(struct zebra_ns *);
extern void rtadv_terminate(struct zebra_ns *);
extern void rtadv_cmd_init(void);
extern void zebra_interface_radv_set(struct zserv *client, u_short length,
struct zebra_vrf *zvrf, int enable);
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
#endif /* _ZEBRA_RTADV_H */

View File

@ -455,8 +455,7 @@ static int fec_send(zebra_fec_t *fec, struct zserv *client)
rn = fec->rn;
/* Get output stream. */
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
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_putl(s, fec->label);
stream_putw_at(s, 0, stream_get_endp(s));
return zebra_server_send_message(client);
return zebra_server_send_message(client, s);
}
/*

View File

@ -32,17 +32,16 @@
#include "zebra/rt.h"
#include "zebra/debug.h"
int zebra_ipmr_route_stats(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS)
{
struct mcast_route_data mroute;
struct stream *s;
int suc = -1;
memset(&mroute, 0, sizeof(mroute));
STREAM_GET(&mroute.sg.src, client->ibuf, 4);
STREAM_GET(&mroute.sg.grp, client->ibuf, 4);
STREAM_GETL(client->ibuf, mroute.ifindex);
STREAM_GET(&mroute.sg.src, msg, 4);
STREAM_GET(&mroute.sg.grp, msg, 4);
STREAM_GETL(msg, mroute.ifindex);
if (IS_ZEBRA_DEBUG_KERNEL) {
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);
stream_failure:
s = client->obuf;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
stream_reset(s);
@ -68,6 +67,5 @@ stream_failure:
stream_putl(s, suc);
stream_putw_at(s, 0, stream_get_endp(s));
zebra_server_send_message(client);
return 0;
zebra_server_send_message(client, s);
}

View File

@ -22,13 +22,14 @@
#ifndef __ZEBRA_MROUTE_H__
#define __ZEBRA_MROUTE_H__
#include "zebra/zserv.h"
struct mcast_route_data {
struct prefix_sg sg;
unsigned int ifindex;
unsigned long long lastused;
};
int zebra_ipmr_route_stats(struct zserv *client, u_short length,
struct zebra_vrf *zvf);
void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS);
#endif

View File

@ -661,8 +661,7 @@ int zebra_ptm_sock_read(struct thread *thread)
}
/* BFD peer/dst register/update */
int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
int command, struct zebra_vrf *zvrf)
void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS)
{
struct stream *s;
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;
unsigned int pid;
if (command == ZEBRA_BFD_DEST_UPDATE)
if (hdr->command == ZEBRA_BFD_DEST_UPDATE)
client->bfd_peer_upd8_cnt++;
else
client->bfd_peer_add_cnt++;
if (IS_ZEBRA_DEBUG_EVENT)
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) {
ptm_cb.t_timer = NULL;
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
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);
@ -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,
tmp_buf);
s = client->ibuf;
s = msg;
STREAM_GETL(s, 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);
zebra_ptm_send_message(ptm_cb.out_data, data_len);
return 0;
return;
stream_failure:
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
}
/* BFD peer/dst deregister */
int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS)
{
struct stream *s;
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)
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) {
ptm_cb.t_timer = NULL;
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
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);
@ -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,
tmp_buf);
s = client->ibuf;
s = msg;
STREAM_GETL(s, 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);
return 0;
return;
stream_failure:
ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
return 0;
}
/* 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;
unsigned int pid;
@ -968,16 +964,16 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
if (IS_ZEBRA_DEBUG_EVENT)
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);
if (ptm_cb.ptm_sock == -1) {
ptm_cb.t_timer = NULL;
thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
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);
@ -1003,7 +999,7 @@ int zebra_ptm_bfd_client_register(struct zserv *client, u_short length)
SET_FLAG(ptm_cb.client_flags[client->proto],
ZEBRA_PTM_BFD_CLIENT_FLAG_REG);
return 0;
return;
stream_failure:
/*
@ -1013,7 +1009,7 @@ stream_failure:
* if (out_ctxt)
* ptm_lib_cleanup_msg(ptm_hdl, out_ctxt);
*/
return 0;
return;
}
/* BFD client deregister */

View File

@ -28,6 +28,8 @@ extern const char ZEBRA_PTM_SOCK_NAME[];
#define ZEBRA_PTM_BFD_CLIENT_FLAG_REG (1 << 1) /* client registered with BFD */
#include "zebra/zserv.h"
/* Zebra ptm context block */
struct zebra_ptm_cb {
int ptm_sock; /* ptm file descriptor. */
@ -62,12 +64,12 @@ int zebra_ptm_connect(struct thread *t);
void zebra_ptm_write(struct vty *vty);
int zebra_ptm_get_enable_state(void);
int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
int command, struct zebra_vrf *zvrf);
int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
struct zebra_vrf *zvrf);
/* ZAPI message handlers */
void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS);
void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS);
void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS);
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_set_ptm_state(struct interface *ifp,
struct zebra_if *zebra_ifp);

View File

@ -38,8 +38,7 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client,
if (!client->ifinfo)
return 0;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, cmd, vrf_id);
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));
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,
@ -93,8 +92,7 @@ static int zsend_bfd_peer_replay(int cmd, struct zserv *client)
{
struct stream *s;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
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));
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)

View File

@ -305,6 +305,8 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6;
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);
@ -421,6 +423,10 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
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 */
/* The nexthops are specific to this route and so the same */
/* 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_IFINDEX:
family = AFI_IP;
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN_RVTEP))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else if (nexthop_active(AFI_IP, re, nexthop, set, rn))
if (nexthop_active(AFI_IP, re, nexthop, set, rn))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
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;
memset(&vtep_ip, 0, sizeof(struct ipaddr));
vtep_ip.ipa_type = IPADDR_V4;
memcpy(&(vtep_ip.ipaddr_v4),
&(tmp_nh->gate.ipv4),
sizeof(struct in_addr));
if (afi == AFI_IP) {
vtep_ip.ipa_type = IPADDR_V4;
memcpy(&(vtep_ip.ipaddr_v4),
&(tmp_nh->gate.ipv4),
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,
&vtep_ip, p);
}

View File

@ -995,8 +995,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
re = rnh->state;
/* Get output stream. */
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
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->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)

View File

@ -1157,8 +1157,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
if (!client)
return 0;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, cmd, VRF_DEFAULT);
stream_putl(s, vni);
@ -1195,7 +1194,7 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
else
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)
return 0;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
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));
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)
return 0;
s = client->obuf;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
stream_reset(s);
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));
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));
zl3vni_get_rmac(zl3vni, &rmac);
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, ZEBRA_L3VNI_ADD, zl3vni_vrf_id(zl3vni));
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));
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)
return 0;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, ZEBRA_L3VNI_DEL, zl3vni_vrf_id(zl3vni));
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));
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)
@ -3723,8 +3719,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
if (!client)
return 0;
s = client->obuf;
stream_reset(s);
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, cmd, vrf_id);
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
client->prefixdel_cnt++;
return zebra_server_send_message(client);
return zebra_server_send_message(client, s);
}
/* 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.
*/
int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
{
struct stream *s;
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(&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. */
/* Message contains VNI, followed by MAC followed by IP (if any)
* followed by remote VTEP IP.
@ -5008,7 +5002,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
}
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
* (IP+MAC).
*/
int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
{
struct stream *s;
vni_t vni;
@ -5045,12 +5038,12 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
zlog_warn(
"%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
__PRETTY_FUNCTION__);
return -1;
return;
}
s = client->ibuf;
s = msg;
while (l < length) {
while (l < hdr->length) {
/* Obtain each remote MACIP and process. */
/* Message contains VNI, followed by MAC followed by IP (if any)
* 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,
sizeof(buf)),
vni, inet_ntoa(vtep_ip));
return -1;
return;
}
/* 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,
sizeof(buf)),
vni, inet_ntoa(vtep_ip));
return -1;
return;
}
} 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:
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.
*/
int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
{
struct stream *s;
u_short l = 0;
@ -5559,18 +5551,18 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
zlog_warn(
"%s: EVPN is not enabled yet we have received a vtep del command",
__PRETTY_FUNCTION__);
return -1;
return;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("Recv MACIP DEL for non-default VRF %u",
zvrf_id(zvrf));
return -1;
return;
}
s = client->ibuf;
s = msg;
while (l < length) {
while (l < hdr->length) {
/* Obtain each remote VTEP and process. */
STREAM_GETL(s, vni);
l += 4;
@ -5623,14 +5615,13 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
}
stream_failure:
return 0;
return;
}
/*
* Handle message from client to add a remote VTEP for a VNI.
*/
int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
{
struct stream *s;
u_short l = 0;
@ -5644,18 +5635,18 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
zlog_warn(
"%s: EVPN not enabled yet we received a vtep_add zapi call",
__PRETTY_FUNCTION__);
return -1;
return;
}
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("Recv MACIP ADD for non-default VRF %u",
zvrf_id(zvrf));
return -1;
return;
}
s = client->ibuf;
s = msg;
while (l < length) {
while (l < hdr->length) {
/* Obtain each remote VTEP and process. */
STREAM_GETL(s, vni);
l += 4;
@ -5705,7 +5696,7 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
}
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
* routes
*/
int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
{
struct stream *s;
int advertise;
@ -6527,19 +6517,19 @@ int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
zvrf_id(zvrf));
return -1;
return;
}
s = client->ibuf;
s = msg;
advertise = stream_getc(s);
vni = stream_get3(s);
zvni = zvni_lookup(vni);
if (!zvni)
return 0;
return;
if (zvni->advertise_subnet == advertise)
return 0;
return;
if (IS_ZEBRA_DEBUG_VXLAN)
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;
if (!ifp)
return 0;
return;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return 0;
return;
zl2_info = zif->l2info.vxl;
vlan_if =
zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
if (!vlan_if)
return 0;
return;
if (zvni->advertise_subnet)
zvni_advertise_subnet(zvni, vlan_if, 1);
else
zvni_advertise_subnet(zvni, vlan_if, 0);
return 0;
}
/*
* Handle message from client to enable/disable advertisement of g/w macip
* routes
*/
int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
{
struct stream *s;
int advertise;
@ -6590,10 +6577,10 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
if (zvrf_id(zvrf) != VRF_DEFAULT) {
zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
zvrf_id(zvrf));
return -1;
return;
}
s = client->ibuf;
s = msg;
STREAM_GETC(s, advertise);
STREAM_GET(&vni, s, 3);
@ -6606,7 +6593,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
: "disabled");
if (zvrf->advertise_gw_macip == advertise)
return 0;
return;
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);
if (!zvni)
return 0;
return;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
@ -6635,26 +6622,26 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
: "disabled");
if (zvni->advertise_gw_macip == advertise)
return 0;
return;
zvni->advertise_gw_macip = advertise;
ifp = zvni->vxlan_if;
if (!ifp)
return 0;
return;
zif = ifp->info;
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
return 0;
return;
zl2_info = zif->l2info.vxl;
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return 0;
return;
if (advertise_gw_macip_enabled(zvni)) {
/* Add primary SVI MAC-IP */
@ -6676,7 +6663,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
}
stream_failure:
return 0;
return;
}
@ -6686,8 +6673,7 @@ stream_failure:
* when disabled, the entries should be deleted and remote VTEPs and MACs
* uninstalled from the kernel.
*/
int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
struct zebra_vrf *zvrf)
void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
{
struct stream *s = NULL;
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) {
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);
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");
if (zvrf->advertise_all_vni == advertise)
return 0;
return;
zvrf->advertise_all_vni = advertise;
if (is_evpn_enabled()) {
@ -6732,13 +6718,13 @@ int zebra_vxlan_advertise_all_vni(struct zserv *client, u_short length,
/* cleanup all l3vnis */
zns = zebra_ns_lookup(NS_DEFAULT);
if (!zns)
return -1;
return;
hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL);
}
stream_failure:
return 0;
return;
}
/*

View File

@ -33,6 +33,7 @@
#include "lib/json.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zserv.h"
/* Is EVPN enabled? */
#define EVPN_ENABLED(zvrf) (zvrf)->advertise_all_vni
@ -51,6 +52,15 @@ static inline int is_evpn_enabled()
#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 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);
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,
struct interface *link_if,
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,
struct interface *br_if,
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_update(struct interface *ifp, u_int16_t chgflags);
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,
char *err, int err_str_sz,
int filter, int add);

File diff suppressed because it is too large Load Diff

View File

@ -47,8 +47,12 @@ struct zserv {
int sock;
/* Input/output buffer to the client. */
struct stream *ibuf;
struct stream *obuf;
struct stream_fifo *ibuf_fifo;
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. */
struct buffer *wb;
@ -129,6 +133,10 @@ struct zserv {
int last_write_cmd;
};
#define ZAPI_HANDLER_ARGS \
struct zserv *client, struct zmsghdr *hdr, struct stream *msg, \
struct zebra_vrf *zvrf
/* Zebra instance */
struct zebra_t {
/* 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 *,
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);