tun.c (8ce74dd6057832618957fc2cbd38fa959c3a0a6c) | tun.c (baeababb5b85d5c4e6c917efe2a1504179438d3b) |
---|---|
1/* 2 * TUN - Universal TUN/TAP device driver. 3 * Copyright (C) 1999-2002 Maxim Krasnyansky <maxk@qualcomm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 51 unchanged lines hidden (view full) --- 60#include <linux/if_arp.h> 61#include <linux/if_ether.h> 62#include <linux/if_tun.h> 63#include <linux/if_vlan.h> 64#include <linux/crc32.h> 65#include <linux/nsproxy.h> 66#include <linux/virtio_net.h> 67#include <linux/rcupdate.h> | 1/* 2 * TUN - Universal TUN/TAP device driver. 3 * Copyright (C) 1999-2002 Maxim Krasnyansky <maxk@qualcomm.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. --- 51 unchanged lines hidden (view full) --- 60#include <linux/if_arp.h> 61#include <linux/if_ether.h> 62#include <linux/if_tun.h> 63#include <linux/if_vlan.h> 64#include <linux/crc32.h> 65#include <linux/nsproxy.h> 66#include <linux/virtio_net.h> 67#include <linux/rcupdate.h> |
68#include <net/ipv6.h> |
|
68#include <net/net_namespace.h> 69#include <net/netns/generic.h> 70#include <net/rtnetlink.h> 71#include <net/sock.h> 72#include <linux/seq_file.h> | 69#include <net/net_namespace.h> 70#include <net/netns/generic.h> 71#include <net/rtnetlink.h> 72#include <net/sock.h> 73#include <linux/seq_file.h> |
74#include <linux/uio.h> |
|
73 74#include <asm/uaccess.h> 75 76/* Uncomment to enable debugging */ 77/* #define TUN_DEBUG 1 */ 78 79#ifdef TUN_DEBUG 80static int debug; --- 88 unchanged lines hidden (view full) --- 169 unsigned int numqueues; 170 unsigned int flags; 171 kuid_t owner; 172 kgid_t group; 173 174 struct net_device *dev; 175 netdev_features_t set_features; 176#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ | 75 76#include <asm/uaccess.h> 77 78/* Uncomment to enable debugging */ 79/* #define TUN_DEBUG 1 */ 80 81#ifdef TUN_DEBUG 82static int debug; --- 88 unchanged lines hidden (view full) --- 171 unsigned int numqueues; 172 unsigned int flags; 173 kuid_t owner; 174 kgid_t group; 175 176 struct net_device *dev; 177 netdev_features_t set_features; 178#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ |
177 NETIF_F_TSO6|NETIF_F_UFO) | 179 NETIF_F_TSO6) |
178 179 int vnet_hdr_sz; 180 int sndbuf; 181 struct tap_filter txflt; 182 struct sock_fprog fprog; 183 /* protected by rtnl lock */ 184 bool filter_attached; 185#ifdef TUN_DEBUG --- 626 unchanged lines hidden (view full) --- 812 rcu_read_unlock(); 813 return NETDEV_TX_OK; 814 815drop: 816 dev->stats.tx_dropped++; 817 skb_tx_error(skb); 818 kfree_skb(skb); 819 rcu_read_unlock(); | 180 181 int vnet_hdr_sz; 182 int sndbuf; 183 struct tap_filter txflt; 184 struct sock_fprog fprog; 185 /* protected by rtnl lock */ 186 bool filter_attached; 187#ifdef TUN_DEBUG --- 626 unchanged lines hidden (view full) --- 814 rcu_read_unlock(); 815 return NETDEV_TX_OK; 816 817drop: 818 dev->stats.tx_dropped++; 819 skb_tx_error(skb); 820 kfree_skb(skb); 821 rcu_read_unlock(); |
820 return NETDEV_TX_OK; | 822 return NET_XMIT_DROP; |
821} 822 823static void tun_net_mclist(struct net_device *dev) 824{ 825 /* 826 * This callback is supposed to deal with mc filter in 827 * _rx_ path and has nothing to do with the _tx_ path. 828 * In rx path we always accept everything userspace gives us. --- 305 unchanged lines hidden (view full) --- 1134 skb->protocol = pi.proto; 1135 skb->dev = tun->dev; 1136 break; 1137 case TUN_TAP_DEV: 1138 skb->protocol = eth_type_trans(skb, tun->dev); 1139 break; 1140 } 1141 | 823} 824 825static void tun_net_mclist(struct net_device *dev) 826{ 827 /* 828 * This callback is supposed to deal with mc filter in 829 * _rx_ path and has nothing to do with the _tx_ path. 830 * In rx path we always accept everything userspace gives us. --- 305 unchanged lines hidden (view full) --- 1136 skb->protocol = pi.proto; 1137 skb->dev = tun->dev; 1138 break; 1139 case TUN_TAP_DEV: 1140 skb->protocol = eth_type_trans(skb, tun->dev); 1141 break; 1142 } 1143 |
1144 skb_reset_network_header(skb); 1145 |
|
1142 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { 1143 pr_debug("GSO!\n"); 1144 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { 1145 case VIRTIO_NET_HDR_GSO_TCPV4: 1146 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; 1147 break; 1148 case VIRTIO_NET_HDR_GSO_TCPV6: 1149 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; 1150 break; 1151 case VIRTIO_NET_HDR_GSO_UDP: | 1146 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { 1147 pr_debug("GSO!\n"); 1148 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { 1149 case VIRTIO_NET_HDR_GSO_TCPV4: 1150 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; 1151 break; 1152 case VIRTIO_NET_HDR_GSO_TCPV6: 1153 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; 1154 break; 1155 case VIRTIO_NET_HDR_GSO_UDP: |
1156 { 1157 static bool warned; 1158 1159 if (!warned) { 1160 warned = true; 1161 netdev_warn(tun->dev, 1162 "%s: using disabled UFO feature; please fix this program\n", 1163 current->comm); 1164 } |
|
1152 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | 1165 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
1166 if (skb->protocol == htons(ETH_P_IPV6)) 1167 ipv6_proxy_select_ident(skb); |
|
1153 break; | 1168 break; |
1169 } |
|
1154 default: 1155 tun->dev->stats.rx_frame_errors++; 1156 kfree_skb(skb); 1157 return -EINVAL; 1158 } 1159 1160 if (gso.gso_type & VIRTIO_NET_HDR_GSO_ECN) 1161 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; --- 12 unchanged lines hidden (view full) --- 1174 1175 /* copy skb_ubuf_info for callback when skb has no error */ 1176 if (zerocopy) { 1177 skb_shinfo(skb)->destructor_arg = msg_control; 1178 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1179 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; 1180 } 1181 | 1170 default: 1171 tun->dev->stats.rx_frame_errors++; 1172 kfree_skb(skb); 1173 return -EINVAL; 1174 } 1175 1176 if (gso.gso_type & VIRTIO_NET_HDR_GSO_ECN) 1177 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; --- 12 unchanged lines hidden (view full) --- 1190 1191 /* copy skb_ubuf_info for callback when skb has no error */ 1192 if (zerocopy) { 1193 skb_shinfo(skb)->destructor_arg = msg_control; 1194 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1195 skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; 1196 } 1197 |
1182 skb_reset_network_header(skb); | |
1183 skb_probe_transport_header(skb, 0); 1184 1185 rxhash = skb_get_hash(skb); 1186 netif_rx_ni(skb); 1187 1188 tun->dev->stats.rx_packets++; 1189 tun->dev->stats.rx_bytes += len; 1190 --- 20 unchanged lines hidden (view full) --- 1211 tun_put(tun); 1212 return result; 1213} 1214 1215/* Put packet to the user space buffer */ 1216static ssize_t tun_put_user(struct tun_struct *tun, 1217 struct tun_file *tfile, 1218 struct sk_buff *skb, | 1198 skb_probe_transport_header(skb, 0); 1199 1200 rxhash = skb_get_hash(skb); 1201 netif_rx_ni(skb); 1202 1203 tun->dev->stats.rx_packets++; 1204 tun->dev->stats.rx_bytes += len; 1205 --- 20 unchanged lines hidden (view full) --- 1226 tun_put(tun); 1227 return result; 1228} 1229 1230/* Put packet to the user space buffer */ 1231static ssize_t tun_put_user(struct tun_struct *tun, 1232 struct tun_file *tfile, 1233 struct sk_buff *skb, |
1219 const struct iovec *iv, int len) | 1234 struct iov_iter *iter) |
1220{ 1221 struct tun_pi pi = { 0, skb->protocol }; | 1235{ 1236 struct tun_pi pi = { 0, skb->protocol }; |
1222 ssize_t total = 0; 1223 int vlan_offset = 0, copied; | 1237 ssize_t total; 1238 int vlan_offset = 0; 1239 int vlan_hlen = 0; 1240 int vnet_hdr_sz = 0; |
1224 | 1241 |
1242 if (vlan_tx_tag_present(skb)) 1243 vlan_hlen = VLAN_HLEN; 1244 1245 if (tun->flags & TUN_VNET_HDR) 1246 vnet_hdr_sz = tun->vnet_hdr_sz; 1247 1248 total = skb->len + vlan_hlen + vnet_hdr_sz; 1249 |
|
1225 if (!(tun->flags & TUN_NO_PI)) { | 1250 if (!(tun->flags & TUN_NO_PI)) { |
1226 if ((len -= sizeof(pi)) < 0) | 1251 if (iov_iter_count(iter) < sizeof(pi)) |
1227 return -EINVAL; 1228 | 1252 return -EINVAL; 1253 |
1229 if (len < skb->len) { | 1254 total += sizeof(pi); 1255 if (iov_iter_count(iter) < total) { |
1230 /* Packet will be striped */ 1231 pi.flags |= TUN_PKT_STRIP; 1232 } 1233 | 1256 /* Packet will be striped */ 1257 pi.flags |= TUN_PKT_STRIP; 1258 } 1259 |
1234 if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) | 1260 if (copy_to_iter(&pi, sizeof(pi), iter) != sizeof(pi)) |
1235 return -EFAULT; | 1261 return -EFAULT; |
1236 total += sizeof(pi); | |
1237 } 1238 | 1262 } 1263 |
1239 if (tun->flags & TUN_VNET_HDR) { | 1264 if (vnet_hdr_sz) { |
1240 struct virtio_net_hdr gso = { 0 }; /* no info leak */ | 1265 struct virtio_net_hdr gso = { 0 }; /* no info leak */ |
1241 if ((len -= tun->vnet_hdr_sz) < 0) | 1266 if (iov_iter_count(iter) < vnet_hdr_sz) |
1242 return -EINVAL; 1243 1244 if (skb_is_gso(skb)) { 1245 struct skb_shared_info *sinfo = skb_shinfo(skb); 1246 1247 /* This is a hint as to how much should be linear. */ 1248 gso.hdr_len = skb_headlen(skb); 1249 gso.gso_size = sinfo->gso_size; 1250 if (sinfo->gso_type & SKB_GSO_TCPV4) 1251 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 1252 else if (sinfo->gso_type & SKB_GSO_TCPV6) 1253 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; | 1267 return -EINVAL; 1268 1269 if (skb_is_gso(skb)) { 1270 struct skb_shared_info *sinfo = skb_shinfo(skb); 1271 1272 /* This is a hint as to how much should be linear. */ 1273 gso.hdr_len = skb_headlen(skb); 1274 gso.gso_size = sinfo->gso_size; 1275 if (sinfo->gso_type & SKB_GSO_TCPV4) 1276 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 1277 else if (sinfo->gso_type & SKB_GSO_TCPV6) 1278 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 { 1257 pr_err("unexpected GSO type: " 1258 "0x%x, gso_size %d, hdr_len %d\n", 1259 sinfo->gso_type, gso.gso_size, 1260 gso.hdr_len); 1261 print_hex_dump(KERN_ERR, "tun: ", 1262 DUMP_PREFIX_NONE, 1263 16, 1, skb->head, 1264 min((int)gso.hdr_len, 64), true); 1265 WARN_ON_ONCE(1); 1266 return -EINVAL; 1267 } 1268 if (sinfo->gso_type & SKB_GSO_TCP_ECN) 1269 gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; 1270 } else 1271 gso.gso_type = VIRTIO_NET_HDR_GSO_NONE; 1272 1273 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1274 gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; | 1279 else { 1280 pr_err("unexpected GSO type: " 1281 "0x%x, gso_size %d, hdr_len %d\n", 1282 sinfo->gso_type, gso.gso_size, 1283 gso.hdr_len); 1284 print_hex_dump(KERN_ERR, "tun: ", 1285 DUMP_PREFIX_NONE, 1286 16, 1, skb->head, 1287 min((int)gso.hdr_len, 64), true); 1288 WARN_ON_ONCE(1); 1289 return -EINVAL; 1290 } 1291 if (sinfo->gso_type & SKB_GSO_TCP_ECN) 1292 gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN; 1293 } else 1294 gso.gso_type = VIRTIO_NET_HDR_GSO_NONE; 1295 1296 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1297 gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; |
1275 gso.csum_start = skb_checksum_start_offset(skb); | 1298 gso.csum_start = skb_checksum_start_offset(skb) + 1299 vlan_hlen; |
1276 gso.csum_offset = skb->csum_offset; 1277 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 1278 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; 1279 } /* else everything is zero */ 1280 | 1300 gso.csum_offset = skb->csum_offset; 1301 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 1302 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; 1303 } /* else everything is zero */ 1304 |
1281 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 1282 sizeof(gso)))) | 1305 if (copy_to_iter(&gso, sizeof(gso), iter) != sizeof(gso)) |
1283 return -EFAULT; | 1306 return -EFAULT; |
1284 total += tun->vnet_hdr_sz; | 1307 1308 iov_iter_advance(iter, vnet_hdr_sz - sizeof(gso)); |
1285 } 1286 | 1309 } 1310 |
1287 copied = total; 1288 total += skb->len; 1289 if (!vlan_tx_tag_present(skb)) { 1290 len = min_t(int, skb->len, len); 1291 } else { 1292 int copy, ret; | 1311 if (vlan_hlen) { 1312 int ret; |
1293 struct { 1294 __be16 h_vlan_proto; 1295 __be16 h_vlan_TCI; 1296 } veth; 1297 1298 veth.h_vlan_proto = skb->vlan_proto; 1299 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); 1300 1301 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 1313 struct { 1314 __be16 h_vlan_proto; 1315 __be16 h_vlan_TCI; 1316 } veth; 1317 1318 veth.h_vlan_proto = skb->vlan_proto; 1319 veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); 1320 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); 1306 ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); 1307 len -= copy; 1308 copied += copy; 1309 if (ret || !len) | 1323 ret = skb_copy_datagram_iter(skb, 0, iter, vlan_offset); 1324 if (ret || !iov_iter_count(iter)) |
1310 goto done; 1311 | 1325 goto done; 1326 |
1312 copy = min_t(int, sizeof(veth), len); 1313 ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); 1314 len -= copy; 1315 copied += copy; 1316 if (ret || !len) | 1327 ret = copy_to_iter(&veth, sizeof(veth), iter); 1328 if (ret != sizeof(veth) || !iov_iter_count(iter)) |
1317 goto done; 1318 } 1319 | 1329 goto done; 1330 } 1331 |
1320 skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); | 1332 skb_copy_datagram_iter(skb, vlan_offset, iter, skb->len - vlan_offset); |
1321 1322done: 1323 tun->dev->stats.tx_packets++; | 1333 1334done: 1335 tun->dev->stats.tx_packets++; |
1324 tun->dev->stats.tx_bytes += len; | 1336 tun->dev->stats.tx_bytes += skb->len + vlan_hlen; |
1325 1326 return total; 1327} 1328 1329static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, | 1337 1338 return total; 1339} 1340 1341static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, |
1330 const struct iovec *iv, ssize_t len, int noblock) | 1342 const struct iovec *iv, unsigned long segs, 1343 ssize_t len, int noblock) |
1331{ 1332 struct sk_buff *skb; 1333 ssize_t ret = 0; 1334 int peeked, err, off = 0; | 1344{ 1345 struct sk_buff *skb; 1346 ssize_t ret = 0; 1347 int peeked, err, off = 0; |
1348 struct iov_iter iter; |
|
1335 1336 tun_debug(KERN_INFO, tun, "tun_do_read\n"); 1337 1338 if (!len) 1339 return ret; 1340 1341 if (tun->dev->reg_state != NETREG_REGISTERED) 1342 return -EIO; 1343 1344 /* Read frames from queue */ 1345 skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, 1346 &peeked, &off, &err); | 1349 1350 tun_debug(KERN_INFO, tun, "tun_do_read\n"); 1351 1352 if (!len) 1353 return ret; 1354 1355 if (tun->dev->reg_state != NETREG_REGISTERED) 1356 return -EIO; 1357 1358 /* Read frames from queue */ 1359 skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0, 1360 &peeked, &off, &err); |
1347 if (skb) { 1348 ret = tun_put_user(tun, tfile, skb, iv, len); 1349 kfree_skb(skb); 1350 } else 1351 ret = err; | 1361 if (!skb) 1362 return ret; |
1352 | 1363 |
1364 iov_iter_init(&iter, READ, iv, segs, len); 1365 ret = tun_put_user(tun, tfile, skb, &iter); 1366 kfree_skb(skb); 1367 |
|
1353 return ret; 1354} 1355 1356static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, 1357 unsigned long count, loff_t pos) 1358{ 1359 struct file *file = iocb->ki_filp; 1360 struct tun_file *tfile = file->private_data; 1361 struct tun_struct *tun = __tun_get(tfile); 1362 ssize_t len, ret; 1363 1364 if (!tun) 1365 return -EBADFD; 1366 len = iov_length(iv, count); 1367 if (len < 0) { 1368 ret = -EINVAL; 1369 goto out; 1370 } 1371 | 1368 return ret; 1369} 1370 1371static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, 1372 unsigned long count, loff_t pos) 1373{ 1374 struct file *file = iocb->ki_filp; 1375 struct tun_file *tfile = file->private_data; 1376 struct tun_struct *tun = __tun_get(tfile); 1377 ssize_t len, ret; 1378 1379 if (!tun) 1380 return -EBADFD; 1381 len = iov_length(iv, count); 1382 if (len < 0) { 1383 ret = -EINVAL; 1384 goto out; 1385 } 1386 |
1372 ret = tun_do_read(tun, tfile, iv, len, | 1387 ret = tun_do_read(tun, tfile, iv, count, len, |
1373 file->f_flags & O_NONBLOCK); 1374 ret = min_t(ssize_t, ret, len); 1375 if (ret > 0) 1376 iocb->ki_pos = ret; 1377out: 1378 tun_put(tun); 1379 return ret; 1380} --- 84 unchanged lines hidden (view full) --- 1465 ret = -EINVAL; 1466 goto out; 1467 } 1468 if (flags & MSG_ERRQUEUE) { 1469 ret = sock_recv_errqueue(sock->sk, m, total_len, 1470 SOL_PACKET, TUN_TX_TIMESTAMP); 1471 goto out; 1472 } | 1388 file->f_flags & O_NONBLOCK); 1389 ret = min_t(ssize_t, ret, len); 1390 if (ret > 0) 1391 iocb->ki_pos = ret; 1392out: 1393 tun_put(tun); 1394 return ret; 1395} --- 84 unchanged lines hidden (view full) --- 1480 ret = -EINVAL; 1481 goto out; 1482 } 1483 if (flags & MSG_ERRQUEUE) { 1484 ret = sock_recv_errqueue(sock->sk, m, total_len, 1485 SOL_PACKET, TUN_TX_TIMESTAMP); 1486 goto out; 1487 } |
1473 ret = tun_do_read(tun, tfile, m->msg_iov, total_len, | 1488 ret = tun_do_read(tun, tfile, m->msg_iov, m->msg_iovlen, total_len, |
1474 flags & MSG_DONTWAIT); 1475 if (ret > total_len) { 1476 m->msg_flags |= MSG_TRUNC; 1477 ret = flags & MSG_TRUNC ? ret : total_len; 1478 } 1479out: 1480 tun_put(tun); 1481 return ret; --- 275 unchanged lines hidden (view full) --- 1757 arg &= ~TUN_F_TSO_ECN; 1758 } 1759 if (arg & TUN_F_TSO4) 1760 features |= NETIF_F_TSO; 1761 if (arg & TUN_F_TSO6) 1762 features |= NETIF_F_TSO6; 1763 arg &= ~(TUN_F_TSO4|TUN_F_TSO6); 1764 } | 1489 flags & MSG_DONTWAIT); 1490 if (ret > total_len) { 1491 m->msg_flags |= MSG_TRUNC; 1492 ret = flags & MSG_TRUNC ? ret : total_len; 1493 } 1494out: 1495 tun_put(tun); 1496 return ret; --- 275 unchanged lines hidden (view full) --- 1772 arg &= ~TUN_F_TSO_ECN; 1773 } 1774 if (arg & TUN_F_TSO4) 1775 features |= NETIF_F_TSO; 1776 if (arg & TUN_F_TSO6) 1777 features |= NETIF_F_TSO6; 1778 arg &= ~(TUN_F_TSO4|TUN_F_TSO6); 1779 } |
1765 1766 if (arg & TUN_F_UFO) { 1767 features |= NETIF_F_UFO; 1768 arg &= ~TUN_F_UFO; 1769 } | |
1770 } 1771 1772 /* This gives the user a way to test for new features in future by 1773 * trying to set them. */ 1774 if (arg) 1775 return -EINVAL; 1776 1777 tun->set_features = features; --- 426 unchanged lines hidden (view full) --- 2204 2205 tun_detach(tfile, true); 2206 put_net(net); 2207 2208 return 0; 2209} 2210 2211#ifdef CONFIG_PROC_FS | 1780 } 1781 1782 /* This gives the user a way to test for new features in future by 1783 * trying to set them. */ 1784 if (arg) 1785 return -EINVAL; 1786 1787 tun->set_features = features; --- 426 unchanged lines hidden (view full) --- 2214 2215 tun_detach(tfile, true); 2216 put_net(net); 2217 2218 return 0; 2219} 2220 2221#ifdef CONFIG_PROC_FS |
2212static void tun_chr_show_fdinfo(struct seq_file *m, struct file *f) | 2222static int tun_chr_show_fdinfo(struct seq_file *m, struct file *f) |
2213{ 2214 struct tun_struct *tun; 2215 struct ifreq ifr; 2216 2217 memset(&ifr, 0, sizeof(ifr)); 2218 2219 rtnl_lock(); 2220 tun = tun_get(f); 2221 if (tun) 2222 tun_get_iff(current->nsproxy->net_ns, tun, &ifr); 2223 rtnl_unlock(); 2224 2225 if (tun) 2226 tun_put(tun); 2227 | 2223{ 2224 struct tun_struct *tun; 2225 struct ifreq ifr; 2226 2227 memset(&ifr, 0, sizeof(ifr)); 2228 2229 rtnl_lock(); 2230 tun = tun_get(f); 2231 if (tun) 2232 tun_get_iff(current->nsproxy->net_ns, tun, &ifr); 2233 rtnl_unlock(); 2234 2235 if (tun) 2236 tun_put(tun); 2237 |
2228 seq_printf(m, "iff:\t%s\n", ifr.ifr_name); | 2238 return seq_printf(m, "iff:\t%s\n", ifr.ifr_name); |
2229} 2230#endif 2231 2232static const struct file_operations tun_fops = { 2233 .owner = THIS_MODULE, 2234 .llseek = no_llseek, 2235 .read = do_sync_read, 2236 .aio_read = tun_chr_aio_read, --- 138 unchanged lines hidden --- | 2239} 2240#endif 2241 2242static const struct file_operations tun_fops = { 2243 .owner = THIS_MODULE, 2244 .llseek = no_llseek, 2245 .read = do_sync_read, 2246 .aio_read = tun_chr_aio_read, --- 138 unchanged lines hidden --- |