Merge pull request #4937 from mjstapp/fix_evpn_brif

zebra: avoid using zebra datastructs in evpn dataplane path
This commit is contained in:
Donald Sharp 2019-09-06 13:47:38 -04:00 committed by GitHub
commit c50addb34a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 78 deletions

View File

@ -2304,13 +2304,7 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx)
} req; } req;
int ret; int ret;
int dst_alen; int dst_alen;
struct zebra_if *zif;
struct interface *br_if;
struct zebra_if *br_zif;
int vid_present = 0; int vid_present = 0;
char vid_buf[20];
struct zebra_ns *zns;
struct interface *ifp;
int cmd; int cmd;
struct in_addr vtep_ip; struct in_addr vtep_ip;
vlanid_t vid; vlanid_t vid;
@ -2320,42 +2314,6 @@ netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx)
else else
cmd = RTM_DELNEIGH; 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)); memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); 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, addattr_l(&req.n, sizeof(req), NDA_LLADDR,
dplane_ctx_mac_get_addr(ctx), 6); 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 dst_alen = 4; // TODO: hardcoded
vtep_ip = *(dplane_ctx_mac_get_vtep_ip(ctx)); vtep_ip = *(dplane_ctx_mac_get_vtep_ip(ctx));
addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen); addattr_l(&req.n, sizeof(req), NDA_DST, &vtep_ip, dst_alen);
br_zif = (struct zebra_if *)br_if->info; vid = dplane_ctx_mac_get_vlan(ctx);
if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) && vid > 0) {
if (vid > 0) {
addattr16(&req.n, sizeof(req), NDA_VLAN, vid); addattr16(&req.n, sizeof(req), NDA_VLAN, vid);
vid_present = 1; 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) { if (IS_ZEBRA_DEBUG_KERNEL) {
char ipbuf[PREFIX_STRLEN]; char ipbuf[PREFIX_STRLEN];
char buf[ETHER_ADDR_STRLEN]; char buf[ETHER_ADDR_STRLEN];
char dst_buf[PREFIX_STRLEN + 10]; 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)); inet_ntop(AF_INET, &vtep_ip, ipbuf, sizeof(ipbuf));
snprintf(dst_buf, sizeof(dst_buf), " dst %s", 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", zlog_debug("Tx %s family %s IF %s(%u)%s %sMAC %s%s",
nl_msg_type_to_str(cmd), nl_msg_type_to_str(cmd),
nl_family_to_str(req.ndm.ndm_family), ifp->name, nl_family_to_str(req.ndm.ndm_family),
ifp->ifindex, vid_present ? vid_buf : "", dplane_ctx_get_ifname(ctx),
dplane_ctx_get_ifindex(ctx), vid_buf,
dplane_ctx_mac_is_sticky(ctx) ? "sticky " : "", dplane_ctx_mac_is_sticky(ctx) ? "sticky " : "",
buf, dst_buf); buf, dst_buf);
} }

View File

