From 0a50c248132f3eec45c3e46ad1cf0dac1cb72e91 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Fri, 27 Mar 2020 14:37:16 -0700 Subject: [PATCH] bgpd: attr changes for EAD routes Add ESI as an inline attribute field along with the other EVPN attributes. This may be re-worked when the rest of the EVPN attributes find a new home. Some cleanup has been done to get rid of stale/unused references to ESI. And also to consolidate duplicate definitions of ES ID types. Signed-off-by: Anuradha Karuppiah --- bgpd/bgp_attr.c | 1 + bgpd/bgp_attr.h | 3 +++ bgpd/bgp_attr_evpn.c | 39 ++++--------------------------- bgpd/bgp_attr_evpn.h | 21 +---------------- bgpd/bgp_evpn.c | 2 +- bgpd/bgp_route.c | 55 ++++++++++---------------------------------- bgpd/bgp_route.h | 2 +- 7 files changed, 23 insertions(+), 100 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 08e50fc4f2..50a2dd3d28 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -718,6 +718,7 @@ bool attrhash_cmp(const void *p1, const void *p2) && IPV4_ADDR_SAME(&attr1->originator_id, &attr2->originator_id) && overlay_index_same(attr1, attr2) + && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) && attr1->nh_ifindex == attr2->nh_ifindex && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex && attr1->distance == attr2->distance diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 94531313ae..4d67194e10 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -253,6 +253,9 @@ struct attr { /* Link bandwidth value, if any. */ uint32_t link_bw; + + /* EVPN ES */ + esi_t esi; }; /* rmap_change_flags definition */ diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 65072088ae..e81ef79fbb 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -54,47 +54,27 @@ void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac) * format accepted: AA:BB:CC:DD:EE:FF:GG:HH:II:JJ * if id is null, check only is done */ -bool str2esi(const char *str, struct eth_segment_id *id) +bool str2esi(const char *str, esi_t *id) { - unsigned int a[ESI_LEN]; + unsigned int a[ESI_BYTES]; int i; if (!str) return false; if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2, a + 3, a + 4, a + 5, a + 6, a + 7, a + 8, a + 9) - != ESI_LEN) { + != ESI_BYTES) { /* error in incoming str length */ return false; } /* valid mac address */ if (!id) return true; - for (i = 0; i < ESI_LEN; ++i) + for (i = 0; i < ESI_BYTES; ++i) id->val[i] = a[i] & 0xff; return true; } -char *esi2str(struct eth_segment_id *id) -{ - char *ptr; - uint8_t *val; - - if (!id) - return NULL; - - val = id->val; - ptr = XMALLOC(MTYPE_TMP, - (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char)); - - snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1), - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", val[0], - val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], - val[9]); - - return ptr; -} - char *ecom_mac2str(char *ecom_mac) { char *en; @@ -292,14 +272,3 @@ extern bool is_zero_gw_ip(const union gw_addr *gw_ip, const afi_t afi) return false; } - -extern bool is_zero_esi(const struct eth_segment_id *esi) -{ - int i; - - for (i = 0; i < ESI_LEN; i++) - if (esi->val[i]) - return false; - - return true; -} diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index c1bfd83765..e878634610 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -21,38 +21,20 @@ #ifndef _QUAGGA_BGP_ATTR_EVPN_H #define _QUAGGA_BGP_ATTR_EVPN_H -/* value of first byte of ESI */ -#define ESI_TYPE_ARBITRARY 0 /* */ -#define ESI_TYPE_LACP 1 /* <> */ -#define ESI_TYPE_BRIDGE 2 /* ::00 */ -#define ESI_TYPE_MAC 3 /* : */ -#define ESI_TYPE_ROUTER 4 /* : */ -#define ESI_TYPE_AS 5 /* : */ - -#define MAX_ESI {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} -#define ESI_LEN 10 - #define MAX_ET 0xffffffff struct attr; -/* EVPN ESI */ -struct eth_segment_id { - uint8_t val[ESI_LEN]; -}; - union gw_addr { struct in_addr ipv4; struct in6_addr ipv6; }; struct bgp_route_evpn { - struct eth_segment_id eth_s_id; union gw_addr gw_ip; }; -extern bool str2esi(const char *str, struct eth_segment_id *id); -extern char *esi2str(struct eth_segment_id *id); +extern bool str2esi(const char *str, esi_t *id); extern char *ecom_mac2str(char *ecom_mac); extern void bgp_add_routermac_ecom(struct attr *attr, @@ -68,5 +50,4 @@ extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag); extern bool is_zero_gw_ip(const union gw_addr *gw_ip, afi_t afi); -extern bool is_zero_esi(const struct eth_segment_id *esi); #endif /* _QUAGGA_BGP_ATTR_EVPN_H */ diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 7909a6feee..605a2c0589 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3537,7 +3537,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, if (attr) { is_valid_update = true; - if (is_zero_mac(&attr->rmac) && is_zero_esi(&evpn.eth_s_id) && + if (is_zero_mac(&attr->rmac) && is_zero_gw_ip(&evpn.gw_ip, gw_afi)) is_valid_update = false; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 6b2a5f55b7..6564da14d7 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -79,6 +79,7 @@ #include "bgpd/bgp_encap_types.h" #include "bgpd/bgp_encap_tlv.h" #include "bgpd/bgp_evpn.h" +#include "bgpd/bgp_evpn_mh.h" #include "bgpd/bgp_evpn_vty.h" #include "bgpd/bgp_flowspec.h" #include "bgpd/bgp_flowspec_util.h" @@ -3172,19 +3173,10 @@ struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance, } static void overlay_index_update(struct attr *attr, - struct eth_segment_id *eth_s_id, union gw_addr *gw_ip) { if (!attr) return; - - if (eth_s_id == NULL) { - memset(&(attr->evpn_overlay.eth_s_id), 0, - sizeof(struct eth_segment_id)); - } else { - memcpy(&(attr->evpn_overlay.eth_s_id), eth_s_id, - sizeof(struct eth_segment_id)); - } if (gw_ip == NULL) { memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr)); } else { @@ -3194,20 +3186,17 @@ static void overlay_index_update(struct attr *attr, } static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, - struct eth_segment_id *eth_s_id, union gw_addr *gw_ip) { - struct eth_segment_id *path_eth_s_id, *path_eth_s_id_remote; union gw_addr *path_gw_ip, *path_gw_ip_remote; union { - struct eth_segment_id esi; + esi_t esi; union gw_addr ip; } temp; if (afi != AFI_L2VPN) return true; - path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id); path_gw_ip = &(path->attr->evpn_overlay.gw_ip); if (gw_ip == NULL) { @@ -3216,17 +3205,7 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, } else path_gw_ip_remote = gw_ip; - if (eth_s_id == NULL) { - memset(&temp, 0, sizeof(temp)); - path_eth_s_id_remote = &temp.esi; - } else - path_eth_s_id_remote = eth_s_id; - - if (!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr))) - return false; - - return !memcmp(path_eth_s_id, path_eth_s_id_remote, - sizeof(struct eth_segment_id)); + return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)); } /* Check if received nexthop is valid or not. */ @@ -3521,7 +3500,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, num_labels * sizeof(mpls_label_t)) == 0) && (overlay_index_equal( - afi, pi, evpn == NULL ? NULL : &evpn->eth_s_id, + afi, pi, evpn == NULL ? NULL : &evpn->gw_ip))) { if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) @@ -3746,7 +3725,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update Overlay Index */ if (afi == AFI_L2VPN) { overlay_index_update( - pi->attr, evpn == NULL ? NULL : &evpn->eth_s_id, + pi->attr, evpn == NULL ? NULL : &evpn->gw_ip); } @@ -3912,7 +3891,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update Overlay Index */ if (afi == AFI_L2VPN) { overlay_index_update(new->attr, - evpn == NULL ? NULL : &evpn->eth_s_id, evpn == NULL ? NULL : &evpn->gw_ip); } /* Nexthop reachability check. */ @@ -5301,7 +5279,7 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, else if (bgp_static->gatewayIp.family == AF_INET6) memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6), sizeof(struct in6_addr)); - overlay_index_update(&attr, bgp_static->eth_s_id, &add); + memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t)); if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) { struct bgp_encap_type_vxlan bet; memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan)); @@ -5352,7 +5330,7 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p, if (pi) { memset(&add, 0, sizeof(union gw_addr)); if (attrhash_cmp(pi->attr, attr_new) - && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add) + && overlay_index_equal(afi, pi, &add) && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) { bgp_dest_unlock_node(dest); bgp_attr_unintern(&attr_new); @@ -5856,7 +5834,7 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty, if (esi) { bgp_static->eth_s_id = XCALLOC(MTYPE_ATTR, - sizeof(struct eth_segment_id)); + sizeof(esi_t)); str2esi(esi, bgp_static->eth_s_id); } if (routermac) { @@ -8340,15 +8318,6 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p, } } - char *str = esi2str(&(attr->evpn_overlay.eth_s_id)); - - if (!json_path) - vty_out(vty, "%s", str); - else - json_object_string_add(json_overlay, "esi", str); - - XFREE(MTYPE_TMP, str); - if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) { inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf, BUFSIZ); @@ -13316,6 +13285,7 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, char buf[PREFIX_STRLEN * 2]; char buf2[SU_ADDRSTRLEN]; char rdbuf[RD_ADDRSTRLEN]; + char esi_buf[ESI_BYTES]; /* Network configuration. */ for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest; @@ -13331,13 +13301,13 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, continue; char *macrouter = NULL; - char *esi = NULL; if (bgp_static->router_mac) macrouter = prefix_mac2str( bgp_static->router_mac, NULL, 0); if (bgp_static->eth_s_id) - esi = esi2str(bgp_static->eth_s_id); + esi_to_str(bgp_static->eth_s_id, + esi_buf, sizeof(esi_buf)); p = bgp_dest_get_prefix(dest); prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest); @@ -13368,11 +13338,10 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n", buf, rdbuf, p->u.prefix_evpn.prefix_addr.eth_tag, - decode_label(&bgp_static->label), esi, buf2, + decode_label(&bgp_static->label), esi_buf, buf2, macrouter); XFREE(MTYPE_TMP, macrouter); - XFREE(MTYPE_TMP, esi); } } } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 32c65c8fac..42cb0ec8a6 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -303,7 +303,7 @@ struct bgp_static { mpls_label_t label; /* EVPN */ - struct eth_segment_id *eth_s_id; + esi_t *eth_s_id; struct ethaddr *router_mac; uint16_t encap_tunneltype; struct prefix gatewayIp; -- 2.39.5