bridge: enable multicast_to_unicast on all wireless bridge ports
authorFelix Fietkau <nbd@openwrt.org>
Sun, 29 Jun 2014 18:31:26 +0000 (20:31 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 29 Jun 2014 18:31:26 +0000 (20:31 +0200)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
device.h
system-linux.c
wireless.c

index 58dcb18525d90d42dcb5d29dfd4415bd6d365bb6..01a68bcc8b5210c66ee856eff184abdba688da6c 100644 (file)
--- 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;
index c6f17e99c8015ca7f414231c6a77139c7a522e2e..5c960b40119854e42e7d5531a6929e7ca6736626 100644 (file)
@@ -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)
index 0e293a0783d189581855737d4ec117f7e8679285..c0f3b710fcefff9b50505931ca6a1eb2445262a9 100644 (file)
@@ -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);