]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
udptunnels: Call handle_offloads after inserting vlan tag.
authorJesse Gross <jesse@nicira.com>
Thu, 9 Apr 2015 18:19:14 +0000 (11:19 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Apr 2015 08:23:44 +0000 (10:23 +0200)
[ Upstream commit b736a623bd099cdf5521ca9bd03559f3bc7fa31c ]

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: 1eaa8178 ("vxlan: Add tx-vlan offload support.")
Signed-off-by: Jesse Gross <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/vxlan.c
net/ipv4/geneve.c

index a8c755dcab1417a27f8939096a23ded65a6af65d..6c83846f914cd6e1b045c900c75cbd8efa46ad6a 100644 (file)
@@ -1578,12 +1578,6 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
        int err;
        bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk);
 
-       skb = udp_tunnel_handle_offloads(skb, udp_sum);
-       if (IS_ERR(skb)) {
-               err = -EINVAL;
-               goto err;
-       }
-
        skb_scrub_packet(skb, xnet);
 
        min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
@@ -1603,6 +1597,12 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
                goto err;
        }
 
+       skb = udp_tunnel_handle_offloads(skb, udp_sum);
+       if (IS_ERR(skb)) {
+               err = -EINVAL;
+               goto err;
+       }
+
        vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
        vxh->vx_flags = htonl(VXLAN_FLAGS);
        vxh->vx_vni = vni;
@@ -1628,10 +1628,6 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
        int err;
        bool udp_sum = !vs->sock->sk->sk_no_check_tx;
 
-       skb = udp_tunnel_handle_offloads(skb, udp_sum);
-       if (IS_ERR(skb))
-               return PTR_ERR(skb);
-
        min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + VXLAN_HLEN + sizeof(struct iphdr)
                        + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
@@ -1647,6 +1643,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
        if (WARN_ON(!skb))
                return -ENOMEM;
 
+       skb = udp_tunnel_handle_offloads(skb, udp_sum);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
        vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
        vxh->vx_flags = htonl(VXLAN_FLAGS);
        vxh->vx_vni = vni;
index 394a200f93c1f5b5338ccab70286545acad1ebda..69711d81a88bcb04b2ec9ce70fcf42db4c394975 100644 (file)
@@ -121,10 +121,6 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
        int min_headroom;
        int err;
 
-       skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx);
-       if (IS_ERR(skb))
-               return PTR_ERR(skb);
-
        min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr)
                        + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
@@ -139,6 +135,10 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
        if (unlikely(!skb))
                return -ENOMEM;
 
+       skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx);
+       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);