diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/bridge/br_device.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r-- | net/bridge/br_device.c | 78 |
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 | ||
194 | static netdev_features_t br_fix_features(struct net_device *dev, | 190 | static 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) | |||
207 | static void br_netpoll_cleanup(struct net_device *dev) | 202 | static 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 | ||
216 | static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, | 212 | static 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 | ||
239 | int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) | 235 | int 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 | ||
320 | static void br_dev_free(struct net_device *dev) | 318 | static 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; |