summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/zebra_vxlan.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 04f9be8ade..f63879159d 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -1961,6 +1961,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
char buf2[INET6_ADDRSTRLEN];
zebra_neigh_t *n = NULL;
zebra_mac_t *zmac = NULL, *old_zmac = NULL;
+ bool check_rbit = false;
/* create a dummy MAC if the MAC is not already present */
zmac = zvni_mac_lookup(zvni, macaddr);
@@ -1990,34 +1991,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
n = zvni_neigh_lookup(zvni, ip);
if (n) {
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
+
+ if (router_flag !=
+ (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG)
+ ? 1 : 0))
+ check_rbit = true;
+
if (memcmp(n->emac.octet, macaddr->octet,
ETH_ALEN) == 0) {
/* 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.
- */
- zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
+ /* 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(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);
- }
+ 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);
+ }
- /* Update the forwarding info. */
- n->ifindex = ifp->ifindex;
- memcpy(&n->emac, macaddr, ETH_ALEN);
+ /* Update the forwarding info. */
+ n->ifindex = ifp->ifindex;
+ memcpy(&n->emac, macaddr, ETH_ALEN);
- /* Link to new MAC */
- listnode_add_sort(zmac->neigh_list, n);
+ /* Link to new MAC */
+ listnode_add_sort(zmac->neigh_list, n);
+ }
} else
/* Neighbor has moved from remote to local. */
@@ -2042,6 +2049,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
n->r_vtep_ip.s_addr = 0;
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
n->ifindex = ifp->ifindex;
+ check_rbit = true;
}
} else {
/* New neighbor - create */
@@ -2058,25 +2066,38 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
/* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
n->ifindex = ifp->ifindex;
+ check_rbit = true;
}
+ /*Mark Router flag (R-bit) */
+ if (router_flag)
+ SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+ else
+ UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+
/* 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)) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
+ "Skipping neigh %s add to client as MAC %s is not local on VNI %u with flags 0x%x",
ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)),
- zvni->vni);
+ zvni->vni, n->flags);
return 0;
}
- /*Set router flag (R-bit) */
- if (router_flag)
- SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+ if (!check_rbit) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "Skipping neigh %s with MAC %s on VNI %u add to client as router flag is not set.",
+ ipaddr2str(ip, buf2, sizeof(buf2)),
+ prefix_mac2str(macaddr, buf, sizeof(buf)),
+ zvni->vni);
+ return 0;
+ }
/* Inform BGP. */
if (IS_ZEBRA_DEBUG_VXLAN)
@@ -4965,10 +4986,11 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
+ "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s %s-> L2-VNI %u",
ipaddr2str(ip, buf2, sizeof(buf2)),
prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
ifp->ifindex, state, ext_learned ? "ext-learned " : "",
+ router_flag ? "router " : "",
zvni->vni);
/* Is this about a local neighbor or a remote one? */
@@ -5151,7 +5173,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
char buf[ETHER_ADDR_STRLEN];
char buf1[INET6_ADDRSTRLEN];
uint8_t sticky = 0;
- u_char remote_gw = 0;
+ uint8_t remote_gw = 0;
+ uint8_t router_flag = 0;
uint8_t flags = 0;
struct interface *ifp = NULL;
struct zebra_if *zif = NULL;
@@ -5194,6 +5217,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
STREAM_GETC(s, flags);
sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
remote_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ router_flag = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
l++;
if (IS_ZEBRA_DEBUG_VXLAN)
@@ -5325,6 +5349,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
*/
n = zvni_neigh_lookup(zvni, &ip);
if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
+ || ((CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) ? 1 : 0)
+ != router_flag)
|| (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
|| !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
update_neigh = 1;
@@ -5365,6 +5391,8 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
/* Set router flag (R-bit) to this Neighbor entry */
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
SET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
+ else
+ UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG);
/* Install the entry. */
zvni_neigh_install(zvni, n);