#include "br_private.h"
#include "br_private_stp.h"
+/* since time values in bpdu are in jiffies and then scaled (1/256)
+ * before sending, make sure that is at least one.
+ */
+#define MESSAGE_AGE_INCR ((HZ < 256) ? 1 : (HZ/256))
+
static const char *br_port_state_names[] = {
[BR_STATE_DISABLED] = "disabled",
[BR_STATE_LISTENING] = "listening",
bpdu.root_path_cost = br->root_path_cost;
bpdu.bridge_id = br->bridge_id;
bpdu.port_id = p->port_id;
- bpdu.message_age = 0;
- if (!br_is_root_bridge(br)) {
+ if (br_is_root_bridge(br))
+ bpdu.message_age = 0;
+ else {
struct net_bridge_port *root
= br_get_port(br, br->root_port);
- bpdu.max_age = root->message_age_timer.expires - jiffies;
-
- if (bpdu.max_age <= 0) bpdu.max_age = 1;
+ bpdu.message_age = br->max_age
+ - (root->message_age_timer.expires - jiffies)
+ + MESSAGE_AGE_INCR;
}
bpdu.max_age = br->max_age;
bpdu.hello_time = br->hello_time;
bpdu.forward_delay = br->forward_delay;
- br_send_config_bpdu(p, &bpdu);
-
- p->topology_change_ack = 0;
- p->config_pending = 0;
-
- mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
+ if (bpdu.message_age < br->max_age) {
+ br_send_config_bpdu(p, &bpdu);
+ p->topology_change_ack = 0;
+ p->config_pending = 0;
+ mod_timer(&p->hold_timer, jiffies + BR_HOLD_TIME);
+ }
}
/* called under bridge lock */
int isroot = br_is_root_bridge(br);
pr_info("%s: topology change detected, %s\n", br->dev->name,
- isroot ? "propgating" : "sending tcn bpdu");
+ isroot ? "propagating" : "sending tcn bpdu");
if (isroot) {
br->topology_change = 1;