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