aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_device.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/bridge/br_device.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r--net/bridge/br_device.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 7c78e264019..dac6a214746 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -31,25 +31,25 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
31 struct net_bridge_mdb_entry *mdst; 31 struct net_bridge_mdb_entry *mdst;
32 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); 32 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
33 33
34 rcu_read_lock();
35#ifdef CONFIG_BRIDGE_NETFILTER 34#ifdef CONFIG_BRIDGE_NETFILTER
36 if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { 35 if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
37 br_nf_pre_routing_finish_bridge_slow(skb); 36 br_nf_pre_routing_finish_bridge_slow(skb);
38 rcu_read_unlock();
39 return NETDEV_TX_OK; 37 return NETDEV_TX_OK;
40 } 38 }
41#endif 39#endif
42 40
43 u64_stats_update_begin(&brstats->syncp);
44 brstats->tx_packets++;
45 brstats->tx_bytes += skb->len;
46 u64_stats_update_end(&brstats->syncp);
47
48 BR_INPUT_SKB_CB(skb)->brdev = dev; 41 BR_INPUT_SKB_CB(skb)->brdev = dev;
49 42
50 skb_reset_mac_header(skb); 43 skb_reset_mac_header(skb);
51 skb_pull(skb, ETH_HLEN); 44 skb_pull(skb, ETH_HLEN);
52 45
46 u64_stats_update_begin(&brstats->syncp);
47 brstats->tx_packets++;
48 /* Exclude ETH_HLEN from byte stats for consistency with Rx chain */
49 brstats->tx_bytes += skb->len;
50 u64_stats_update_end(&brstats->syncp);
51
52 rcu_read_lock();
53 if (is_broadcast_ether_addr(dest)) 53 if (is_broadcast_ether_addr(dest))
54 br_flood_deliver(br, skb); 54 br_flood_deliver(br, skb);
55 else if (is_multicast_ether_addr(dest)) { 55 else if (is_multicast_ether_addr(dest)) {
@@ -128,9 +128,9 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
128 const struct br_cpu_netstats *bstats 128 const struct br_cpu_netstats *bstats
129 = per_cpu_ptr(br->stats, cpu); 129 = per_cpu_ptr(br->stats, cpu);
130 do { 130 do {
131 start = u64_stats_fetch_begin_bh(&bstats->syncp); 131 start = u64_stats_fetch_begin(&bstats->syncp);
132 memcpy(&tmp, bstats, sizeof(tmp)); 132 memcpy(&tmp, bstats, sizeof(tmp));
133 } while (u64_stats_fetch_retry_bh(&bstats->syncp, start)); 133 } while (u64_stats_fetch_retry(&bstats->syncp, start));
134 sum.tx_bytes += tmp.tx_bytes; 134 sum.tx_bytes += tmp.tx_bytes;
135 sum.tx_packets += tmp.tx_packets; 135 sum.tx_packets += tmp.tx_packets;
136 sum.rx_bytes += tmp.rx_bytes; 136 sum.rx_bytes += tmp.rx_bytes;
@@ -168,15 +168,11 @@ static int br_set_mac_address(struct net_device *dev, void *p)
168 struct sockaddr *addr = p; 168 struct sockaddr *addr = p;
169 169
170 if (!is_valid_ether_addr(addr->sa_data)) 170 if (!is_valid_ether_addr(addr->sa_data))
171 return -EADDRNOTAVAIL; 171 return -EINVAL;
172 172
173 spin_lock_bh(&br->lock); 173 spin_lock_bh(&br->lock);
174 if (!ether_addr_equal(dev->dev_addr, addr->sa_data)) { 174 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
175 dev->addr_assign_type &= ~NET_ADDR_RANDOM; 175 br_stp_change_bridge_id(br, addr->sa_data);
176 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
177 br_fdb_change_mac_address(br, addr->sa_data);
178 br_stp_change_bridge_id(br, addr->sa_data);
179 }
180 br->flags |= BR_SET_MAC_ADDR; 176 br->flags |= BR_SET_MAC_ADDR;
181 spin_unlock_bh(&br->lock); 177 spin_unlock_bh(&br->lock);
182 178
@@ -191,8 +187,7 @@ static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
191 strcpy(info->bus_info, "N/A"); 187 strcpy(info->bus_info, "N/A");
192} 188}
193 189
194static netdev_features_t br_fix_features(struct net_device *dev, 190static u32 br_fix_features(struct net_device *dev, u32 features)
195 netdev_features_t features)
196{ 191{
197 struct net_bridge *br = netdev_priv(dev); 192 struct net_bridge *br = netdev_priv(dev);
198 193
@@ -207,23 +202,24 @@ static void br_poll_controller(struct net_device *br_dev)
207static void br_netpoll_cleanup(struct net_device *dev) 202static void br_netpoll_cleanup(struct net_device *dev)
208{ 203{
209 struct net_bridge *br = netdev_priv(dev); 204 struct net_bridge *br = netdev_priv(dev);
210 struct net_bridge_port *p; 205 struct net_bridge_port *p, *n;
211 206
212 list_for_each_entry(p, &br->port_list, list) 207 list_for_each_entry_safe(p, n, &br->port_list, list) {
213 br_netpoll_disable(p); 208 br_netpoll_disable(p);
209 }
214} 210}
215 211
216static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, 212static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
217 gfp_t gfp)
218{ 213{
219 struct net_bridge *br = netdev_priv(dev); 214 struct net_bridge *br = netdev_priv(dev);
220 struct net_bridge_port *p; 215 struct net_bridge_port *p, *n;
221 int err = 0; 216 int err = 0;
222 217
223 list_for_each_entry(p, &br->port_list, list) { 218 list_for_each_entry_safe(p, n, &br->port_list, list) {
224 if (!p->dev) 219 if (!p->dev)
225 continue; 220 continue;
226 err = br_netpoll_enable(p, gfp); 221
222 err = br_netpoll_enable(p);
227 if (err) 223 if (err)
228 goto fail; 224 goto fail;
229 } 225 }
@@ -236,17 +232,20 @@ fail:
236 goto out; 232 goto out;
237} 233}
238 234
239int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) 235int br_netpoll_enable(struct net_bridge_port *p)
240{ 236{
241 struct netpoll *np; 237 struct netpoll *np;
242 int err = 0; 238 int err = 0;
243 239
244 np = kzalloc(sizeof(*p->np), gfp); 240 np = kzalloc(sizeof(*p->np), GFP_KERNEL);
245 err = -ENOMEM; 241 err = -ENOMEM;
246 if (!np) 242 if (!np)
247 goto out; 243 goto out;
248 244
249 err = __netpoll_setup(np, p->dev, gfp); 245 np->dev = p->dev;
246 strlcpy(np->dev_name, p->dev->name, IFNAMSIZ);
247
248 err = __netpoll_setup(np);
250 if (err) { 249 if (err) {
251 kfree(np); 250 kfree(np);
252 goto out; 251 goto out;
@@ -267,7 +266,11 @@ void br_netpoll_disable(struct net_bridge_port *p)
267 266
268 p->np = NULL; 267 p->np = NULL;
269 268
270 __netpoll_free_rcu(np); 269 /* Wait for transmitting packets to finish before freeing. */
270 synchronize_rcu_bh();
271
272 __netpoll_cleanup(np);
273 kfree(np);
271} 274}
272 275
273#endif 276#endif
@@ -299,7 +302,7 @@ static const struct net_device_ops br_netdev_ops = {
299 .ndo_start_xmit = br_dev_xmit, 302 .ndo_start_xmit = br_dev_xmit,
300 .ndo_get_stats64 = br_get_stats64, 303 .ndo_get_stats64 = br_get_stats64,
301 .ndo_set_mac_address = br_set_mac_address, 304 .ndo_set_mac_address = br_set_mac_address,
302 .ndo_set_rx_mode = br_dev_set_multicast_list, 305 .ndo_set_multicast_list = br_dev_set_multicast_list,
303 .ndo_change_mtu = br_change_mtu, 306 .ndo_change_mtu = br_change_mtu,
304 .ndo_do_ioctl = br_dev_ioctl, 307 .ndo_do_ioctl = br_dev_ioctl,
305#ifdef CONFIG_NET_POLL_CONTROLLER 308#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -310,11 +313,6 @@ static const struct net_device_ops br_netdev_ops = {
310 .ndo_add_slave = br_add_slave, 313 .ndo_add_slave = br_add_slave,
311 .ndo_del_slave = br_del_slave, 314 .ndo_del_slave = br_del_slave,
312 .ndo_fix_features = br_fix_features, 315 .ndo_fix_features = br_fix_features,
313 .ndo_fdb_add = br_fdb_add,
314 .ndo_fdb_del = br_fdb_delete,
315 .ndo_fdb_dump = br_fdb_dump,
316 .ndo_bridge_getlink = br_getlink,
317 .ndo_bridge_setlink = br_setlink,
318}; 316};
319 317
320static void br_dev_free(struct net_device *dev) 318static void br_dev_free(struct net_device *dev)
@@ -333,7 +331,7 @@ void br_dev_setup(struct net_device *dev)
333{ 331{
334 struct net_bridge *br = netdev_priv(dev); 332 struct net_bridge *br = netdev_priv(dev);
335 333
336 eth_hw_addr_random(dev); 334 random_ether_addr(dev->dev_addr);
337 ether_setup(dev); 335 ether_setup(dev);
338 336
339 dev->netdev_ops = &br_netdev_ops; 337 dev->netdev_ops = &br_netdev_ops;
@@ -344,10 +342,10 @@ void br_dev_setup(struct net_device *dev)
344 dev->priv_flags = IFF_EBRIDGE; 342 dev->priv_flags = IFF_EBRIDGE;
345 343
346 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 344 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
347 NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | NETIF_F_LLTX | 345 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
348 NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX; 346 NETIF_F_NETNS_LOCAL | NETIF_F_HW_VLAN_TX;
349 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 347 dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
350 NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | 348 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM |
351 NETIF_F_HW_VLAN_TX; 349 NETIF_F_HW_VLAN_TX;
352 350
353 br->dev = dev; 351 br->dev = dev;
@@ -358,11 +356,9 @@ void br_dev_setup(struct net_device *dev)
358 br->bridge_id.prio[0] = 0x80; 356 br->bridge_id.prio[0] = 0x80;
359 br->bridge_id.prio[1] = 0x00; 357 br->bridge_id.prio[1] = 0x00;
360 358
361 memcpy(br->group_addr, eth_reserved_addr_base, ETH_ALEN); 359 memcpy(br->group_addr, br_group_address, ETH_ALEN);
362 360
363 br->stp_enabled = BR_NO_STP; 361 br->stp_enabled = BR_NO_STP;
364 br->group_fwd_mask = BR_GROUPFWD_DEFAULT;
365
366 br->designated_root = br->bridge_id; 362 br->designated_root = br->bridge_id;
367 br->bridge_max_age = br->max_age = 20 * HZ; 363 br->bridge_max_age = br->max_age = 20 * HZ;
368 br->bridge_hello_time = br->hello_time = 2 * HZ; 364 br->bridge_hello_time = br->hello_time = 2 * HZ;