Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evpn: support for masterless VTEPs #8070

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 48 additions & 28 deletions zebra/zebra_vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
zebra_l3vni_t *zl3vni = NULL;
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
zebra_mac_t *zmac = NULL;

ifp = (struct interface *)rn->info;
if (!ifp)
Expand Down Expand Up @@ -965,12 +966,8 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
"EVPN hash already present for IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);

/*
* Inform BGP if intf is up and mapped to
* bridge.
*/
if (if_is_operative(ifp) &&
zif->brslave_info.br_if)
/* Inform BGP if intf is up */
if (if_is_operative(ifp))
zebra_evpn_send_add_to_client(zevpn);

/* Send Local MAC-entries to client */
Expand Down Expand Up @@ -1016,13 +1013,24 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
zl3vni->l2vnis, zevpn);
}

/*
* Inform BGP if intf is up and mapped to
* bridge.
*/
if (if_is_operative(ifp) &&
zif->brslave_info.br_if)
/* Inform BGP if intf is up */
if (if_is_operative(ifp))
zebra_evpn_send_add_to_client(zevpn);
if (!zif->brslave_info.br_if) {
struct ethaddr macaddr;
char buf[ETHER_ADDR_STRLEN];

memcpy(&macaddr.octet, ifp->hw_addr,
ETH_ALEN);
zlog_debug("Adv MAC %s",
prefix_mac2str(&macaddr, buf,
sizeof(buf)));
zmac = zebra_evpn_mac_add(zevpn,
&macaddr);
zebra_evpn_mac_send_add_to_client(
vni, &macaddr, zmac->flags,
zmac->loc_seq, zmac->es);
}
}
}
}
Expand Down Expand Up @@ -2096,8 +2104,8 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
zevpn->vxlan_if = ifp;
zevpn->local_vtep_ip = vxl->vtep_ip;

/* Inform BGP if the VNI is up and mapped to a bridge. */
if (if_is_operative(ifp) && zif->brslave_info.br_if) {
/* Inform BGP if the VNI is up */
if (if_is_operative(ifp)) {
zebra_evpn_send_add_to_client(zevpn);
zebra_evpn_read_mac_neigh(zevpn, ifp);
}
Expand Down Expand Up @@ -4222,7 +4230,6 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
zebra_evpn_t *zevpn;
zebra_vtep_t *zvtep;
struct interface *ifp;
struct zebra_if *zif;

if (!is_evpn_enabled()) {
zlog_debug(
Expand Down Expand Up @@ -4274,10 +4281,9 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
zevpn->vni, zevpn);
continue;
}
zif = ifp->info;

/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
/* If down we're done. */
if (!if_is_operative(ifp))
continue;

/* If the remote VTEP does not exist, there's nothing more to
Expand Down Expand Up @@ -4309,7 +4315,6 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
struct in_addr vtep_ip;
zebra_evpn_t *zevpn;
struct interface *ifp;
struct zebra_if *zif;
int flood_control;
zebra_vtep_t *zvtep;

Expand Down Expand Up @@ -4360,10 +4365,9 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
continue;
}

zif = ifp->info;

/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't unconditionally drop this dependency. For cases where the the BD is represented by a {bridge, vlan} this may create problems including invalid memory access based on the sequence of events.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the correct thing to do here be to check the interface type, and if it is a type that should depend on bridge membership (let's say all interface types except for VTEPs to be conservative) then retain this condition, otherwise drop the dependency?

/* If down we're done. */
if (!if_is_operative(ifp))
continue;

zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
Expand Down Expand Up @@ -4755,6 +4759,7 @@ int zebra_vxlan_if_up(struct interface *ifp)
struct zebra_l2info_vxlan *vxl = NULL;
zebra_evpn_t *zevpn = NULL;
zebra_l3vni_t *zl3vni = NULL;
zebra_mac_t *zmac = NULL;

/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
Expand Down Expand Up @@ -4809,11 +4814,26 @@ int zebra_vxlan_if_up(struct interface *ifp)
listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
}

/* If part of a bridge, inform BGP about this VNI. */
/* Inform BGP about this VNI. */
zebra_evpn_send_add_to_client(zevpn);

/* Also, read and populate local MACs and neighbors. */
if (zif->brslave_info.br_if) {
zebra_evpn_send_add_to_client(zevpn);
/* If part of a bridge read the macfdb for the bridge.
*/
zebra_evpn_read_mac_neigh(zevpn, ifp);
} else {
/* Otherwise advertise the vtep itself. */
struct ethaddr macaddr;
char buf[ETHER_ADDR_STRLEN];

memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
zlog_debug("Adv MAC %s",
prefix_mac2str(&macaddr, buf, sizeof(buf)));
zmac = zebra_evpn_mac_add(zevpn, &macaddr);
zebra_evpn_mac_send_add_to_client(
vni, &macaddr, zmac->flags, zmac->loc_seq,
zmac->es);
}
}

Expand Down Expand Up @@ -5026,8 +5046,8 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
/* Take further actions needed.
* Note that if we are here, there is a change of interest.
*/
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
/* If down we're done. */
if (!if_is_operative(ifp))
return 0;

/* Inform BGP, if there is a change of interest. */
Expand Down Expand Up @@ -5167,8 +5187,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
zif->brslave_info.bridge_ifindex);
}

/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
/* If down we're done. */
if (!if_is_operative(ifp))
return 0;

/* Inform BGP */
Expand Down