This patch hides the multicast_mode setting in the UI and adds a new multicast_forceflood command. multicast_forceflood is basically the inverse of the current multicast_mode setting.
For the netlink config additions to batman-adv "multicast_mode" was not added. Instead a "multicast_forceflood" attribute was introduced.
The multicast_mode batctl command is kept for compatibility for now but should be removed eventually.
Signed-off-by: Linus Lüssing linus.luessing@c0d3.blue --- Makefile | 1 + README.rst | 8 ++--- functions.c | 16 ++++++++- functions.h | 1 + main.c | 3 ++ main.h | 1 + man/batctl.8 | 8 +++-- multicast_forceflood.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ multicast_mode.c | 3 +- sys.c | 30 +++++++++++++--- 10 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 multicast_forceflood.c
diff --git a/Makefile b/Makefile index 4d8b709..7c050c0 100755 --- a/Makefile +++ b/Makefile @@ -68,6 +68,7 @@ $(eval $(call add_command,isolation_mark,y)) $(eval $(call add_command,log,y)) $(eval $(call add_command,loglevel,y)) $(eval $(call add_command,mcast_flags,y)) +$(eval $(call add_command,multicast_forceflood,y)) $(eval $(call add_command,multicast_mode,y)) $(eval $(call add_command,nc_nodes,y)) $(eval $(call add_command,neighbors,y)) diff --git a/README.rst b/README.rst index 4c0f544..6db68d7 100644 --- a/README.rst +++ b/README.rst @@ -468,14 +468,14 @@ Usage:: Note that network coding requires a working promiscuous mode on all interfaces.
-batctl multicast_mode -===================== +batctl multicast_forceflood +===========================
-display or modify the multicast mode setting +display or modify the multicast forceflood setting
Usage::
- batctl multicast_mode|mm [0|1] + batctl multicast_forceflood|mff [0|1]
batctl mcast_flags diff --git a/functions.c b/functions.c index 76deab7..a202969 100644 --- a/functions.c +++ b/functions.c @@ -175,6 +175,16 @@ static bool ether_addr_valid(const uint8_t *addr) return true; }
+static void print_inv_bool(char *line) +{ + if (!strncmp("enabled", line, strlen("enabled"))) + printf("disabled\n"); + else if (!strncmp("disabled", line, strlen("disabled"))) + printf("enabled\n"); + else + printf("%s", line); +} + int read_file(const char *dir, const char *fname, int read_opt, float orig_timeout, float watch_interval, size_t header_lines) { @@ -237,7 +247,11 @@ int read_file(const char *dir, const char *fname, int read_opt, continue;
if (!(read_opt & USE_BAT_HOSTS)) { - printf("%s", line_ptr); + if (read_opt & INVERSE_BOOL) + print_inv_bool(line_ptr); + else + printf("%s", line_ptr); + continue; }
diff --git a/functions.h b/functions.h index e2bbb4e..b3f2159 100644 --- a/functions.h +++ b/functions.h @@ -91,6 +91,7 @@ enum { SKIP_HEADER = 0x100, UNICAST_ONLY = 0x200, MULTICAST_ONLY = 0x400, + INVERSE_BOOL = 0x800, };
#endif diff --git a/main.c b/main.c index 2a28642..199c7a4 100644 --- a/main.c +++ b/main.c @@ -74,6 +74,9 @@ static void print_usage(void) if (cmd->type != type[i]) continue;
+ if (!cmd->usage) + continue; + if (strcmp(cmd->name, cmd->abbr) == 0) snprintf(buf, sizeof(buf), "%s", cmd->name); else diff --git a/main.h b/main.h index fca2a32..92d0e61 100644 --- a/main.h +++ b/main.h @@ -67,6 +67,7 @@ extern char module_ver_path[]; enum command_flags { COMMAND_FLAG_MESH_IFACE = BIT(0), COMMAND_FLAG_NETLINK = BIT(1), + COMMAND_FLAG_INVERSE = BIT(2), };
enum command_type { diff --git a/man/batctl.8 b/man/batctl.8 index ed8e71f..695067f 100644 --- a/man/batctl.8 +++ b/man/batctl.8 @@ -101,9 +101,11 @@ disable fragmentation. If no parameter is given the current network coding mode setting is displayed. Otherwise the parameter is used to enable or disable network coding. .br -.IP "\fBmulticast_mode\fP|\fBmm\fP [\fB0\fP|\fB1\fP]" -If no parameter is given the current multicast mode setting is displayed. Otherwise the parameter is used to enable or -disable multicast optimizations (i.e. disabling means always sending own multicast frames via classic flooding). +.IP "\fBmulticast_forceflood\fP|\fBmff\fP [\fB0\fP|\fB1\fP]" +If no parameter is given the current multicast forceflood setting is displayed. Otherwise the parameter is used to enable or +disable multicast forceflood. This setting defines whether multicast optimizations should be replaced by simple broadcast-like +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. .br .IP "\fBloglevel\fP|\fBll\fP [\fBlevel\fP[ \fBlevel\fP[ \fBlevel\fP]] \fB...\fP]" If no parameter is given the current log level settings are displayed otherwise the parameter(s) is/are used to set the log diff --git a/multicast_forceflood.c b/multicast_forceflood.c new file mode 100644 index 0000000..daaa6d0 --- /dev/null +++ b/multicast_forceflood.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors: + * + * Linus Lüssing linus.luessing@c0d3.blue + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * 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_forceflood; + +static int print_multicast_forceflood(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_FORCEFLOOD_ENABLED]) + return NL_OK; + + printf("%s\n", nla_get_u8(attrs[BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED]) ? "enabled" : "disabled"); + + *result = 0; + return NL_STOP; +} + +static int get_multicast_forceflood(struct state *state) +{ + return sys_simple_nlquery(state, BATADV_CMD_GET_MESH, + NULL, print_multicast_forceflood); +} + +static int set_attrs_multicast_forceflood(struct nl_msg *msg, void *arg) +{ + struct state *state = arg; + struct settings_data *settings = state->cmd->arg; + struct simple_boolean_data *data = settings->data; + + nla_put_u8(msg, BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED, data->val); + + return 0; +} + +static int set_multicast_forceflood(struct state *state) +{ + return sys_simple_nlquery(state, BATADV_CMD_SET_MESH, + set_attrs_multicast_forceflood, NULL); +} + +static struct settings_data batctl_settings_multicast_forceflood = { + .sysfs_name = "multicast_mode", + .data = &multicast_forceflood, + .parse = parse_simple_boolean, + .netlink_get = get_multicast_forceflood, + .netlink_set = set_multicast_forceflood, +}; + +COMMAND_NAMED(SUBCOMMAND, multicast_forceflood, "mff", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK | COMMAND_FLAG_INVERSE, + &batctl_settings_multicast_forceflood, + "[0|1] \tdisplay or modify multicast_forceflood setting"); diff --git a/multicast_mode.c b/multicast_mode.c index 836a744..fb17586 100644 --- a/multicast_mode.c +++ b/multicast_mode.c @@ -91,5 +91,4 @@ static struct settings_data batctl_settings_multicast_mode = {
COMMAND_NAMED(SUBCOMMAND, multicast_mode, "mm", handle_sys_setting, COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, - &batctl_settings_multicast_mode, - "[0|1] \tdisplay or modify multicast_mode setting"); + &batctl_settings_multicast_mode, NULL); diff --git a/sys.c b/sys.c index 9a7966f..b0864cd 100644 --- a/sys.c +++ b/sys.c @@ -156,7 +156,8 @@ int sys_simple_print_boolean(struct nl_msg *msg, void *arg, static void settings_usage(struct state *state) { fprintf(stderr, "Usage: batctl [options] %s|%s [parameters] %s\n", - state->cmd->name, state->cmd->abbr, state->cmd->usage); + state->cmd->name, state->cmd->abbr, + state->cmd->usage ? state->cmd->usage : "");
fprintf(stderr, "parameters:\n"); fprintf(stderr, " \t -h print this help\n"); @@ -167,6 +168,7 @@ static int sys_read_setting(struct state *state, const char *path_buff, { struct settings_data *settings = state->cmd->arg; int res = EXIT_FAILURE; + int read_opt = NO_FLAGS;
if (settings->netlink_get) { res = settings->netlink_get(state); @@ -176,8 +178,12 @@ static int sys_read_setting(struct state *state, const char *path_buff, return EXIT_SUCCESS; }
- if (sysfs_name) - res = read_file(path_buff, sysfs_name, NO_FLAGS, 0, 0, 0); + if (sysfs_name) { + if (state->cmd->flags & COMMAND_FLAG_INVERSE) + read_opt |= INVERSE_BOOL; + + res = read_file(path_buff, sysfs_name, read_opt, 0, 0, 0); + }
return res; } @@ -187,6 +193,7 @@ static int sys_write_setting(struct state *state, const char *path_buff, { struct settings_data *settings = state->cmd->arg; int res = EXIT_FAILURE; + char *argv1 = argv[1];
if (settings->netlink_set) { res = settings->netlink_set(state); @@ -196,9 +203,22 @@ static int sys_write_setting(struct state *state, const char *path_buff, return EXIT_SUCCESS; }
- if (sysfs_name) + if (sysfs_name) { + if (state->cmd->flags & COMMAND_FLAG_INVERSE) { + if (!strncmp("0", argv[1], strlen("0")) || + !strncmp("disable", argv[1], strlen("disable")) || + !strncmp("disabled", argv[1], strlen("disabled"))) { + argv1 = "enabled"; + } else if (!strncmp("1", argv[1], strlen("1")) || + !strncmp("enable", argv[1], strlen("enable")) || + !strncmp("enabled", argv[1], strlen("enabled"))) { + argv1 = "disabled"; + } + } + res = write_file(path_buff, sysfs_name, - argv[1], argc > 2 ? argv[2] : NULL); + argv1, argc > 2 ? argv[2] : NULL); + }
return res; }