summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-06-29 20:31:26 +0200
committerFelix Fietkau <nbd@openwrt.org>2014-06-29 20:31:26 +0200
commita3bf8cbe10b0bad85475f4c3dc2bae4afb65774b (patch)
tree76b05f206dee6b86e1d32a54e760945b94340e3a
parent61e627ed78ed47e40cc63a24ff8fb2f5fb2c418f (diff)
bridge: enable multicast_to_unicast on all wireless bridge ports
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--device.h1
-rw-r--r--system-linux.c18
-rw-r--r--wireless.c6
3 files changed, 22 insertions, 3 deletions
diff --git a/device.h b/device.h
index 58dcb18..01a68bc 100644
--- a/device.h
+++ b/device.h
@@ -138,6 +138,7 @@ struct device {
bool current_config;
bool default_config;
+ bool wireless;
/* set interface up or down */
device_state_cb set_state;
diff --git a/system-linux.c b/system-linux.c
index c6f17e9..5c960b4 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -452,15 +452,27 @@ static char *system_get_bridge(const char *name, char *buf, int buflen)
return path + 1;
}
+static void system_bridge_set_wireless(const char *bridge, const char *dev)
+{
+ snprintf(dev_buf, sizeof(dev_buf),
+ "/sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast",
+ bridge, dev);
+ system_set_sysctl(dev_buf, "1");
+}
+
int system_bridge_addif(struct device *bridge, struct device *dev)
{
char *oldbr;
+ int ret = 0;
oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
- if (oldbr && !strcmp(oldbr, bridge->ifname))
- return 0;
+ if (!oldbr || strcmp(oldbr, bridge->ifname) != 0)
+ ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
+
+ if (dev->wireless)
+ system_bridge_set_wireless(bridge->ifname, dev->ifname);
- return system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
+ return ret;
}
int system_bridge_delif(struct device *bridge, struct device *dev)
diff --git a/wireless.c b/wireless.c
index 0e293a0..c0f3b71 100644
--- a/wireless.c
+++ b/wireless.c
@@ -202,6 +202,12 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, bool
if (!vif->network || !vif->ifname)
return;
+ if (up) {
+ struct device *dev = device_get(vif->ifname, 2);
+ if (dev)
+ dev->wireless = true;
+ }
+
blobmsg_for_each_attr(cur, vif->network, rem) {
network = blobmsg_data(cur);