summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--device.c9
-rw-r--r--device.h3
-rw-r--r--scripts/netifd-wireless.sh1
-rw-r--r--system-linux.c13
-rw-r--r--wireless.c4
5 files changed, 26 insertions, 4 deletions
diff --git a/device.c b/device.c
index 66eb6d4..3768773 100644
--- a/device.c
+++ b/device.c
@@ -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");
diff --git a/device.h b/device.h
index 77ebe84..c31399c 100644
--- a/device.h
+++ b/device.h
@@ -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;
}
diff --git a/wireless.c b/wireless.c
index 337f563..d0d2942 100644
--- a/wireless.c
+++ b/wireless.c
@@ -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