448 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
449 align = NET_IP_ALIGN;
450 if (unlikely(len < ETH_HLEN))
451 return -EINVAL;
452 }
453
454 if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
455 tun->dev->stats.rx_dropped++;
456 return -ENOMEM;
457 }
458
459 if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
460 tun->dev->stats.rx_dropped++;
461 kfree_skb(skb);
462 return -EFAULT;
463 }
464
465 if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
466 if (!skb_partial_csum_set(skb, gso.csum_start,
467 gso.csum_offset)) {
468 tun->dev->stats.rx_frame_errors++;
469 kfree_skb(skb);
470 return -EINVAL;
471 }
472 } else if (tun->flags & TUN_NOCHECKSUM)
473 skb->ip_summed = CHECKSUM_UNNECESSARY;
474
475 switch (tun->flags & TUN_TYPE_MASK) {
476 case TUN_TUN_DEV:
477 if (tun->flags & TUN_NO_PI) {
478 switch (skb->data[0] & 0xf0) {
479 case 0x40:
480 pi.proto = htons(ETH_P_IP);
481 break;
482 case 0x60:
483 pi.proto = htons(ETH_P_IPV6);
484 break;
485 default:
486 tun->dev->stats.rx_dropped++;
487 kfree_skb(skb);
488 return -EINVAL;