@ -152,6 +152,7 @@ struct dplane_intf_info {
*/ */
struct dplane_mac_info { struct dplane_mac_info {
vlanid_t vid; vlanid_t vid;
ifindex_t br_ifindex;
struct ethaddr mac; struct ethaddr mac;
struct in_addr vtep_ip; struct in_addr vtep_ip;
bool is_sticky; bool is_sticky;
@ -377,6 +378,7 @@ static enum zebra_dplane_result intf_addr_update_internal(
enum dplane_op_e op); enum dplane_op_e op);
static enum zebra_dplane_result mac_update_internal( static enum zebra_dplane_result mac_update_internal(
enum dplane_op_e op, const struct interface *ifp, enum dplane_op_e op, const struct interface *ifp,
const struct interface *br_ifp,
vlanid_t vid, const struct ethaddr *mac, vlanid_t vid, const struct ethaddr *mac,
struct in_addr vtep_ip, bool sticky); struct in_addr vtep_ip, bool sticky);
static enum zebra_dplane_result neigh_update_internal( 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); 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 */ /* Accessors for neighbor information */
const struct ipaddr *dplane_ctx_neigh_get_ipaddr( const struct ipaddr *dplane_ctx_neigh_get_ipaddr(
const struct zebra_dplane_ctx *ctx) 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). * Enqueue vxlan/evpn mac add (or update).
*/ */
enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
const struct interface *bridge_ifp,
vlanid_t vid, vlanid_t vid,
const struct ethaddr *mac, const struct ethaddr *mac,
struct in_addr vtep_ip, 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; enum zebra_dplane_result result;
/* Use common helper api */ /* Use common helper api */
result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, vid, result = mac_update_internal(DPLANE_OP_MAC_INSTALL, ifp, bridge_ifp,
mac, vtep_ip, sticky); vid, mac, vtep_ip, sticky);
return result; return result;
} }
@ -2151,6 +2160,7 @@ enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
* Enqueue vxlan/evpn mac delete. * Enqueue vxlan/evpn mac delete.
*/ */
enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
const struct interface *bridge_ifp,
vlanid_t vid, vlanid_t vid,
const struct ethaddr *mac, const struct ethaddr *mac,
struct in_addr vtep_ip) 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; enum zebra_dplane_result result;
/* Use common helper api */ /* Use common helper api */
result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, vid, mac, result = mac_update_internal(DPLANE_OP_MAC_DELETE, ifp, bridge_ifp,
vtep_ip, false); vid, mac, vtep_ip, false);
return result; return result;
} }
@ -2169,6 +2179,7 @@ enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
static enum zebra_dplane_result static enum zebra_dplane_result
mac_update_internal(enum dplane_op_e op, mac_update_internal(enum dplane_op_e op,
const struct interface *ifp, const struct interface *ifp,
const struct interface *br_ifp,
vlanid_t vid, vlanid_t vid,
const struct ethaddr *mac, const struct ethaddr *mac,
struct in_addr vtep_ip, struct in_addr vtep_ip,
@ -2204,6 +2215,7 @@ mac_update_internal(enum dplane_op_e op,
/* Init the mac-specific data area */ /* Init the mac-specific data area */
memset(&ctx->u.macinfo, 0, sizeof(ctx->u.macinfo)); 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.vtep_ip = vtep_ip;
ctx->u.macinfo.mac = *mac; ctx->u.macinfo.mac = *mac;
ctx->u.macinfo.vid = vid; ctx->u.macinfo.vid = vid;

View File

@ -328,6 +328,7 @@ const struct ethaddr *dplane_ctx_mac_get_addr(
const struct zebra_dplane_ctx *ctx); const struct zebra_dplane_ctx *ctx);
const struct in_addr *dplane_ctx_mac_get_vtep_ip( const struct in_addr *dplane_ctx_mac_get_vtep_ip(
const struct zebra_dplane_ctx *ctx); const struct zebra_dplane_ctx *ctx);
ifindex_t dplane_ctx_mac_get_br_ifindex(const struct zebra_dplane_ctx *ctx);
/* Accessors for neighbor information */ /* Accessors for neighbor information */
const struct ipaddr *dplane_ctx_neigh_get_ipaddr( 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. * Enqueue evpn mac operations for the dataplane.
*/ */
enum zebra_dplane_result dplane_mac_add(const struct interface *ifp, enum zebra_dplane_result dplane_mac_add(const struct interface *ifp,
const struct interface *bridge_ifp,
vlanid_t vid, vlanid_t vid,
const struct ethaddr *mac, const struct ethaddr *mac,
struct in_addr vtep_ip, struct in_addr vtep_ip,
bool sticky); bool sticky);
enum zebra_dplane_result dplane_mac_del(const struct interface *ifp, enum zebra_dplane_result dplane_mac_del(const struct interface *ifp,
const struct interface *bridge_ifp,
vlanid_t vid, vlanid_t vid,
const struct ethaddr *mac, const struct ethaddr *mac,
struct in_addr vtep_ip); struct in_addr vtep_ip);

View File

@ -2553,8 +2553,9 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
return 0; return 0;
if (!zvni->vxlan_if) { if (!zvni->vxlan_if) {
zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf", if (IS_ZEBRA_DEBUG_VXLAN)
zvni->vni, zvni); zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
zvni->vni, zvni);
return -1; return -1;
} }
@ -2843,9 +2844,12 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
/* mac entry should be present */ /* mac entry should be present */
mac = zvni_mac_lookup(zvni, &n->emac); mac = zvni_mac_lookup(zvni, &n->emac);
if (!mac) { if (!mac) {
zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u", if (IS_ZEBRA_DEBUG_VXLAN)
prefix_mac2str(&n->emac, buf1, sizeof(buf1)), zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u",
ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni); prefix_mac2str(&n->emac,
buf1, sizeof(buf1)),
ipaddr2str(ip, buf2, sizeof(buf2)),
zvni->vni);
return -1; return -1;
} }
@ -3736,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) static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
{ {
struct zebra_if *zif; const struct zebra_if *zif, *br_zif;
struct zebra_l2info_vxlan *vxl; const struct zebra_l2info_vxlan *vxl;
bool sticky; bool sticky;
enum zebra_dplane_result res; enum zebra_dplane_result res;
const struct interface *br_ifp;
vlanid_t vid;
if (!(mac->flags & ZEBRA_MAC_REMOTE)) if (!(mac->flags & ZEBRA_MAC_REMOTE))
return 0; return 0;
@ -3747,13 +3753,25 @@ static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
zif = zvni->vxlan_if->info; zif = zvni->vxlan_if->info;
if (!zif) if (!zif)
return -1; return -1;
br_ifp = zif->brslave_info.br_if;
if (br_ifp == NULL)
return -1;
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
sticky = !!CHECK_FLAG(mac->flags, sticky = !!CHECK_FLAG(mac->flags,
(ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)); (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
res = dplane_mac_add(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr, br_zif = (const struct zebra_if *)(br_ifp->info);
mac->fwd_info.r_vtep_ip, sticky);
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) if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
return 0; return 0;
else else
@ -3765,30 +3783,44 @@ 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) static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac)
{ {
struct zebra_if *zif; const struct zebra_if *zif, *br_zif;
struct zebra_l2info_vxlan *vxl; const struct zebra_l2info_vxlan *vxl;
struct in_addr vtep_ip; struct in_addr vtep_ip;
struct interface *ifp; const struct interface *ifp, *br_ifp;
vlanid_t vid;
enum zebra_dplane_result res; enum zebra_dplane_result res;
if (!(mac->flags & ZEBRA_MAC_REMOTE)) if (!(mac->flags & ZEBRA_MAC_REMOTE))
return 0; return 0;
if (!zvni->vxlan_if) { if (!zvni->vxlan_if) {
zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf", if (IS_ZEBRA_DEBUG_VXLAN)
zvni->vni, zvni); zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
zvni->vni, zvni);
return -1; return -1;
} }
zif = zvni->vxlan_if->info; zif = zvni->vxlan_if->info;
if (!zif) if (!zif)
return -1; return -1;
br_ifp = zif->brslave_info.br_if;
if (br_ifp == NULL)
return -1;
vxl = &zif->l2info.vxl; 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; ifp = zvni->vxlan_if;
vtep_ip = mac->fwd_info.r_vtep_ip; 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) if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
return 0; return 0;
else else
@ -4491,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) static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
{ {
struct zebra_if *zif = NULL; const struct zebra_if *zif = NULL, *br_zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; const struct zebra_l2info_vxlan *vxl = NULL;
const struct interface *br_ifp;
enum zebra_dplane_result res; enum zebra_dplane_result res;
vlanid_t vid;
if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
|| !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC))) || !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
@ -4503,9 +4537,20 @@ static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
if (!zif) if (!zif)
return -1; return -1;
br_ifp = zif->brslave_info.br_if;
if (br_ifp == NULL)
return -1;
vxl = &zif->l2info.vxl; 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); &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
if (res != ZEBRA_DPLANE_REQUEST_FAILURE) if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
return 0; return 0;
@ -4519,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) static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
{ {
char buf[ETHER_ADDR_STRLEN]; char buf[ETHER_ADDR_STRLEN];
struct zebra_if *zif = NULL; const struct zebra_if *zif = NULL, *br_zif;
struct zebra_l2info_vxlan *vxl = NULL; const struct zebra_l2info_vxlan *vxl = NULL;
const struct interface *br_ifp;
vlanid_t vid;
enum zebra_dplane_result res; enum zebra_dplane_result res;
if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE))
@ -4528,10 +4575,12 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
return 0; return 0;
if (!zl3vni->vxlan_if) { if (!zl3vni->vxlan_if) {
zlog_debug( if (IS_ZEBRA_DEBUG_VXLAN)
"RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if", zlog_debug(
prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)), "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
zl3vni->vni, zl3vni); prefix_mac2str(&zrmac->macaddr,
buf, sizeof(buf)),
zl3vni->vni, zl3vni);
return -1; return -1;
} }
@ -4539,9 +4588,19 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac)
if (!zif) if (!zif)
return -1; return -1;
br_ifp = zif->brslave_info.br_if;
if (br_ifp == NULL)
return -1;
vxl = &zif->l2info.vxl; 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); &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip);
if (res != ZEBRA_DPLANE_REQUEST_FAILURE) if (res != ZEBRA_DPLANE_REQUEST_FAILURE)
return 0; return 0;