summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNiels Boehm <blubberdiblub@gmail.com>2013-02-04 18:05:17 +0000
committerJo-Philipp Wich <jow@openwrt.org>2013-04-23 16:00:13 +0200
commit2008ae9a80fb82b0018fd510043c291b58e7cc46 (patch)
tree694ac0ac18e5c41286b4c9d0704d9883d10f07c9
parentcbb2b3270ad59ca91a04aba94eee0c73e24ce80b (diff)
add bridge priority option
[netifd] add bridge priority option Using the bridge priority (lower numbers are higher in the hierarchy), one can ensure that the router is chosen as root bridge in a setup with spanning tree protocol. For instance, one can set the priority of network lan to 32767, causing the router to win over all directly and indirectly connected nodes that have a default priority of 32768. The reason for doing that is that otherwise it has a default priority 32768 as well and any other connected node could win and get root bridge. In a home setup, those nodes are often desktop or laptop boxes and get switched off from time to time. As a consequence, root bridges vanish or new root bridges get chosen relatively often, resulting in frequent topology changes to the STP network. While the new topology has not settled, packets can get lost, causing noticeable interruptions of network traffic. Setting the router's bridge on a lower numbered priority (and thus higher in the selection hierarchy) solves the problem in the vast majority of the cases by ensuring that the device that is most likely powered on 24/7 gets chosen as root and prevents topology changes. Signed-off-by: Niels Boehm <blubberdiblub@gmail.com>
-rw-r--r--bridge.c7
-rw-r--r--system-linux.c6
-rw-r--r--system.h2
3 files changed, 15 insertions, 0 deletions
diff --git a/bridge.c b/bridge.c
index 1d02f83..83c9d79 100644
--- a/bridge.c
+++ b/bridge.c
@@ -26,6 +26,7 @@ enum {
BRIDGE_ATTR_IFNAME,
BRIDGE_ATTR_STP,
BRIDGE_ATTR_FORWARD_DELAY,
+ BRIDGE_ATTR_PRIORITY,
BRIDGE_ATTR_IGMP_SNOOP,
BRIDGE_ATTR_AGEING_TIME,
BRIDGE_ATTR_HELLO_TIME,
@@ -37,6 +38,7 @@ static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = {
[BRIDGE_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_ARRAY },
[BRIDGE_ATTR_STP] = { "stp", BLOBMSG_TYPE_BOOL },
[BRIDGE_ATTR_FORWARD_DELAY] = { "forward_delay", BLOBMSG_TYPE_INT32 },
+ [BRIDGE_ATTR_PRIORITY] = { "priority", BLOBMSG_TYPE_INT32 },
[BRIDGE_ATTR_AGEING_TIME] = { "ageing_time", BLOBMSG_TYPE_INT32 },
[BRIDGE_ATTR_HELLO_TIME] = { "hello_time", BLOBMSG_TYPE_INT32 },
[BRIDGE_ATTR_MAX_AGE] = { "max_age", BLOBMSG_TYPE_INT32 },
@@ -469,6 +471,11 @@ bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
cfg->forward_delay = blobmsg_get_u32(cur);
+ if ((cur = tb[BRIDGE_ATTR_PRIORITY])) {
+ cfg->priority = blobmsg_get_u32(cur);
+ cfg->flags |= BRIDGE_OPT_PRIORITY;
+ }
+
if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
cfg->igmp_snoop = blobmsg_get_bool(cur);
diff --git a/system-linux.c b/system-linux.c
index d788a01..604c206 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -581,6 +581,12 @@ int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
system_set_dev_sysctl("/sys/devices/virtual/net/%s/bridge/multicast_snooping",
bridge->ifname, cfg->igmp_snoop ? "1" : "0");
+ if (cfg->flags & BRIDGE_OPT_PRIORITY) {
+ args[0] = BRCTL_SET_BRIDGE_PRIORITY;
+ args[1] = cfg->priority;
+ system_bridge_if(bridge->ifname, NULL, SIOCDEVPRIVATE, &args);
+ }
+
if (cfg->flags & BRIDGE_OPT_AGEING_TIME) {
args[0] = BRCTL_SET_AGEING_TIME;
args[1] = sec_to_jiffies(cfg->ageing_time);
diff --git a/system.h b/system.h
index 9b555e8..1b16bb9 100644
--- a/system.h
+++ b/system.h
@@ -38,12 +38,14 @@ enum bridge_opt {
BRIDGE_OPT_AGEING_TIME = (1 << 0),
BRIDGE_OPT_HELLO_TIME = (1 << 1),
BRIDGE_OPT_MAX_AGE = (1 << 2),
+ BRIDGE_OPT_PRIORITY = (1 << 3),
};
struct bridge_config {
enum bridge_opt flags;
bool stp;
bool igmp_snoop;
+ unsigned short priority;
int forward_delay;
int ageing_time;