tun.c (6288cf1e768ae73db5ddaaae54d85245cc1c2b56) tun.c (6403eab143205a45a5493166ff8bf7e3646f4a77)
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.

--- 109 unchanged lines hidden (view full) ---

118
119struct tun_struct {
120 struct tun_file *tfile;
121 unsigned int flags;
122 uid_t owner;
123 gid_t group;
124
125 struct net_device *dev;
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.

--- 109 unchanged lines hidden (view full) ---

118
119struct tun_struct {
120 struct tun_file *tfile;
121 unsigned int flags;
122 uid_t owner;
123 gid_t group;
124
125 struct net_device *dev;
126 u32 set_features;
127#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
128 NETIF_F_TSO6|NETIF_F_UFO)
126 struct fasync_struct *fasync;
127
128 struct tap_filter txflt;
129 struct socket socket;
130 struct socket_wq wq;
131
132 int vnet_hdr_sz;
133

--- 312 unchanged lines hidden (view full) ---

446tun_net_change_mtu(struct net_device *dev, int new_mtu)
447{
448 if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
449 return -EINVAL;
450 dev->mtu = new_mtu;
451 return 0;
452}
453
129 struct fasync_struct *fasync;
130
131 struct tap_filter txflt;
132 struct socket socket;
133 struct socket_wq wq;
134
135 int vnet_hdr_sz;
136

--- 312 unchanged lines hidden (view full) ---

449tun_net_change_mtu(struct net_device *dev, int new_mtu)
450{
451 if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
452 return -EINVAL;
453 dev->mtu = new_mtu;
454 return 0;
455}
456
457static u32 tun_net_fix_features(struct net_device *dev, u32 features)
458{
459 struct tun_struct *tun = netdev_priv(dev);
460
461 return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
462}
463
454static const struct net_device_ops tun_netdev_ops = {
455 .ndo_uninit = tun_net_uninit,
456 .ndo_open = tun_net_open,
457 .ndo_stop = tun_net_close,
458 .ndo_start_xmit = tun_net_xmit,
459 .ndo_change_mtu = tun_net_change_mtu,
464static const struct net_device_ops tun_netdev_ops = {
465 .ndo_uninit = tun_net_uninit,
466 .ndo_open = tun_net_open,
467 .ndo_stop = tun_net_close,
468 .ndo_start_xmit = tun_net_xmit,
469 .ndo_change_mtu = tun_net_change_mtu,
470 .ndo_fix_features = tun_net_fix_features,
460};
461
462static const struct net_device_ops tap_netdev_ops = {
463 .ndo_uninit = tun_net_uninit,
464 .ndo_open = tun_net_open,
465 .ndo_stop = tun_net_close,
466 .ndo_start_xmit = tun_net_xmit,
467 .ndo_change_mtu = tun_net_change_mtu,
471};
472
473static const struct net_device_ops tap_netdev_ops = {
474 .ndo_uninit = tun_net_uninit,
475 .ndo_open = tun_net_open,
476 .ndo_stop = tun_net_close,
477 .ndo_start_xmit = tun_net_xmit,
478 .ndo_change_mtu = tun_net_change_mtu,
479 .ndo_fix_features = tun_net_fix_features,
468 .ndo_set_multicast_list = tun_net_mclist,
469 .ndo_set_mac_address = eth_mac_addr,
470 .ndo_validate_addr = eth_validate_addr,
471};
472
473/* Initialize net device. */
474static void tun_net_init(struct net_device *dev)
475{

--- 147 unchanged lines hidden (view full) ---

623
624 if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
625 if (!skb_partial_csum_set(skb, gso.csum_start,
626 gso.csum_offset)) {
627 tun->dev->stats.rx_frame_errors++;
628 kfree_skb(skb);
629 return -EINVAL;
630 }
480 .ndo_set_multicast_list = tun_net_mclist,
481 .ndo_set_mac_address = eth_mac_addr,
482 .ndo_validate_addr = eth_validate_addr,
483};
484
485/* Initialize net device. */
486static void tun_net_init(struct net_device *dev)
487{

--- 147 unchanged lines hidden (view full) ---

635
636 if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
637 if (!skb_partial_csum_set(skb, gso.csum_start,
638 gso.csum_offset)) {
639 tun->dev->stats.rx_frame_errors++;
640 kfree_skb(skb);
641 return -EINVAL;
642 }
631 } else if (tun->flags & TUN_NOCHECKSUM)
632 skb->ip_summed = CHECKSUM_UNNECESSARY;
643 }
633
634 switch (tun->flags & TUN_TYPE_MASK) {
635 case TUN_TUN_DEV:
636 if (tun->flags & TUN_NO_PI) {
637 switch (skb->data[0] & 0xf0) {
638 case 0x40:
639 pi.proto = htons(ETH_P_IP);
640 break;

--- 9 unchanged lines hidden (view full) ---

650
651 skb_reset_mac_header(skb);
652 skb->protocol = pi.proto;
653 skb->dev = tun->dev;
654 break;
655 case TUN_TAP_DEV:
656 skb->protocol = eth_type_trans(skb, tun->dev);
657 break;
644
645 switch (tun->flags & TUN_TYPE_MASK) {
646 case TUN_TUN_DEV:
647 if (tun->flags & TUN_NO_PI) {
648 switch (skb->data[0] & 0xf0) {
649 case 0x40:
650 pi.proto = htons(ETH_P_IP);
651 break;

--- 9 unchanged lines hidden (view full) ---

661
662 skb_reset_mac_header(skb);
663 skb->protocol = pi.proto;
664 skb->dev = tun->dev;
665 break;
666 case TUN_TAP_DEV:
667 skb->protocol = eth_type_trans(skb, tun->dev);
668 break;
658 };
669 }
659
660 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
661 pr_debug("GSO!\n");
662 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
663 case VIRTIO_NET_HDR_GSO_TCPV4:
664 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
665 break;
666 case VIRTIO_NET_HDR_GSO_TCPV6:

--- 416 unchanged lines hidden (view full) ---

1083 sk->sk_sndbuf = INT_MAX;
1084
1085 tun_sk(sk)->tun = tun;
1086
1087 security_tun_dev_post_create(sk);
1088
1089 tun_net_init(dev);
1090
670
671 if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
672 pr_debug("GSO!\n");
673 switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
674 case VIRTIO_NET_HDR_GSO_TCPV4:
675 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
676 break;
677 case VIRTIO_NET_HDR_GSO_TCPV6:

--- 416 unchanged lines hidden (view full) ---

1094 sk->sk_sndbuf = INT_MAX;
1095
1096 tun_sk(sk)->tun = tun;
1097
1098 security_tun_dev_post_create(sk);
1099
1100 tun_net_init(dev);
1101
1091 if (strchr(dev->name, '%')) {
1092 err = dev_alloc_name(dev, dev->name);
1093 if (err < 0)
1094 goto err_free_sk;
1095 }
1102 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
1103 TUN_USER_FEATURES;
1104 dev->features = dev->hw_features;
1096
1097 err = register_netdevice(tun->dev);
1098 if (err < 0)
1099 goto err_free_sk;
1100
1101 if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
1102 device_create_file(&tun->dev->dev, &dev_attr_owner) ||
1103 device_create_file(&tun->dev->dev, &dev_attr_group))

--- 49 unchanged lines hidden (view full) ---

1153
1154 ifr->ifr_flags = tun_flags(tun);
1155
1156 return 0;
1157}
1158
1159/* This is like a cut-down ethtool ops, except done via tun fd so no
1160 * privs required. */
1105
1106 err = register_netdevice(tun->dev);
1107 if (err < 0)
1108 goto err_free_sk;
1109
1110 if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
1111 device_create_file(&tun->dev->dev, &dev_attr_owner) ||
1112 device_create_file(&tun->dev->dev, &dev_attr_group))

--- 49 unchanged lines hidden (view full) ---

1162
1163 ifr->ifr_flags = tun_flags(tun);
1164
1165 return 0;
1166}
1167
1168/* This is like a cut-down ethtool ops, except done via tun fd so no
1169 * privs required. */
1161static int set_offload(struct net_device *dev, unsigned long arg)
1170static int set_offload(struct tun_struct *tun, unsigned long arg)
1162{
1171{
1163 u32 old_features, features;
1172 u32 features = 0;
1164
1173
1165 old_features = dev->features;
1166 /* Unset features, set them as we chew on the arg. */
1167 features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
1168 |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
1169 |NETIF_F_UFO));
1170
1171 if (arg & TUN_F_CSUM) {
1174 if (arg & TUN_F_CSUM) {
1172 features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
1175 features |= NETIF_F_HW_CSUM;
1173 arg &= ~TUN_F_CSUM;
1174
1175 if (arg & (TUN_F_TSO4|TUN_F_TSO6)) {
1176 if (arg & TUN_F_TSO_ECN) {
1177 features |= NETIF_F_TSO_ECN;
1178 arg &= ~TUN_F_TSO_ECN;
1179 }
1180 if (arg & TUN_F_TSO4)

--- 9 unchanged lines hidden (view full) ---

1190 }
1191 }
1192
1193 /* This gives the user a way to test for new features in future by
1194 * trying to set them. */
1195 if (arg)
1196 return -EINVAL;
1197
1176 arg &= ~TUN_F_CSUM;
1177
1178 if (arg & (TUN_F_TSO4|TUN_F_TSO6)) {
1179 if (arg & TUN_F_TSO_ECN) {
1180 features |= NETIF_F_TSO_ECN;
1181 arg &= ~TUN_F_TSO_ECN;
1182 }
1183 if (arg & TUN_F_TSO4)

--- 9 unchanged lines hidden (view full) ---

1193 }
1194 }
1195
1196 /* This gives the user a way to test for new features in future by
1197 * trying to set them. */
1198 if (arg)
1199 return -EINVAL;
1200
1198 dev->features = features;
1199 if (old_features != dev->features)
1200 netdev_features_change(dev);
1201 tun->set_features = features;
1202 netdev_update_features(tun->dev);
1201
1202 return 0;
1203}
1204
1205static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1206 unsigned long arg, int ifreq_len)
1207{
1208 struct tun_file *tfile = file->private_data;

--- 48 unchanged lines hidden (view full) ---

1257 break;
1258
1259 if (copy_to_user(argp, &ifr, ifreq_len))
1260 ret = -EFAULT;
1261 break;
1262
1263 case TUNSETNOCSUM:
1264 /* Disable/Enable checksum */
1203
1204 return 0;
1205}
1206
1207static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1208 unsigned long arg, int ifreq_len)
1209{
1210 struct tun_file *tfile = file->private_data;

--- 48 unchanged lines hidden (view full) ---

1259 break;
1260
1261 if (copy_to_user(argp, &ifr, ifreq_len))
1262 ret = -EFAULT;
1263 break;
1264
1265 case TUNSETNOCSUM:
1266 /* Disable/Enable checksum */
1265 if (arg)
1266 tun->flags |= TUN_NOCHECKSUM;
1267 else
1268 tun->flags &= ~TUN_NOCHECKSUM;
1269
1267
1270 tun_debug(KERN_INFO, tun, "checksum %s\n",
1268 /* [unimplemented] */
1269 tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n",
1271 arg ? "disabled" : "enabled");
1272 break;
1273
1274 case TUNSETPERSIST:
1275 /* Disable/Enable persist mode */
1276 if (arg)
1277 tun->flags |= TUN_PERSIST;
1278 else

--- 32 unchanged lines hidden (view full) ---

1311 break;
1312
1313#ifdef TUN_DEBUG
1314 case TUNSETDEBUG:
1315 tun->debug = arg;
1316 break;
1317#endif
1318 case TUNSETOFFLOAD:
1270 arg ? "disabled" : "enabled");
1271 break;
1272
1273 case TUNSETPERSIST:
1274 /* Disable/Enable persist mode */
1275 if (arg)
1276 tun->flags |= TUN_PERSIST;
1277 else

