diff options
author | Jeff Garzik <jeff@garzik.org> | 2010-02-26 16:43:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-28 04:40:30 -0500 |
commit | 9675478bbafed08848bf8d7e28400d5e46330b23 (patch) | |
tree | e6657e754b88ddc7074aae790510b23d93180308 /net | |
parent | 6c74651c3bce418d3b29edfdeb72664f9441509a (diff) |
ethtool: do not set some flags, if others failed
NETIF_F_NTUPLE flag setting introduced a bug: non-ntuple flags
like LRO may be successfully set, before ioctl(2) returns failure
to userspace.
The set-flags operation should be all-or-none, rather than leaving
things in an inconsistent state prior to reporting failure to
userspace.
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/ethtool.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 31b1eddc1b84..0f2f82185ec4 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -135,21 +135,23 @@ u32 ethtool_op_get_flags(struct net_device *dev) | |||
135 | int ethtool_op_set_flags(struct net_device *dev, u32 data) | 135 | int ethtool_op_set_flags(struct net_device *dev, u32 data) |
136 | { | 136 | { |
137 | const struct ethtool_ops *ops = dev->ethtool_ops; | 137 | const struct ethtool_ops *ops = dev->ethtool_ops; |
138 | unsigned long features = dev->features; | ||
138 | 139 | ||
139 | if (data & ETH_FLAG_LRO) | 140 | if (data & ETH_FLAG_LRO) |
140 | dev->features |= NETIF_F_LRO; | 141 | features |= NETIF_F_LRO; |
141 | else | 142 | else |
142 | dev->features &= ~NETIF_F_LRO; | 143 | features &= ~NETIF_F_LRO; |
143 | 144 | ||
144 | if (data & ETH_FLAG_NTUPLE) { | 145 | if (data & ETH_FLAG_NTUPLE) { |
145 | if (!ops->set_rx_ntuple) | 146 | if (!ops->set_rx_ntuple) |
146 | return -EOPNOTSUPP; | 147 | return -EOPNOTSUPP; |
147 | dev->features |= NETIF_F_NTUPLE; | 148 | features |= NETIF_F_NTUPLE; |
148 | } else { | 149 | } else { |
149 | /* safe to clear regardless */ | 150 | /* safe to clear regardless */ |
150 | dev->features &= ~NETIF_F_NTUPLE; | 151 | features &= ~NETIF_F_NTUPLE; |
151 | } | 152 | } |
152 | 153 | ||
154 | dev->features = features; | ||
153 | return 0; | 155 | return 0; |
154 | } | 156 | } |
155 | 157 | ||