diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 0e341a8c6b..add999bd44 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -304,15 +304,3 @@ extern int bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, return -1; return 0; } - -extern bool is_zero_gw_ip(const union gw_addr *gw_ip, const afi_t afi) -{ - if (afi == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED(&gw_ip->ipv6)) - return true; - - if (afi == AF_INET && gw_ip->ipv4.s_addr == INADDR_ANY) - return true; - - return false; -} - diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index 102509fdd7..64f0e7c51a 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -25,11 +25,6 @@ struct attr; -union gw_addr { - struct in_addr ipv4; - struct in6_addr ipv6; -}; - enum overlay_index_type { OVERLAY_INDEX_TYPE_NONE, OVERLAY_INDEX_GATEWAY_IP, @@ -45,7 +40,7 @@ enum overlay_index_type { struct bgp_route_evpn { enum overlay_index_type type; esi_t eth_s_id; - union gw_addr gw_ip; + struct ipaddr gw_ip; }; extern bool str2esi(const char *str, esi_t *id); @@ -64,6 +59,4 @@ extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag, bool *proxy); extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg); -extern bool is_zero_gw_ip(const union gw_addr *gw_ip, afi_t afi); - #endif /* _QUAGGA_BGP_ATTR_EVPN_H */ diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index ea54c14222..ffa4aca3fb 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1335,7 +1335,8 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, if (src_attr && !IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) { attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; - memcpy(&attr.evpn_overlay.gw_ip.ipv6, + SET_IPADDR_V6(&attr.evpn_overlay.gw_ip); + memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6, &src_attr->mp_nexthop_global, sizeof(struct in6_addr)); } @@ -1344,7 +1345,8 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) { if (src_attr && src_attr->nexthop.s_addr != 0) { attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; - memcpy(&attr.evpn_overlay.gw_ip.ipv4, + SET_IPADDR_V4(&attr.evpn_overlay.gw_ip); + memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4, &src_attr->nexthop, sizeof(struct in_addr)); } } @@ -2470,11 +2472,11 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, if (afi == AFI_IP6) { memcpy(&attr.mp_nexthop_global, - &attr.evpn_overlay.gw_ip.ipv6, + &attr.evpn_overlay.gw_ip.ipaddr_v6, sizeof(struct in6_addr)); attr.mp_nexthop_len = IPV6_MAX_BYTELEN; } else { - attr.nexthop = attr.evpn_overlay.gw_ip.ipv4; + attr.nexthop = attr.evpn_overlay.gw_ip.ipaddr_v4; attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); } } @@ -4041,7 +4043,6 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, uint32_t eth_tag; mpls_label_t label; /* holds the VNI as in the packet */ int ret; - afi_t gw_afi; bool is_valid_update = true; /* Type-5 route should be 34 or 58 bytes: @@ -4100,17 +4101,17 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, SET_IPADDR_V4(&p.prefix.prefix_addr.ip); memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4); pfx += 4; - memcpy(&evpn.gw_ip.ipv4, pfx, 4); + SET_IPADDR_V4(&evpn.gw_ip); + memcpy(&evpn.gw_ip.ipaddr_v4, pfx, 4); pfx += 4; - gw_afi = AF_INET; } else { SET_IPADDR_V6(&p.prefix.prefix_addr.ip); memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); pfx += IPV6_MAX_BYTELEN; - memcpy(&evpn.gw_ip.ipv6, pfx, IPV6_MAX_BYTELEN); + SET_IPADDR_V6(&evpn.gw_ip); + memcpy(&evpn.gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); pfx += IPV6_MAX_BYTELEN; - gw_afi = AF_INET6; } /* Get the VNI (in MPLS label field). Stored as bytes here. */ @@ -4127,20 +4128,20 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, * An update containing a non-zero gateway IP and a non-zero ESI * at the same time is should be treated as withdraw */ - if (bgp_evpn_is_esi_valid(&evpn.eth_s_id) - && !is_zero_gw_ip(&evpn.gw_ip, gw_afi)) { + if (bgp_evpn_is_esi_valid(&evpn.eth_s_id) && + !ipaddr_is_zero(&evpn.gw_ip)) { flog_err(EC_BGP_EVPN_ROUTE_INVALID, "%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.", peer->host); is_valid_update = false; } else if (bgp_evpn_is_esi_valid(&evpn.eth_s_id)) evpn.type = OVERLAY_INDEX_ESI; - else if (!is_zero_gw_ip(&evpn.gw_ip, gw_afi)) + else if (!ipaddr_is_zero(&evpn.gw_ip)) evpn.type = OVERLAY_INDEX_GATEWAY_IP; if (attr) { - if (is_zero_mac(&attr->rmac) - && !bgp_evpn_is_esi_valid(&evpn.eth_s_id) - && is_zero_gw_ip(&evpn.gw_ip, gw_afi) && label == 0) { + if (is_zero_mac(&attr->rmac) && + !bgp_evpn_is_esi_valid(&evpn.eth_s_id) && + ipaddr_is_zero(&evpn.gw_ip) && label == 0) { flog_err(EC_BGP_EVPN_ROUTE_INVALID, "%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero", peer->host); @@ -4213,9 +4214,10 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, bgp_attr_get_evpn_overlay(attr); if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) - stream_put_ipv4(s, evpn_overlay->gw_ip.ipv4.s_addr); + stream_put_ipv4(s, + evpn_overlay->gw_ip.ipaddr_v4.s_addr); else - stream_put(s, &(evpn_overlay->gw_ip.ipv6), 16); + stream_put(s, &(evpn_overlay->gw_ip.ipaddr_v6), 16); } else { if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) stream_put_ipv4(s, 0); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 08ab08ce45..23631d89cb 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6097,13 +6097,13 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, if (bgp_static->gatewayIp.family == AF_INET) { SET_IPADDR_V4(&attr.evpn_overlay.gw_ip); memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4, - &bgp_static->gatewayIp.u.prefix4, - IPV4_MAX_BYTELEN); + &bgp_static->gatewayIp.u.prefix4, + IPV4_MAX_BYTELEN); } else if (bgp_static->gatewayIp.family == AF_INET6) { SET_IPADDR_V6(&attr.evpn_overlay.gw_ip); memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6, - &bgp_static->gatewayIp.u.prefix6, - IPV6_MAX_BYTELEN); + &bgp_static->gatewayIp.u.prefix6, + IPV6_MAX_BYTELEN); } memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t)); if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) { @@ -9497,10 +9497,7 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p, const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr); - if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) - inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ); - else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) - inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ); + ipaddr2str(&eo->gw_ip, buf, BUFSIZ); if (!json_path) vty_out(vty, "/%s", buf); @@ -9913,12 +9910,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { char gwip_buf[INET6_ADDRSTRLEN]; - if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)&bn->p)) - inet_ntop(AF_INET, &attr->evpn_overlay.gw_ip.ipv4, - gwip_buf, sizeof(gwip_buf)); - else - inet_ntop(AF_INET6, &attr->evpn_overlay.gw_ip.ipv6, - gwip_buf, sizeof(gwip_buf)); + ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf, + sizeof(gwip_buf)); if (json_paths) json_object_string_add(json_path, "gatewayIP", diff --git a/lib/ipaddr.h b/lib/ipaddr.h index 730c7ce130..a334ea969e 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -170,6 +170,19 @@ static inline int ipaddr_cmp(const struct ipaddr *a, const struct ipaddr *b) } } +static inline bool ipaddr_is_zero(const struct ipaddr *ip) +{ + switch (ip->ipa_type) { + case IPADDR_NONE: + return true; + case IPADDR_V4: + return ip->ipaddr_v4.s_addr == INADDR_ANY; + case IPADDR_V6: + return IN6_IS_ADDR_UNSPECIFIED(&ip->ipaddr_v6); + } + return true; +} + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pIA" (struct ipaddr *) #endif