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 58dcb18..01a68bc 100644 (file)
--- a/device.h
+++ b/device.h
@@ -138,6 +138,7 @@ struct device {
 
        bool current_config;
        bool default_config;
 
        bool current_config;
        bool default_config;
+       bool wireless;
 
        /* set interface up or down */
        device_state_cb set_state;
 
        /* set interface up or down */
        device_state_cb set_state;
index c6f17e9..5c960b4 100644 (file)
@@ -452,15 +452,27 @@ static char *system_get_bridge(const char *name, char *buf, int buflen)
        return path + 1;
 }
 
        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 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));
 
        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)
 }
 
 int system_bridge_delif(struct device *bridge, struct device *dev)
index 0e293a0..c0f3b71 100644 (file)
@@ -202,6 +202,12 @@ static void wireless_interface_handle_link(struct wireless_interface *vif, bool
        if (!vif->network || !vif->ifname)
                return;
 
        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);
 
        blobmsg_for_each_attr(cur, vif->network, rem) {
                network = blobmsg_data(cur);