X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=net%2Fcore%2Fethtool.c;h=8d5e5a09b5760003466518030aa3822a493b80ae;hp=2797e2815418993515d39314fdaba8a9f6926b7f;hb=c58b8e4a25a1ba347a0e5d21984c97bd296f1691;hpb=48cb37bd9e053429aacb7c2726da3300aba60c68 diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 2797e2815418..8d5e5a09b576 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) { @@ -143,7 +143,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) { struct ethtool_drvinfo info; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; if (!ops->get_drvinfo) return -EOPNOTSUPP; @@ -169,7 +169,7 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) { struct ethtool_regs regs; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; void *regbuf; int reglen, ret; @@ -282,7 +282,7 @@ static int ethtool_get_link(struct net_device *dev, void __user *useraddr) static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u8 *data; int ret; @@ -327,7 +327,7 @@ static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u8 *data; int ret; @@ -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; @@ -640,7 +640,7 @@ static int ethtool_set_gso(struct net_device *dev, char __user *useraddr) static int ethtool_self_test(struct net_device *dev, char __user *useraddr) { struct ethtool_test test; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; int ret; @@ -673,7 +673,7 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) { struct ethtool_gstrings gstrings; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u8 *data; int ret; @@ -733,7 +733,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) { struct ethtool_stats stats; - struct ethtool_ops *ops = dev->ethtool_ops; + const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; int ret; @@ -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;