[OpenWrt-Devel] [PATCHv2 netifd 2/3] bridge: Allow setting multicast_to_unicast option

Linus Lüssing linus.luessing at c0d3.blue
Tue Aug 4 19:00:04 EDT 2015


With this patch the multicast_to_unicast feature can be disabled for all
wireless interfaces via an according option on the uci bridge interface.

This patch also exports the setting information to wireless handler
scripts. The hostapd script will need that information to determine
whether to enable or disable ap-isolation, for instance.

Signed-off-by: Linus Lüssing <linus.luessing at c0d3.blue>
---
 device.c                   |    9 +++++++++
 device.h                   |    3 +++
 scripts/netifd-wireless.sh |    1 +
 system-linux.c             |   13 +++++++++----
 wireless.c                 |    4 ++++
 5 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/device.c b/device.c
index b5bee11..b44ccb8 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);
 }
 
@@ -884,6 +891,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 373445c..4344d8a 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 c5d8a96..4d81929 100644
--- a/scripts/netifd-wireless.sh
+++ b/scripts/netifd-wireless.sh
@@ -260,6 +260,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
 			json_get_var _w_type mode
 			json_select ..
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
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list