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 ++