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>
This commit is contained in:
parent
ae6af0120d
commit
3e7a1c7c56
|
@ -270,7 +270,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
const u8 proto, int tunnel_hlen);
|
const u8 proto, int tunnel_hlen);
|
||||||
int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
|
int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
|
||||||
int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
|
int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
void __user *data, int cmd);
|
||||||
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
|
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
|
||||||
int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
|
int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
|
||||||
|
|
||||||
|
|
|
@ -923,7 +923,7 @@ static const struct net_device_ops ipgre_netdev_ops = {
|
||||||
.ndo_stop = ipgre_close,
|
.ndo_stop = ipgre_close,
|
||||||
#endif
|
#endif
|
||||||
.ndo_start_xmit = ipgre_xmit,
|
.ndo_start_xmit = ipgre_xmit,
|
||||||
.ndo_do_ioctl = ip_tunnel_ioctl,
|
.ndo_siocdevprivate = ip_tunnel_siocdevprivate,
|
||||||
.ndo_change_mtu = ip_tunnel_change_mtu,
|
.ndo_change_mtu = ip_tunnel_change_mtu,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip_tunnel_get_iflink,
|
.ndo_get_iflink = ip_tunnel_get_iflink,
|
||||||
|
|
|
@ -958,19 +958,20 @@ int ip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip_tunnel_ctl);
|
EXPORT_SYMBOL_GPL(ip_tunnel_ctl);
|
||||||
|
|
||||||
int ip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
void __user *data, int cmd)
|
||||||
{
|
{
|
||||||
struct ip_tunnel_parm p;
|
struct ip_tunnel_parm p;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, cmd);
|
err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, cmd);
|
||||||
if (!err && copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (!err && copy_to_user(data, &p, sizeof(p)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ip_tunnel_ioctl);
|
EXPORT_SYMBOL_GPL(ip_tunnel_siocdevprivate);
|
||||||
|
|
||||||
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
|
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
|
||||||
{
|
{
|
||||||
|
|
|
@ -405,7 +405,7 @@ static const struct net_device_ops vti_netdev_ops = {
|
||||||
.ndo_init = vti_tunnel_init,
|
.ndo_init = vti_tunnel_init,
|
||||||
.ndo_uninit = ip_tunnel_uninit,
|
.ndo_uninit = ip_tunnel_uninit,
|
||||||
.ndo_start_xmit = vti_tunnel_xmit,
|
.ndo_start_xmit = vti_tunnel_xmit,
|
||||||
.ndo_do_ioctl = ip_tunnel_ioctl,
|
.ndo_siocdevprivate = ip_tunnel_siocdevprivate,
|
||||||
.ndo_change_mtu = ip_tunnel_change_mtu,
|
.ndo_change_mtu = ip_tunnel_change_mtu,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip_tunnel_get_iflink,
|
.ndo_get_iflink = ip_tunnel_get_iflink,
|
||||||
|
|
|
@ -347,7 +347,7 @@ static const struct net_device_ops ipip_netdev_ops = {
|
||||||
.ndo_init = ipip_tunnel_init,
|
.ndo_init = ipip_tunnel_init,
|
||||||
.ndo_uninit = ip_tunnel_uninit,
|
.ndo_uninit = ip_tunnel_uninit,
|
||||||
.ndo_start_xmit = ipip_tunnel_xmit,
|
.ndo_start_xmit = ipip_tunnel_xmit,
|
||||||
.ndo_do_ioctl = ip_tunnel_ioctl,
|
.ndo_siocdevprivate = ip_tunnel_siocdevprivate,
|
||||||
.ndo_change_mtu = ip_tunnel_change_mtu,
|
.ndo_change_mtu = ip_tunnel_change_mtu,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip_tunnel_get_iflink,
|
.ndo_get_iflink = ip_tunnel_get_iflink,
|
||||||
|
|
|
@ -1244,8 +1244,9 @@ static void ip6gre_tnl_parm_to_user(struct ip6_tnl_parm2 *u,
|
||||||
memcpy(u->name, p->name, sizeof(u->name));
|
memcpy(u->name, p->name, sizeof(u->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
static int ip6gre_tunnel_siocdevprivate(struct net_device *dev,
|
||||||
struct ifreq *ifr, int cmd)
|
struct ifreq *ifr, void __user *data,
|
||||||
|
int cmd)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct ip6_tnl_parm2 p;
|
struct ip6_tnl_parm2 p;
|
||||||
|
@ -1259,7 +1260,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETTUNNEL:
|
case SIOCGETTUNNEL:
|
||||||
if (dev == ign->fb_tunnel_dev) {
|
if (dev == ign->fb_tunnel_dev) {
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
|
if (copy_from_user(&p, data, sizeof(p))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1270,7 +1271,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
||||||
}
|
}
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&p, 0, sizeof(p));
|
||||||
ip6gre_tnl_parm_to_user(&p, &t->parms);
|
ip6gre_tnl_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1281,7 +1282,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
@ -1318,7 +1319,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
||||||
|
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&p, 0, sizeof(p));
|
||||||
ip6gre_tnl_parm_to_user(&p, &t->parms);
|
ip6gre_tnl_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
} else
|
} else
|
||||||
err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
|
err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
|
||||||
|
@ -1331,7 +1332,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
|
||||||
|
|
||||||
if (dev == ign->fb_tunnel_dev) {
|
if (dev == ign->fb_tunnel_dev) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
goto done;
|
goto done;
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
ip6gre_tnl_parm_from_user(&p1, &p);
|
ip6gre_tnl_parm_from_user(&p1, &p);
|
||||||
|
@ -1398,7 +1399,7 @@ static const struct net_device_ops ip6gre_netdev_ops = {
|
||||||
.ndo_init = ip6gre_tunnel_init,
|
.ndo_init = ip6gre_tunnel_init,
|
||||||
.ndo_uninit = ip6gre_tunnel_uninit,
|
.ndo_uninit = ip6gre_tunnel_uninit,
|
||||||
.ndo_start_xmit = ip6gre_tunnel_xmit,
|
.ndo_start_xmit = ip6gre_tunnel_xmit,
|
||||||
.ndo_do_ioctl = ip6gre_tunnel_ioctl,
|
.ndo_siocdevprivate = ip6gre_tunnel_siocdevprivate,
|
||||||
.ndo_change_mtu = ip6_tnl_change_mtu,
|
.ndo_change_mtu = ip6_tnl_change_mtu,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip6_tnl_get_iflink,
|
.ndo_get_iflink = ip6_tnl_get_iflink,
|
||||||
|
|
|
@ -1581,9 +1581,10 @@ ip6_tnl_parm_to_user(struct ip6_tnl_parm *u, const struct __ip6_tnl_parm *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ip6_tnl_ioctl - configure ipv6 tunnels from userspace
|
* ip6_tnl_siocdevprivate - configure ipv6 tunnels from userspace
|
||||||
* @dev: virtual device associated with tunnel
|
* @dev: virtual device associated with tunnel
|
||||||
* @ifr: parameters passed from userspace
|
* @ifr: unused
|
||||||
|
* @data: parameters passed from userspace
|
||||||
* @cmd: command to be performed
|
* @cmd: command to be performed
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
|
@ -1609,7 +1610,8 @@ ip6_tnl_parm_to_user(struct ip6_tnl_parm *u, const struct __ip6_tnl_parm *p)
|
||||||
**/
|
**/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
ip6_tnl_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
void __user *data, int cmd)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct ip6_tnl_parm p;
|
struct ip6_tnl_parm p;
|
||||||
|
@ -1623,7 +1625,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETTUNNEL:
|
case SIOCGETTUNNEL:
|
||||||
if (dev == ip6n->fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
|
if (copy_from_user(&p, data, sizeof(p))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1635,9 +1637,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
memset(&p, 0, sizeof(p));
|
memset(&p, 0, sizeof(p));
|
||||||
}
|
}
|
||||||
ip6_tnl_parm_to_user(&p, &t->parms);
|
ip6_tnl_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) {
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SIOCADDTUNNEL:
|
case SIOCADDTUNNEL:
|
||||||
case SIOCCHGTUNNEL:
|
case SIOCCHGTUNNEL:
|
||||||
|
@ -1645,7 +1646,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||||
break;
|
break;
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
break;
|
break;
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
|
if (p.proto != IPPROTO_IPV6 && p.proto != IPPROTO_IPIP &&
|
||||||
|
@ -1669,7 +1670,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (!IS_ERR(t)) {
|
if (!IS_ERR(t)) {
|
||||||
err = 0;
|
err = 0;
|
||||||
ip6_tnl_parm_to_user(&p, &t->parms);
|
ip6_tnl_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1683,7 +1684,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
|
|
||||||
if (dev == ip6n->fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
break;
|
break;
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
ip6_tnl_parm_from_user(&p1, &p);
|
ip6_tnl_parm_from_user(&p1, &p);
|
||||||
|
@ -1802,7 +1803,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
|
||||||
.ndo_init = ip6_tnl_dev_init,
|
.ndo_init = ip6_tnl_dev_init,
|
||||||
.ndo_uninit = ip6_tnl_dev_uninit,
|
.ndo_uninit = ip6_tnl_dev_uninit,
|
||||||
.ndo_start_xmit = ip6_tnl_start_xmit,
|
.ndo_start_xmit = ip6_tnl_start_xmit,
|
||||||
.ndo_do_ioctl = ip6_tnl_ioctl,
|
.ndo_siocdevprivate = ip6_tnl_siocdevprivate,
|
||||||
.ndo_change_mtu = ip6_tnl_change_mtu,
|
.ndo_change_mtu = ip6_tnl_change_mtu,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip6_tnl_get_iflink,
|
.ndo_get_iflink = ip6_tnl_get_iflink,
|
||||||
|
|
|
@ -771,13 +771,14 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vti6_ioctl - configure vti6 tunnels from userspace
|
* vti6_siocdevprivate - configure vti6 tunnels from userspace
|
||||||
* @dev: virtual device associated with tunnel
|
* @dev: virtual device associated with tunnel
|
||||||
* @ifr: parameters passed from userspace
|
* @ifr: unused
|
||||||
|
* @data: parameters passed from userspace
|
||||||
* @cmd: command to be performed
|
* @cmd: command to be performed
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* vti6_ioctl() is used for managing vti6 tunnels
|
* vti6_siocdevprivate() is used for managing vti6 tunnels
|
||||||
* from userspace.
|
* from userspace.
|
||||||
*
|
*
|
||||||
* The possible commands are the following:
|
* The possible commands are the following:
|
||||||
|
@ -798,7 +799,7 @@ vti6_parm_to_user(struct ip6_tnl_parm2 *u, const struct __ip6_tnl_parm *p)
|
||||||
* %-ENODEV if attempting to change or delete a nonexisting device
|
* %-ENODEV if attempting to change or delete a nonexisting device
|
||||||
**/
|
**/
|
||||||
static int
|
static int
|
||||||
vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
vti6_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct ip6_tnl_parm2 p;
|
struct ip6_tnl_parm2 p;
|
||||||
|
@ -810,7 +811,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETTUNNEL:
|
case SIOCGETTUNNEL:
|
||||||
if (dev == ip6n->fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
|
if (copy_from_user(&p, data, sizeof(p))) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -822,7 +823,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (!t)
|
if (!t)
|
||||||
t = netdev_priv(dev);
|
t = netdev_priv(dev);
|
||||||
vti6_parm_to_user(&p, &t->parms);
|
vti6_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
break;
|
break;
|
||||||
case SIOCADDTUNNEL:
|
case SIOCADDTUNNEL:
|
||||||
|
@ -831,7 +832,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||||
break;
|
break;
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
break;
|
break;
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (p.proto != IPPROTO_IPV6 && p.proto != 0)
|
if (p.proto != IPPROTO_IPV6 && p.proto != 0)
|
||||||
|
@ -852,7 +853,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
if (t) {
|
if (t) {
|
||||||
err = 0;
|
err = 0;
|
||||||
vti6_parm_to_user(&p, &t->parms);
|
vti6_parm_to_user(&p, &t->parms);
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
|
if (copy_to_user(data, &p, sizeof(p)))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
@ -865,7 +866,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
|
|
||||||
if (dev == ip6n->fb_tnl_dev) {
|
if (dev == ip6n->fb_tnl_dev) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
break;
|
break;
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
vti6_parm_from_user(&p1, &p);
|
vti6_parm_from_user(&p1, &p);
|
||||||
|
@ -890,7 +891,7 @@ static const struct net_device_ops vti6_netdev_ops = {
|
||||||
.ndo_init = vti6_dev_init,
|
.ndo_init = vti6_dev_init,
|
||||||
.ndo_uninit = vti6_dev_uninit,
|
.ndo_uninit = vti6_dev_uninit,
|
||||||
.ndo_start_xmit = vti6_tnl_xmit,
|
.ndo_start_xmit = vti6_tnl_xmit,
|
||||||
.ndo_do_ioctl = vti6_ioctl,
|
.ndo_siocdevprivate = vti6_siocdevprivate,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip6_tnl_get_iflink,
|
.ndo_get_iflink = ip6_tnl_get_iflink,
|
||||||
};
|
};
|
||||||
|
|
|
@ -299,9 +299,8 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipip6_tunnel_get_prl(struct net_device *dev, struct ifreq *ifr)
|
static int ipip6_tunnel_get_prl(struct net_device *dev, struct ip_tunnel_prl __user *a)
|
||||||
{
|
{
|
||||||
struct ip_tunnel_prl __user *a = ifr->ifr_ifru.ifru_data;
|
|
||||||
struct ip_tunnel *t = netdev_priv(dev);
|
struct ip_tunnel *t = netdev_priv(dev);
|
||||||
struct ip_tunnel_prl kprl, *kp;
|
struct ip_tunnel_prl kprl, *kp;
|
||||||
struct ip_tunnel_prl_entry *prl;
|
struct ip_tunnel_prl_entry *prl;
|
||||||
|
@ -454,8 +453,8 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipip6_tunnel_prl_ctl(struct net_device *dev, struct ifreq *ifr,
|
static int ipip6_tunnel_prl_ctl(struct net_device *dev,
|
||||||
int cmd)
|
struct ip_tunnel_prl __user *data, int cmd)
|
||||||
{
|
{
|
||||||
struct ip_tunnel *t = netdev_priv(dev);
|
struct ip_tunnel *t = netdev_priv(dev);
|
||||||
struct ip_tunnel_prl prl;
|
struct ip_tunnel_prl prl;
|
||||||
|
@ -466,7 +465,7 @@ static int ipip6_tunnel_prl_ctl(struct net_device *dev, struct ifreq *ifr,
|
||||||
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev)
|
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
|
if (copy_from_user(&prl, data, sizeof(prl)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
@ -1198,14 +1197,14 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipip6_tunnel_get6rd(struct net_device *dev, struct ifreq *ifr)
|
ipip6_tunnel_get6rd(struct net_device *dev, struct ip_tunnel_parm __user *data)
|
||||||
{
|
{
|
||||||
struct ip_tunnel *t = netdev_priv(dev);
|
struct ip_tunnel *t = netdev_priv(dev);
|
||||||
struct ip_tunnel_6rd ip6rd;
|
struct ip_tunnel_6rd ip6rd;
|
||||||
struct ip_tunnel_parm p;
|
struct ip_tunnel_parm p;
|
||||||
|
|
||||||
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) {
|
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev) {
|
||||||
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
|
if (copy_from_user(&p, data, sizeof(p)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
t = ipip6_tunnel_locate(t->net, &p, 0);
|
t = ipip6_tunnel_locate(t->net, &p, 0);
|
||||||
}
|
}
|
||||||
|
@ -1216,13 +1215,14 @@ ipip6_tunnel_get6rd(struct net_device *dev, struct ifreq *ifr)
|
||||||
ip6rd.relay_prefix = t->ip6rd.relay_prefix;
|
ip6rd.relay_prefix = t->ip6rd.relay_prefix;
|
||||||
ip6rd.prefixlen = t->ip6rd.prefixlen;
|
ip6rd.prefixlen = t->ip6rd.prefixlen;
|
||||||
ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen;
|
ip6rd.relay_prefixlen = t->ip6rd.relay_prefixlen;
|
||||||
if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd, sizeof(ip6rd)))
|
if (copy_to_user(data, &ip6rd, sizeof(ip6rd)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipip6_tunnel_6rdctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
ipip6_tunnel_6rdctl(struct net_device *dev, struct ip_tunnel_6rd __user *data,
|
||||||
|
int cmd)
|
||||||
{
|
{
|
||||||
struct ip_tunnel *t = netdev_priv(dev);
|
struct ip_tunnel *t = netdev_priv(dev);
|
||||||
struct ip_tunnel_6rd ip6rd;
|
struct ip_tunnel_6rd ip6rd;
|
||||||
|
@ -1230,7 +1230,7 @@ ipip6_tunnel_6rdctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||||
|
|
||||||
if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN))
|
if (!ns_capable(t->net->user_ns, CAP_NET_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data, sizeof(ip6rd)))
|
if (copy_from_user(&ip6rd, data, sizeof(ip6rd)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (cmd != SIOCDEL6RD) {
|
if (cmd != SIOCDEL6RD) {
|
||||||
|
@ -1369,27 +1369,28 @@ ipip6_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
ipip6_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
|
||||||
|
void __user *data, int cmd)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCGETTUNNEL:
|
case SIOCGETTUNNEL:
|
||||||
case SIOCADDTUNNEL:
|
case SIOCADDTUNNEL:
|
||||||
case SIOCCHGTUNNEL:
|
case SIOCCHGTUNNEL:
|
||||||
case SIOCDELTUNNEL:
|
case SIOCDELTUNNEL:
|
||||||
return ip_tunnel_ioctl(dev, ifr, cmd);
|
return ip_tunnel_siocdevprivate(dev, ifr, data, cmd);
|
||||||
case SIOCGETPRL:
|
case SIOCGETPRL:
|
||||||
return ipip6_tunnel_get_prl(dev, ifr);
|
return ipip6_tunnel_get_prl(dev, data);
|
||||||
case SIOCADDPRL:
|
case SIOCADDPRL:
|
||||||
case SIOCDELPRL:
|
case SIOCDELPRL:
|
||||||
case SIOCCHGPRL:
|
case SIOCCHGPRL:
|
||||||
return ipip6_tunnel_prl_ctl(dev, ifr, cmd);
|
return ipip6_tunnel_prl_ctl(dev, data, cmd);
|
||||||
#ifdef CONFIG_IPV6_SIT_6RD
|
#ifdef CONFIG_IPV6_SIT_6RD
|
||||||
case SIOCGET6RD:
|
case SIOCGET6RD:
|
||||||
return ipip6_tunnel_get6rd(dev, ifr);
|
return ipip6_tunnel_get6rd(dev, data);
|
||||||
case SIOCADD6RD:
|
case SIOCADD6RD:
|
||||||
case SIOCCHG6RD:
|
case SIOCCHG6RD:
|
||||||
case SIOCDEL6RD:
|
case SIOCDEL6RD:
|
||||||
return ipip6_tunnel_6rdctl(dev, ifr, cmd);
|
return ipip6_tunnel_6rdctl(dev, data, cmd);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1400,7 +1401,7 @@ static const struct net_device_ops ipip6_netdev_ops = {
|
||||||
.ndo_init = ipip6_tunnel_init,
|
.ndo_init = ipip6_tunnel_init,
|
||||||
.ndo_uninit = ipip6_tunnel_uninit,
|
.ndo_uninit = ipip6_tunnel_uninit,
|
||||||
.ndo_start_xmit = sit_tunnel_xmit,
|
.ndo_start_xmit = sit_tunnel_xmit,
|
||||||
.ndo_do_ioctl = ipip6_tunnel_ioctl,
|
.ndo_siocdevprivate = ipip6_tunnel_siocdevprivate,
|
||||||
.ndo_get_stats64 = dev_get_tstats64,
|
.ndo_get_stats64 = dev_get_tstats64,
|
||||||
.ndo_get_iflink = ip_tunnel_get_iflink,
|
.ndo_get_iflink = ip_tunnel_get_iflink,
|
||||||
.ndo_tunnel_ctl = ipip6_tunnel_ctl,
|
.ndo_tunnel_ctl = ipip6_tunnel_ctl,
|
||||||
|
|
Loading…
Reference in New Issue