summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@c0d3.blue>2015-08-23 17:19:27 +0200
committerFelix Fietkau <nbd@openwrt.org>2015-08-25 08:46:30 +0200
commit1488a64acb77f721fc10d90b0453d95b488460e1 (patch)
treed3a3849cfc1d0cbfc467dba7b3ee7fff7e56282e
parent827145f01d849c663f18e356157fd71f1a7cc45d (diff)
bridge: Allow setting multicast_to_unicast option
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@c0d3.blue>
-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