--- 32 unchanged lines hidden (view full) ---

1310 break;
1311
1312#ifdef TUN_DEBUG
1313 case TUNSETDEBUG:
1314 tun->debug = arg;
1315 break;
1316#endif
1317 case TUNSETOFFLOAD:
1319 ret = set_offload(tun->dev, arg);
1318 ret = set_offload(tun, arg);
1320 break;
1321
1322 case TUNSETTXFILTER:
1323 /* Can be set only for TAPs */
1324 ret = -EINVAL;
1325 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1326 break;
1327 ret = update_filter(&tun->txflt, (void __user *)arg);

--- 215 unchanged lines hidden (view full) ---

1543};
1544
1545/* ethtool interface */
1546
1547static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1548{
1549 cmd->supported = 0;
1550 cmd->advertising = 0;
1319 break;
1320
1321 case TUNSETTXFILTER:
1322 /* Can be set only for TAPs */
1323 ret = -EINVAL;
1324 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1325 break;
1326 ret = update_filter(&tun->txflt, (void __user *)arg);

--- 215 unchanged lines hidden (view full) ---

1542};
1543
1544/* ethtool interface */
1545
1546static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1547{
1548 cmd->supported = 0;
1549 cmd->advertising = 0;
1551 cmd->speed = SPEED_10;
1550 ethtool_cmd_speed_set(cmd, SPEED_10);
1552 cmd->duplex = DUPLEX_FULL;
1553 cmd->port = PORT_TP;
1554 cmd->phy_address = 0;
1555 cmd->transceiver = XCVR_INTERNAL;
1556 cmd->autoneg = AUTONEG_DISABLE;
1557 cmd->maxtxpkt = 0;
1558 cmd->maxrxpkt = 0;
1559 return 0;

--- 30 unchanged lines hidden (view full) ---

1590static void tun_set_msglevel(struct net_device *dev, u32 value)
1591{
1592#ifdef TUN_DEBUG
1593 struct tun_struct *tun = netdev_priv(dev);
1594 tun->debug = value;
1595#endif
1596}
1597
1551 cmd->duplex = DUPLEX_FULL;
1552 cmd->port = PORT_TP;
1553 cmd->phy_address = 0;
1554 cmd->transceiver = XCVR_INTERNAL;
1555 cmd->autoneg = AUTONEG_DISABLE;
1556 cmd->maxtxpkt = 0;
1557 cmd->maxrxpkt = 0;
1558 return 0;

--- 30 unchanged lines hidden (view full) ---

1589static void tun_set_msglevel(struct net_device *dev, u32 value)
1590{
1591#ifdef TUN_DEBUG
1592 struct tun_struct *tun = netdev_priv(dev);
1593 tun->debug = value;
1594#endif
1595}
1596
1598static u32 tun_get_rx_csum(struct net_device *dev)
1599{
1600 struct tun_struct *tun = netdev_priv(dev);
1601 return (tun->flags & TUN_NOCHECKSUM) == 0;
1602}
1603
1604static int tun_set_rx_csum(struct net_device *dev, u32 data)
1605{
1606 struct tun_struct *tun = netdev_priv(dev);
1607 if (data)
1608 tun->flags &= ~TUN_NOCHECKSUM;
1609 else
1610 tun->flags |= TUN_NOCHECKSUM;
1611 return 0;
1612}
1613
1614static const struct ethtool_ops tun_ethtool_ops = {
1615 .get_settings = tun_get_settings,
1616 .get_drvinfo = tun_get_drvinfo,
1617 .get_msglevel = tun_get_msglevel,
1618 .set_msglevel = tun_set_msglevel,
1619 .get_link = ethtool_op_get_link,
1597static const struct ethtool_ops tun_ethtool_ops = {
1598 .get_settings = tun_get_settings,
1599 .get_drvinfo = tun_get_drvinfo,
1600 .get_msglevel = tun_get_msglevel,
1601 .set_msglevel = tun_set_msglevel,
1602 .get_link = ethtool_op_get_link,
1620 .get_rx_csum = tun_get_rx_csum,
1621 .set_rx_csum = tun_set_rx_csum
1622};
1623
1624
1625static int __init tun_init(void)
1626{
1627 int ret = 0;
1628
1629 pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);

--- 50 unchanged lines hidden ---
1603};
1604
1605
1606static int __init tun_init(void)
1607{
1608 int ret = 0;
1609
1610 pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);

--- 50 unchanged lines hidden ---