X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fcore%2Fethtool.c;h=8d5e5a09b5760003466518030aa3822a493b80ae;hb=0a09d9a49cc4a7f65b76f848821d4a8bb7cc1230;hp=e0ca04f38cef3d7058e4ffe548e9b2aa85f92f47;hpb=a68aa1cc6f3203b8a332683ebde67a00f39eec43;p=powerpc.git diff --git a/net/core/ethtool.c b/net/core/ethtool.c index e0ca04f38c..8d5e5a09b5 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -17,7 +17,7 @@ #include #include -/* +/* * Some useful ethtool_ops methods that're device independent. * If we find that all drivers want to do the same thing here, * we can turn these into dev_() function calls. @@ -87,12 +87,12 @@ int ethtool_op_get_perm_addr(struct net_device *dev, struct ethtool_perm_addr *a unsigned char len = dev->addr_len; if ( addr->size < len ) return -ETOOSMALL; - + addr->size = len; memcpy(data, dev->perm_addr, len); return 0; } - + u32 ethtool_op_get_ufo(struct net_device *dev) { @@ -550,7 +550,7 @@ static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) if (copy_from_user(&edata, useraddr, sizeof(edata))) return -EFAULT; - if (edata.data && + if (edata.data && !(dev->features & NETIF_F_ALL_CSUM)) return -EINVAL; @@ -806,13 +806,6 @@ int dev_ethtool(struct ifreq *ifr) int rc; unsigned long old_features; - /* - * XXX: This can be pushed down into the ethtool_* handlers that - * need it. Keep existing behaviour for the moment. - */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!dev || !netif_device_present(dev)) return -ENODEV; @@ -822,7 +815,28 @@ int dev_ethtool(struct ifreq *ifr) if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) return -EFAULT; - if(dev->ethtool_ops->begin) + /* Allow some commands to be done by anyone */ + switch(ethcmd) { + case ETHTOOL_GDRVINFO: + case ETHTOOL_GMSGLVL: + case ETHTOOL_GCOALESCE: + case ETHTOOL_GRINGPARAM: + case ETHTOOL_GPAUSEPARAM: + case ETHTOOL_GRXCSUM: + case ETHTOOL_GTXCSUM: + case ETHTOOL_GSG: + case ETHTOOL_GSTRINGS: + case ETHTOOL_GTSO: + case ETHTOOL_GPERMADDR: + case ETHTOOL_GUFO: + case ETHTOOL_GGSO: + break; + default: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + } + + if (dev->ethtool_ops->begin) if ((rc = dev->ethtool_ops->begin(dev)) < 0) return rc; @@ -937,8 +951,8 @@ int dev_ethtool(struct ifreq *ifr) default: rc = -EOPNOTSUPP; } - - if(dev->ethtool_ops->complete) + + if (dev->ethtool_ops->complete) dev->ethtool_ops->complete(dev); if (old_features != dev->features) @@ -947,6 +961,10 @@ int dev_ethtool(struct ifreq *ifr) return rc; ioctl: + /* Keep existing behaviour for the moment. */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (dev->do_ioctl) return dev->do_ioctl(dev, ifr, SIOCETHTOOL); return -EOPNOTSUPP;