datapath: Account for "udptunnels: Call handle_offloads after inserting vlan tag."
authorJesse Gross <jesse@nicira.com>
Tue, 7 Apr 2015 23:11:23 +0000 (16:11 -0700)
committerJesse Gross <jesse@nicira.com>
Thu, 9 Apr 2015 21:34:51 +0000 (14:34 -0700)
Upstream commit:
    udptunnels: Call handle_offloads after inserting vlan tag.

    handle_offloads() calls skb_reset_inner_headers() to store
    the layer pointers to the encapsulated packet. However, we
    currently push the vlag tag (if there is one) onto the packet
    afterwards. This changes the MAC header for the encapsulated
    packet but it is not reflected in skb->inner_mac_header, which
    breaks GSO and drivers which attempt to use this for encapsulation
    offloads.

    Fixes: b736a623 ("vxlan: Add tx-vlan offload support.")
Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Upstream: 4aac884d ("udptunnels: Call handle_offloads after inserting vlan tag.")
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
datapath/linux/compat/geneve.c
datapath/linux/compat/vxlan.c

index 5fc6c67..48a306e 100644 (file)
@@ -91,10 +91,6 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
        int min_headroom;
        int err;
 
-       skb = udp_tunnel_handle_offloads(skb, csum, (opt_len == 0));
-       if (IS_ERR(skb))
-               return PTR_ERR(skb);
-
        min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
                        + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr)
                        + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
@@ -109,6 +105,10 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
        if (unlikely(!skb))
                return -ENOMEM;
 
+       skb = udp_tunnel_handle_offloads(skb, csum, (opt_len == 0));
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
        gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
        geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
 
index 8af3433..51135fa 100644 (file)
@@ -191,10 +191,6 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
        int err;
        bool udp_sum = !!(vxflags & VXLAN_F_UDP_CSUM);
 
-       skb = udp_tunnel_handle_offloads(skb, udp_sum, true);
-       if (IS_ERR(skb))
-               return PTR_ERR(skb);
-
        min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
                        + VXLAN_HLEN + sizeof(struct iphdr)
                        + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
@@ -210,6 +206,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
        if (WARN_ON(!skb))
                return -ENOMEM;
 
+       skb = udp_tunnel_handle_offloads(skb, udp_sum, true);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
        vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
        vxh->vx_flags = htonl(VXLAN_HF_VNI);
        vxh->vx_vni = md->vni;