summaryrefslogtreecommitdiffhomepage
path: root/bridge.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-05-23 16:09:45 +0200
committerFelix Fietkau <nbd@openwrt.org>2012-05-23 16:09:45 +0200
commit7db45fcc1faa7c62541b762aa7ba2e99b1bc6342 (patch)
treee4c388a5bf712e5bdd0d74fde064fc8f1834f29f /bridge.c
parente7ac4074bf497cd19e38adbb49e2b3eb275eeb05 (diff)
bridge: set the mac address based on the first active member
Diffstat (limited to 'bridge.c')
-rw-r--r--bridge.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/bridge.c b/bridge.c
index b1b79e8..1725162 100644
--- a/bridge.c
+++ b/bridge.c
@@ -84,6 +84,7 @@ struct bridge_state {
bool active;
bool force_active;
+ struct bridge_member *primary_port;
struct vlist_tree members;
int n_present;
};
@@ -96,6 +97,23 @@ struct bridge_member {
char name[];
};
+static void
+bridge_reset_primary(struct bridge_state *bst)
+{
+ struct bridge_member *bm;
+
+ bst->primary_port = NULL;
+ vlist_for_each_element(&bst->members, bm, node) {
+ if (!bm->present)
+ continue;
+
+ bst->primary_port = bm;
+ memcpy(bst->dev.settings.macaddr, bm->dev.dev->settings.macaddr, 6);
+ bst->dev.settings.flags |= DEV_OPT_MACADDR;
+ return;
+ }
+}
+
static int
bridge_disable_member(struct bridge_member *bm)
{
@@ -145,6 +163,9 @@ bridge_remove_member(struct bridge_member *bm)
if (!bm->present)
return;
+ if (bm == bst->primary_port);
+ bridge_reset_primary(bst);
+
if (bst->dev.active)
bridge_disable_member(bm);
@@ -228,6 +249,7 @@ bridge_set_up(struct bridge_state *bst)
return -ENOENT;
}
+ bridge_reset_primary(bst);
ret = bst->set_state(&bst->dev, true);
if (ret < 0)
bridge_set_down(bst);