Commit 174fbb30 authored by Jesse Gross's avatar Jesse Gross Committed by Greg Kroah-Hartman

udptunnels: Call handle_offloads after inserting vlan tag.

[ Upstream commit b736a623 ]

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: default avatarJesse Gross <jesse@nicira.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d385d003
...@@ -1578,12 +1578,6 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, ...@@ -1578,12 +1578,6 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
int err; int err;
bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); 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); skb_scrub_packet(skb, xnet);
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
...@@ -1603,6 +1597,12 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, ...@@ -1603,6 +1597,12 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
goto err; 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 = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = htonl(VXLAN_FLAGS); vxh->vx_flags = htonl(VXLAN_FLAGS);
vxh->vx_vni = vni; vxh->vx_vni = vni;
...@@ -1628,10 +1628,6 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, ...@@ -1628,10 +1628,6 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
int err; int err;
bool udp_sum = !vs->sock->sk->sk_no_check_tx; 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 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
+ VXLAN_HLEN + sizeof(struct iphdr) + VXLAN_HLEN + sizeof(struct iphdr)
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
...@@ -1647,6 +1643,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, ...@@ -1647,6 +1643,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
if (WARN_ON(!skb)) if (WARN_ON(!skb))
return -ENOMEM; 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 = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxh->vx_flags = htonl(VXLAN_FLAGS); vxh->vx_flags = htonl(VXLAN_FLAGS);
vxh->vx_vni = vni; vxh->vx_vni = vni;
......
...@@ -121,10 +121,6 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, ...@@ -121,10 +121,6 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
int min_headroom; int min_headroom;
int err; 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 min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
+ GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr) + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr)
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
...@@ -139,6 +135,10 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, ...@@ -139,6 +135,10 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
if (unlikely(!skb)) if (unlikely(!skb))
return -ENOMEM; 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); gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
geneve_build_header(gnvh, tun_flags, vni, opt_len, opt); geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment