diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2014-10-30 18:27:17 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2015-01-01 01:27:51 +0000 |
commit | 540aa5b743b3ba2c7651f3e311a0fc8d4865534e (patch) | |
tree | aff2ade4c63653cb26417148c12c88ab3cecef14 /drivers/net | |
parent | 543563d72f5b098ab719f296b6357d88701c1a1e (diff) |
drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets
commit 5188cd44c55db3e92cd9e77a40b5baa7ed4340f7 upstream.
UFO is now disabled on all drivers that work with virtio net headers,
but userland may try to send UFO/IPv6 packets anyway. Instead of
sending with ID=0, we should select identifiers on their behalf (as we
used to).
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: For 3.2, net/ipv6/output_core.c is a completely new file]
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/macvtap.c | 3 | ||||
-rw-r--r-- | drivers/net/tun.c | 5 |
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index b0f901518b76..0e6e57ed1a2f 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -15,6 +15,7 @@ #include <linux/cdev.h> #include <linux/fs.h> +#include <net/ipv6.h> #include <net/net_namespace.h> #include <net/rtnetlink.h> #include <net/sock.h> @@ -577,6 +578,8 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, break; case VIRTIO_NET_HDR_GSO_UDP: gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); break; default: return -EINVAL; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ee1aab0805d1..2fbbca670457 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -64,6 +64,7 @@ #include <linux/nsproxy.h> #include <linux/virtio_net.h> #include <linux/rcupdate.h> +#include <net/ipv6.h> #include <net/net_namespace.h> #include <net/netns/generic.h> #include <net/rtnetlink.h> @@ -695,6 +696,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, break; } + skb_reset_network_header(skb); + if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { @@ -706,6 +709,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, break; case VIRTIO_NET_HDR_GSO_UDP: skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); break; default: tun->dev->stats.rx_frame_errors++; |