zebra: Fix MAC change handling for a neighbor

When the MAC changes for a local neighbor, ensure that the neighbor data
structure as well as the link between the neighbor and MAC data structures
is updated correctly.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by:   Mitesh Kanjariya <mitesh@cumulusnetworks.com>
Reviewed-by:   Donald Sharp <sharpd@cumulusnetworks.com>

Ticket: CM-17565
Reviewed By: CCR-6605
Testing Done: Manual, evpn-smoke
This commit is contained in:
vivek 2017-08-13 21:52:04 -07:00 committed by Mitesh Kanjariya
parent cb499ebbaa
commit b682f6de5a
7 changed files with 118 additions and 113 deletions

View File

@ -2683,10 +2683,7 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
if (bgp_debug_update(ri->peer, &rn->p, if (bgp_debug_update(ri->peer, &rn->p,
NULL, 1)) NULL, 1))
zlog_debug( zlog_debug(
"%u: prefix %s with " "%u: prefix %s with attr %s - DENIED due to martian or self nexthop",
"attr %s - DENIED"
"due to martian or seld"
"nexthop",
bgp->vrf_id, bgp->vrf_id,
prefix2str( prefix2str(
&rn->p, &rn->p,

View File

@ -28,8 +28,7 @@
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw); extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len); extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len); extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
extern void extern void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json);
bgp_evpn_route2json (struct prefix_evpn *p, json_object *json);
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p, extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
struct prefix_rd *prd, mpls_label_t *label, struct prefix_rd *prd, mpls_label_t *label,
struct attr *attr, int addpath_encode, struct attr *attr, int addpath_encode,

View File

@ -521,6 +521,7 @@ static void show_vni_entry(struct hash_backet *backet, void *args[])
if (json) { if (json) {
char vni_str[VNI_STR_LEN]; char vni_str[VNI_STR_LEN];
json_object_object_add(json_vni, "exportRTs", json_export_rtl); json_object_object_add(json_vni, "exportRTs", json_export_rtl);
snprintf(vni_str, VNI_STR_LEN, "%u", vpn->vni); snprintf(vni_str, VNI_STR_LEN, "%u", vpn->vni);
json_object_object_add(json, vni_str, json_vni); json_object_object_add(json, vni_str, json_vni);

View File

@ -6246,7 +6246,8 @@ static void route_vty_out_route(struct prefix *p, struct vty *vty,
|| (IN_CLASSB(destination) && p->prefixlen == 16) || (IN_CLASSB(destination) && p->prefixlen == 16)
|| (IN_CLASSA(destination) && p->prefixlen == 8) || (IN_CLASSA(destination) && p->prefixlen == 8)
|| p->u.prefix4.s_addr == 0) { || p->u.prefix4.s_addr == 0) {
/* When mask is natural, mask is not displayed. */ /* When mask is natural,
mask is not displayed. */
} else } else
len += vty_out(vty, "/%d", p->prefixlen); len += vty_out(vty, "/%d", p->prefixlen);
} else { } else {

View File

@ -9040,8 +9040,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
" Hostname Capability:"); " Hostname Capability:");
if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_ADV)) { if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_ADV)) {
vty_out(vty, " advertised (name: %s, " vty_out(vty, " advertised (name: %s,domain name: %s)",
"domain name: %s)",
bgp->peer_self->hostname ? bgp->peer_self->hostname ?
bgp->peer_self->hostname bgp->peer_self->hostname
: "n/a", : "n/a",
@ -9053,8 +9052,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
} }
if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_RCV)) { if (CHECK_FLAG(p->cap, PEER_CAP_HOSTNAME_RCV)) {
vty_out(vty, " received (name: %s, " vty_out(vty, " received (name: %s,domain name: %s)",
"domain name: %s)",
p->hostname ? p->hostname ?
p->hostname : "n/a", p->hostname : "n/a",
p->domainname ? p->domainname ?

View File

@ -230,9 +230,9 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
if (zif->zif_type == ZEBRA_IF_VXLAN) if (zif->zif_type == ZEBRA_IF_VXLAN)
zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE); zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
} else if (old_bridge_ifindex != IFINDEX_INTERNAL) { } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
/* In the case of VxLAN, invoke the handler for EVPN. Note that /* In the case of VxLAN, invoke the handler for EVPN.
* this should be done *prior* to unmapping the interface from the * Note that this should be done *prior* to unmapping the interface
* bridge. * from the bridge.
*/ */
if (zif->zif_type == ZEBRA_IF_VXLAN) if (zif->zif_type == ZEBRA_IF_VXLAN)
zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE); zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);

