diff options
-rw-r--r-- | device.c | 9 | ||||
-rw-r--r-- | device.h | 3 | ||||
-rw-r--r-- | scripts/netifd-wireless.sh | 1 | ||||
-rw-r--r-- | system-linux.c | 13 | ||||
-rw-r--r-- | wireless.c | 4 |
5 files changed, 26 insertions, 4 deletions
@@ -48,6 +48,7 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = { [DEV_ATTR_RPS] = { .name = "rps", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_XPS] = { .name = "xps", .type = BLOBMSG_TYPE_BOOL }, [DEV_ATTR_DADTRANSMITS] = { .name = "dadtransmits", .type = BLOBMSG_TYPE_INT32 }, + [DEV_ATTR_MULTICAST_TO_UNICAST] = { .name = "multicast_to_unicast", .type = BLOBMSG_TYPE_BOOL }, }; const struct uci_blob_param_list device_attr_list = { @@ -174,6 +175,7 @@ device_merge_settings(struct device *dev, struct device_settings *n) s->neigh6reachabletime : os->neigh6reachabletime; n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ? s->dadtransmits : os->dadtransmits; + n->multicast_to_unicast = s->multicast_to_unicast; n->flags = s->flags | os->flags; } @@ -274,6 +276,11 @@ device_init_settings(struct device *dev, struct blob_attr **tb) s->flags |= DEV_OPT_DADTRANSMITS; } + if ((cur = tb[DEV_ATTR_MULTICAST_TO_UNICAST])) { + s->multicast_to_unicast = blobmsg_get_bool(cur); + s->flags |= DEV_OPT_MULTICAST_TO_UNICAST; + } + device_set_disabled(dev, disabled); } @@ -891,6 +898,8 @@ device_dump_status(struct blob_buf *b, struct device *dev) } if (st.flags & DEV_OPT_DADTRANSMITS) blobmsg_add_u32(b, "dadtransmits", st.dadtransmits); + if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST) + blobmsg_add_u8(b, "multicast_to_unicast", st.multicast_to_unicast); } s = blobmsg_open_table(b, "statistics"); @@ -42,6 +42,7 @@ enum { DEV_ATTR_RPS, DEV_ATTR_XPS, DEV_ATTR_DADTRANSMITS, + DEV_ATTR_MULTICAST_TO_UNICAST, __DEV_ATTR_MAX, }; @@ -84,6 +85,7 @@ enum { DEV_OPT_XPS = (1 << 11), DEV_OPT_MTU6 = (1 << 12), DEV_OPT_DADTRANSMITS = (1 << 13), + DEV_OPT_MULTICAST_TO_UNICAST = (1 << 14), }; /* events broadcasted to all users of a device */ @@ -141,6 +143,7 @@ struct device_settings { bool rps; bool xps; unsigned int dadtransmits; + bool multicast_to_unicast; }; /* diff --git a/scripts/netifd-wireless.sh b/scripts/netifd-wireless.sh index f981f1b..83a8223 100644 --- a/scripts/netifd-wireless.sh +++ b/scripts/netifd-wireless.sh @@ -274,6 +274,7 @@ for_each_interface() { json_select "$_w_iface" if [ -n "$_w_types" ]; then json_get_var network_bridge bridge + json_get_var multicast_to_unicast multicast_to_unicast json_select config _wireless_set_brsnoop_isolation "$multicast_to_unicast" json_get_var _w_type mode diff --git a/system-linux.c b/system-linux.c index 9c4bea6..944245c 100644 --- a/system-linux.c +++ b/system-linux.c @@ -567,14 +567,19 @@ static char *system_get_bridge(const char *name, char *buf, int buflen) } static void -system_bridge_set_wireless(struct device *dev) +system_bridge_set_wireless(struct device *bridge, struct device *dev) { + bool mcast_to_ucast = true; bool hairpin = true; - if (dev->wireless_isolate) + if (bridge->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST && + !bridge->settings.multicast_to_unicast) + mcast_to_ucast = false; + + if (!mcast_to_ucast || dev->wireless_isolate) hairpin = false; - system_bridge_set_multicast_to_unicast(dev, "1"); + system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0"); system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0"); } @@ -588,7 +593,7 @@ int system_bridge_addif(struct device *bridge, struct device *dev) ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL); if (dev->wireless) - system_bridge_set_wireless(dev); + system_bridge_set_wireless(bridge, dev); return ret; } @@ -92,6 +92,10 @@ vif_config_add_bridge(struct blob_buf *buf, struct blob_attr *networks, bool pre dev->hotplug_ops->prepare(dev); blobmsg_add_string(buf, "bridge", dev->ifname); + + if (dev->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST) + blobmsg_add_u8(buf, "multicast_to_unicast", + dev->settings.multicast_to_unicast); } static void |