@@ -66,6 +66,7 @@ $(eval $(call add_command,mesh_json,y))
$(eval $(call add_command,multicast_fanout,y))
$(eval $(call add_command,multicast_forceflood,y))
$(eval $(call add_command,multicast_mode,y))
+$(eval $(call add_command,multicast_mld_rtr_only,y))
$(eval $(call add_command,neighbors,y))
$(eval $(call add_command,neighbors_json,y))
$(eval $(call add_command,network_coding,y))
@@ -669,6 +669,16 @@ Usage::
batctl multicast_forceflood|mff [0|1]
+batctl multicast_mld_rtr_only
+-----------------------------
+
+display or modify the multicast MLD router only setting
+
+Usage::
+
+ batctl multicast_mld_rtr_only|mro [0|1]
+
+
batctl network_coding
---------------------
@@ -481,6 +481,15 @@ enum batadv_nl_attrs {
*/
BATADV_ATTR_MULTICAST_FANOUT,
+ /**
+ * @BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED: defines how IGMP/MLD
+ * reports are forwarded in the mesh. If set to non-zero then IGMP/MLD
+ * reports are only forwarded to detected multicast routers. If set to
+ * zero then they are flooded instead.
+ * Warning: The former is experimental and potentially unsafe!
+ */
+ BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED,
+
/* add attributes above here, update the policy in netlink.c */
/**
@@ -283,6 +283,10 @@ static void event_parse_set_mesh(struct nlattr **attrs)
printf("* multicast_forceflood %s\n",
u8_to_boolstr(attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]));
+ if (attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED])
+ printf("* multicast_forceflood %s\n",
+ u8_to_boolstr(attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED]));
+
if (attrs[BATADV_ATTR_NETWORK_CODING_ENABLED])
printf("* network_coding %s\n",
u8_to_boolstr(attrs[BATADV_ATTR_NETWORK_CODING_ENABLED]));
@@ -341,6 +341,24 @@ disable multicast forceflood. This setting defines whether multicast optimizatio
flooding of multicast packets. If set to non-zero then all nodes in the mesh are going to use classic flooding for any
multicast packet with no optimizations.
.TP
+[\fBmeshif\fP \fInetdev\fP] \fBmulticast_mld_rtr_only\fP|\fBmro\fP [\fI0\fP|\fI1\fP]
+If no parameter is given the current multicast MLD router only setting is displayed. Otherwise the parameter is used to
+set the IGMP/MLD report forwarding behaviour. If enabled then MLD reports are forwarded to detected multicast routers only.
+If disabled then they are flooded instead.
+
+.br
+.br
+Warning: Enabling this is experimental and potentially unsafe!
+
+.br
+.br
+If the IGMP/MLD querier is configured directly on the bridge on top of
+bat0. But there is no multicast router on or behind this node. Then this
+bridge will be unable to detect multicast listeners on/behind other
+nodes which have the MLD-RTR-ONLY setting enabled. (A workaround for this
+can then in turn be to set multicast_router=2 on the bat0 bridge port
+on the node with the IGMP/MLD querier.)
+.TP
[\fBmeshif\fP \fInetdev\fP] \fBnetwork_coding\fP|\fBnc\fP [\fI0\fP|\fI1\fP]
If no parameter is given the current network coding mode setting is displayed. Otherwise the parameter is used to enable or
disable network coding.
new file mode 100644
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing <linus.luessing@c0d3.blue>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include "main.h"
+
+#include <errno.h>
+#include <linux/genetlink.h>
+#include <netlink/genl/genl.h>
+
+#include "batman_adv.h"
+#include "netlink.h"
+#include "sys.h"
+
+static struct simple_boolean_data multicast_mld_rtr_only;
+
+static int print_multicast_mld_rtr_only(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *attrs[BATADV_ATTR_MAX + 1];
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ struct genlmsghdr *ghdr;
+ int *result = arg;
+
+ if (!genlmsg_valid_hdr(nlh, 0))
+ return NL_OK;
+
+ ghdr = nlmsg_data(nlh);
+
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+ genlmsg_len(ghdr), batadv_netlink_policy)) {
+ return NL_OK;
+ }
+
+ if (!attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED])
+ return NL_OK;
+
+ printf("%s\n", nla_get_u8(attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED]) ? "enabled" : "disabled");
+
+ *result = 0;
+ return NL_STOP;
+}
+
+static int get_multicast_mld_rtr_only(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_GET_MESH,
+ NULL, print_multicast_mld_rtr_only);
+}
+
+static int set_attrs_multicast_mld_rtr_only(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+ struct settings_data *settings = state->cmd->arg;
+ struct simple_boolean_data *data = settings->data;
+
+ if (data->val)
+ printf("Warning: MLD-RTR-ONLY is experimental and has known, broken scenarios\n");
+
+ nla_put_u8(msg, BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED, data->val);
+
+ return 0;
+}
+
+static int set_multicast_mld_rtr_only(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_SET_MESH,
+ set_attrs_multicast_mld_rtr_only, NULL);
+}
+
+static struct settings_data batctl_settings_multicast_mld_rtr_only = {
+ .data = &multicast_mld_rtr_only,
+ .parse = parse_simple_boolean,
+ .netlink_get = get_multicast_mld_rtr_only,
+ .netlink_set = set_multicast_mld_rtr_only,
+};
+
+COMMAND_NAMED(SUBCOMMAND_MIF, multicast_mld_rtr_only, "mro", handle_sys_setting,
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+ &batctl_settings_multicast_mld_rtr_only,
+ "[0|1] \tdisplay or modify multicast_mld_rtr_only setting");