View File

@ -2889,10 +2889,9 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
zebra_vni_t *zvni; zebra_vni_t *zvni;
zebra_neigh_t *n; zebra_neigh_t *n;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
zebra_mac_t *zmac; zebra_mac_t *zmac, *old_zmac;
char buf[ETHER_ADDR_STRLEN]; char buf[ETHER_ADDR_STRLEN];
char buf2[INET6_ADDRSTRLEN]; char buf2[INET6_ADDRSTRLEN];
int send_upd = 1, send_del = 0;
/* We are only interested in neighbors on an SVI that resides on top /* We are only interested in neighbors on an SVI that resides on top
* of a VxLAN bridge. * of a VxLAN bridge.
@ -2947,19 +2946,35 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
if (memcmp(n->emac.octet, macaddr->octet, if (memcmp(n->emac.octet, macaddr->octet,
ETH_ALEN) ETH_ALEN)
== 0) { == 0) {
if (n->ifindex == ifp->ifindex) /* Update any params and return - client doesn't
/* we're not interested in whatever has * care about a purely local change.
* changed. */
return 0;
/* client doesn't care about a purely local
* change. */
send_upd = 0;
} else
/* If the MAC has changed, issue a delete first
* as this means a
* different MACIP route.
*/ */
send_del = 1; n->ifindex = ifp->ifindex;
return 0;
} else {
/* If the MAC has changed,
* need to issue a delete first
* as this means a different MACIP route.
* Also, need to do some unlinking/relinking.
*/
zvni_neigh_send_del_to_client(zvrf, zvni->vni,
&n->ip, &n->emac,
0);
old_zmac = zvni_mac_lookup(zvni, &n->emac);
if (old_zmac) {
listnode_delete(old_zmac->neigh_list,
n);
zvni_deref_ip2mac(zvni, old_zmac, 0);
}
/* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
n->ifindex = ifp->ifindex;
memcpy(&n->emac, macaddr, ETH_ALEN);
/* Link to new MAC */
listnode_add_sort(zmac->neigh_list, n);
}
} else if (ext_learned) } else if (ext_learned)
/* The neighbor is remote and that is the notification we got. /* The neighbor is remote and that is the notification we got.
*/ */
@ -2973,6 +2988,8 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
{ {
UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE); UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
n->r_vtep_ip.s_addr = 0; n->r_vtep_ip.s_addr = 0;
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
n->ifindex = ifp->ifindex;
} }
} else { } else {
n = zvni_neigh_add(zvni, ip, macaddr); n = zvni_neigh_add(zvni, ip, macaddr);
@ -2984,16 +3001,10 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
ifp->name, ifp->ifindex, zvni->vni); ifp->name, ifp->ifindex, zvni->vni);
return -1; return -1;
} }
}
/* Issue delete for older info, if needed. */
if (send_del)
zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
0);
/* Set "local" forwarding info. */ /* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
n->ifindex = ifp->ifindex; n->ifindex = ifp->ifindex;
}
/* Before we program this in BGP, we need to check if MAC is locally /* Before we program this in BGP, we need to check if MAC is locally
* learnt as well */ * learnt as well */
@ -3008,8 +3019,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
return 0; return 0;
} }
/* Inform BGP if required. */ /* Inform BGP. */
if (send_upd) {
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug( zlog_debug(
"%u: neigh %s (MAC %s) is now ACTIVE on VNI %u", "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
@ -3022,8 +3032,6 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
macaddr, 0); macaddr, 0);
} }
return 0;
}
/* /*
* Handle message from client to delete a remote MACIP for a VNI. * Handle message from client to delete a remote MACIP for a VNI.
@ -3820,7 +3828,8 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
if (!if_is_operative(ifp) || !zif->brslave_info.br_if) if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
continue; continue;
/* If the remote VTEP already exists, there's nothing more to do. */ /* If the remote VTEP already exists,
there's nothing more to do. */
if (zvni_vtep_find(zvni, &vtep_ip)) if (zvni_vtep_find(zvni, &vtep_ip))
continue; continue;