diff options
Diffstat (limited to 'zebra/zebra_vxlan.c')
| -rw-r--r-- | zebra/zebra_vxlan.c | 105 |
1 files changed, 57 insertions, 48 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 2240d7c763..4a5fc38493 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1441,7 +1441,7 @@ static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) return; zl2_info = zif->l2info.vxl; @@ -1485,7 +1485,7 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) return; zl2_info = zif->l2info.vxl; @@ -2889,10 +2889,9 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, zebra_vni_t *zvni; zebra_neigh_t *n; struct zebra_vrf *zvrf; - zebra_mac_t *zmac; + zebra_mac_t *zmac, *old_zmac; char buf[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; - int send_upd = 1, send_del = 0; /* We are only interested in neighbors on an SVI that resides on top * 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, ETH_ALEN) == 0) { - if (n->ifindex == ifp->ifindex) - /* we're not interested in whatever has - * 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. + /* Update any params and return - client doesn't + * care about a purely local change. + */ + 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. */ - send_del = 1; + 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) /* 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); n->r_vtep_ip.s_addr = 0; + SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->ifindex = ifp->ifindex; } } else { n = zvni_neigh_add(zvni, ip, macaddr); @@ -2984,17 +3001,11 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, ifp->name, ifp->ifindex, zvni->vni); return -1; } + /* Set "local" forwarding info. */ + SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); + n->ifindex = ifp->ifindex; } - /* 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_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); - n->ifindex = ifp->ifindex; - /* Before we program this in BGP, we need to check if MAC is locally * learnt as well */ if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) { @@ -3008,23 +3019,20 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp, return 0; } - /* Inform BGP if required. */ - if (send_upd) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u", - ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), - prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni); - - ZEBRA_NEIGH_SET_ACTIVE(n); - return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, - macaddr, 0); - } + /* Inform BGP. */ + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u", + ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)), + prefix_mac2str(macaddr, buf, sizeof(buf)), + zvni->vni); - return 0; + ZEBRA_NEIGH_SET_ACTIVE(n); + return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, + macaddr, 0); } + /* * Handle message from client to delete a remote MACIP for a VNI. */ @@ -3096,7 +3104,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) continue; /* The remote VTEP specified is normally expected to exist, but @@ -3246,7 +3254,7 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) continue; /* The remote VTEP specified should normally exist, but it is @@ -3738,14 +3746,14 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length, ifp = zvni->vxlan_if; if (!ifp) { - zlog_err ("VNI %u hash %p doesn't have intf upon remote VTEP DEL", - zvni->vni, zvni); - continue; + zlog_err("VNI %u hash %p doesn't have intf upon remote VTEP DEL", + zvni->vni, zvni); + 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) continue; /* If the remote VTEP does not exist, there's nothing more to @@ -3817,10 +3825,11 @@ int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) 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)) continue; @@ -4366,7 +4375,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock, 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 (!if_is_operative(ifp) || !zif->brslave_info.br_if) return 0; zl2_info = zif->l2info.vxl; |
