summaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-12-08 20:39:29 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-12-08 20:39:29 -0500
commitba00410b8131b23edfb0e09f8b6dd26c8eb621fb (patch)
treec08504e4d2fa51ac91cef544f336d0169806c49f /drivers/net/tun.c
parent8ce74dd6057832618957fc2cbd38fa959c3a0a6c (diff)
parentaa583096d9767892983332e7c1a984bd17e3cd39 (diff)
Merge branch 'iov_iter' into for-next
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c53
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a3420e091689..4d332dc93b70 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -65,6 +65,7 @@
65#include <linux/nsproxy.h> 65#include <linux/nsproxy.h>
66#include <linux/virtio_net.h> 66#include <linux/virtio_net.h>
67#include <linux/rcupdate.h> 67#include <linux/rcupdate.h>
68#include <net/ipv6.h>
68#include <net/net_namespace.h> 69#include <net/net_namespace.h>
69#include <net/netns/generic.h> 70#include <net/netns/generic.h>
70#include <net/rtnetlink.h> 71#include <net/rtnetlink.h>
@@ -174,7 +175,7 @@ struct tun_struct {
174 struct net_device *dev; 175 struct net_device *dev;
175 netdev_features_t set_features; 176 netdev_features_t set_features;
176#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ 177#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
177 NETIF_F_TSO6|NETIF_F_UFO) 178 NETIF_F_TSO6)
178 179
179 int vnet_hdr_sz; 180 int vnet_hdr_sz;
180 int sndbuf; 181 int sndbuf;
@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1139 break; 1140 break;
1140 } 1141 }
1141 1142
1143 skb_reset_network_header(skb);
1144
1142 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { 1145 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
1143 pr_debug("GSO!\n"); 1146 pr_debug("GSO!\n");
1144 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { 1147 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
@@ -1149,8 +1152,20 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1149 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; 1152 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
1150 break; 1153 break;
1151 case VIRTIO_NET_HDR_GSO_UDP: 1154 case VIRTIO_NET_HDR_GSO_UDP:
1155 {
1156 static bool warned;
1157
1158 if (!warned) {
1159 warned = true;
1160 netdev_warn(tun->dev,
1161 "%s: using disabled UFO feature; please fix this program\n",
1162 current->comm);
1163 }
1152 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1164 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1165 if (skb->protocol == htons(ETH_P_IPV6))
1166 ipv6_proxy_select_ident(skb);
1153 break; 1167 break;
1168 }
1154 default: 1169 default:
1155 tun->dev->stats.rx_frame_errors++; 1170 tun->dev->stats.rx_frame_errors++;
1156 kfree_skb(skb); 1171 kfree_skb(skb);
@@ -1179,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1179 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; 1194 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
1180 } 1195 }
1181 1196
1182 skb_reset_network_header(skb);
1183 skb_probe_transport_header(skb, 0); 1197 skb_probe_transport_header(skb, 0);
1184 1198
1185 rxhash = skb_get_hash(skb); 1199 rxhash = skb_get_hash(skb);
@@ -1221,12 +1235,20 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1221 struct tun_pi pi = { 0, skb->protocol }; 1235 struct tun_pi pi = { 0, skb->protocol };
1222 ssize_t total = 0; 1236 ssize_t total = 0;
1223 int vlan_offset = 0, copied; 1237 int vlan_offset = 0, copied;
1238 int vlan_hlen = 0;
1239 int vnet_hdr_sz = 0;
1240
1241 if (vlan_tx_tag_present(skb))
1242 vlan_hlen = VLAN_HLEN;
1243
1244 if (tun->flags & TUN_VNET_HDR)
1245 vnet_hdr_sz = tun->vnet_hdr_sz;
1224 1246
1225 if (!(tun->flags & TUN_NO_PI)) { 1247 if (!(tun->flags & TUN_NO_PI)) {
1226 if ((len -= sizeof(pi)) < 0) 1248 if ((len -= sizeof(pi)) < 0)
1227 return -EINVAL; 1249 return -EINVAL;
1228 1250
1229 if (len < skb->len) { 1251 if (len < skb->len + vlan_hlen + vnet_hdr_sz) {
1230 /* Packet will be striped */ 1252 /* Packet will be striped */
1231 pi.flags |= TUN_PKT_STRIP; 1253 pi.flags |= TUN_PKT_STRIP;
1232 } 1254 }
@@ -1236,9 +1258,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1236 total += sizeof(pi); 1258 total += sizeof(pi);
1237 } 1259 }
1238 1260
1239 if (tun->flags & TUN_VNET_HDR) { 1261 if (vnet_hdr_sz) {
1240 struct virtio_net_hdr gso = { 0 }; /* no info leak */ 1262 struct virtio_net_hdr gso = { 0 }; /* no info leak */
1241 if ((len -= tun->vnet_hdr_sz) < 0) 1263 if ((len -= vnet_hdr_sz) < 0)
1242 return -EINVAL; 1264 return -EINVAL;
1243 1265
1244 if (skb_is_gso(skb)) { 1266 if (skb_is_gso(skb)) {
@@ -1251,8 +1273,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1251 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 1273 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
1252 else if (sinfo->gso_type & SKB_GSO_TCPV6) 1274 else if (sinfo->gso_type & SKB_GSO_TCPV6)
1253 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; 1275 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 { 1276 else {
1257 pr_err("unexpected GSO type: " 1277 pr_err("unexpected GSO type: "
1258 "0x%x, gso_size %d, hdr_len %d\n", 1278 "0x%x, gso_size %d, hdr_len %d\n",
@@ -1272,7 +1292,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1272 1292
1273 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1293 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1274 gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; 1294 gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
1275 gso.csum_start = skb_checksum_start_offset(skb); 1295 gso.csum_start = skb_checksum_start_offset(skb) +
1296 vlan_hlen;
1276 gso.csum_offset = skb->csum_offset; 1297 gso.csum_offset = skb->csum_offset;
1277 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 1298 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
1278 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; 1299 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -1281,14 +1302,13 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1281 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 1302 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
1282 sizeof(gso)))) 1303 sizeof(gso))))
1283 return -EFAULT; 1304 return -EFAULT;
1284 total += tun->vnet_hdr_sz; 1305 total += vnet_hdr_sz;
1285 } 1306 }
1286 1307
1287 copied = total; 1308 copied = total;
1288 total += skb->len; 1309 len = min_t(int, skb->len + vlan_hlen, len);
1289 if (!vlan_tx_tag_present(skb)) { 1310 total += skb->len + vlan_hlen;
1290 len = min_t(int, skb->len, len); 1311 if (vlan_hlen) {
1291 } else {
1292 int copy, ret; 1312 int copy, ret;
1293 struct { 1313 struct {
1294 __be16 h_vlan_proto; 1314 __be16 h_vlan_proto;
@@ -1299,8 +1319,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1299 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); 1319 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
1300 1320
1301 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); 1321 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
1302 len = min_t(int, skb->len + VLAN_HLEN, len);
1303 total += VLAN_HLEN;
1304 1322
1305 copy = min_t(int, vlan_offset, len); 1323 copy = min_t(int, vlan_offset, len);
1306 ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); 1324 ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
@@ -1762,11 +1780,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
1762 features |= NETIF_F_TSO6; 1780 features |= NETIF_F_TSO6;
1763 arg &= ~(TUN_F_TSO4|TUN_F_TSO6); 1781 arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
1764 } 1782 }
1765
1766 if (arg & TUN_F_UFO) {
1767 features |= NETIF_F_UFO;
1768 arg &= ~TUN_F_UFO;
1769 }
1770 } 1783 }
1771 1784
1772 /* This gives the user a way to test for new features in future by 1785 /* This gives the user a way to test for new features in future by