diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_if.c | 2 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 2 | ||||
-rw-r--r-- | net/bridge/br_private.h | 1 | ||||
-rw-r--r-- | net/bridge/br_private_stp.h | 3 | ||||
-rw-r--r-- | net/bridge/br_stp.c | 31 | ||||
-rw-r--r-- | net/bridge/br_stp_bpdu.c | 15 | ||||
-rw-r--r-- | net/bridge/br_stp_if.c | 3 | ||||
-rw-r--r-- | net/bridge/br_stp_timer.c | 1 | ||||
-rw-r--r-- | net/core/link_watch.c | 2 |
9 files changed, 39 insertions, 21 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 1bacca4cb676..3176e2e13d9b 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -388,7 +388,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
388 | br_ifinfo_notify(RTM_NEWLINK, p); | 388 | br_ifinfo_notify(RTM_NEWLINK, p); |
389 | 389 | ||
390 | if (changed_addr) | 390 | if (changed_addr) |
391 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 391 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); |
392 | 392 | ||
393 | dev_set_mtu(br->dev, br_min_mtu(br)); | 393 | dev_set_mtu(br->dev, br_min_mtu(br)); |
394 | 394 | ||
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 6814083a92f4..5b1ed1ba9aa7 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 | ||
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 54578f274d85..78cc364997d9 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; |
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h index 642ef47a867e..05ed9bc7e426 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); | |||
56 | extern void br_config_bpdu_generation(struct net_bridge *); | 56 | extern void br_config_bpdu_generation(struct net_bridge *); |
57 | extern void br_configuration_update(struct net_bridge *); | 57 | extern void br_configuration_update(struct net_bridge *); |
58 | extern void br_port_state_selection(struct net_bridge *); | 58 | extern void br_port_state_selection(struct net_bridge *); |
59 | extern void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu); | 59 | extern void br_received_config_bpdu(struct net_bridge_port *p, |
60 | const struct br_config_bpdu *bpdu); | ||
60 | extern void br_received_tcn_bpdu(struct net_bridge_port *p); | 61 | extern void br_received_tcn_bpdu(struct net_bridge_port *p); |
61 | extern void br_transmit_config(struct net_bridge_port *p); | 62 | extern void br_transmit_config(struct net_bridge_port *p); |
62 | extern void br_transmit_tcn(struct net_bridge *br); | 63 | extern void br_transmit_tcn(struct net_bridge *br); |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index bb4383e84de9..ad0a3f7cf6cc 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 */ |
185 | static inline void br_record_config_information(struct net_bridge_port *p, | 182 | static 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 */ |
198 | static inline void br_record_config_timeout_values(struct net_bridge *br, | 196 | static 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 */ |
257 | static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_bpdu *bpdu) | 255 | static 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 */ |
288 | static inline void br_topology_change_acknowledged(struct net_bridge *br) | 287 | static 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 */ |
330 | static inline void br_reply(struct net_bridge_port *p) | 329 | static 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 */ |
434 | static inline void br_topology_change_acknowledge(struct net_bridge_port *p) | 434 | static 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 */ |
441 | void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu) | 441 | void 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 289646ec9b7b..e16aade51ae0 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 6f615b8192f4..10eda3cd1d71 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 3e965140051e..58de2a0f9975 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/core/link_watch.c b/net/core/link_watch.c index a7b342131869..357bd4ee4baa 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) | |||
126 | return; | 126 | return; |
127 | 127 | ||
128 | /* It's already running which is good enough. */ | 128 | /* It's already running which is good enough. */ |
129 | if (!cancel_delayed_work(&linkwatch_work)) | 129 | if (!__cancel_delayed_work(&linkwatch_work)) |
130 | return; | 130 | return; |
131 | 131 | ||
132 | /* Otherwise we reschedule it again for immediate execution. */ | 132 | /* Otherwise we reschedule it again for immediate execution. */ |