From 478566d68b50a988b25066e519493308b309f3bd Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 5 Sep 2019 12:58:58 -0400 Subject: zebra: avoid using zebra datastructs in evpn dataplane path Some netlink-facing code used for evpn/vxlan programming was being run in the dataplane pthread, but accessing zebra core datastructs. Move some additional data into the dataplane context, and use it in the netlink path instead. Signed-off-by: Mark Stapp --- zebra/rt_netlink.c | 64 ++++++++++------------------------------- zebra/zebra_dplane.c | 20 ++++++++++--- zebra/zebra_dplane.h | 3 ++ zebra/zebra_vxlan.c | 80 +++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 100 insertions(+), 67 deletions(-) (limited to 'zebra') diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5edcf9bb8..91a302403 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2304,13 +2304,7 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx) } req; int ret; int dst_alen; - struct zebra_if *zif; - struct interface *br_if; - struct zebra_if *br_zif; int vid_present = 0; - char vid_buf[20]; - struct zebra_ns *zns; - struct interface *ifp; int cmd; struct in_addr vtep_ip; vlanid_t vid; @@ -2320,42 +2314,6 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx) else cmd = RTM_DELNEIGH; - /* Locate zebra ns and interface objects from context data */ - zns = zebra_ns_lookup(dplane_ctx_get_ns(ctx)->ns_id); - if (zns == NULL) { - /* Nothing to be done */ - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("MAC %s on IF %s(%u) - zebra ns unknown", - (cmd == RTM_NEWNEIGH) ? "add" : "del", - dplane_ctx_get_ifname(ctx), - dplane_ctx_get_ifindex(ctx)); - - return ZEBRA_DPLANE_REQUEST_FAILURE; - } - - ifp = if_lookup_by_index_per_ns(zns, dplane_ctx_get_ifindex(ctx)); - if (ifp == NULL) { - /* Nothing to be done */ - /* Nothing to be done */ - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("MAC %s on IF %s(%u) - interface unknown", - (cmd == RTM_NEWNEIGH) ? "add" : "del", - dplane_ctx_get_ifname(ctx), - dplane_ctx_get_ifindex(ctx)); - return ZEBRA_DPLANE_REQUEST_FAILURE; - } - - vid = dplane_ctx_mac_get_vlan(ctx); - - zif = ifp->info; - if ((br_if = zif->brslave_info.br_if) == NULL) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("MAC %s on IF %s(%u) - no mapping to bridge", - (cmd == RTM_NEWNEIGH) ? "add" : "del", - ifp->name, ifp->ifindex); - return ZEBRA_DPLANE_REQUEST_FAILURE; - } - memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); @@ -2374,24 +2332,31 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx) addattr_l(&req.n, sizeof(req), NDA_LLADDR, dplane_ctx_mac_get_addr(ctx), 6); - req.ndm.ndm_ifindex = ifp->ifindex; + req.ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx); dst_alen = 4; // TODO: hardcoded vtep_ip = *(dplane_ctx_mac_get_vtep_ip(ctx)); addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen); - br_zif = (struct zebra_if *)br_if->info; - if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) && vid > 0) { + vid = dplane_ctx_mac_get_vlan(ctx); + + if (vid > 0) { addattr16(&req.n, sizeof(req), NDA_VLAN, vid); vid_present = 1; - sprintf(vid_buf, " VLAN %u", vid); } - addattr32(&req.n, sizeof(req), NDA_MASTER, br_if->ifindex); + addattr32(&req.n, sizeof(req), NDA_MASTER, + dplane_ctx_mac_get_br_ifindex(ctx)); if (IS_ZEBRA_DEBUG_KERNEL) { char ipbuf[PREFIX_STRLEN]; char buf[ETHER_ADDR_STRLEN]; char dst_buf[PREFIX_STRLEN + 10]; + char vid_buf[20]; + + if (vid_present) + snprintf(vid_buf, sizeof(vid_buf), " VLAN %u", vid); + else + vid_buf[0] = '\0'; inet_ntop(AF_INET, &vtep_ip, ipbuf, sizeof(ipbuf)); snprintf(dst_buf, sizeof(dst_buf), " dst %s", ipbuf); @@ -2399,8 +2364,9 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx) zlog_debug("Tx %s family %s IF %s(%u)%s %sMAC %s%s", nl_msg_type_to_str(cmd), - nl_family_to_str(req.ndm.ndm_family), ifp->name, - ifp->ifindex, vid_present ? vid_buf : "", + nl_family_to_str(req.ndm.ndm_family), + dplane_ctx_get_ifname(ctx), + dplane_ctx_get_ifindex(ctx), vid_buf, dplane_ctx_mac_is_sticky(ctx) ? "sticky " : "", buf, dst_buf); } diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 2bf541617..12f8a1ae3 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -152,6 +152,7 @@ struct dplane_intf_info { */ struct dplane_mac_info { vlanid_t vid; + ifindex_t br_ifindex; struct ethaddr mac; struct in_addr vtep_ip; bool is_sticky; @@ -377,6 +378,7 @@ static enum zebra_dplane_result intf_addr_update_internal( enum dplane_op_e op); static enum zebra_dplane_result mac_update_internal( enum dplane_op_e op, const struct interface *ifp, + const struct interface *br_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip, bool sticky); static enum zebra_dplane_result neigh_update_internal( @@ -1272,6 +1274,12 @@ const struct in_addr *dplane_ctx_mac_get_vtep_ip( return &(ctx->u.macinfo.vtep_ip); } +ifindex_t dplane_ctx_mac_get_br_ifindex(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + return ctx->u.macinfo.br_ifindex; +} + /* Accessors for neighbor information */ const struct ipaddr *dplane_ctx_neigh_get_ipaddr( const struct zebra_dplane_ctx *ctx) @@ -2134,6 +2142,7 @@ static enum zebra_dplane_result intf_addr_update_internal( * Enqueue vxlan/evpn mac add (or update). */ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip, @@ -2142,8 +2151,8 @@ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, enum zebra_dplane_result result; /* Use common helper api */ - result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, vid, - mac, vtep_ip, sticky); + result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp, + vid, mac, vtep_ip, sticky); return result; } @@ -2151,6 +2160,7 @@ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, * Enqueue vxlan/evpn mac delete. */ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip) @@ -2158,8 +2168,8 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, enum zebra_dplane_result result; /* Use common helper api */ - result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, vid, mac, - vtep_ip, false); + result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp, + vid, mac, vtep_ip, false); return result; } @@ -2169,6 +2179,7 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, static enum zebra_dplane_result mac_update_internal(enum dplane_op_e op, const struct interface *ifp, + const struct interface *br_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip, @@ -2204,6 +2215,7 @@ mac_update_internal(enum dplane_op_e op, /* Init the mac-specific data area */ memset(&ctx->u.macinfo, 0, sizeof(ctx->u.macinfo)); + ctx->u.macinfo.br_ifindex = br_ifp->ifindex; ctx->u.macinfo.vtep_ip = vtep_ip; ctx->u.macinfo.mac = *mac; ctx->u.macinfo.vid = vid; diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 31f0fc98b..30dfdafdf 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -328,6 +328,7 @@ const struct ethaddr *dplane_ctx_mac_get_addr( const struct zebra_dplane_ctx *ctx); const struct in_addr *dplane_ctx_mac_get_vtep_ip( const struct zebra_dplane_ctx *ctx); +ifindex_t dplane_ctx_mac_get_br_ifindex(const struct zebra_dplane_ctx *ctx); /* Accessors for neighbor information */ const struct ipaddr *dplane_ctx_neigh_get_ipaddr( @@ -402,12 +403,14 @@ enum zebra_dplane_result dplane_intf_addr_unset(const struct interface *ifp, * Enqueue evpn mac operations for the dataplane. */ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip, bool sticky); enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, + const struct interface *bridge_ifp, vlanid_t vid, const struct ethaddr *mac, struct in_addr vtep_ip); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index cd388188d..c7f2976ac 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3740,10 +3740,12 @@ static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if) */ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac) { - struct zebra_if *zif; - struct zebra_l2info_vxlan *vxl; + const struct zebra_if *zif, *br_zif; + const struct zebra_l2info_vxlan *vxl; bool sticky; enum zebra_dplane_result res; + const struct interface *br_ifp; + vlanid_t vid; if (!(mac->flags & ZEBRA_MAC_REMOTE)) return 0; @@ -3751,13 +3753,25 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac) zif = zvni->vxlan_if->info; if (!zif) return -1; + + br_ifp = zif->brslave_info.br_if; + if (br_ifp == NULL) + return -1; + vxl = &zif->l2info.vxl; sticky = !!CHECK_FLAG(mac->flags, (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)); - res = dplane_mac_add(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr, - mac->fwd_info.r_vtep_ip, sticky); + br_zif = (const struct zebra_if *)(br_ifp->info); + + if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif)) + vid = vxl->access_vlan; + else + vid = 0; + + res = dplane_mac_add(zvni->vxlan_if, br_ifp, vid, + &mac->macaddr, mac->fwd_info.r_vtep_ip, sticky); if (res != ZEBRA_DPLANE_REQUEST_FAILURE) return 0; else @@ -3769,10 +3783,11 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac) */ static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac) { - struct zebra_if *zif; - struct zebra_l2info_vxlan *vxl; + const struct zebra_if *zif, *br_zif; + const struct zebra_l2info_vxlan *vxl; struct in_addr vtep_ip; - struct interface *ifp; + const struct interface *ifp, *br_ifp; + vlanid_t vid; enum zebra_dplane_result res; if (!(mac->flags & ZEBRA_MAC_REMOTE)) @@ -3788,12 +3803,24 @@ static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac) zif = zvni->vxlan_if->info; if (!zif) return -1; + + br_ifp = zif->brslave_info.br_if; + if (br_ifp == NULL) + return -1; + vxl = &zif->l2info.vxl; + br_zif = (const struct zebra_if *)br_ifp->info; + + if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif)) + vid = vxl->access_vlan; + else + vid = 0; + ifp = zvni->vxlan_if; vtep_ip = mac->fwd_info.r_vtep_ip; - res = dplane_mac_del(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip); + res = dplane_mac_del(ifp, br_ifp, vid, &mac->macaddr, vtep_ip); if (res != ZEBRA_DPLANE_REQUEST_FAILURE) return 0; else @@ -4496,9 +4523,11 @@ static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) */ static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) { - struct zebra_if *zif = NULL; - struct zebra_l2info_vxlan *vxl = NULL; + const struct zebra_if *zif = NULL, *br_zif = NULL; + const struct zebra_l2info_vxlan *vxl = NULL; + const struct interface *br_ifp; enum zebra_dplane_result res; + vlanid_t vid; if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC))) @@ -4508,9 +4537,20 @@ static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) if (!zif) return -1; + br_ifp = zif->brslave_info.br_if; + if (br_ifp == NULL) + return -1; + vxl = &zif->l2info.vxl; - res = dplane_mac_add(zl3vni->vxlan_if, vxl->access_vlan, + br_zif = (const struct zebra_if *)br_ifp->info; + + if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif)) + vid = vxl->access_vlan; + else + vid = 0; + + res = dplane_mac_add(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0); if (res != ZEBRA_DPLANE_REQUEST_FAILURE) return 0; @@ -4524,8 +4564,10 @@ static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) { char buf[ETHER_ADDR_STRLEN]; - struct zebra_if *zif = NULL; - struct zebra_l2info_vxlan *vxl = NULL; + const struct zebra_if *zif = NULL, *br_zif; + const struct zebra_l2info_vxlan *vxl = NULL; + const struct interface *br_ifp; + vlanid_t vid; enum zebra_dplane_result res; if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) @@ -4546,9 +4588,19 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac) if (!zif) return -1; + br_ifp = zif->brslave_info.br_if; + if (br_ifp == NULL) + return -1; + vxl = &zif->l2info.vxl; - res = dplane_mac_del(zl3vni->vxlan_if, vxl->access_vlan, + br_zif = (const struct zebra_if *)br_ifp->info; + if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif)) + vid = vxl->access_vlan; + else + vid = 0; + + res = dplane_mac_del(zl3vni->vxlan_if, br_ifp, vid, &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip); if (res != ZEBRA_DPLANE_REQUEST_FAILURE) return 0; -- cgit v1.2.3