aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-04-22 02:31:16 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-28 16:33:08 -0400
commitc4d27ef957cd9261c0bc8488edaf8390e412cd35 (patch)
treef8e263ca9a1842803a2265bffd5eaa3e5b3d9660 /net/bridge
parent1742f183fc218798dab6fcf0ded25b6608fc0a48 (diff)
bridge: convert br_features_recompute() to ndo_fix_features
Note: netdev_update_features() needs only rtnl_lock as br->port_list is only changed while holding it. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c61
-rw-r--r--net/bridge/br_if.c17
-rw-r--r--net/bridge/br_notify.c5
-rw-r--r--net/bridge/br_private.h3
4 files changed, 19 insertions, 67 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 45cfd54b06d3..a6b2f86378c7 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -90,8 +90,7 @@ static int br_dev_open(struct net_device *dev)
90 struct net_bridge *br = netdev_priv(dev); 90 struct net_bridge *br = netdev_priv(dev);
91 91
92 netif_carrier_off(dev); 92 netif_carrier_off(dev);
93 93 netdev_update_features(dev);
94 br_features_recompute(br);
95 netif_start_queue(dev); 94 netif_start_queue(dev);
96 br_stp_enable_bridge(br); 95 br_stp_enable_bridge(br);
97 br_multicast_open(br); 96 br_multicast_open(br);
@@ -188,48 +187,11 @@ static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
188 strcpy(info->bus_info, "N/A"); 187 strcpy(info->bus_info, "N/A");
189} 188}
190 189
191static int br_set_sg(struct net_device *dev, u32 data) 190static u32 br_fix_features(struct net_device *dev, u32 features)
192{
193 struct net_bridge *br = netdev_priv(dev);
194
195 if (data)
196 br->feature_mask |= NETIF_F_SG;
197 else
198 br->feature_mask &= ~NETIF_F_SG;
199
200 br_features_recompute(br);
201 return 0;
202}
203
204static int br_set_tso(struct net_device *dev, u32 data)
205{ 191{
206 struct net_bridge *br = netdev_priv(dev); 192 struct net_bridge *br = netdev_priv(dev);
207 193
208 if (data) 194 return br_features_recompute(br, features);
209 br->feature_mask |= NETIF_F_TSO;
210 else
211 br->feature_mask &= ~NETIF_F_TSO;
212
213 br_features_recompute(br);
214 return 0;
215}
216
217static int br_set_tx_csum(struct net_device *dev, u32 data)
218{
219 struct net_bridge *br = netdev_priv(dev);
220
221 if (data)
222 br->feature_mask |= NETIF_F_NO_CSUM;
223 else
224 br->feature_mask &= ~NETIF_F_ALL_CSUM;
225
226 br_features_recompute(br);
227 return 0;
228}
229
230static int br_set_flags(struct net_device *netdev, u32 data)
231{
232 return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN);
233} 195}
234 196
235#ifdef CONFIG_NET_POLL_CONTROLLER 197#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -330,16 +292,6 @@ static int br_del_slave(struct net_device *dev, struct net_device *slave_dev)
330static const struct ethtool_ops br_ethtool_ops = { 292static const struct ethtool_ops br_ethtool_ops = {
331 .get_drvinfo = br_getinfo, 293 .get_drvinfo = br_getinfo,
332 .get_link = ethtool_op_get_link, 294 .get_link = ethtool_op_get_link,
333 .get_tx_csum = ethtool_op_get_tx_csum,
334 .set_tx_csum = br_set_tx_csum,
335 .get_sg = ethtool_op_get_sg,
336 .set_sg = br_set_sg,
337 .get_tso = ethtool_op_get_tso,
338 .set_tso = br_set_tso,
339 .get_ufo = ethtool_op_get_ufo,
340 .set_ufo = ethtool_op_set_ufo,
341 .get_flags = ethtool_op_get_flags,
342 .set_flags = br_set_flags,
343}; 295};
344 296
345static const struct net_device_ops br_netdev_ops = { 297static const struct net_device_ops br_netdev_ops = {
@@ -359,6 +311,7 @@ static const struct net_device_ops br_netdev_ops = {
359#endif 311#endif
360 .ndo_add_slave = br_add_slave, 312 .ndo_add_slave = br_add_slave,
361 .ndo_del_slave = br_del_slave, 313 .ndo_del_slave = br_del_slave,
314 .ndo_fix_features = br_fix_features,
362}; 315};
363 316
364static void br_dev_free(struct net_device *dev) 317static void br_dev_free(struct net_device *dev)
@@ -389,7 +342,10 @@ void br_dev_setup(struct net_device *dev)
389 342
390 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 343 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
391 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | 344 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
392 NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX; 345 NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX;
346 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
347 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM |
348 NETIF_F_HW_VLAN_TX;
393 349
394 br->dev = dev; 350 br->dev = dev;
395 spin_lock_init(&br->lock); 351 spin_lock_init(&br->lock);
@@ -401,7 +357,6 @@ void br_dev_setup(struct net_device *dev)
401 357
402 memcpy(br->group_addr, br_group_address, ETH_ALEN); 358 memcpy(br->group_addr, br_group_address, ETH_ALEN);
403 359
404 br->feature_mask = dev->features;
405 br->stp_enabled = BR_NO_STP; 360 br->stp_enabled = BR_NO_STP;
406 br->designated_root = br->bridge_id; 361 br->designated_root = br->bridge_id;
407 br->bridge_max_age = br->max_age = 20 * HZ; 362 br->bridge_max_age = br->max_age = 20 * HZ;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 7f5379c593d9..1156460773dc 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -291,15 +291,15 @@ int br_min_mtu(const struct net_bridge *br)
291/* 291/*
292 * Recomputes features using slave's features 292 * Recomputes features using slave's features
293 */ 293 */
294void br_features_recompute(struct net_bridge *br) 294u32 br_features_recompute(struct net_bridge *br, u32 features)
295{ 295{
296 struct net_bridge_port *p; 296 struct net_bridge_port *p;
297 u32 features, mask; 297 u32 mask;
298 298
299 features = mask = br->feature_mask;
300 if (list_empty(&br->port_list)) 299 if (list_empty(&br->port_list))
301 goto done; 300 return features;
302 301
302 mask = features;
303 features &= ~NETIF_F_ONE_FOR_ALL; 303 features &= ~NETIF_F_ONE_FOR_ALL;
304 304
305 list_for_each_entry(p, &br->port_list, list) { 305 list_for_each_entry(p, &br->port_list, list) {
@@ -307,8 +307,7 @@ void br_features_recompute(struct net_bridge *br)
307 p->dev->features, mask); 307 p->dev->features, mask);
308 } 308 }
309 309
310done: 310 return features;
311 br->dev->features = netdev_fix_features(br->dev, features);
312} 311}
313 312
314/* called with RTNL */ 313/* called with RTNL */
@@ -373,9 +372,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
373 372
374 list_add_rcu(&p->list, &br->port_list); 373 list_add_rcu(&p->list, &br->port_list);
375 374
375 netdev_update_features(br->dev);
376
376 spin_lock_bh(&br->lock); 377 spin_lock_bh(&br->lock);
377 changed_addr = br_stp_recalculate_bridge_id(br); 378 changed_addr = br_stp_recalculate_bridge_id(br);
378 br_features_recompute(br);
379 379
380 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && 380 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
381 (br->dev->flags & IFF_UP)) 381 (br->dev->flags & IFF_UP))
@@ -423,9 +423,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
423 423
424 spin_lock_bh(&br->lock); 424 spin_lock_bh(&br->lock);
425 br_stp_recalculate_bridge_id(br); 425 br_stp_recalculate_bridge_id(br);
426 br_features_recompute(br);
427 spin_unlock_bh(&br->lock); 426 spin_unlock_bh(&br->lock);
428 427
428 netdev_update_features(br->dev);
429
429 return 0; 430 return 0;
430} 431}
431 432
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 606b323e8a0c..6545ee9591d1 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -66,10 +66,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
66 break; 66 break;
67 67
68 case NETDEV_FEAT_CHANGE: 68 case NETDEV_FEAT_CHANGE:
69 spin_lock_bh(&br->lock); 69 netdev_update_features(br->dev);
70 if (netif_running(br->dev))
71 br_features_recompute(br);
72 spin_unlock_bh(&br->lock);
73 break; 70 break;
74 71
75 case NETDEV_DOWN: 72 case NETDEV_DOWN:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index e2a40343aa09..54578f274d85 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -183,7 +183,6 @@ struct net_bridge
183 struct br_cpu_netstats __percpu *stats; 183 struct br_cpu_netstats __percpu *stats;
184 spinlock_t hash_lock; 184 spinlock_t hash_lock;
185 struct hlist_head hash[BR_HASH_SIZE]; 185 struct hlist_head hash[BR_HASH_SIZE];
186 u32 feature_mask;
187#ifdef CONFIG_BRIDGE_NETFILTER 186#ifdef CONFIG_BRIDGE_NETFILTER
188 struct rtable fake_rtable; 187 struct rtable fake_rtable;
189 bool nf_call_iptables; 188 bool nf_call_iptables;
@@ -379,7 +378,7 @@ extern int br_add_if(struct net_bridge *br,
379extern int br_del_if(struct net_bridge *br, 378extern int br_del_if(struct net_bridge *br,
380 struct net_device *dev); 379 struct net_device *dev);
381extern int br_min_mtu(const struct net_bridge *br); 380extern int br_min_mtu(const struct net_bridge *br);
382extern void br_features_recompute(struct net_bridge *br); 381extern u32 br_features_recompute(struct net_bridge *br, u32 features);
383 382
384/* br_input.c */ 383/* br_input.c */
385extern int br_handle_frame_finish(struct sk_buff *skb); 384extern int br_handle_frame_finish(struct sk_buff *skb);