bridge: enable multicast_to_unicast on all wireless bridge ports
[project/netifd.git] / system-linux.c
index af54bfd..5c960b4 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)
@@ -791,7 +803,7 @@ nla_put_failure:
        return -ENOMEM;
 }
 
-int system_macvlan_del(struct device *macvlan)
+static int system_link_del(struct device *dev)
 {
        struct nl_msg *msg;
        struct ifinfomsg iim = {
@@ -805,12 +817,13 @@ int system_macvlan_del(struct device *macvlan)
                return -1;
 
        nlmsg_append(msg, &iim, sizeof(iim), 0);
+       nla_put_string(msg, IFLA_IFNAME, dev->ifname);
+       return system_rtnl_call(msg);
+}
 
-       nla_put_string(msg, IFLA_IFNAME, macvlan->ifname);
-
-       system_rtnl_call(msg);
-
-       return 0;
+int system_macvlan_del(struct device *macvlan)
+{
+       return system_link_del(macvlan);
 }
 
 static int system_vlan(struct device *dev, int id)
@@ -896,24 +909,7 @@ nla_put_failure:
 
 int system_vlandev_del(struct device *vlandev)
 {
-       struct nl_msg *msg;
-       struct ifinfomsg iim = {
-               .ifi_family = AF_UNSPEC,
-               .ifi_index = 0,
-       };
-
-       msg = nlmsg_alloc_simple(RTM_DELLINK, NLM_F_REQUEST);
-
-       if (!msg)
-               return -1;
-
-       nlmsg_append(msg, &iim, sizeof(iim), 0);
-
-       nla_put_string(msg, IFLA_IFNAME, vlandev->ifname);
-
-       system_rtnl_call(msg);
-
-       return 0;
+       return system_link_del(vlandev);
 }
 
 static void
@@ -1480,14 +1476,15 @@ bool system_resolve_rt_table(const char *name, unsigned int *id)
        if (table == RT_TABLE_UNSPEC)
                return false;
 
-       /* do not consider main table special */
-       if (table == RT_TABLE_MAIN)
-               table = RT_TABLE_UNSPEC;
-
        *id = table;
        return true;
 }
 
+bool system_is_default_rt_table(unsigned int id)
+{
+       return (id == RT_TABLE_MAIN);
+}
+
 static int system_iprule(struct iprule *rule, int cmd)
 {
        int alen = ((rule->flags & IPRULE_FAMILY) == IPRULE_INET4) ? 4 : 16;