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 ---