diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-06-29 22:44:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-30 17:09:35 -0400 |
commit | 1437ce3983bcbc0447a0dedcd644c14fe833d266 (patch) | |
tree | 073ba0dc60127b08b65fbcca4d0d7c15318c08f8 /net/core | |
parent | b3003be36a3c9215cd17182349981581de269048 (diff) |
ethtool: Change ethtool_op_set_flags to validate flags
ethtool_op_set_flags() does not check for unsupported flags, and has
no way of doing so. This means it is not suitable for use as a
default implementation of ethtool_ops::set_flags.
Add a 'supported' parameter specifying the flags that the driver and
hardware support, validate the requested flags against this, and
change all current callers to pass this parameter.
Change some other trivial implementations of ethtool_ops::set_flags to
call ethtool_op_set_flags().
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/ethtool.c | 28 |
1 files changed, 5 insertions, 23 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index a0f4964033d2..5d42fae520d9 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -144,31 +144,13 @@ u32 ethtool_op_get_flags(struct net_device *dev) | |||
144 | } | 144 | } |
145 | EXPORT_SYMBOL(ethtool_op_get_flags); | 145 | EXPORT_SYMBOL(ethtool_op_get_flags); |
146 | 146 | ||
147 | int ethtool_op_set_flags(struct net_device *dev, u32 data) | 147 | int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) |
148 | { | 148 | { |
149 | const struct ethtool_ops *ops = dev->ethtool_ops; | 149 | if (data & ~supported) |
150 | unsigned long features = dev->features; | 150 | return -EINVAL; |
151 | |||
152 | if (data & ETH_FLAG_LRO) | ||
153 | features |= NETIF_F_LRO; | ||
154 | else | ||
155 | features &= ~NETIF_F_LRO; | ||
156 | |||
157 | if (data & ETH_FLAG_NTUPLE) { | ||
158 | if (!ops->set_rx_ntuple) | ||
159 | return -EOPNOTSUPP; | ||
160 | features |= NETIF_F_NTUPLE; | ||
161 | } else { | ||
162 | /* safe to clear regardless */ | ||
163 | features &= ~NETIF_F_NTUPLE; | ||
164 | } | ||
165 | |||
166 | if (data & ETH_FLAG_RXHASH) | ||
167 | features |= NETIF_F_RXHASH; | ||
168 | else | ||
169 | features &= ~NETIF_F_RXHASH; | ||
170 | 151 | ||
171 | dev->features = features; | 152 | dev->features = ((dev->features & ~flags_dup_features) | |
153 | (data & flags_dup_features)); | ||
172 | return 0; | 154 | return 0; |
173 | } | 155 | } |
174 | EXPORT_SYMBOL(ethtool_op_set_flags); | 156 | EXPORT_SYMBOL(ethtool_op_set_flags); |