From 4da87fc2f76bb16cb7f1c154074e2acb5c6ae008 Mon Sep 17 00:00:00 2001 From: Divakar Date: Sat, 27 Feb 2016 09:27:06 +0530 Subject: [PATCH] Keeping ingres vif id in L2 header for post GRO processing Currently the L2 header used for both L2 and L3 GRO processing is only next hop id. Post GRO, the nexthop is retrieved from this id and packet is subjected to this nexthop for further processing. The ingress interface filled in the packet is nh_dev of this nexthop. This is resulting in ingress interface as Tap interface though packet acttually ingressed on Fabric interface. This can potentially lead to issues in the packet's further processing as Tap interface is not the real ingress interface. As a fix, the ingress interface id is also pushed as L2 header. Change-Id: I6fbe055fff7da4c957fde29d132b56ea19bd2f3f closes-bug: #1550632 --- dp-core/vr_datapath.c | 11 +++++++++-- linux/vr_host_interface.c | 17 +++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/dp-core/vr_datapath.c b/dp-core/vr_datapath.c index d96a52d85..c4a135d7a 100644 --- a/dp-core/vr_datapath.c +++ b/dp-core/vr_datapath.c @@ -689,7 +689,7 @@ vr_tag_pkt(struct vr_packet *pkt, unsigned short vlan_id) int vr_gro_input(struct vr_packet *pkt, struct vr_nexthop *nh) { - unsigned short *nh_id; + unsigned short *nh_id, *vif_id; int handled = 1; if (!vr_gro_process) @@ -700,8 +700,15 @@ vr_gro_input(struct vr_packet *pkt, struct vr_nexthop *nh) vr_pfree(pkt, VP_DROP_PUSH); return handled; } - *nh_id = nh->nh_id; + + vif_id = (unsigned short *)pkt_push(pkt, sizeof(*vif_id)); + if (!vif_id) { + vr_pfree(pkt, VP_DROP_PUSH); + return handled; + } + *vif_id = pkt->vp_if->vif_idx; + handled = vr_gro_process(pkt, nh->nh_dev, (nh->nh_family == AF_BRIDGE)); return handled; } diff --git a/linux/vr_host_interface.c b/linux/vr_host_interface.c index 0c6383e6c..149f89f5d 100644 --- a/linux/vr_host_interface.c +++ b/linux/vr_host_interface.c @@ -1770,9 +1770,12 @@ pkt_gro_dev_setup(struct net_device *dev) * undergoing GRO at the moment. In our case, each VM wil have * unique nexthop id associated with it, so we can use nexthop id * as the MAC header to combine packets destined for the same vif. + * In addition to nh id, we need to keep the context of receiving + * inteface, post gro, for packet processing. So vif id inaddition + * to nh id is used as L2 header */ - dev->hard_header_len = sizeof(unsigned short); + dev->hard_header_len = 2 * sizeof(unsigned short); dev->type = ARPHRD_VOID; dev->netdev_ops = &pkt_gro_dev_ops; @@ -1786,7 +1789,7 @@ static void pkt_l2_gro_dev_setup(struct net_device *dev) { pkt_gro_dev_setup(dev); - dev->hard_header_len = sizeof(unsigned short) + VR_ETHER_HLEN; + dev->hard_header_len = 2 * sizeof(unsigned short) + VR_ETHER_HLEN; return; } @@ -1985,7 +1988,7 @@ lh_gro_process(struct vr_packet *pkt, struct vr_interface *vif, bool l2_pkt) static rx_handler_result_t pkt_gro_dev_rx_handler(struct sk_buff **pskb) { - unsigned short nh_id, drop_reason; + unsigned short nh_id, vif_id, drop_reason; struct vr_nexthop *nh; struct vr_interface *vif; struct vr_interface *gro_vif; @@ -2004,7 +2007,8 @@ pkt_gro_dev_rx_handler(struct sk_buff **pskb) goto drop; } #else - nh_id = *((unsigned short *) skb_mac_header(skb)); + vif_id = *((unsigned short *)skb_mac_header(skb)); + nh_id = *((unsigned short *)(skb_mac_header(skb) + sizeof(vif_id))); #endif @@ -2034,6 +2038,11 @@ pkt_gro_dev_rx_handler(struct sk_buff **pskb) * since vif was not available when we did linux_get_packet, set vif * manually here */ + vif = __vrouter_get_interface(router, vif_id); + if (!vif) { + drop_reason = VP_DROP_INVALID_IF; + goto drop; + } pkt->vp_if = vif; vr_init_forwarding_md(&fmd);