Skip to content

Commit

Permalink
Forcing L3 processing for Ecmp
Browse files Browse the repository at this point in the history
When an ARP request is received from a VM which is part of ECMP to a non
ECMP destination, ARP response is sent using the stitching
information of destination route. This leads to VM learning  destination
VM's MAC directly enabling an L2 switching. But as source VM is part of
ECMP, the packets need to be L3 routed, as there is no ECMP support for L2
switched packet and also the reverse path packets (from non ECMP to ECMP)
are as such L3 routed.
Responding to VM with stiched MAC, leads to following issue in particular. IP
packet from VM will come to Vrouter module with L2 Mac, and this results in
flow trap to Agent. Agent while setting the forward L2 flow, attempts to set
RPF nexthop, which is composite Nexthop and asserts as L2 flow can not have
composite nexthop.

To fix this, ARP response is sent now with VRRP mac, which makes the flow as
L3 flow.

Change-Id: I3ba4c66288f86e190d39f8761d4952b42050ebd8
closes-bug: #1472796
  • Loading branch information
divakardhar committed Jul 23, 2015
1 parent 0b517ae commit a4069fa
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
16 changes: 12 additions & 4 deletions dp-core/vr_ip_mtrie.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,16 +852,22 @@ mtrie_lookup(unsigned int vrf_id, struct vr_route_req *rt)

/* we do not support any thing other than /32 route lookup */
if ((rt->rtr_req.rtr_family == AF_INET) &&
(rt->rtr_req.rtr_prefix_len != IP4_PREFIX_LEN))
(rt->rtr_req.rtr_prefix_len != IP4_PREFIX_LEN)) {
rt->rtr_nh = default_nh;
return default_nh;
}

if ((rt->rtr_req.rtr_family == AF_INET6) &&
(rt->rtr_req.rtr_prefix_len != IP6_PREFIX_LEN))
(rt->rtr_req.rtr_prefix_len != IP6_PREFIX_LEN)) {
rt->rtr_nh = default_nh;
return default_nh;
}

table = vrfid_to_mtrie(vrf_id, rt->rtr_req.rtr_family);
if (!table)
if (!table) {
rt->rtr_nh = default_nh;
return default_nh;
}

ent = &table->root;

Expand All @@ -882,8 +888,10 @@ mtrie_lookup(unsigned int vrf_id, struct vr_route_req *rt)
}

bkt = PTR_TO_BUCKET(ptr);
if (!bkt)
if (!bkt) {
rt->rtr_nh = default_nh;
return default_nh;
}

for (level = 0; level < ip_bkt_get_max_level(rt->rtr_req.rtr_family); level++) {
index = rt_to_index(rt, level);
Expand Down
19 changes: 18 additions & 1 deletion dp-core/vr_proto_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1003,11 +1003,28 @@ vm_arp_request(struct vr_interface *vif, struct vr_packet *pkt,
rt.rtr_req.rtr_vrf_id = fmd->fmd_dvrf;
rt.rtr_req.rtr_family = AF_INET;
rt.rtr_req.rtr_prefix = (uint8_t *)&rt_prefix;
*(uint32_t *)rt.rtr_req.rtr_prefix = (sarp->arp_dpa);
rt.rtr_req.rtr_prefix_size = 4;
rt.rtr_req.rtr_prefix_len = 32;
rt.rtr_req.rtr_mac = mac;

if (!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;

/* If ECMP, we need to route the L3 packets */
VR_MAC_COPY(dmac, vif->vif_mac);
return MR_PROXY;
}

rt.rtr_nh = NULL;
}

*(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 a4069fa

Please sign in to comment.