aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_device.c135
-rw-r--r--net/bridge/br_fdb.c4
-rw-r--r--net/bridge/br_forward.c34
-rw-r--r--net/bridge/br_if.c33
-rw-r--r--net/bridge/br_input.c21
-rw-r--r--net/bridge/br_netfilter.c29
-rw-r--r--net/bridge/br_netlink.c9
-rw-r--r--net/bridge/br_notify.c5
-rw-r--r--net/bridge/br_private.h64
-rw-r--r--net/bridge/br_stp_bpdu.c5
-rw-r--r--net/bridge/netfilter/ebt_redirect.c3
-rw-r--r--net/bridge/netfilter/ebt_ulog.c8
-rw-r--r--net/bridge/netfilter/ebtables.c11
14 files changed, 217 insertions, 146 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 76357b547752..c8436fa31344 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -63,7 +63,6 @@ static int __init br_init(void)
63 goto err_out4; 63 goto err_out4;
64 64
65 brioctl_set(br_ioctl_deviceless_stub); 65 brioctl_set(br_ioctl_deviceless_stub);
66 br_handle_frame_hook = br_handle_frame;
67 66
68#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) 67#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
69 br_fdb_test_addr_hook = br_fdb_test_addr; 68 br_fdb_test_addr_hook = br_fdb_test_addr;
@@ -100,7 +99,6 @@ static void __exit br_deinit(void)
100 br_fdb_test_addr_hook = NULL; 99 br_fdb_test_addr_hook = NULL;
101#endif 100#endif
102 101
103 br_handle_frame_hook = NULL;
104 br_fdb_fini(); 102 br_fdb_fini();
105} 103}
106 104
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index eedf2c94820e..edf639e96281 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -38,8 +38,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
38 } 38 }
39#endif 39#endif
40 40
41 u64_stats_update_begin(&brstats->syncp);
41 brstats->tx_packets++; 42 brstats->tx_packets++;
42 brstats->tx_bytes += skb->len; 43 brstats->tx_bytes += skb->len;
44 u64_stats_update_end(&brstats->syncp);
43 45
44 BR_INPUT_SKB_CB(skb)->brdev = dev; 46 BR_INPUT_SKB_CB(skb)->brdev = dev;
45 47
@@ -47,6 +49,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
47 skb_pull(skb, ETH_HLEN); 49 skb_pull(skb, ETH_HLEN);
48 50
49 if (is_multicast_ether_addr(dest)) { 51 if (is_multicast_ether_addr(dest)) {
52 if (unlikely(netpoll_tx_running(dev))) {
53 br_flood_deliver(br, skb);
54 goto out;
55 }
50 if (br_multicast_rcv(br, NULL, skb)) 56 if (br_multicast_rcv(br, NULL, skb))
51 goto out; 57 goto out;
52 58
@@ -92,21 +98,25 @@ static int br_dev_stop(struct net_device *dev)
92 return 0; 98 return 0;
93} 99}
94 100
95static struct net_device_stats *br_get_stats(struct net_device *dev) 101static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev)
96{ 102{
97 struct net_bridge *br = netdev_priv(dev); 103 struct net_bridge *br = netdev_priv(dev);
98 struct net_device_stats *stats = &dev->stats; 104 struct rtnl_link_stats64 *stats = &dev->stats64;
99 struct br_cpu_netstats sum = { 0 }; 105 struct br_cpu_netstats tmp, sum = { 0 };
100 unsigned int cpu; 106 unsigned int cpu;
101 107
102 for_each_possible_cpu(cpu) { 108 for_each_possible_cpu(cpu) {
109 unsigned int start;
103 const struct br_cpu_netstats *bstats 110 const struct br_cpu_netstats *bstats
104 = per_cpu_ptr(br->stats, cpu); 111 = per_cpu_ptr(br->stats, cpu);
105 112 do {
106 sum.tx_bytes += bstats->tx_bytes; 113 start = u64_stats_fetch_begin(&bstats->syncp);
107 sum.tx_packets += bstats->tx_packets; 114 memcpy(&tmp, bstats, sizeof(tmp));
108 sum.rx_bytes += bstats->rx_bytes; 115 } while (u64_stats_fetch_retry(&bstats->syncp, start));
109 sum.rx_packets += bstats->rx_packets; 116 sum.tx_bytes += tmp.tx_bytes;
117 sum.tx_packets += tmp.tx_packets;
118 sum.rx_bytes += tmp.rx_bytes;
119 sum.rx_packets += tmp.rx_packets;
110 } 120 }
111 121
112 stats->tx_bytes = sum.tx_bytes; 122 stats->tx_bytes = sum.tx_bytes;
@@ -127,7 +137,7 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
127 137
128#ifdef CONFIG_BRIDGE_NETFILTER 138#ifdef CONFIG_BRIDGE_NETFILTER
129 /* remember the MTU in the rtable for PMTU */ 139 /* remember the MTU in the rtable for PMTU */
130 br->fake_rtable.u.dst.metrics[RTAX_MTU - 1] = new_mtu; 140 br->fake_rtable.dst.metrics[RTAX_MTU - 1] = new_mtu;
131#endif 141#endif
132 142
133 return 0; 143 return 0;
@@ -199,73 +209,81 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
199} 209}
200 210
201#ifdef CONFIG_NET_POLL_CONTROLLER 211#ifdef CONFIG_NET_POLL_CONTROLLER
202static bool br_devices_support_netpoll(struct net_bridge *br) 212static void br_poll_controller(struct net_device *br_dev)
203{ 213{
204 struct net_bridge_port *p;
205 bool ret = true;
206 int count = 0;
207 unsigned long flags;
208
209 spin_lock_irqsave(&br->lock, flags);
210 list_for_each_entry(p, &br->port_list, list) {
211 count++;
212 if ((p->dev->priv_flags & IFF_DISABLE_NETPOLL) ||
213 !p->dev->netdev_ops->ndo_poll_controller)
214 ret = false;
215 }
216 spin_unlock_irqrestore(&br->lock, flags);
217 return count != 0 && ret;
218} 214}
219 215
220static void br_poll_controller(struct net_device *br_dev) 216static void br_netpoll_cleanup(struct net_device *dev)
221{ 217{
222 struct netpoll *np = br_dev->npinfo->netpoll; 218 struct net_bridge *br = netdev_priv(dev);
219 struct net_bridge_port *p, *n;
223 220
224 if (np->real_dev != br_dev) 221 list_for_each_entry_safe(p, n, &br->port_list, list) {
225 netpoll_poll_dev(np->real_dev); 222 br_netpoll_disable(p);
223 }
226} 224}
227 225
228void br_netpoll_cleanup(struct net_device *dev) 226static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
229{ 227{
230 struct net_bridge *br = netdev_priv(dev); 228 struct net_bridge *br = netdev_priv(dev);
231 struct net_bridge_port *p, *n; 229 struct net_bridge_port *p, *n;
232 const struct net_device_ops *ops; 230 int err = 0;
233 231
234 br->dev->npinfo = NULL;
235 list_for_each_entry_safe(p, n, &br->port_list, list) { 232 list_for_each_entry_safe(p, n, &br->port_list, list) {
236 if (p->dev) { 233 if (!p->dev)
237 ops = p->dev->netdev_ops; 234 continue;
238 if (ops->ndo_netpoll_cleanup) 235
239 ops->ndo_netpoll_cleanup(p->dev); 236 err = br_netpoll_enable(p);
240 else 237 if (err)
241 p->dev->npinfo = NULL; 238 goto fail;
242 }
243 } 239 }
240
241out:
242 return err;
243
244fail:
245 br_netpoll_cleanup(dev);
246 goto out;
244} 247}
245 248
246void br_netpoll_disable(struct net_bridge *br, 249int br_netpoll_enable(struct net_bridge_port *p)
247 struct net_device *dev)
248{ 250{
249 if (br_devices_support_netpoll(br)) 251 struct netpoll *np;
250 br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; 252 int err = 0;
251 if (dev->netdev_ops->ndo_netpoll_cleanup) 253
252 dev->netdev_ops->ndo_netpoll_cleanup(dev); 254 np = kzalloc(sizeof(*p->np), GFP_KERNEL);
253 else 255 err = -ENOMEM;
254 dev->npinfo = NULL; 256 if (!np)
257 goto out;
258
259 np->dev = p->dev;
260
261 err = __netpoll_setup(np);
262 if (err) {
263 kfree(np);
264 goto out;
265 }
266
267 p->np = np;
268
269out:
270 return err;
255} 271}
256 272
257void br_netpoll_enable(struct net_bridge *br, 273void br_netpoll_disable(struct net_bridge_port *p)
258 struct net_device *dev)
259{ 274{
260 if (br_devices_support_netpoll(br)) { 275 struct netpoll *np = p->np;
261 br->dev->priv_flags &= ~IFF_DISABLE_NETPOLL; 276
262 if (br->dev->npinfo) 277 if (!np)
263 dev->npinfo = br->dev->npinfo; 278 return;
264 } else if (!(br->dev->priv_flags & IFF_DISABLE_NETPOLL)) { 279
265 br->dev->priv_flags |= IFF_DISABLE_NETPOLL; 280 p->np = NULL;
266 br_info(br,"new device %s does not support netpoll (disabling)", 281
267 dev->name); 282 /* Wait for transmitting packets to finish before freeing. */
268 } 283 synchronize_rcu_bh();
284
285 __netpoll_cleanup(np);
286 kfree(np);
269} 287}
270 288
271#endif 289#endif
@@ -288,12 +306,13 @@ static const struct net_device_ops br_netdev_ops = {
288 .ndo_open = br_dev_open, 306 .ndo_open = br_dev_open,
289 .ndo_stop = br_dev_stop, 307 .ndo_stop = br_dev_stop,
290 .ndo_start_xmit = br_dev_xmit, 308 .ndo_start_xmit = br_dev_xmit,
291 .ndo_get_stats = br_get_stats, 309 .ndo_get_stats64 = br_get_stats64,
292 .ndo_set_mac_address = br_set_mac_address, 310 .ndo_set_mac_address = br_set_mac_address,
293 .ndo_set_multicast_list = br_dev_set_multicast_list, 311 .ndo_set_multicast_list = br_dev_set_multicast_list,
294 .ndo_change_mtu = br_change_mtu, 312 .ndo_change_mtu = br_change_mtu,
295 .ndo_do_ioctl = br_dev_ioctl, 313 .ndo_do_ioctl = br_dev_ioctl,
296#ifdef CONFIG_NET_POLL_CONTROLLER 314#ifdef CONFIG_NET_POLL_CONTROLLER
315 .ndo_netpoll_setup = br_netpoll_setup,
297 .ndo_netpoll_cleanup = br_netpoll_cleanup, 316 .ndo_netpoll_cleanup = br_netpoll_cleanup,
298 .ndo_poll_controller = br_poll_controller, 317 .ndo_poll_controller = br_poll_controller,
299#endif 318#endif
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index b01dde35a69e..a744296fc675 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -240,11 +240,11 @@ int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
240 struct net_bridge_fdb_entry *fdb; 240 struct net_bridge_fdb_entry *fdb;
241 int ret; 241 int ret;
242 242
243 if (!dev->br_port) 243 if (!br_port_exists(dev))
244 return 0; 244 return 0;
245 245
246 rcu_read_lock(); 246 rcu_read_lock();
247 fdb = __br_fdb_get(dev->br_port->br, addr); 247 fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr);
248 ret = fdb && fdb->dst->dev != dev && 248 ret = fdb && fdb->dst->dev != dev &&
249 fdb->dst->state == BR_STATE_FORWARDING; 249 fdb->dst->state == BR_STATE_FORWARDING;
250 rcu_read_unlock(); 250 rcu_read_unlock();
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index a4e72a89e4ff..cbfe87f0f34a 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -50,14 +50,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
50 kfree_skb(skb); 50 kfree_skb(skb);
51 else { 51 else {
52 skb_push(skb, ETH_HLEN); 52 skb_push(skb, ETH_HLEN);
53 53 dev_queue_xmit(skb);
54#ifdef CONFIG_NET_POLL_CONTROLLER
55 if (unlikely(skb->dev->priv_flags & IFF_IN_NETPOLL)) {
56 netpoll_send_skb(skb->dev->npinfo->netpoll, skb);
57 skb->dev->priv_flags &= ~IFF_IN_NETPOLL;
58 } else
59#endif
60 dev_queue_xmit(skb);
61 } 54 }
62 } 55 }
63 56
@@ -73,23 +66,20 @@ int br_forward_finish(struct sk_buff *skb)
73 66
74static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) 67static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
75{ 68{
76#ifdef CONFIG_NET_POLL_CONTROLLER
77 struct net_bridge *br = to->br;
78 if (unlikely(br->dev->priv_flags & IFF_IN_NETPOLL)) {
79 struct netpoll *np;
80 to->dev->npinfo = skb->dev->npinfo;
81 np = skb->dev->npinfo->netpoll;
82 np->real_dev = np->dev = to->dev;
83 to->dev->priv_flags |= IFF_IN_NETPOLL;
84 }
85#endif
86 skb->dev = to->dev; 69 skb->dev = to->dev;
70
71 if (unlikely(netpoll_tx_running(to->dev))) {
72 if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
73 kfree_skb(skb);
74 else {
75 skb_push(skb, ETH_HLEN);
76 br_netpoll_send_skb(to, skb);
77 }
78 return;
79 }
80
87 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, 81 NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
88 br_forward_finish); 82 br_forward_finish);
89#ifdef CONFIG_NET_POLL_CONTROLLER
90 if (skb->dev->npinfo)
91 skb->dev->npinfo->netpoll->dev = br->dev;
92#endif
93} 83}
94 84
95static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) 85static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 18b245e2c00e..c03d2c3ff03e 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -147,14 +147,17 @@ static void del_nbp(struct net_bridge_port *p)
147 147
148 list_del_rcu(&p->list); 148 list_del_rcu(&p->list);
149 149
150 rcu_assign_pointer(dev->br_port, NULL); 150 dev->priv_flags &= ~IFF_BRIDGE_PORT;
151
152 netdev_rx_handler_unregister(dev);
151 153
152 br_multicast_del_port(p); 154 br_multicast_del_port(p);
153 155
154 kobject_uevent(&p->kobj, KOBJ_REMOVE); 156 kobject_uevent(&p->kobj, KOBJ_REMOVE);
155 kobject_del(&p->kobj); 157 kobject_del(&p->kobj);
156 158
157 br_netpoll_disable(br, dev); 159 br_netpoll_disable(p);
160
158 call_rcu(&p->rcu, destroy_nbp_rcu); 161 call_rcu(&p->rcu, destroy_nbp_rcu);
159} 162}
160 163
@@ -167,8 +170,6 @@ static void del_br(struct net_bridge *br, struct list_head *head)
167 del_nbp(p); 170 del_nbp(p);
168 } 171 }
169 172
170 br_netpoll_cleanup(br->dev);
171
172 del_timer_sync(&br->gc_timer); 173 del_timer_sync(&br->gc_timer);
173 174
174 br_sysfs_delbr(br->dev); 175 br_sysfs_delbr(br->dev);
@@ -400,7 +401,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
400 return -ELOOP; 401 return -ELOOP;
401 402
402 /* Device is already being bridged */ 403 /* Device is already being bridged */
403 if (dev->br_port != NULL) 404 if (br_port_exists(dev))
404 return -EBUSY; 405 return -EBUSY;
405 406
406 /* No bridging devices that dislike that (e.g. wireless) */ 407 /* No bridging devices that dislike that (e.g. wireless) */
@@ -428,7 +429,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
428 if (err) 429 if (err)
429 goto err2; 430 goto err2;
430 431
431 rcu_assign_pointer(dev->br_port, p); 432 if (br_netpoll_info(br) && ((err = br_netpoll_enable(p))))
433 goto err3;
434
435 err = netdev_rx_handler_register(dev, br_handle_frame, p);
436 if (err)
437 goto err3;
438
439 dev->priv_flags |= IFF_BRIDGE_PORT;
440
432 dev_disable_lro(dev); 441 dev_disable_lro(dev);
433 442
434 list_add_rcu(&p->list, &br->port_list); 443 list_add_rcu(&p->list, &br->port_list);
@@ -448,9 +457,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
448 457
449 kobject_uevent(&p->kobj, KOBJ_ADD); 458 kobject_uevent(&p->kobj, KOBJ_ADD);
450 459
451 br_netpoll_enable(br, dev);
452
453 return 0; 460 return 0;
461err3:
462 sysfs_remove_link(br->ifobj, p->dev->name);
454err2: 463err2:
455 br_fdb_delete_by_port(br, p, 1); 464 br_fdb_delete_by_port(br, p, 1);
456err1: 465err1:
@@ -467,9 +476,13 @@ put_back:
467/* called with RTNL */ 476/* called with RTNL */
468int br_del_if(struct net_bridge *br, struct net_device *dev) 477int br_del_if(struct net_bridge *br, struct net_device *dev)
469{ 478{
470 struct net_bridge_port *p = dev->br_port; 479 struct net_bridge_port *p;
480
481 if (!br_port_exists(dev))
482 return -EINVAL;
471 483
472 if (!p || p->br != br) 484 p = br_port_get(dev);
485 if (p->br != br)
473 return -EINVAL; 486 return -EINVAL;
474 487
475 del_nbp(p); 488 del_nbp(p);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index d36e700f7a26..5fc1c5b1c360 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -27,8 +27,10 @@ static int br_pass_frame_up(struct sk_buff *skb)
27 struct net_bridge *br = netdev_priv(brdev); 27 struct net_bridge *br = netdev_priv(brdev);
28 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); 28 struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
29 29
30 u64_stats_update_begin(&brstats->syncp);
30 brstats->rx_packets++; 31 brstats->rx_packets++;
31 brstats->rx_bytes += skb->len; 32 brstats->rx_bytes += skb->len;
33 u64_stats_update_end(&brstats->syncp);
32 34
33 indev = skb->dev; 35 indev = skb->dev;
34 skb->dev = brdev; 36 skb->dev = brdev;
@@ -41,7 +43,7 @@ static int br_pass_frame_up(struct sk_buff *skb)
41int br_handle_frame_finish(struct sk_buff *skb) 43int br_handle_frame_finish(struct sk_buff *skb)
42{ 44{
43 const unsigned char *dest = eth_hdr(skb)->h_dest; 45 const unsigned char *dest = eth_hdr(skb)->h_dest;
44 struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); 46 struct net_bridge_port *p = br_port_get_rcu(skb->dev);
45 struct net_bridge *br; 47 struct net_bridge *br;
46 struct net_bridge_fdb_entry *dst; 48 struct net_bridge_fdb_entry *dst;
47 struct net_bridge_mdb_entry *mdst; 49 struct net_bridge_mdb_entry *mdst;
@@ -111,10 +113,9 @@ drop:
111/* note: already called with rcu_read_lock (preempt_disabled) */ 113/* note: already called with rcu_read_lock (preempt_disabled) */
112static int br_handle_local_finish(struct sk_buff *skb) 114static int br_handle_local_finish(struct sk_buff *skb)
113{ 115{
114 struct net_bridge_port *p = rcu_dereference(skb->dev->br_port); 116 struct net_bridge_port *p = br_port_get_rcu(skb->dev);
115 117
116 if (p) 118 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
117 br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
118 return 0; /* process further */ 119 return 0; /* process further */
119} 120}
120 121
@@ -131,15 +132,19 @@ static inline int is_link_local(const unsigned char *dest)
131} 132}
132 133
133/* 134/*
134 * Called via br_handle_frame_hook.
135 * Return NULL if skb is handled 135 * Return NULL if skb is handled
136 * note: already called with rcu_read_lock (preempt_disabled) 136 * note: already called with rcu_read_lock (preempt_disabled) from
137 * netif_receive_skb
137 */ 138 */
138struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) 139struct sk_buff *br_handle_frame(struct sk_buff *skb)
139{ 140{
141 struct net_bridge_port *p;
140 const unsigned char *dest = eth_hdr(skb)->h_dest; 142 const unsigned char *dest = eth_hdr(skb)->h_dest;
141 int (*rhook)(struct sk_buff *skb); 143 int (*rhook)(struct sk_buff *skb);
142 144
145 if (skb->pkt_type == PACKET_LOOPBACK)
146 return skb;
147
143 if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) 148 if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
144 goto drop; 149 goto drop;
145 150
@@ -147,6 +152,8 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
147 if (!skb) 152 if (!skb)
148 return NULL; 153 return NULL;
149 154
155 p = br_port_get_rcu(skb->dev);
156
150 if (unlikely(is_link_local(dest))) { 157 if (unlikely(is_link_local(dest))) {
151 /* Pause frames shouldn't be passed up by driver anyway */ 158 /* Pause frames shouldn't be passed up by driver anyway */
152 if (skb->protocol == htons(ETH_P_PAUSE)) 159 if (skb->protocol == htons(ETH_P_PAUSE))
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 44420992f72f..84060bc48f11 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -117,26 +117,27 @@ void br_netfilter_rtable_init(struct net_bridge *br)
117{ 117{
118 struct rtable *rt = &br->fake_rtable; 118 struct rtable *rt = &br->fake_rtable;
119 119
120 atomic_set(&rt->u.dst.__refcnt, 1); 120 atomic_set(&rt->dst.__refcnt, 1);
121 rt->u.dst.dev = br->dev; 121 rt->dst.dev = br->dev;
122 rt->u.dst.path = &rt->u.dst; 122 rt->dst.path = &rt->dst;
123 rt->u.dst.metrics[RTAX_MTU - 1] = 1500; 123 rt->dst.metrics[RTAX_MTU - 1] = 1500;
124 rt->u.dst.flags = DST_NOXFRM; 124 rt->dst.flags = DST_NOXFRM;
125 rt->u.dst.ops = &fake_dst_ops; 125 rt->dst.ops = &fake_dst_ops;
126} 126}
127 127
128static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) 128static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
129{ 129{
130 struct net_bridge_port *port = rcu_dereference(dev->br_port); 130 if (!br_port_exists(dev))
131 131 return NULL;
132 return port ? &port->br->fake_rtable : NULL; 132 return &br_port_get_rcu(dev)->br->fake_rtable;
133} 133}
134 134
135static inline struct net_device *bridge_parent(const struct net_device *dev) 135static inline struct net_device *bridge_parent(const struct net_device *dev)
136{ 136{
137 struct net_bridge_port *port = rcu_dereference(dev->br_port); 137 if (!br_port_exists(dev))
138 return NULL;
138 139
139 return port ? port->br->dev : NULL; 140 return br_port_get_rcu(dev)->br->dev;
140} 141}
141 142
142static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) 143static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
@@ -244,8 +245,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
244 kfree_skb(skb); 245 kfree_skb(skb);
245 return 0; 246 return 0;
246 } 247 }
247 dst_hold(&rt->u.dst); 248 skb_dst_set_noref(skb, &rt->dst);
248 skb_dst_set(skb, &rt->u.dst);
249 249
250 skb->dev = nf_bridge->physindev; 250 skb->dev = nf_bridge->physindev;
251 nf_bridge_update_protocol(skb); 251 nf_bridge_update_protocol(skb);
@@ -396,8 +396,7 @@ bridged_dnat:
396 kfree_skb(skb); 396 kfree_skb(skb);
397 return 0; 397 return 0;
398 } 398 }
399 dst_hold(&rt->u.dst); 399 skb_dst_set_noref(skb, &rt->dst);
400 skb_dst_set(skb, &rt->u.dst);
401 } 400 }
402 401
403 skb->dev = nf_bridge->physindev; 402 skb->dev = nf_bridge->physindev;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index fe0a79018ab2..4a6a378c84e3 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -120,10 +120,11 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
120 idx = 0; 120 idx = 0;
121 for_each_netdev(net, dev) { 121 for_each_netdev(net, dev) {
122 /* not a bridge port */ 122 /* not a bridge port */
123 if (dev->br_port == NULL || idx < cb->args[0]) 123 if (!br_port_exists(dev) || idx < cb->args[0])
124 goto skip; 124 goto skip;
125 125
126 if (br_fill_ifinfo(skb, dev->br_port, NETLINK_CB(cb->skb).pid, 126 if (br_fill_ifinfo(skb, br_port_get(dev),
127 NETLINK_CB(cb->skb).pid,
127 cb->nlh->nlmsg_seq, RTM_NEWLINK, 128 cb->nlh->nlmsg_seq, RTM_NEWLINK,
128 NLM_F_MULTI) < 0) 129 NLM_F_MULTI) < 0)
129 break; 130 break;
@@ -168,9 +169,9 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
168 if (!dev) 169 if (!dev)
169 return -ENODEV; 170 return -ENODEV;
170 171
171 p = dev->br_port; 172 if (!br_port_exists(dev))
172 if (!p)
173 return -EINVAL; 173 return -EINVAL;
174 p = br_port_get(dev);
174 175
175 /* if kernel STP is running, don't allow changes */ 176 /* if kernel STP is running, don't allow changes */
176 if (p->br->stp_enabled == BR_KERNEL_STP) 177 if (p->br->stp_enabled == BR_KERNEL_STP)
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 717e1fd6133c..404d4e14c6a7 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -32,14 +32,15 @@ struct notifier_block br_device_notifier = {
32static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 32static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
33{ 33{
34 struct net_device *dev = ptr; 34 struct net_device *dev = ptr;
35 struct net_bridge_port *p = dev->br_port; 35 struct net_bridge_port *p = br_port_get(dev);
36 struct net_bridge *br; 36 struct net_bridge *br;
37 int err; 37 int err;
38 38
39 /* not a port of a bridge */ 39 /* not a port of a bridge */
40 if (p == NULL) 40 if (!br_port_exists(dev))
41 return NOTIFY_DONE; 41 return NOTIFY_DONE;
42 42
43 p = br_port_get(dev);
43 br = p->br; 44 br = p->br;
44 45
45 switch (event) { 46 switch (event) {
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 0f4a74bc6a9b..3f0678fd1fd0 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -15,6 +15,8 @@
15 15
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/if_bridge.h> 17#include <linux/if_bridge.h>
18#include <linux/netpoll.h>
19#include <linux/u64_stats_sync.h>
18#include <net/route.h> 20#include <net/route.h>
19 21
20#define BR_HASH_BITS 8 22#define BR_HASH_BITS 8
@@ -143,13 +145,23 @@ struct net_bridge_port
143#ifdef CONFIG_SYSFS 145#ifdef CONFIG_SYSFS
144 char sysfs_name[IFNAMSIZ]; 146 char sysfs_name[IFNAMSIZ];
145#endif 147#endif
148
149#ifdef CONFIG_NET_POLL_CONTROLLER
150 struct netpoll *np;
151#endif
146}; 152};
147 153
154#define br_port_get_rcu(dev) \
155 ((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data))
156#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
157#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
158
148struct br_cpu_netstats { 159struct br_cpu_netstats {
149 unsigned long rx_packets; 160 u64 rx_packets;
150 unsigned long rx_bytes; 161 u64 rx_bytes;
151 unsigned long tx_packets; 162 u64 tx_packets;
152 unsigned long tx_bytes; 163 u64 tx_bytes;
164 struct u64_stats_sync syncp;
153}; 165};
154 166
155struct net_bridge 167struct net_bridge
@@ -273,16 +285,41 @@ extern void br_dev_setup(struct net_device *dev);
273extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, 285extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
274 struct net_device *dev); 286 struct net_device *dev);
275#ifdef CONFIG_NET_POLL_CONTROLLER 287#ifdef CONFIG_NET_POLL_CONTROLLER
276extern void br_netpoll_cleanup(struct net_device *dev); 288static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
277extern void br_netpoll_enable(struct net_bridge *br, 289{
278 struct net_device *dev); 290 return br->dev->npinfo;
279extern void br_netpoll_disable(struct net_bridge *br, 291}
280 struct net_device *dev); 292
293static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
294 struct sk_buff *skb)
295{
296 struct netpoll *np = p->np;
297
298 if (np)
299 netpoll_send_skb(np, skb);
300}
301
302extern int br_netpoll_enable(struct net_bridge_port *p);
303extern void br_netpoll_disable(struct net_bridge_port *p);
281#else 304#else
282#define br_netpoll_cleanup(br) 305static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
283#define br_netpoll_enable(br, dev) 306{
284#define br_netpoll_disable(br, dev) 307 return NULL;
308}
309
310static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
311 struct sk_buff *skb)
312{
313}
285 314
315static inline int br_netpoll_enable(struct net_bridge_port *p)
316{
317 return 0;
318}
319
320static inline void br_netpoll_disable(struct net_bridge_port *p)
321{
322}
286#endif 323#endif
287 324
288/* br_fdb.c */ 325/* br_fdb.c */
@@ -331,8 +368,7 @@ extern void br_features_recompute(struct net_bridge *br);
331 368
332/* br_input.c */ 369/* br_input.c */
333extern int br_handle_frame_finish(struct sk_buff *skb); 370extern int br_handle_frame_finish(struct sk_buff *skb);
334extern struct sk_buff *br_handle_frame(struct net_bridge_port *p, 371extern struct sk_buff *br_handle_frame(struct sk_buff *skb);
335 struct sk_buff *skb);
336 372
337/* br_ioctl.c */ 373/* br_ioctl.c */
338extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 374extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 217bd225a42f..70aecb48fb69 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -137,12 +137,13 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
137 struct net_device *dev) 137 struct net_device *dev)
138{ 138{
139 const unsigned char *dest = eth_hdr(skb)->h_dest; 139 const unsigned char *dest = eth_hdr(skb)->h_dest;
140 struct net_bridge_port *p = rcu_dereference(dev->br_port); 140 struct net_bridge_port *p;
141 struct net_bridge *br; 141 struct net_bridge *br;
142 const unsigned char *buf; 142 const unsigned char *buf;
143 143
144 if (!p) 144 if (!br_port_exists(dev))
145 goto err; 145 goto err;
146 p = br_port_get_rcu(dev);
146 147
147 if (!pskb_may_pull(skb, 4)) 148 if (!pskb_may_pull(skb, 4))
148 goto err; 149 goto err;
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index 9e19166ba453..46624bb6d9be 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -24,8 +24,9 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
24 return EBT_DROP; 24 return EBT_DROP;
25 25
26 if (par->hooknum != NF_BR_BROUTING) 26 if (par->hooknum != NF_BR_BROUTING)
27 /* rcu_read_lock()ed by nf_hook_slow */
27 memcpy(eth_hdr(skb)->h_dest, 28 memcpy(eth_hdr(skb)->h_dest,
28 par->in->br_port->br->dev->dev_addr, ETH_ALEN); 29 br_port_get_rcu(par->in)->br->dev->dev_addr, ETH_ALEN);
29 else 30 else
30 memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN); 31 memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);
31 skb->pkt_type = PACKET_HOST; 32 skb->pkt_type = PACKET_HOST;
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index ae3c7cef1484..26377e96fa1c 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -177,8 +177,9 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
177 if (in) { 177 if (in) {
178 strcpy(pm->physindev, in->name); 178 strcpy(pm->physindev, in->name);
179 /* If in isn't a bridge, then physindev==indev */ 179 /* If in isn't a bridge, then physindev==indev */
180 if (in->br_port) 180 if (br_port_exists(in))
181 strcpy(pm->indev, in->br_port->br->dev->name); 181 /* rcu_read_lock()ed by nf_hook_slow */
182 strcpy(pm->indev, br_port_get_rcu(in)->br->dev->name);
182 else 183 else
183 strcpy(pm->indev, in->name); 184 strcpy(pm->indev, in->name);
184 } else 185 } else
@@ -187,7 +188,8 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
187 if (out) { 188 if (out) {
188 /* If out exists, then out is a bridge port */ 189 /* If out exists, then out is a bridge port */
189 strcpy(pm->physoutdev, out->name); 190 strcpy(pm->physoutdev, out->name);
190 strcpy(pm->outdev, out->br_port->br->dev->name); 191 /* rcu_read_lock()ed by nf_hook_slow */
192 strcpy(pm->outdev, br_port_get_rcu(out)->br->dev->name);
191 } else 193 } else
192 pm->outdev[0] = pm->physoutdev[0] = '\0'; 194 pm->outdev[0] = pm->physoutdev[0] = '\0';
193 195
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 59ca00e40dec..bcc102e3be4d 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -140,11 +140,14 @@ ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h,
140 return 1; 140 return 1;
141 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) 141 if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
142 return 1; 142 return 1;
143 if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check( 143 /* rcu_read_lock()ed by nf_hook_slow */
144 e->logical_in, in->br_port->br->dev), EBT_ILOGICALIN)) 144 if (in && br_port_exists(in) &&
145 FWINV2(ebt_dev_check(e->logical_in, br_port_get_rcu(in)->br->dev),
146 EBT_ILOGICALIN))
145 return 1; 147 return 1;
146 if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check( 148 if (out && br_port_exists(out) &&
147 e->logical_out, out->br_port->br->dev), EBT_ILOGICALOUT)) 149 FWINV2(ebt_dev_check(e->logical_out, br_port_get_rcu(out)->br->dev),
150 EBT_ILOGICALOUT))
148 return 1; 151 return 1;
149 152
150 if (e->bitmask & EBT_SOURCEMAC) { 153 if (e->bitmask & EBT_SOURCEMAC) {