From c8d3fcc185a46bdfee7f41d3bcfbbcbfc8694beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Tue, 26 Sep 2023 18:08:55 +0200 Subject: [PATCH] gluon-mesh-batman-adv-brmldproxy: avoid MLD report broadcasts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far batman-adv flooded all MLD reports. However in our use-case, with the limitations we already have (*) it is safe to send MLD reports to detected multicast routers only. This reduces MLD report overhead even further than brmldproxy alone already does. And in particular results in no MLD reports in the mesh if no multicast router is present. This should, after some more testing from others, potentially make the gluon-mesh-batman-adv-brmldproxy package suitable for being included by default. As overhead downsides should then be negligible. Note: This change to the MLD report forwarding behaviour is only applied if the gluon-mesh-batman-adv-brmldproxy is installed (and brmldproxy then not manually disabled). Otherwise these changes to batman-adv and batctl are unused. (*): non-Gluon nodes still need to manually set multicast_router=2 on the bat0 bridge port. Signed-off-by: Linus Lüssing --- .../files/lib/netifd/proto/gluon_bat0.sh | 3 + ...rd-MLD-reports-only-to-mcast-routers.patch | 288 ++++++++++++++++++ ...h-for-setting-multicast_mld_rtr_only.patch | 226 ++++++++++++++ 3 files changed, 517 insertions(+) create mode 100644 patches/packages/routing/0004-batman-adv-mcast-add-option-to-forward-MLD-reports-only-to-mcast-routers.patch create mode 100644 patches/packages/routing/0005-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch diff --git a/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh b/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh index 91ea0d35679..1ed252474cf 100755 --- a/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh +++ b/package/gluon-mesh-batman-adv/files/lib/netifd/proto/gluon_bat0.sh @@ -66,6 +66,9 @@ proto_gluon_bat0_setup() { ;; esac + [ -x /etc/init.d/brmldproxy ] && /etc/init.d/brmldproxy enabled && \ + batctl multicast_mld_rtr_only 1 + local primary0_mac="$(lua -e 'print(require("gluon.util").generate_mac(3))')" diff --git a/patches/packages/routing/0004-batman-adv-mcast-add-option-to-forward-MLD-reports-only-to-mcast-routers.patch b/patches/packages/routing/0004-batman-adv-mcast-add-option-to-forward-MLD-reports-only-to-mcast-routers.patch new file mode 100644 index 00000000000..1405c525327 --- /dev/null +++ b/patches/packages/routing/0004-batman-adv-mcast-add-option-to-forward-MLD-reports-only-to-mcast-routers.patch @@ -0,0 +1,288 @@ +From: Linus Lüssing +Date: Tue, 26 Sep 2023 17:55:43 +0200 +Subject: batman-adv: mcast: add option to forward MLD reports only to mcast routers + +In most setups it is sufficient for us to only send MLD reports to nodes +which have a multicast router attached. Which reduces overall overhead, +especially in large batman-adv mesh networks, where broadcasts are +particularly undesirable. + +However there is one specific, known issue / broken scenario with this +setting: + +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.) + +Therefore MLD report flooding is kept the default and MLD report to +multicast routers only forwarding is considered experimental and +warned about. + +Signed-off-by: Linus Lüssing + +diff --git a/batman-adv/patches/0035-batman-adv-mcast-add-option-to-forward-MLD-reports-o.patch b/batman-adv/patches/0035-batman-adv-mcast-add-option-to-forward-MLD-reports-o.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..47392c98d7950454e8096019fab04dee27ac1531 +--- /dev/null ++++ b/batman-adv/patches/0035-batman-adv-mcast-add-option-to-forward-MLD-reports-o.patch +@@ -0,0 +1,257 @@ ++From 67e5b92b81178cd87d8470f86e4f289c900d96a5 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Linus=20L=C3=BCssing?= ++Date: Tue, 26 Sep 2023 06:35:08 +0200 ++Subject: [PATCH] batman-adv: mcast: add option to forward MLD reports only to ++ mcast routers ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++In most setups it is sufficient for us to only send MLD reports to nodes ++which have a multicast router attached. Which reduces overall overhead, ++especially in large batman-adv mesh networks, where broadcasts are ++particularly undesirable. ++ ++However there is one specific, known issue / broken scenario with this ++setting: ++ ++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.) ++ ++Therefore MLD report flooding is kept the default and MLD report to ++multicast routers only forwarding is considered experimental and ++warned about. ++ ++Signed-off-by: Linus Lüssing ++--- ++ include/uapi/linux/batman_adv.h | 9 ++++++ ++ net/batman-adv/multicast.c | 52 +++++++++++++++++++++++++-------- ++ net/batman-adv/netlink.c | 17 +++++++++++ ++ net/batman-adv/soft-interface.c | 1 + ++ net/batman-adv/types.h | 7 +++++ ++ 5 files changed, 74 insertions(+), 12 deletions(-) ++ ++diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h ++index e5b62f6c35a2..885cc2482dc8 100644 ++--- a/include/uapi/linux/batman_adv.h +++++ b/include/uapi/linux/batman_adv.h ++@@ -493,6 +493,15 @@ enum batadv_nl_attrs { ++ */ ++ BATADV_ATTR_NOFLOOD_MASK, ++ +++ /** +++ * @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/net/batman-adv/multicast.c b/net/batman-adv/multicast.c ++index 7e8515bbf2e9..2c9467afdd99 100644 ++--- a/net/batman-adv/multicast.c +++++ b/net/batman-adv/multicast.c ++@@ -973,8 +973,14 @@ static int batadv_mcast_forw_mode_check_ipv4(struct batadv_priv *bat_priv, ++ if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*iphdr))) ++ return -ENOMEM; ++ ++- if (batadv_mcast_is_report_ipv4(skb)) +++ if (batadv_mcast_is_report_ipv4(skb)) { +++ if (atomic_read(&bat_priv->multicast_mld_rtr_only)) { +++ *is_routable = IGMP_HOST_MEMBERSHIP_REPORT; +++ return 0; +++ } +++ ++ return -EINVAL; +++ } ++ ++ iphdr = ip_hdr(skb); ++ ++@@ -1037,8 +1043,14 @@ static int batadv_mcast_forw_mode_check_ipv6(struct batadv_priv *bat_priv, ++ if (!pskb_may_pull(skb, sizeof(struct ethhdr) + sizeof(*ip6hdr))) ++ return -ENOMEM; ++ ++- if (batadv_mcast_is_report_ipv6(skb)) +++ if (batadv_mcast_is_report_ipv6(skb)) { +++ if (atomic_read(&bat_priv->multicast_mld_rtr_only)) { +++ *is_routable = ICMPV6_MGM_REPORT; +++ return 0; +++ } +++ ++ return -EINVAL; +++ } ++ ++ ip6hdr = ipv6_hdr(skb); ++ ++@@ -1125,17 +1137,19 @@ static int batadv_mcast_forw_want_all_ip_count(struct batadv_priv *bat_priv, ++ * @protocol: the ethernet protocol type to count multicast routers for ++ * ++ * Return: the number of nodes which want all routable IPv4 multicast traffic ++- * if the protocol is ETH_P_IP or the number of nodes which want all routable ++- * IPv6 traffic if the protocol is ETH_P_IPV6. Otherwise returns 0. +++ * if the protocol is ETH_P_IP or IGMP_HOST_MEMBERSHIP_REPORT. Or the number of +++ * nodes which want all routable IPv6 traffic if the protocol is ETH_P_IPV6 or +++ * ICMPV6_MGM_REPORT. Otherwise returns 0. ++ */ ++- ++ static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv, ++ int protocol) ++ { ++ switch (protocol) { ++ case ETH_P_IP: +++ case IGMP_HOST_MEMBERSHIP_REPORT: ++ return atomic_read(&bat_priv->mcast.num_want_all_rtr4); ++ case ETH_P_IPV6: +++ case ICMPV6_MGM_REPORT: ++ return atomic_read(&bat_priv->mcast.num_want_all_rtr6); ++ default: ++ return 0; ++@@ -1154,10 +1168,11 @@ enum batadv_forw_mode ++ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, ++ int *is_routable) ++ { ++- int ret, tt_count, ip_count, unsnoop_count, total_count; +++ atomic_t *unsnoop_cnt_atom = &bat_priv->mcast.num_want_all_unsnoopables; +++ int ret, ip_count, rtr_count, total_count; +++ int tt_count = 0, unsnoop_count = 0; ++ bool is_unsnoopable = false; ++ struct ethhdr *ethhdr; ++- int rtr_count = 0; ++ ++ ret = batadv_mcast_forw_mode_check(bat_priv, skb, &is_unsnoopable, ++ is_routable); ++@@ -1168,11 +1183,17 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, ++ ++ ethhdr = eth_hdr(skb); ++ ++- tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest, ++- BATADV_NO_FLAGS); ++- ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, ethhdr); ++- unsnoop_count = !is_unsnoopable ? 0 : ++- atomic_read(&bat_priv->mcast.num_want_all_unsnoopables); +++ if (*is_routable != IGMP_HOST_MEMBERSHIP_REPORT && +++ *is_routable != ICMPV6_MGM_REPORT) { +++ tt_count = batadv_tt_global_hash_count(bat_priv, ethhdr->h_dest, +++ BATADV_NO_FLAGS); +++ +++ if (is_unsnoopable) +++ unsnoop_count = atomic_read(unsnoop_cnt_atom); +++ } +++ +++ ip_count = batadv_mcast_forw_want_all_ip_count(bat_priv, +++ ethhdr); ++ rtr_count = batadv_mcast_forw_rtr_count(bat_priv, *is_routable); ++ ++ total_count = tt_count + ip_count + unsnoop_count + rtr_count; ++@@ -1462,8 +1483,10 @@ batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv, ++ { ++ switch (ntohs(eth_hdr(skb)->h_proto)) { ++ case ETH_P_IP: +++ case IGMP_HOST_MEMBERSHIP_REPORT: ++ return batadv_mcast_forw_want_all_rtr4(bat_priv, skb, vid); ++ case ETH_P_IPV6: +++ case ICMPV6_MGM_REPORT: ++ return batadv_mcast_forw_want_all_rtr6(bat_priv, skb, vid); ++ default: ++ /* we shouldn't be here... */ ++@@ -1493,12 +1516,17 @@ int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, ++ { ++ int ret; ++ +++ if (is_routable == IGMP_HOST_MEMBERSHIP_REPORT || +++ is_routable == ICMPV6_MGM_REPORT) +++ goto skip_mc_listeners; +++ ++ ret = batadv_mcast_forw_tt(bat_priv, skb, vid); ++ if (ret != NET_XMIT_SUCCESS) { ++ kfree_skb(skb); ++ return ret; ++ } ++ +++skip_mc_listeners: ++ ret = batadv_mcast_forw_want_all(bat_priv, skb, vid); ++ if (ret != NET_XMIT_SUCCESS) { ++ kfree_skb(skb); ++diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c ++index 7a7e41371a2f..b3a8752b5705 100644 ++--- a/net/batman-adv/netlink.c +++++ b/net/batman-adv/netlink.c ++@@ -149,6 +149,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { ++ [BATADV_ATTR_LOG_LEVEL] = { .type = NLA_U32 }, ++ [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NLA_U8 }, ++ [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NLA_U32 }, +++ [BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED] = { .type = NLA_U8 }, ++ [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NLA_U8 }, ++ [BATADV_ATTR_ORIG_INTERVAL] = { .type = NLA_U32 }, ++ [BATADV_ATTR_ELP_INTERVAL] = { .type = NLA_U32 }, ++@@ -357,6 +358,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg, ++ if (nla_put_u32(msg, BATADV_ATTR_MULTICAST_FANOUT, ++ atomic_read(&bat_priv->multicast_fanout))) ++ goto nla_put_failure; +++ +++ if (nla_put_u8(msg, BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED, +++ atomic_read(&bat_priv->multicast_mld_rtr_only))) +++ goto nla_put_failure; ++ #endif /* CONFIG_BATMAN_ADV_MCAST */ ++ ++ #ifdef CONFIG_BATMAN_ADV_NC ++@@ -615,6 +620,18 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info) ++ ++ atomic_set(&bat_priv->multicast_fanout, nla_get_u32(attr)); ++ } +++ +++ if (info->attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED]) { +++ u8 mld_rtr_only; +++ +++ attr = info->attrs[BATADV_ATTR_MULTICAST_MLD_RTR_ONLY_ENABLED]; +++ mld_rtr_only = !!nla_get_u8(attr); +++ if (mld_rtr_only) +++ batadv_info(bat_priv->soft_iface, +++ "Warning: MLD-RTR-ONLY is experimental and has known, broken scenarios\n"); +++ +++ atomic_set(&bat_priv->multicast_mld_rtr_only, mld_rtr_only); +++ } ++ #endif /* CONFIG_BATMAN_ADV_MCAST */ ++ ++ #ifdef CONFIG_BATMAN_ADV_NC ++diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c ++index 340e5a75c689..8949e8bbb81c 100644 ++--- a/net/batman-adv/soft-interface.c +++++ b/net/batman-adv/soft-interface.c ++@@ -779,6 +779,7 @@ static int batadv_softif_init_late(struct net_device *dev) ++ #ifdef CONFIG_BATMAN_ADV_MCAST ++ atomic_set(&bat_priv->multicast_mode, 1); ++ atomic_set(&bat_priv->multicast_fanout, 16); +++ atomic_set(&bat_priv->multicast_mld_rtr_only, 0); ++ atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); ++ atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); ++ atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); ++diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h ++index d92605579811..1f4709f54a29 100644 ++--- a/net/batman-adv/types.h +++++ b/net/batman-adv/types.h ++@@ -1613,6 +1613,13 @@ struct batadv_priv { ++ * multicast-to-unicast conversion ++ */ ++ atomic_t multicast_fanout; +++ +++ /** +++ * @multicast_mld_rtr_only: bool indicating whether to send IGMP/MLD +++ * reports only to multicast routers or to flood them otherwise. +++ * Warning: The former is experimental and potentially unsafe! +++ */ +++ atomic_t multicast_mld_rtr_only; ++ #endif ++ ++ /** @orig_interval: OGM broadcast interval in milliseconds */ ++-- ++2.40.1 ++ diff --git a/patches/packages/routing/0005-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch b/patches/packages/routing/0005-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch new file mode 100644 index 00000000000..e82b89c91b4 --- /dev/null +++ b/patches/packages/routing/0005-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch @@ -0,0 +1,226 @@ +From: Linus Lüssing +Date: Tue, 26 Sep 2023 17:58:22 +0200 +Subject: batctl: add switch for setting multicast_mld_rtr_only + +This patch adds an option for the new multicast_mld_rtr_only setting in +batman-adv. + +Signed-off-by: Linus Lüssing + +diff --git a/batctl/patches/0013-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch b/batctl/patches/0013-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..ec1a192840f87a19e9a45ebca7ac8f40236340c1 +--- /dev/null ++++ b/batctl/patches/0013-batctl-add-switch-for-setting-multicast_mld_rtr_only.patch +@@ -0,0 +1,211 @@ ++From 7b0ac996e5bf0060a62e05cae35c772de790e0d4 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Linus=20L=C3=BCssing?= ++Date: Tue, 26 Sep 2023 17:09:27 +0200 ++Subject: [PATCH] batctl: add switch for setting multicast_mld_rtr_only ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This patch adds an option for the new multicast_mld_rtr_only setting in ++batman-adv. ++ ++Signed-off-by: Linus Lüssing ++--- ++ 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 0610e3c8eb6d..8bb2c673be8e 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 0b0f62f30a7a..a00613ad800c 100644 ++--- a/README.rst +++++ b/README.rst ++@@ -673,6 +673,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 e5b62f6c35a2..885cc2482dc8 100644 ++--- a/batman_adv.h +++++ b/batman_adv.h ++@@ -493,6 +493,15 @@ enum batadv_nl_attrs { ++ */ ++ BATADV_ATTR_NOFLOOD_MASK, ++ +++ /** +++ * @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 +++ * +++ * License-Filename: LICENSES/preferred/GPL-2.0 +++ */ +++ +++#include "main.h" +++ +++#include +++#include +++#include +++ +++#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.40.1 ++