aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 42b6c6319bc2..2533f5cf2e4b 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -398,12 +398,12 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
398 if (tun->flags & TUN_FASYNC) 398 if (tun->flags & TUN_FASYNC)
399 kill_fasync(&tun->fasync, SIGIO, POLL_IN); 399 kill_fasync(&tun->fasync, SIGIO, POLL_IN);
400 wake_up_interruptible(&tun->socket.wait); 400 wake_up_interruptible(&tun->socket.wait);
401 return 0; 401 return NETDEV_TX_OK;
402 402
403drop: 403drop:
404 dev->stats.tx_dropped++; 404 dev->stats.tx_dropped++;
405 kfree_skb(skb); 405 kfree_skb(skb);
406 return 0; 406 return NETDEV_TX_OK;
407} 407}
408 408
409static void tun_net_mclist(struct net_device *dev) 409static void tun_net_mclist(struct net_device *dev)
@@ -641,6 +641,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
641 case VIRTIO_NET_HDR_GSO_TCPV6: 641 case VIRTIO_NET_HDR_GSO_TCPV6:
642 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; 642 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
643 break; 643 break;
644 case VIRTIO_NET_HDR_GSO_UDP:
645 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
646 break;
644 default: 647 default:
645 tun->dev->stats.rx_frame_errors++; 648 tun->dev->stats.rx_frame_errors++;
646 kfree_skb(skb); 649 kfree_skb(skb);
@@ -726,6 +729,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
726 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; 729 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
727 else if (sinfo->gso_type & SKB_GSO_TCPV6) 730 else if (sinfo->gso_type & SKB_GSO_TCPV6)
728 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; 731 gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
732 else if (sinfo->gso_type & SKB_GSO_UDP)
733 gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
729 else 734 else
730 BUG(); 735 BUG();
731 if (sinfo->gso_type & SKB_GSO_TCP_ECN) 736 if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -997,7 +1002,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
997 goto err_free_sk; 1002 goto err_free_sk;
998 } 1003 }
999 1004
1000 err = -EINVAL;
1001 err = register_netdevice(tun->dev); 1005 err = register_netdevice(tun->dev);
1002 if (err < 0) 1006 if (err < 0)
1003 goto err_free_sk; 1007 goto err_free_sk;
@@ -1069,7 +1073,8 @@ static int set_offload(struct net_device *dev, unsigned long arg)
1069 old_features = dev->features; 1073 old_features = dev->features;
1070 /* Unset features, set them as we chew on the arg. */ 1074 /* Unset features, set them as we chew on the arg. */
1071 features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST 1075 features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
1072 |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6)); 1076 |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
1077 |NETIF_F_UFO));
1073 1078
1074 if (arg & TUN_F_CSUM) { 1079 if (arg & TUN_F_CSUM) {
1075 features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; 1080 features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
@@ -1086,6 +1091,11 @@ static int set_offload(struct net_device *dev, unsigned long arg)
1086 features |= NETIF_F_TSO6; 1091 features |= NETIF_F_TSO6;
1087 arg &= ~(TUN_F_TSO4|TUN_F_TSO6); 1092 arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
1088 } 1093 }
1094
1095 if (arg & TUN_F_UFO) {
1096 features |= NETIF_F_UFO;
1097 arg &= ~TUN_F_UFO;
1098 }
1089 } 1099 }
1090 1100
1091 /* This gives the user a way to test for new features in future by 1101 /* This gives the user a way to test for new features in future by