[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 = {
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;
}
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);
}
}
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");
DEV_ATTR_RPS,
DEV_ATTR_XPS,
DEV_ATTR_DADTRANSMITS,
+ DEV_ATTR_MULTICAST_TO_UNICAST,
__DEV_ATTR_MAX,
};
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 */
bool rps;
bool xps;
unsigned int dadtransmits;
+ bool multicast_to_unicast;
};
/*
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
}
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");
}
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;
}
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