Skip to content

Commit

Permalink
Replyin to ARP request of ECMP source only if VM is hosted
Browse files Browse the repository at this point in the history
When an ARP request is received on compute node on fabric interface from
an ECMP source, ARP response is sent with Vhost mac even though the ARP
request is not meant for any VM on that compute node. Because of this,
even if BMS pings another BMS, every compute node receiving this ARP
request is responding with Vhost mac leading to ARP cache poisoning in
BMS.

As a fix, only if ARP request is meant for a VM on compute node, the
response is sent with Vhost mac.

No source IP lookup for ARP requests from BMS

For the packets from VM to an ECMP destination we are forcing the
packets to be L3 routed. When ARP request comes for that VM from one of
the ECMP sources, though we have the stiching for VM's IP we give
Vhost's MAC to route the packets as packets need to be routed in this
direction as well. This functioanlity is added with the fix for the bug
1472796.
But the fix for the above bug should not handle the ARP request coming
from BMS (in TSN) as TSN is never a gateway for BMS. Such ARP request
should be flooded. So the fix is to not force the L3 if ARP request is
from BMS.

Change-Id: I4036dcd6eaf757b579de8ae391855aa7269a9ac1
closes-bug: #1485804
closes-bug: #1491644
  • Loading branch information
divakardhar committed Feb 20, 2016
1 parent 0c639ac commit 806037a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
20 changes: 13 additions & 7 deletions dp-core/vr_datapath.c
Expand Up @@ -65,6 +65,12 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
}
}

/* If ECMP source, we force routing */
if (fmd->fmd_ecmp_src_nh_index != -1) {
resp_mac = vif->vif_mac;
fmd->fmd_ecmp_src_nh_index = -1;
}


/*
* situations that are handled here (from_fabric)
Expand Down Expand Up @@ -112,9 +118,8 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
* the originator is a bare metal (fmd->fmd_src)
*/
if (to_vcp || to_gateway ||
((nh) &&
((nh->nh_type == NH_ENCAP) ||
(fmd->fmd_src == TOR_SOURCE)))) {
(nh && ((nh->nh_type == NH_ENCAP) ||
(fmd->fmd_src == TOR_SOURCE)))) {
if (stats)
stats->vrf_arp_physical_stitch++;
} else {
Expand All @@ -123,11 +128,12 @@ vr_get_proxy_mac(struct vr_packet *pkt, struct vr_forwarding_md *fmd,
return MR_FLOOD;
}
} else {
/*
* if there is no stitching information, but flood flag is set
* we should flood
*/

if (!stitched && flood) {
/*
* if there is no stitching information, but flood flag is set
* we should flood
*/
if (stats)
stats->vrf_arp_virtual_flood++;
return MR_FLOOD;
Expand Down
28 changes: 28 additions & 0 deletions dp-core/vr_proto_ip.c
Expand Up @@ -990,6 +990,34 @@ vm_arp_request(struct vr_interface *vif, struct vr_packet *pkt,
rt.rtr_req.rtr_prefix_len = 32;
rt.rtr_req.rtr_mac = mac;

/*
* If ARP request is coming from other compute nodes, and if that
* particular compute node is part of ECMP, we need to route these
* packets though we have stiched mac for VM, as packets from VM to
* that ECMP are routed packets
* ARP requests from Tor have to be flooded so that required nodes
* will answer that
*/
if ((fmd->fmd_src != TOR_SOURCE) && !vr_grat_arp(sarp)) {
*(uint32_t *)rt.rtr_req.rtr_prefix = (sarp->arp_spa);
vr_inet_route_lookup(fmd->fmd_dvrf, &rt);

if (rt.rtr_nh->nh_type == NH_COMPOSITE) {
/* The source of ARP request can not be anything other than ECMP */
if (!(rt.rtr_nh->nh_flags & NH_FLAG_COMPOSITE_ECMP))
return MR_DROP;

/* Mark it as ecmp source. -1 is invalid */
fmd->fmd_ecmp_src_nh_index = 0;
}

rt.rtr_nh = NULL;
rt.rtr_req.rtr_prefix_len = 32;
rt.rtr_req.rtr_index = VR_BE_INVALID_INDEX;
}


*(uint32_t *)rt.rtr_req.rtr_prefix = (sarp->arp_dpa);
vr_inet_route_lookup(fmd->fmd_dvrf, &rt);

if (vr_grat_arp(sarp)) {
Expand Down

0 comments on commit 806037a

Please sign in to comment.