tun.c (a8f9bfdf982e2b1fb9f094e4de9ab08c57f3d2fd) | tun.c (2eb783c43e7cf807a45899c10ed556b6dc116625) |
---|---|
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. --- 1222 unchanged lines hidden (view full) --- 1231 struct tun_file *tfile, 1232 struct sk_buff *skb, 1233 const struct iovec *iv, int len) 1234{ 1235 struct tun_pi pi = { 0, skb->protocol }; 1236 ssize_t total = 0; 1237 int vlan_offset = 0, copied; 1238 int vlan_hlen = 0; | 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. --- 1222 unchanged lines hidden (view full) --- 1231 struct tun_file *tfile, 1232 struct sk_buff *skb, 1233 const struct iovec *iv, int len) 1234{ 1235 struct tun_pi pi = { 0, skb->protocol }; 1236 ssize_t total = 0; 1237 int vlan_offset = 0, copied; 1238 int vlan_hlen = 0; |
1239 int vnet_hdr_sz = 0; |
|
1239 1240 if (vlan_tx_tag_present(skb)) 1241 vlan_hlen = VLAN_HLEN; 1242 | 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; 1246 |
|
1243 if (!(tun->flags & TUN_NO_PI)) { 1244 if ((len -= sizeof(pi)) < 0) 1245 return -EINVAL; 1246 | 1247 if (!(tun->flags & TUN_NO_PI)) { 1248 if ((len -= sizeof(pi)) < 0) 1249 return -EINVAL; 1250 |
1247 if (len < skb->len) { | 1251 if (len < skb->len + vlan_hlen + vnet_hdr_sz) { |
1248 /* Packet will be striped */ 1249 pi.flags |= TUN_PKT_STRIP; 1250 } 1251 1252 if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) 1253 return -EFAULT; 1254 total += sizeof(pi); 1255 } 1256 | 1252 /* Packet will be striped */ 1253 pi.flags |= TUN_PKT_STRIP; 1254 } 1255 1256 if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) 1257 return -EFAULT; 1258 total += sizeof(pi); 1259 } 1260 |
1257 if (tun->flags & TUN_VNET_HDR) { | 1261 if (vnet_hdr_sz) { |
1258 struct virtio_net_hdr gso = { 0 }; /* no info leak */ | 1262 struct virtio_net_hdr gso = { 0 }; /* no info leak */ |
1259 if ((len -= tun->vnet_hdr_sz) < 0) | 1263 if ((len -= vnet_hdr_sz) < 0) |
1260 return -EINVAL; 1261 1262 if (skb_is_gso(skb)) { 1263 struct skb_shared_info *sinfo = skb_shinfo(skb); 1264 1265 /* This is a hint as to how much should be linear. */ 1266 gso.hdr_len = skb_headlen(skb); 1267 gso.gso_size = sinfo->gso_size; --- 25 unchanged lines hidden (view full) --- 1293 gso.csum_offset = skb->csum_offset; 1294 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 1295 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; 1296 } /* else everything is zero */ 1297 1298 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 1299 sizeof(gso)))) 1300 return -EFAULT; | 1264 return -EINVAL; 1265 1266 if (skb_is_gso(skb)) { 1267 struct skb_shared_info *sinfo = skb_shinfo(skb); 1268 1269 /* This is a hint as to how much should be linear. */ 1270 gso.hdr_len = skb_headlen(skb); 1271 gso.gso_size = sinfo->gso_size; --- 25 unchanged lines hidden (view full) --- 1297 gso.csum_offset = skb->csum_offset; 1298 } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { 1299 gso.flags = VIRTIO_NET_HDR_F_DATA_VALID; 1300 } /* else everything is zero */ 1301 1302 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 1303 sizeof(gso)))) 1304 return -EFAULT; |
1301 total += tun->vnet_hdr_sz; | 1305 total += vnet_hdr_sz; |
1302 } 1303 1304 copied = total; 1305 len = min_t(int, skb->len + vlan_hlen, len); 1306 total += skb->len + vlan_hlen; 1307 if (vlan_hlen) { 1308 int copy, ret; 1309 struct { --- 1074 unchanged lines hidden --- | 1306 } 1307 1308 copied = total; 1309 len = min_t(int, skb->len + vlan_hlen, len); 1310 total += skb->len + vlan_hlen; 1311 if (vlan_hlen) { 1312 int copy, ret; 1313 struct { --- 1074 unchanged lines hidden --- |