Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ip_tunnel: use ndo_siocdevprivate

The various ipv4 and ipv6 tunnel drivers each implement a set
of 12 SIOCDEVPRIVATE commands for managing tunnels. These
all work correctly in compat mode.

Move them over to the new .ndo_siocdevprivate operation.

Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: David Ahern <dsahern@kernel.org>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Arnd Bergmann and committed by
David S. Miller
3e7a1c7c ae6af012

+59 -53
+2 -1
include/net/ip_tunnels.h
··· 270 270 void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, 271 271 const u8 proto, int tunnel_hlen); 272 272 int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd); 273 - int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 273 + int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 274 + void __user *data, int cmd); 274 275 int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); 275 276 int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); 276 277
+1 -1
net/ipv4/ip_gre.c
··· 923 923 .ndo_stop = ipgre_close, 924 924 #endif 925 925 .ndo_start_xmit = ipgre_xmit, 926 - .ndo_do_ioctl = ip_tunnel_ioctl, 926 + .ndo_siocdevprivate = ip_tunnel_siocdevprivate, 927 927 .ndo_change_mtu = ip_tunnel_change_mtu, 928 928 .ndo_get_stats64 = dev_get_tstats64, 929 929 .ndo_get_iflink = ip_tunnel_get_iflink,
+5 -4
net/ipv4/ip_tunnel.c
··· 958 958 } 959 959 EXPORT_SYMBOL_GPL(ip_tunnel_ctl); 960 960 961 - int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 961 + int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 962 + void __user *data, int cmd) 962 963 { 963 964 struct ip_tunnel_parm p; 964 965 int err; 965 966 966 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 967 + if (copy_from_user(&p, data, sizeof(p))) 967 968 return -EFAULT; 968 969 err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, cmd); 969 - if (!err && copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 970 + if (!err && copy_to_user(data, &p, sizeof(p))) 970 971 return -EFAULT; 971 972 return err; 972 973 } 973 - EXPORT_SYMBOL_GPL(ip_tunnel_ioctl); 974 + EXPORT_SYMBOL_GPL(ip_tunnel_siocdevprivate); 974 975 975 976 int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict) 976 977 {
+1 -1
net/ipv4/ip_vti.c
··· 405 405 .ndo_init = vti_tunnel_init, 406 406 .ndo_uninit = ip_tunnel_uninit, 407 407 .ndo_start_xmit = vti_tunnel_xmit, 408 - .ndo_do_ioctl = ip_tunnel_ioctl, 408 + .ndo_siocdevprivate = ip_tunnel_siocdevprivate, 409 409 .ndo_change_mtu = ip_tunnel_change_mtu, 410 410 .ndo_get_stats64 = dev_get_tstats64, 411 411 .ndo_get_iflink = ip_tunnel_get_iflink,
+1 -1
net/ipv4/ipip.c
··· 347 347 .ndo_init = ipip_tunnel_init, 348 348 .ndo_uninit = ip_tunnel_uninit, 349 349 .ndo_start_xmit = ipip_tunnel_xmit, 350 - .ndo_do_ioctl = ip_tunnel_ioctl, 350 + .ndo_siocdevprivate = ip_tunnel_siocdevprivate, 351 351 .ndo_change_mtu = ip_tunnel_change_mtu, 352 352 .ndo_get_stats64 = dev_get_tstats64, 353 353 .ndo_get_iflink = ip_tunnel_get_iflink,
+9 -8
net/ipv6/ip6_gre.c
··· 1244 1244 memcpy(u->name, p->name, sizeof(u->name)); 1245 1245 } 1246 1246 1247 - static int ip6gre_tunnel_ioctl(struct net_device *dev, 1248 - struct ifreq *ifr, int cmd) 1247 + static int ip6gre_tunnel_siocdevprivate(struct net_device *dev, 1248 + struct ifreq *ifr, void __user *data, 1249 + int cmd) 1249 1250 { 1250 1251 int err = 0; 1251 1252 struct ip6_tnl_parm2 p; ··· 1260 1259 switch (cmd) { 1261 1260 case SIOCGETTUNNEL: 1262 1261 if (dev == ign->fb_tunnel_dev) { 1263 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 1262 + if (copy_from_user(&p, data, sizeof(p))) { 1264 1263 err = -EFAULT; 1265 1264 break; 1266 1265 } ··· 1271 1270 } 1272 1271 memset(&p, 0, sizeof(p)); 1273 1272 ip6gre_tnl_parm_to_user(&p, &t->parms); 1274 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1273 + if (copy_to_user(data, &p, sizeof(p))) 1275 1274 err = -EFAULT; 1276 1275 break; 1277 1276 ··· 1282 1281 goto done; 1283 1282 1284 1283 err = -EFAULT; 1285 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1284 + if (copy_from_user(&p, data, sizeof(p))) 1286 1285 goto done; 1287 1286 1288 1287 err = -EINVAL; ··· 1319 1318 1320 1319 memset(&p, 0, sizeof(p)); 1321 1320 ip6gre_tnl_parm_to_user(&p, &t->parms); 1322 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1321 + if (copy_to_user(data, &p, sizeof(p))) 1323 1322 err = -EFAULT; 1324 1323 } else 1325 1324 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); ··· 1332 1331 1333 1332 if (dev == ign->fb_tunnel_dev) { 1334 1333 err = -EFAULT; 1335 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1334 + if (copy_from_user(&p, data, sizeof(p))) 1336 1335 goto done; 1337 1336 err = -ENOENT; 1338 1337 ip6gre_tnl_parm_from_user(&p1, &p); ··· 1399 1398 .ndo_init = ip6gre_tunnel_init, 1400 1399 .ndo_uninit = ip6gre_tunnel_uninit, 1401 1400 .ndo_start_xmit = ip6gre_tunnel_xmit, 1402 - .ndo_do_ioctl = ip6gre_tunnel_ioctl, 1401 + .ndo_siocdevprivate = ip6gre_tunnel_siocdevprivate, 1403 1402 .ndo_change_mtu = ip6_tnl_change_mtu, 1404 1403 .ndo_get_stats64 = dev_get_tstats64, 1405 1404 .ndo_get_iflink = ip6_tnl_get_iflink,
+11 -10
net/ipv6/ip6_tunnel.c
··· 1581 1581 } 1582 1582 1583 1583 /** 1584 - * ip6_tnl_ioctl - configure ipv6 tunnels from userspace 1584 + * ip6_tnl_siocdevprivate - configure ipv6 tunnels from userspace 1585 1585 * @dev: virtual device associated with tunnel 1586 - * @ifr: parameters passed from userspace 1586 + * @ifr: unused 1587 + * @data: parameters passed from userspace 1587 1588 * @cmd: command to be performed 1588 1589 * 1589 1590 * Description: ··· 1610 1609 **/ 1611 1610 1612 1611 static int 1613 - ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1612 + ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 1613 + void __user *data, int cmd) 1614 1614 { 1615 1615 int err = 0; 1616 1616 struct ip6_tnl_parm p; ··· 1625 1623 switch (cmd) { 1626 1624 case SIOCGETTUNNEL: 1627 1625 if (dev == ip6n->fb_tnl_dev) { 1628 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 1626 + if (copy_from_user(&p, data, sizeof(p))) { 1629 1627 err = -EFAULT; 1630 1628 break; 1631 1629 } ··· 1637 1635 memset(&p, 0, sizeof(p)); 1638 1636 } 1639 1637 ip6_tnl_parm_to_user(&p, &t->parms); 1640 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) { 1638 + if (copy_to_user(data, &p, sizeof(p))) 1641 1639 err = -EFAULT; 1642 - } 1643 1640 break; 1644 1641 case SIOCADDTUNNEL: 1645 1642 case SIOCCHGTUNNEL: ··· 1646 1645 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 1647 1646 break; 1648 1647 err = -EFAULT; 1649 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1648 + if (copy_from_user(&p, data, sizeof(p))) 1650 1649 break; 1651 1650 err = -EINVAL; 1652 1651 if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP && ··· 1670 1669 if (!IS_ERR(t)) { 1671 1670 err = 0; 1672 1671 ip6_tnl_parm_to_user(&p, &t->parms); 1673 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1672 + if (copy_to_user(data, &p, sizeof(p))) 1674 1673 err = -EFAULT; 1675 1674 1676 1675 } else { ··· 1684 1683 1685 1684 if (dev == ip6n->fb_tnl_dev) { 1686 1685 err = -EFAULT; 1687 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1686 + if (copy_from_user(&p, data, sizeof(p))) 1688 1687 break; 1689 1688 err = -ENOENT; 1690 1689 ip6_tnl_parm_from_user(&p1, &p); ··· 1803 1802 .ndo_init = ip6_tnl_dev_init, 1804 1803 .ndo_uninit = ip6_tnl_dev_uninit, 1805 1804 .ndo_start_xmit = ip6_tnl_start_xmit, 1806 - .ndo_do_ioctl = ip6_tnl_ioctl, 1805 + .ndo_siocdevprivate = ip6_tnl_siocdevprivate, 1807 1806 .ndo_change_mtu = ip6_tnl_change_mtu, 1808 1807 .ndo_get_stats64 = dev_get_tstats64, 1809 1808 .ndo_get_iflink = ip6_tnl_get_iflink,
+11 -10
net/ipv6/ip6_vti.c
··· 771 771 } 772 772 773 773 /** 774 - * vti6_ioctl - configure vti6 tunnels from userspace 774 + * vti6_siocdevprivate - configure vti6 tunnels from userspace 775 775 * @dev: virtual device associated with tunnel 776 - * @ifr: parameters passed from userspace 776 + * @ifr: unused 777 + * @data: parameters passed from userspace 777 778 * @cmd: command to be performed 778 779 * 779 780 * Description: 780 - * vti6_ioctl() is used for managing vti6 tunnels 781 + * vti6_siocdevprivate() is used for managing vti6 tunnels 781 782 * from userspace. 782 783 * 783 784 * The possible commands are the following: ··· 799 798 * %-ENODEV if attempting to change or delete a nonexisting device 800 799 **/ 801 800 static int 802 - vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 801 + vti6_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) 803 802 { 804 803 int err = 0; 805 804 struct ip6_tnl_parm2 p; ··· 811 810 switch (cmd) { 812 811 case SIOCGETTUNNEL: 813 812 if (dev == ip6n->fb_tnl_dev) { 814 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 813 + if (copy_from_user(&p, data, sizeof(p))) { 815 814 err = -EFAULT; 816 815 break; 817 816 } ··· 823 822 if (!t) 824 823 t = netdev_priv(dev); 825 824 vti6_parm_to_user(&p, &t->parms); 826 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 825 + if (copy_to_user(data, &p, sizeof(p))) 827 826 err = -EFAULT; 828 827 break; 829 828 case SIOCADDTUNNEL: ··· 832 831 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 833 832 break; 834 833 err = -EFAULT; 835 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 834 + if (copy_from_user(&p, data, sizeof(p))) 836 835 break; 837 836 err = -EINVAL; 838 837 if (p.proto != IPPROTO_IPV6 && p.proto != 0) ··· 853 852 if (t) { 854 853 err = 0; 855 854 vti6_parm_to_user(&p, &t->parms); 856 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 855 + if (copy_to_user(data, &p, sizeof(p))) 857 856 err = -EFAULT; 858 857 859 858 } else ··· 866 865 867 866 if (dev == ip6n->fb_tnl_dev) { 868 867 err = -EFAULT; 869 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 868 + if (copy_from_user(&p, data, sizeof(p))) 870 869 break; 871 870 err = -ENOENT; 872 871 vti6_parm_from_user(&p1, &p); ··· 891 890 .ndo_init = vti6_dev_init, 892 891 .ndo_uninit = vti6_dev_uninit, 893 892 .ndo_start_xmit = vti6_tnl_xmit, 894 - .ndo_do_ioctl = vti6_ioctl, 893 + .ndo_siocdevprivate = vti6_siocdevprivate, 895 894 .ndo_get_stats64 = dev_get_tstats64, 896 895 .ndo_get_iflink = ip6_tnl_get_iflink, 897 896 };
+18 -17
net/ipv6/sit.c
··· 299 299 300 300 } 301 301 302 - static int ipip6_tunnel_get_prl(struct net_device *dev, struct ifreq *ifr) 302 + static int ipip6_tunnel_get_prl(struct net_device *dev, struct ip_tunnel_prl __user *a) 303 303 { 304 - struct ip_tunnel_prl __user *a = ifr->ifr_ifru.ifru_data; 305 304 struct ip_tunnel *t = netdev_priv(dev); 306 305 struct ip_tunnel_prl kprl, *kp; 307 306 struct ip_tunnel_prl_entry *prl; ··· 453 454 return err; 454 455 } 455 456 456 - static int ipip6_tunnel_prl_ctl(struct net_device *dev, struct ifreq *ifr, 457 - int cmd) 457 + static int ipip6_tunnel_prl_ctl(struct net_device *dev, 458 + struct ip_tunnel_prl __user *data, int cmd) 458 459 { 459 460 struct ip_tunnel *t = netdev_priv(dev); 460 461 struct ip_tunnel_prl prl; ··· 465 466 if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) 466 467 return -EINVAL; 467 468 468 - if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) 469 + if (copy_from_user(&prl, data, sizeof(prl))) 469 470 return -EFAULT; 470 471 471 472 switch (cmd) { ··· 1197 1198 } 1198 1199 1199 1200 static int 1200 - ipip6_tunnel_get6rd(struct net_device *dev, struct ifreq *ifr) 1201 + ipip6_tunnel_get6rd(struct net_device *dev, struct ip_tunnel_parm __user *data) 1201 1202 { 1202 1203 struct ip_tunnel *t = netdev_priv(dev); 1203 1204 struct ip_tunnel_6rd ip6rd; 1204 1205 struct ip_tunnel_parm p; 1205 1206 1206 1207 if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) { 1207 - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 1208 + if (copy_from_user(&p, data, sizeof(p))) 1208 1209 return -EFAULT; 1209 1210 t = ipip6_tunnel_locate(t->net, &p, 0); 1210 1211 } ··· 1215 1216 ip6rd.relay_prefix = t->ip6rd.relay_prefix; 1216 1217 ip6rd.prefixlen = t->ip6rd.prefixlen; 1217 1218 ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen; 1218 - if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd, sizeof(ip6rd))) 1219 + if (copy_to_user(data, &ip6rd, sizeof(ip6rd))) 1219 1220 return -EFAULT; 1220 1221 return 0; 1221 1222 } 1222 1223 1223 1224 static int 1224 - ipip6_tunnel_6rdctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1225 + ipip6_tunnel_6rdctl(struct net_device *dev, struct ip_tunnel_6rd __user *data, 1226 + int cmd) 1225 1227 { 1226 1228 struct ip_tunnel *t = netdev_priv(dev); 1227 1229 struct ip_tunnel_6rd ip6rd; ··· 1230 1230 1231 1231 if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN)) 1232 1232 return -EPERM; 1233 - if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data, sizeof(ip6rd))) 1233 + if (copy_from_user(&ip6rd, data, sizeof(ip6rd))) 1234 1234 return -EFAULT; 1235 1235 1236 1236 if (cmd != SIOCDEL6RD) { ··· 1369 1369 } 1370 1370 1371 1371 static int 1372 - ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1372 + ipip6_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr, 1373 + void __user *data, int cmd) 1373 1374 { 1374 1375 switch (cmd) { 1375 1376 case SIOCGETTUNNEL: 1376 1377 case SIOCADDTUNNEL: 1377 1378 case SIOCCHGTUNNEL: 1378 1379 case SIOCDELTUNNEL: 1379 - return ip_tunnel_ioctl(dev, ifr, cmd); 1380 + return ip_tunnel_siocdevprivate(dev, ifr, data, cmd); 1380 1381 case SIOCGETPRL: 1381 - return ipip6_tunnel_get_prl(dev, ifr); 1382 + return ipip6_tunnel_get_prl(dev, data); 1382 1383 case SIOCADDPRL: 1383 1384 case SIOCDELPRL: 1384 1385 case SIOCCHGPRL: 1385 - return ipip6_tunnel_prl_ctl(dev, ifr, cmd); 1386 + return ipip6_tunnel_prl_ctl(dev, data, cmd); 1386 1387 #ifdef CONFIG_IPV6_SIT_6RD 1387 1388 case SIOCGET6RD: 1388 - return ipip6_tunnel_get6rd(dev, ifr); 1389 + return ipip6_tunnel_get6rd(dev, data); 1389 1390 case SIOCADD6RD: 1390 1391 case SIOCCHG6RD: 1391 1392 case SIOCDEL6RD: 1392 - return ipip6_tunnel_6rdctl(dev, ifr, cmd); 1393 + return ipip6_tunnel_6rdctl(dev, data, cmd); 1393 1394 #endif 1394 1395 default: 1395 1396 return -EINVAL; ··· 1401 1400 .ndo_init = ipip6_tunnel_init, 1402 1401 .ndo_uninit = ipip6_tunnel_uninit, 1403 1402 .ndo_start_xmit = sit_tunnel_xmit, 1404 - .ndo_do_ioctl = ipip6_tunnel_ioctl, 1403 + .ndo_siocdevprivate = ipip6_tunnel_siocdevprivate, 1405 1404 .ndo_get_stats64 = dev_get_tstats64, 1406 1405 .ndo_get_iflink = ip_tunnel_get_iflink, 1407 1406 .ndo_tunnel_ctl = ipip6_tunnel_ctl,