summaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2014-10-30 14:27:12 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-30 20:01:18 -0400
commit3d0ad09412ffe00c9afa201d01effdb6023d09b4 (patch)
tree5244d50331be01616a16bf6f122a8769a1a928d8 /drivers/net/tun.c
parent39bb5e62867de82b269b07df900165029b928359 (diff)
drivers/net: Disable UFO through virtio
IPv6 does not allow fragmentation by routers, so there is no fragmentation ID in the fixed header. UFO for IPv6 requires the ID to be passed separately, but there is no provision for this in the virtio net protocol. Until recently our software implementation of UFO/IPv6 generated a new ID, but this was a bug. Now we will use ID=0 for any UFO/IPv6 packet passed through a tap, which is even worse. Unfortunately there is no distinction between UFO/IPv4 and v6 features, so disable UFO on taps and virtio_net completely until we have a proper solution. We cannot depend on VM managers respecting the tap feature flags, so keep accepting UFO packets but log a warning the first time we do this. 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>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 186ce541c657..280d3d2a9792 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -174,7 +174,7 @@ struct tun_struct {
174 struct net_device *dev; 174 struct net_device *dev;
175 netdev_features_t set_features; 175 netdev_features_t set_features;
176#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ 176#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
177 NETIF_F_TSO6|NETIF_F_UFO) 177 NETIF_F_TSO6)
178 178
179 int vnet_hdr_sz; 179 int vnet_hdr_sz;
180 int sndbuf; 180 int sndbuf;
@@ -1149,8 +1149,18 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1149 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; 1149 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
1150 break; 1150 break;
1151 case VIRTIO_NET_HDR_GSO_UDP: 1151 case VIRTIO_NET_HDR_GSO_UDP:
1152 {
1153 static bool warned;
1154
1155 if (!warned) {
1156 warned = true;
1157 netdev_warn(tun->dev,
1158 "%s: using disabled UFO feature; please fix this program\n",
1159 current->comm);
1160 }
1152 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1161 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1153 break; 1162 break;
1163 }
1154 default: 1164 default:
1155 tun->dev->stats.rx_frame_errors++; 1165 tun->dev->stats.rx_frame_errors++;
1156 kfree_skb(skb); 1166 kfree_skb(skb);
@@ -1251,8 +1261,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1251 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 1261 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
1252 else if (sinfo->gso_type & SKB_GSO_TCPV6) 1262 else if (sinfo->gso_type & SKB_GSO_TCPV6)
1253 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; 1263 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
1254 else if (sinfo->gso_type & SKB_GSO_UDP)
1255 gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
1256 else { 1264 else {
1257 pr_err("unexpected GSO type: " 1265 pr_err("unexpected GSO type: "
1258 "0x%x, gso_size %d, hdr_len %d\n", 1266 "0x%x, gso_size %d, hdr_len %d\n",
@@ -1762,11 +1770,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
1762 features |= NETIF_F_TSO6; 1770 features |= NETIF_F_TSO6;
1763 arg &= ~(TUN_F_TSO4|TUN_F_TSO6); 1771 arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
1764 } 1772 }
1765
1766 if (arg & TUN_F_UFO) {
1767 features |= NETIF_F_UFO;
1768 arg &= ~TUN_F_UFO;
1769 }
1770 } 1773 }
1771 1774
1772 /* This gives the user a way to test for new features in future by 1775 /* This gives the user a way to test for new features in future by