diff --git a/dp-core/vr_ip_mtrie.c b/dp-core/vr_ip_mtrie.c index 6936bf5db..81dd01a26 100644 --- a/dp-core/vr_ip_mtrie.c +++ b/dp-core/vr_ip_mtrie.c @@ -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; @@ -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); diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index 1f7c589b3..c32544b85 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -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)) {