This patch adds an option for the new multicast_mld_rtr_only setting in
batman-adv.

Signed-off-by: Linus Lüssing <[email protected]>
---
 Makefile                 |  1 +
 README.rst               | 10 +++++
 batman_adv.h             |  9 +++++
 event.c                  |  4 ++
 man/batctl.8             | 18 +++++++++
 multicast_mld_rtr_only.c | 83 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 125 insertions(+)
 create mode 100644 multicast_mld_rtr_only.c

diff --git a/Makefile b/Makefile
index c1212c444971..9e6f535c7816 100755
--- a/Makefile
+++ b/Makefile
@@ -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))
diff --git a/README.rst b/README.rst
index 3495fba02e0e..63b16b0f66af 100644
--- a/README.rst
+++ b/README.rst
@@ -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
 ---------------------
 
diff --git a/batman_adv.h b/batman_adv.h
index 35dc016c9bb4..11cd170036ff 100644
--- a/batman_adv.h
+++ b/batman_adv.h
@@ -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 */
 
        /**
diff --git a/event.c b/event.c
index 274f99fcb65a..14700ea57ae0 100644
--- a/event.c
+++ b/event.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]));
diff --git a/man/batctl.8 b/man/batctl.8
index b5be0b801708..9d830907ac7f 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -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.
diff --git a/multicast_mld_rtr_only.c b/multicast_mld_rtr_only.c
new file mode 100644
index 000000000000..599f96fb2375
--- /dev/null
+++ b/multicast_mld_rtr_only.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing <[email protected]>
+ *
+ * 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");
-- 
2.45.2

Reply via email to