aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c14
-rw-r--r--net/bridge/br_fdb.c2
-rw-r--r--net/bridge/br_if.c23
-rw-r--r--net/bridge/br_multicast.c23
-rw-r--r--net/bridge/br_netfilter.c18
-rw-r--r--net/bridge/br_netlink.c18
-rw-r--r--net/bridge/br_notify.c7
-rw-r--r--net/bridge/br_private.h2
-rw-r--r--net/bridge/br_private_stp.h3
-rw-r--r--net/bridge/br_stp.c31
-rw-r--r--net/bridge/br_stp_bpdu.c15
-rw-r--r--net/bridge/br_stp_if.c3
-rw-r--r--net/bridge/br_stp_timer.c1
-rw-r--r--net/bridge/netfilter/Kconfig2
-rw-r--r--net/bridge/netfilter/ebt_ulog.c1
-rw-r--r--net/bridge/netfilter/ebtables.c3
16 files changed, 110 insertions, 56 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 32b8f9f7f79..dac6a214746 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -38,16 +38,17 @@ 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);
42 brstats->tx_packets++;
43 brstats->tx_bytes += skb->len;
44 u64_stats_update_end(&brstats->syncp);
45
46 BR_INPUT_SKB_CB(skb)->brdev = dev; 41 BR_INPUT_SKB_CB(skb)->brdev = dev;
47 42
48 skb_reset_mac_header(skb); 43 skb_reset_mac_header(skb);
49 skb_pull(skb, ETH_HLEN); 44 skb_pull(skb, ETH_HLEN);
50 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
51 rcu_read_lock(); 52 rcu_read_lock();
52 if (is_broadcast_ether_addr(dest)) 53 if (is_broadcast_ether_addr(dest))
53 br_flood_deliver(br, skb); 54 br_flood_deliver(br, skb);
@@ -91,7 +92,6 @@ static int br_dev_open(struct net_device *dev)
91{ 92{
92 struct net_bridge *br = netdev_priv(dev); 93 struct net_bridge *br = netdev_priv(dev);
93 94
94 netif_carrier_off(dev);
95 netdev_update_features(dev); 95 netdev_update_features(dev);
96 netif_start_queue(dev); 96 netif_start_queue(dev);
97 br_stp_enable_bridge(br); 97 br_stp_enable_bridge(br);
@@ -108,8 +108,6 @@ static int br_dev_stop(struct net_device *dev)
108{ 108{
109 struct net_bridge *br = netdev_priv(dev); 109 struct net_bridge *br = netdev_priv(dev);
110 110
111 netif_carrier_off(dev);
112
113 br_stp_disable_bridge(br); 111 br_stp_disable_bridge(br);
114 br_multicast_stop(br); 112 br_multicast_stop(br);
115 113
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index e0dfbc151dd..68def3b7fb4 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -21,7 +21,7 @@
21#include <linux/jhash.h> 21#include <linux/jhash.h>
22#include <linux/random.h> 22#include <linux/random.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <asm/atomic.h> 24#include <linux/atomic.h>
25#include <asm/unaligned.h> 25#include <asm/unaligned.h>
26#include "br_private.h" 26#include "br_private.h"
27 27
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 1bacca4cb67..1d420f64ff2 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -161,9 +161,10 @@ static void del_nbp(struct net_bridge_port *p)
161 call_rcu(&p->rcu, destroy_nbp_rcu); 161 call_rcu(&p->rcu, destroy_nbp_rcu);
162} 162}
163 163
164/* called with RTNL */ 164/* Delete bridge device */
165static void del_br(struct net_bridge *br, struct list_head *head) 165void br_dev_delete(struct net_device *dev, struct list_head *head)
166{ 166{
167 struct net_bridge *br = netdev_priv(dev);
167 struct net_bridge_port *p, *n; 168 struct net_bridge_port *p, *n;
168 169
169 list_for_each_entry_safe(p, n, &br->port_list, list) { 170 list_for_each_entry_safe(p, n, &br->port_list, list) {
@@ -231,6 +232,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
231int br_add_bridge(struct net *net, const char *name) 232int br_add_bridge(struct net *net, const char *name)
232{ 233{
233 struct net_device *dev; 234 struct net_device *dev;
235 int res;
234 236
235 dev = alloc_netdev(sizeof(struct net_bridge), name, 237 dev = alloc_netdev(sizeof(struct net_bridge), name,
236 br_dev_setup); 238 br_dev_setup);
@@ -240,7 +242,10 @@ int br_add_bridge(struct net *net, const char *name)
240 242
241 dev_net_set(dev, net); 243 dev_net_set(dev, net);
242 244
243 return register_netdev(dev); 245 res = register_netdev(dev);
246 if (res)
247 free_netdev(dev);
248 return res;
244} 249}
245 250
246int br_del_bridge(struct net *net, const char *name) 251int br_del_bridge(struct net *net, const char *name)
@@ -264,7 +269,7 @@ int br_del_bridge(struct net *net, const char *name)
264 } 269 }
265 270
266 else 271 else
267 del_br(netdev_priv(dev), NULL); 272 br_dev_delete(dev, NULL);
268 273
269 rtnl_unlock(); 274 rtnl_unlock();
270 return ret; 275 return ret;
@@ -388,7 +393,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
388 br_ifinfo_notify(RTM_NEWLINK, p); 393 br_ifinfo_notify(RTM_NEWLINK, p);
389 394
390 if (changed_addr) 395 if (changed_addr)
391 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 396 call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
392 397
393 dev_set_mtu(br->dev, br_min_mtu(br)); 398 dev_set_mtu(br->dev, br_min_mtu(br));
394 399
@@ -417,6 +422,7 @@ put_back:
417int br_del_if(struct net_bridge *br, struct net_device *dev) 422int br_del_if(struct net_bridge *br, struct net_device *dev)
418{ 423{
419 struct net_bridge_port *p; 424 struct net_bridge_port *p;
425 bool changed_addr;
420 426
421 p = br_port_get_rtnl(dev); 427 p = br_port_get_rtnl(dev);
422 if (!p || p->br != br) 428 if (!p || p->br != br)
@@ -425,9 +431,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
425 del_nbp(p); 431 del_nbp(p);
426 432
427 spin_lock_bh(&br->lock); 433 spin_lock_bh(&br->lock);
428 br_stp_recalculate_bridge_id(br); 434 changed_addr = br_stp_recalculate_bridge_id(br);
429 spin_unlock_bh(&br->lock); 435 spin_unlock_bh(&br->lock);
430 436
437 if (changed_addr)
438 call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
439
431 netdev_update_features(br->dev); 440 netdev_update_features(br->dev);
432 441
433 return 0; 442 return 0;
@@ -441,7 +450,7 @@ void __net_exit br_net_exit(struct net *net)
441 rtnl_lock(); 450 rtnl_lock();
442 for_each_netdev(net, dev) 451 for_each_netdev(net, dev)
443 if (dev->priv_flags & IFF_EBRIDGE) 452 if (dev->priv_flags & IFF_EBRIDGE)
444 del_br(netdev_priv(dev), &list); 453 br_dev_delete(dev, &list);
445 454
446 unregister_netdevice_many(&list); 455 unregister_netdevice_many(&list);
447 rtnl_unlock(); 456 rtnl_unlock();
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 2d85ca7111d..e79ff75b0e7 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1456{ 1456{
1457 struct sk_buff *skb2; 1457 struct sk_buff *skb2;
1458 const struct ipv6hdr *ip6h; 1458 const struct ipv6hdr *ip6h;
1459 struct icmp6hdr *icmp6h; 1459 u8 icmp6_type;
1460 u8 nexthdr; 1460 u8 nexthdr;
1461 unsigned len; 1461 unsigned len;
1462 int offset; 1462 int offset;
@@ -1501,10 +1501,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1501 1501
1502 __skb_pull(skb2, offset); 1502 __skb_pull(skb2, offset);
1503 skb_reset_transport_header(skb2); 1503 skb_reset_transport_header(skb2);
1504 skb_postpull_rcsum(skb2, skb_network_header(skb2),
1505 skb_network_header_len(skb2));
1504 1506
1505 icmp6h = icmp6_hdr(skb2); 1507 icmp6_type = icmp6_hdr(skb2)->icmp6_type;
1506 1508
1507 switch (icmp6h->icmp6_type) { 1509 switch (icmp6_type) {
1508 case ICMPV6_MGM_QUERY: 1510 case ICMPV6_MGM_QUERY:
1509 case ICMPV6_MGM_REPORT: 1511 case ICMPV6_MGM_REPORT:
1510 case ICMPV6_MGM_REDUCTION: 1512 case ICMPV6_MGM_REDUCTION:
@@ -1520,16 +1522,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1520 err = pskb_trim_rcsum(skb2, len); 1522 err = pskb_trim_rcsum(skb2, len);
1521 if (err) 1523 if (err)
1522 goto out; 1524 goto out;
1525 err = -EINVAL;
1523 } 1526 }
1524 1527
1528 ip6h = ipv6_hdr(skb2);
1529
1525 switch (skb2->ip_summed) { 1530 switch (skb2->ip_summed) {
1526 case CHECKSUM_COMPLETE: 1531 case CHECKSUM_COMPLETE:
1527 if (!csum_fold(skb2->csum)) 1532 if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len,
1533 IPPROTO_ICMPV6, skb2->csum))
1528 break; 1534 break;
1529 /*FALLTHROUGH*/ 1535 /*FALLTHROUGH*/
1530 case CHECKSUM_NONE: 1536 case CHECKSUM_NONE:
1531 skb2->csum = 0; 1537 skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
1532 if (skb_checksum_complete(skb2)) 1538 &ip6h->daddr,
1539 skb2->len,
1540 IPPROTO_ICMPV6, 0));
1541 if (__skb_checksum_complete(skb2))
1533 goto out; 1542 goto out;
1534 } 1543 }
1535 1544
@@ -1537,7 +1546,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1537 1546
1538 BR_INPUT_SKB_CB(skb)->igmp = 1; 1547 BR_INPUT_SKB_CB(skb)->igmp = 1;
1539 1548
1540 switch (icmp6h->icmp6_type) { 1549 switch (icmp6_type) {
1541 case ICMPV6_MGM_REPORT: 1550 case ICMPV6_MGM_REPORT:
1542 { 1551 {
1543 struct mld_msg *mld; 1552 struct mld_msg *mld;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 56149ec36d7..5693e5f9e03 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -109,11 +109,17 @@ static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
109 return NULL; 109 return NULL;
110} 110}
111 111
112static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr)
113{
114 return NULL;
115}
116
112static struct dst_ops fake_dst_ops = { 117static struct dst_ops fake_dst_ops = {
113 .family = AF_INET, 118 .family = AF_INET,
114 .protocol = cpu_to_be16(ETH_P_IP), 119 .protocol = cpu_to_be16(ETH_P_IP),
115 .update_pmtu = fake_update_pmtu, 120 .update_pmtu = fake_update_pmtu,
116 .cow_metrics = fake_cow_metrics, 121 .cow_metrics = fake_cow_metrics,
122 .neigh_lookup = fake_neigh_lookup,
117}; 123};
118 124
119/* 125/*
@@ -135,7 +141,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
135 rt->dst.dev = br->dev; 141 rt->dst.dev = br->dev;
136 rt->dst.path = &rt->dst; 142 rt->dst.path = &rt->dst;
137 dst_init_metrics(&rt->dst, br_dst_default_metrics, true); 143 dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
138 rt->dst.flags = DST_NOXFRM; 144 rt->dst.flags = DST_NOXFRM | DST_NOPEER;
139 rt->dst.ops = &fake_dst_ops; 145 rt->dst.ops = &fake_dst_ops;
140} 146}
141 147
@@ -343,24 +349,26 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
343static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) 349static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
344{ 350{
345 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 351 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
352 struct neighbour *neigh;
346 struct dst_entry *dst; 353 struct dst_entry *dst;
347 354
348 skb->dev = bridge_parent(skb->dev); 355 skb->dev = bridge_parent(skb->dev);
349 if (!skb->dev) 356 if (!skb->dev)
350 goto free_skb; 357 goto free_skb;
351 dst = skb_dst(skb); 358 dst = skb_dst(skb);
352 if (dst->hh) { 359 neigh = dst_get_neighbour(dst);
353 neigh_hh_bridge(dst->hh, skb); 360 if (neigh->hh.hh_len) {
361 neigh_hh_bridge(&neigh->hh, skb);
354 skb->dev = nf_bridge->physindev; 362 skb->dev = nf_bridge->physindev;
355 return br_handle_frame_finish(skb); 363 return br_handle_frame_finish(skb);
356 } else if (dst->neighbour) { 364 } else {
357 /* the neighbour function below overwrites the complete 365 /* the neighbour function below overwrites the complete
358 * MAC header, so we save the Ethernet source address and 366 * MAC header, so we save the Ethernet source address and
359 * protocol number. */ 367 * protocol number. */
360 skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN); 368 skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
361 /* tell br_dev_xmit to continue with forwarding */ 369 /* tell br_dev_xmit to continue with forwarding */
362 nf_bridge->mask |= BRNF_BRIDGED_DNAT; 370 nf_bridge->mask |= BRNF_BRIDGED_DNAT;
363 return dst->neighbour->output(skb); 371 return neigh->output(neigh, skb);
364 } 372 }
365free_skb: 373free_skb:
366 kfree_skb(skb); 374 kfree_skb(skb);
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index ffb0dc4cc0e..e5f9ece3c9a 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -188,6 +188,8 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
188 188
189 p->state = new_state; 189 p->state = new_state;
190 br_log_state(p); 190 br_log_state(p);
191 br_ifinfo_notify(RTM_NEWLINK, p);
192
191 return 0; 193 return 0;
192} 194}
193 195
@@ -208,6 +210,7 @@ static struct rtnl_link_ops br_link_ops __read_mostly = {
208 .priv_size = sizeof(struct net_bridge), 210 .priv_size = sizeof(struct net_bridge),
209 .setup = br_dev_setup, 211 .setup = br_dev_setup,
210 .validate = br_validate, 212 .validate = br_validate,
213 .dellink = br_dev_delete,
211}; 214};
212 215
213int __init br_netlink_init(void) 216int __init br_netlink_init(void)
@@ -218,19 +221,24 @@ int __init br_netlink_init(void)
218 if (err < 0) 221 if (err < 0)
219 goto err1; 222 goto err1;
220 223
221 err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo); 224 err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL,
225 br_dump_ifinfo, NULL);
222 if (err) 226 if (err)
223 goto err2; 227 goto err2;
224 err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL); 228 err = __rtnl_register(PF_BRIDGE, RTM_SETLINK,
229 br_rtm_setlink, NULL, NULL);
225 if (err) 230 if (err)
226 goto err3; 231 goto err3;
227 err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL); 232 err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH,
233 br_fdb_add, NULL, NULL);
228 if (err) 234 if (err)
229 goto err3; 235 goto err3;
230 err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL); 236 err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH,
237 br_fdb_delete, NULL, NULL);
231 if (err) 238 if (err)
232 goto err3; 239 goto err3;
233 err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump); 240 err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH,
241 NULL, br_fdb_dump, NULL);
234 if (err) 242 if (err)
235 goto err3; 243 goto err3;
236 244
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 6545ee9591d..a76b6213555 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
34 struct net_device *dev = ptr; 34 struct net_device *dev = ptr;
35 struct net_bridge_port *p; 35 struct net_bridge_port *p;
36 struct net_bridge *br; 36 struct net_bridge *br;
37 bool changed_addr;
37 int err; 38 int err;
38 39
39 /* register of bridge completed, add sysfs entries */ 40 /* register of bridge completed, add sysfs entries */
@@ -57,8 +58,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
57 case NETDEV_CHANGEADDR: 58 case NETDEV_CHANGEADDR:
58 spin_lock_bh(&br->lock); 59 spin_lock_bh(&br->lock);
59 br_fdb_changeaddr(p, dev->dev_addr); 60 br_fdb_changeaddr(p, dev->dev_addr);
60 br_stp_recalculate_bridge_id(br); 61 changed_addr = br_stp_recalculate_bridge_id(br);
61 spin_unlock_bh(&br->lock); 62 spin_unlock_bh(&br->lock);
63
64 if (changed_addr)
65 call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
66
62 break; 67 break;
63 68
64 case NETDEV_CHANGE: 69 case NETDEV_CHANGE:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 54578f274d8..857a021deea 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -124,6 +124,7 @@ struct net_bridge_port
124 bridge_id designated_bridge; 124 bridge_id designated_bridge;
125 u32 path_cost; 125 u32 path_cost;
126 u32 designated_cost; 126 u32 designated_cost;
127 unsigned long designated_age;
127 128
128 struct timer_list forward_delay_timer; 129 struct timer_list forward_delay_timer;
129 struct timer_list hold_timer; 130 struct timer_list hold_timer;
@@ -293,6 +294,7 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
293 294
294/* br_device.c */ 295/* br_device.c */
295extern void br_dev_setup(struct net_device *dev); 296extern void br_dev_setup(struct net_device *dev);
297extern void br_dev_delete(struct net_device *dev, struct list_head *list);
296extern netdev_tx_t br_dev_xmit(struct sk_buff *skb, 298extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
297 struct net_device *dev); 299 struct net_device *dev);
298#ifdef CONFIG_NET_POLL_CONTROLLER 300#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index 642ef47a867..05ed9bc7e42 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -56,7 +56,8 @@ extern void br_become_root_bridge(struct net_bridge *br);
56extern void br_config_bpdu_generation(struct net_bridge *); 56extern void br_config_bpdu_generation(struct net_bridge *);
57extern void br_configuration_update(struct net_bridge *); 57extern void br_configuration_update(struct net_bridge *);
58extern void br_port_state_selection(struct net_bridge *); 58extern void br_port_state_selection(struct net_bridge *);
59extern void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu); 59extern void br_received_config_bpdu(struct net_bridge_port *p,
60 const struct br_config_bpdu *bpdu);
60extern void br_received_tcn_bpdu(struct net_bridge_port *p); 61extern void br_received_tcn_bpdu(struct net_bridge_port *p);
61extern void br_transmit_config(struct net_bridge_port *p); 62extern void br_transmit_config(struct net_bridge_port *p);
62extern void br_transmit_tcn(struct net_bridge *br); 63extern void br_transmit_tcn(struct net_bridge *br);
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index bb4383e84de..ad0a3f7cf6c 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -109,7 +109,6 @@ static void br_root_selection(struct net_bridge *br)
109 list_for_each_entry(p, &br->port_list, list) { 109 list_for_each_entry(p, &br->port_list, list) {
110 if (br_should_become_root_port(p, root_port)) 110 if (br_should_become_root_port(p, root_port))
111 root_port = p->port_no; 111 root_port = p->port_no;
112
113 } 112 }
114 113
115 br->root_port = root_port; 114 br->root_port = root_port;
@@ -145,7 +144,6 @@ void br_transmit_config(struct net_bridge_port *p)
145 struct br_config_bpdu bpdu; 144 struct br_config_bpdu bpdu;
146 struct net_bridge *br; 145 struct net_bridge *br;
147 146
148
149 if (timer_pending(&p->hold_timer)) { 147 if (timer_pending(&p->hold_timer)) {
150 p->config_pending = 1; 148 p->config_pending = 1;
151 return; 149 return;
@@ -164,8 +162,7 @@ void br_transmit_config(struct net_bridge_port *p)
164 else { 162 else {
165 struct net_bridge_port *root 163 struct net_bridge_port *root
166 = br_get_port(br, br->root_port); 164 = br_get_port(br, br->root_port);
167 bpdu.message_age = br->max_age 165 bpdu.message_age = (jiffies - root->designated_age)
168 - (root->message_age_timer.expires - jiffies)
169 + MESSAGE_AGE_INCR; 166 + MESSAGE_AGE_INCR;
170 } 167 }
171 bpdu.max_age = br->max_age; 168 bpdu.max_age = br->max_age;
@@ -182,20 +179,21 @@ void br_transmit_config(struct net_bridge_port *p)
182} 179}
183 180
184/* called under bridge lock */ 181/* called under bridge lock */
185static inline void br_record_config_information(struct net_bridge_port *p, 182static void br_record_config_information(struct net_bridge_port *p,
186 const struct br_config_bpdu *bpdu) 183 const struct br_config_bpdu *bpdu)
187{ 184{
188 p->designated_root = bpdu->root; 185 p->designated_root = bpdu->root;
189 p->designated_cost = bpdu->root_path_cost; 186 p->designated_cost = bpdu->root_path_cost;
190 p->designated_bridge = bpdu->bridge_id; 187 p->designated_bridge = bpdu->bridge_id;
191 p->designated_port = bpdu->port_id; 188 p->designated_port = bpdu->port_id;
189 p->designated_age = jiffies + bpdu->message_age;
192 190
193 mod_timer(&p->message_age_timer, jiffies 191 mod_timer(&p->message_age_timer, jiffies
194 + (p->br->max_age - bpdu->message_age)); 192 + (p->br->max_age - bpdu->message_age));
195} 193}
196 194
197/* called under bridge lock */ 195/* called under bridge lock */
198static inline void br_record_config_timeout_values(struct net_bridge *br, 196static void br_record_config_timeout_values(struct net_bridge *br,
199 const struct br_config_bpdu *bpdu) 197 const struct br_config_bpdu *bpdu)
200{ 198{
201 br->max_age = bpdu->max_age; 199 br->max_age = bpdu->max_age;
@@ -254,7 +252,8 @@ static void br_designated_port_selection(struct net_bridge *br)
254} 252}
255 253
256/* called under bridge lock */ 254/* called under bridge lock */
257static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_bpdu *bpdu) 255static int br_supersedes_port_info(const struct net_bridge_port *p,
256 const struct br_config_bpdu *bpdu)
258{ 257{
259 int t; 258 int t;
260 259
@@ -285,7 +284,7 @@ static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_b
285} 284}
286 285
287/* called under bridge lock */ 286/* called under bridge lock */
288static inline void br_topology_change_acknowledged(struct net_bridge *br) 287static void br_topology_change_acknowledged(struct net_bridge *br)
289{ 288{
290 br->topology_change_detected = 0; 289 br->topology_change_detected = 0;
291 del_timer(&br->tcn_timer); 290 del_timer(&br->tcn_timer);
@@ -327,7 +326,7 @@ void br_config_bpdu_generation(struct net_bridge *br)
327} 326}
328 327
329/* called under bridge lock */ 328/* called under bridge lock */
330static inline void br_reply(struct net_bridge_port *p) 329static void br_reply(struct net_bridge_port *p)
331{ 330{
332 br_transmit_config(p); 331 br_transmit_config(p);
333} 332}
@@ -363,6 +362,8 @@ static void br_make_blocking(struct net_bridge_port *p)
363 362
364 p->state = BR_STATE_BLOCKING; 363 p->state = BR_STATE_BLOCKING;
365 br_log_state(p); 364 br_log_state(p);
365 br_ifinfo_notify(RTM_NEWLINK, p);
366
366 del_timer(&p->forward_delay_timer); 367 del_timer(&p->forward_delay_timer);
367 } 368 }
368} 369}
@@ -379,15 +380,14 @@ static void br_make_forwarding(struct net_bridge_port *p)
379 p->state = BR_STATE_FORWARDING; 380 p->state = BR_STATE_FORWARDING;
380 br_topology_change_detection(br); 381 br_topology_change_detection(br);
381 del_timer(&p->forward_delay_timer); 382 del_timer(&p->forward_delay_timer);
382 } 383 } else if (br->stp_enabled == BR_KERNEL_STP)
383 else if (br->stp_enabled == BR_KERNEL_STP)
384 p->state = BR_STATE_LISTENING; 384 p->state = BR_STATE_LISTENING;
385 else 385 else
386 p->state = BR_STATE_LEARNING; 386 p->state = BR_STATE_LEARNING;
387 387
388 br_multicast_enable_port(p); 388 br_multicast_enable_port(p);
389
390 br_log_state(p); 389 br_log_state(p);
390 br_ifinfo_notify(RTM_NEWLINK, p);
391 391
392 if (br->forward_delay != 0) 392 if (br->forward_delay != 0)
393 mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay); 393 mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
@@ -431,14 +431,15 @@ void br_port_state_selection(struct net_bridge *br)
431} 431}
432 432
433/* called under bridge lock */ 433/* called under bridge lock */
434static inline void br_topology_change_acknowledge(struct net_bridge_port *p) 434static void br_topology_change_acknowledge(struct net_bridge_port *p)
435{ 435{
436 p->topology_change_ack = 1; 436 p->topology_change_ack = 1;
437 br_transmit_config(p); 437 br_transmit_config(p);
438} 438}
439 439
440/* called under bridge lock */ 440/* called under bridge lock */
441void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu) 441void br_received_config_bpdu(struct net_bridge_port *p,
442 const struct br_config_bpdu *bpdu)
442{ 443{
443 struct net_bridge *br; 444 struct net_bridge *br;
444 int was_root; 445 int was_root;
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 289646ec9b7..e16aade51ae 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -210,10 +210,19 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
210 bpdu.hello_time = br_get_ticks(buf+28); 210 bpdu.hello_time = br_get_ticks(buf+28);
211 bpdu.forward_delay = br_get_ticks(buf+30); 211 bpdu.forward_delay = br_get_ticks(buf+30);
212 212
213 br_received_config_bpdu(p, &bpdu); 213 if (bpdu.message_age > bpdu.max_age) {
214 } 214 if (net_ratelimit())
215 br_notice(p->br,
216 "port %u config from %pM"
217 " (message_age %ul > max_age %ul)\n",
218 p->port_no,
219 eth_hdr(skb)->h_source,
220 bpdu.message_age, bpdu.max_age);
221 goto out;
222 }
215 223
216 else if (buf[0] == BPDU_TYPE_TCN) { 224 br_received_config_bpdu(p, &bpdu);
225 } else if (buf[0] == BPDU_TYPE_TCN) {
217 br_received_tcn_bpdu(p); 226 br_received_tcn_bpdu(p);
218 } 227 }
219 out: 228 out:
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 6f615b8192f..10eda3cd1d7 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -88,6 +88,7 @@ void br_stp_enable_port(struct net_bridge_port *p)
88 br_init_port(p); 88 br_init_port(p);
89 br_port_state_selection(p->br); 89 br_port_state_selection(p->br);
90 br_log_state(p); 90 br_log_state(p);
91 br_ifinfo_notify(RTM_NEWLINK, p);
91} 92}
92 93
93/* called under bridge lock */ 94/* called under bridge lock */
@@ -104,6 +105,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
104 p->topology_change_ack = 0; 105 p->topology_change_ack = 0;
105 p->config_pending = 0; 106 p->config_pending = 0;
106 107
108 br_ifinfo_notify(RTM_NEWLINK, p);
109
107 del_timer(&p->message_age_timer); 110 del_timer(&p->message_age_timer);
108 del_timer(&p->forward_delay_timer); 111 del_timer(&p->forward_delay_timer);
109 del_timer(&p->hold_timer); 112 del_timer(&p->hold_timer);
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 3e965140051..58de2a0f997 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -97,6 +97,7 @@ static void br_forward_delay_timer_expired(unsigned long arg)
97 netif_carrier_on(br->dev); 97 netif_carrier_on(br->dev);
98 } 98 }
99 br_log_state(p); 99 br_log_state(p);
100 br_ifinfo_notify(RTM_NEWLINK, p);
100 spin_unlock(&br->lock); 101 spin_unlock(&br->lock);
101} 102}
102 103
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index ba6f73eb06c..a9aff9c7d02 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -4,7 +4,7 @@
4 4
5menuconfig BRIDGE_NF_EBTABLES 5menuconfig BRIDGE_NF_EBTABLES
6 tristate "Ethernet Bridge tables (ebtables) support" 6 tristate "Ethernet Bridge tables (ebtables) support"
7 depends on BRIDGE && BRIDGE_NETFILTER 7 depends on BRIDGE && NETFILTER
8 select NETFILTER_XTABLES 8 select NETFILTER_XTABLES
9 help 9 help
10 ebtables is a general, extensible frame/packet identification 10 ebtables is a general, extensible frame/packet identification
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 26377e96fa1..bf2a333ca7c 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -216,7 +216,6 @@ unlock:
216nlmsg_failure: 216nlmsg_failure:
217 pr_debug("error during NLMSG_PUT. This should " 217 pr_debug("error during NLMSG_PUT. This should "
218 "not happen, please report to author.\n"); 218 "not happen, please report to author.\n");
219 goto unlock;
220alloc_failure: 219alloc_failure:
221 goto unlock; 220 goto unlock;
222} 221}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 2b5ca1a0054..5864cc49136 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1198,7 +1198,8 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table)
1198 1198
1199 if (table->check && table->check(newinfo, table->valid_hooks)) { 1199 if (table->check && table->check(newinfo, table->valid_hooks)) {
1200 BUGPRINT("The table doesn't like its own initial data, lol\n"); 1200 BUGPRINT("The table doesn't like its own initial data, lol\n");
1201 return ERR_PTR(-EINVAL); 1201 ret = -EINVAL;
1202 goto free_chainstack;
1202 } 1203 }
1203 1204
1204 table->private = newinfo; 1205 table->private = newinfo;