batctl: upgrade package to latest release 2019.3

* add tcpdump support for MCAST TVLV, unicast fragments and coded packets
* implement support for multicast RTR flags
* avoid some kernel deprecation warning by using more generic netlink over
  sysfs
* use type specific prefixes to select mesh interface or vlan instead of '-m'
* add support for hardif specific settings

Signed-off-by: Sven Eckelmann <sven@narfation.org>
This commit is contained in:
Sven Eckelmann 2019-08-01 17:44:55 +02:00
parent a74938ea46
commit a03d198516
5 changed files with 3 additions and 882 deletions

View File

@ -9,9 +9,9 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batctl
PKG_VERSION:=2019.2
PKG_RELEASE:=1
PKG_HASH:=fb656208ff7d4cd8b1b422f60c9e6d8747302a347cbf6c199d7afa9b80f80ea3
PKG_VERSION:=2019.3
PKG_RELEASE:=0
PKG_HASH:=2bd93fa14925a8dc63a67e64266c8ccd2fa3ac44b10253d93e6f8a630350070c
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)

View File

@ -1,324 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:14 +0200
Subject: batctl: Make vlan setting explicit
The requirement to have a VLAN master device on top of the batadv mesh
interface is artificially limiting the capabilities of batctl. Not all
master devices in linux which register a VLAN are from type "vlan" and are
only registering a single VLAN.
For example VLAN aware bridges can create multiple VLANs. These require
that the VLAN is identified using the VID and not the vlan device.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17947/
diff --git a/ap_isolation.c b/ap_isolation.c
index 71dcd00eac845d488c4969b17e1339f181c6c913..7c34649225dcc9cc557cc5bb4cbfa2343f8c0763 100644
--- a/ap_isolation.c
+++ b/ap_isolation.c
@@ -81,3 +81,8 @@ COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting,
COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
&batctl_settings_ap_isolation,
"[0|1] \tdisplay or modify ap_isolation setting");
+
+COMMAND_NAMED(SUBCOMMAND_VID, ap_isolation, "ap", handle_sys_setting,
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+ &batctl_settings_ap_isolation,
+ "[0|1] \tdisplay or modify ap_isolation setting for vlan device or id");
diff --git a/main.c b/main.c
index 278683c6080e3ff4a9f3225931d0c5eb44f89595..6ca13ac0ec4c82ee969be04737a339fd702b52bd 100644
--- a/main.c
+++ b/main.c
@@ -28,48 +28,75 @@ extern const struct command *__stop___command[];
static void print_usage(void)
{
- enum command_type type[] = {
- SUBCOMMAND,
- DEBUGTABLE,
+ struct {
+ const char *label;
+ uint32_t types;
+ } type[] = {
+ {
+ .label = "commands:\n",
+ .types = BIT(SUBCOMMAND) |
+ BIT(SUBCOMMAND_VID),
+ },
+ {
+ .label = "debug tables: \tdisplay the corresponding debug table\n",
+ .types = BIT(DEBUGTABLE),
+ },
+ };
+ const char *default_prefixes[] = {
+ "",
+ NULL,
+ };
+ const char *vlan_prefixes[] = {
+ "vlan <vdev> ",
+ "vid <vid> ",
+ NULL,
};
const struct command **p;
- char buf[32];
+ const char **prefixes;
+ const char **prefix;
+ char buf[64];
size_t i;
fprintf(stderr, "Usage: batctl [options] command|debug table [parameters]\n");
fprintf(stderr, "options:\n");
- fprintf(stderr, " \t-m mesh interface or VLAN created on top of a mesh interface (default 'bat0')\n");
+ fprintf(stderr, " \t-m mesh interface (default 'bat0')\n");
fprintf(stderr, " \t-h print this help (or 'batctl <command|debug table> -h' for the parameter help)\n");
fprintf(stderr, " \t-v print version\n");
for (i = 0; i < sizeof(type) / sizeof(*type); i++) {
fprintf(stderr, "\n");
- switch (type[i]) {
- case SUBCOMMAND:
- fprintf(stderr, "commands:\n");
- break;
- case DEBUGTABLE:
- fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n");
- break;
- }
+ fprintf(stderr, "%s", type[i].label);
for (p = __start___command; p < __stop___command; p++) {
const struct command *cmd = *p;
- if (cmd->type != type[i])
+ if (!(BIT(cmd->type) & type[i].types))
continue;
if (!cmd->usage)
continue;
- if (strcmp(cmd->name, cmd->abbr) == 0)
- snprintf(buf, sizeof(buf), "%s", cmd->name);
- else
- snprintf(buf, sizeof(buf), "%s|%s", cmd->name,
- cmd->abbr);
+ switch (cmd->type) {
+ case SUBCOMMAND_VID:
+ prefixes = vlan_prefixes;
+ break;
+ default:
+ prefixes = default_prefixes;
+ break;
+ }
- fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage);
+ for (prefix = &prefixes[0]; *prefix; prefix++) {
+ if (strcmp(cmd->name, cmd->abbr) == 0)
+ snprintf(buf, sizeof(buf), "%s%s",
+ *prefix, cmd->name);
+ else
+ snprintf(buf, sizeof(buf), "%s%s|%s",
+ *prefix, cmd->name, cmd->abbr);
+
+ fprintf(stderr, " \t%-35s%s\n", buf,
+ cmd->usage);
+ }
}
}
}
@@ -93,13 +120,19 @@ static void version(void)
exit(EXIT_SUCCESS);
}
-static const struct command *find_command(const char *name)
+static const struct command *find_command(struct state *state, const char *name)
{
const struct command **p;
for (p = __start___command; p < __stop___command; p++) {
const struct command *cmd = *p;
+ if (state->vid >= 0 && cmd->type != SUBCOMMAND_VID)
+ continue;
+
+ if (state->vid < 0 && cmd->type == SUBCOMMAND_VID)
+ continue;
+
if (strcmp(cmd->name, name) == 0)
return cmd;
@@ -110,6 +143,51 @@ static const struct command *find_command(const char *name)
return NULL;
}
+static int parse_dev_args(struct state *state, int argc, char *argv[])
+{
+ unsigned long vid;
+ char *endptr;
+
+ /* not enough arguments to parse */
+ if (argc < 2) {
+ translate_mesh_iface(state);
+ return 0;
+ }
+
+ if (strcmp(argv[0], "vid") == 0) {
+ if (argv[1] == '\0') {
+ fprintf(stderr, "Error - unparsable vid\n");
+ return -EINVAL;
+ }
+
+ vid = strtoul(argv[1], &endptr, 0);
+ if (!endptr || *endptr != '\0') {
+ fprintf(stderr, "Error - unparsable vid\n");
+ return -EINVAL;
+ }
+
+ if (vid > 4095) {
+ fprintf(stderr, "Error - too large vid (max 4095)\n");
+ return -ERANGE;
+ }
+
+ /* get mesh interface and overwrite vid afterwards */
+ translate_mesh_iface(state);
+ state->vid = vid;
+
+ return 2;
+ } else if (strcmp(argv[0], "vlan") == 0) {
+ state->arg_iface = argv[1];
+ translate_mesh_iface(state);
+
+ return 2;
+ } else {
+ /* parse vlan as part of -m parameter */
+ translate_mesh_iface(state);
+ return 0;
+ }
+}
+
int main(int argc, char **argv)
{
const struct command *cmd;
@@ -117,6 +195,7 @@ int main(int argc, char **argv)
.arg_iface = mesh_dfl_iface,
.cmd = NULL,
};
+ int dev_arguments;
int opt;
int ret;
@@ -152,7 +231,15 @@ int main(int argc, char **argv)
argc -= optind;
optind = 0;
- cmd = find_command(argv[0]);
+ /* parse arguments to identify vlan, ... */
+ dev_arguments = parse_dev_args(&state, argc, argv);
+ if (dev_arguments < 0)
+ goto err;
+
+ argv += dev_arguments;
+ argc -= dev_arguments;
+
+ cmd = find_command(&state, argv[0]);
if (!cmd) {
fprintf(stderr,
"Error - no valid command or debug table specified: %s\n",
@@ -162,8 +249,6 @@ int main(int argc, char **argv)
state.cmd = cmd;
- translate_mesh_iface(&state);
-
if (cmd->flags & COMMAND_FLAG_MESH_IFACE &&
check_mesh_iface(&state) < 0) {
fprintf(stderr,
diff --git a/main.h b/main.h
index 1a4701513c49ad8974b9c9189619f5dde622acd4..1d952610aefb8367bd52e24bea8c04c3d70b94ea 100644
--- a/main.h
+++ b/main.h
@@ -58,6 +58,7 @@ enum command_flags {
enum command_type {
SUBCOMMAND,
+ SUBCOMMAND_VID,
DEBUGTABLE,
};
@@ -84,7 +85,7 @@ struct command {
};
#define COMMAND_NAMED(_type, _name, _abbr, _handler, _flags, _arg, _usage) \
- static const struct command command_ ## _name = { \
+ static const struct command command_ ## _name ## _ ## _type = { \
.type = (_type), \
.name = (#_name), \
.abbr = _abbr, \
@@ -93,8 +94,8 @@ struct command {
.arg = (_arg), \
.usage = (_usage), \
}; \
- static const struct command *__command_ ## _name \
- __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
+ static const struct command *__command_ ## _name ## _ ## _type \
+ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name ## _ ## _type
#define COMMAND(_type, _handler, _abbr, _flags, _arg, _usage) \
COMMAND_NAMED(_type, _handler, _abbr, _handler, _flags, _arg, _usage)
diff --git a/man/batctl.8 b/man/batctl.8
index 0b430313075b5a7a4c796eba0867954e10061002..acb4288c4e6f59b322d20631ef8e3aee6f2215e5 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -68,7 +68,7 @@ free all attached interfaces and remove batman-adv interface.
If no parameter is given the current originator interval setting is displayed otherwise the parameter is used to set the
originator interval. The interval is in units of milliseconds.
.br
-.IP "\fBap_isolation\fP|\fBap\fP [\fB0\fP|\fB1\fP]"
+.IP "[\fBvlan <vdev>\fP|\fBvid <vid>\fP] \fBap_isolation\fP|\fBap\fP [\fB0\fP|\fB1\fP]"
If no parameter is given the current ap isolation setting is displayed. Otherwise the parameter is used to enable or
disable ap isolation. This command can be used in conjunction with "\-m" option to target per VLAN configurations.
.br
diff --git a/sys.c b/sys.c
index 39123db87d391b8898b7454eba7708515bfb3c78..f19719cfad61f36f2a5c1078305de83eb5be142a 100644
--- a/sys.c
+++ b/sys.c
@@ -141,9 +141,35 @@ 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->usage : "");
+ const char *default_prefixes[] = {
+ "",
+ NULL,
+ };
+ const char *vlan_prefixes[] = {
+ "vlan <vdev> ",
+ "vid <vid> ",
+ NULL,
+ };
+ const char *linestart = "Usage:";
+ const char **prefixes;
+ const char **prefix;
+
+ switch (state->cmd->type) {
+ case SUBCOMMAND_VID:
+ prefixes = vlan_prefixes;
+ break;
+ default:
+ prefixes = default_prefixes;
+ break;
+ }
+
+ for (prefix = &prefixes[0]; *prefix; prefix++) {
+ fprintf(stderr, "%s batctl [options] %s%s|%s [parameters] %s\n",
+ linestart, *prefix, state->cmd->name, state->cmd->abbr,
+ state->cmd->usage ? state->cmd->usage : "");
+
+ linestart = " ";
+ }
fprintf(stderr, "parameters:\n");
fprintf(stderr, " \t -h print this help\n");

View File

@ -1,183 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:15 +0200
Subject: batctl: Integrate hardif setting framework
batctl currently supports settings which are either mesh interface or vlan
specific. But B.A.T.M.A.N. V introduced two additional settings which are
hard (slave) interface specific.
To support these, an additional command prefix called hardif is implemented
for some sysfs commands:
$ batctl -m bat0 hardif eth0 ...
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17948/
diff --git a/main.c b/main.c
index 6ca13ac0ec4c82ee969be04737a339fd702b52bd..c806dbf4373fd082ff368cba391bdf14eebf4eae 100644
--- a/main.c
+++ b/main.c
@@ -35,7 +35,8 @@ static void print_usage(void)
{
.label = "commands:\n",
.types = BIT(SUBCOMMAND) |
- BIT(SUBCOMMAND_VID),
+ BIT(SUBCOMMAND_VID) |
+ BIT(SUBCOMMAND_HIF),
},
{
.label = "debug tables: \tdisplay the corresponding debug table\n",
@@ -51,6 +52,10 @@ static void print_usage(void)
"vid <vid> ",
NULL,
};
+ const char *hardif_prefixes[] = {
+ "hardif <netdev> ",
+ NULL,
+ };
const struct command **p;
const char **prefixes;
const char **prefix;
@@ -81,6 +86,9 @@ static void print_usage(void)
case SUBCOMMAND_VID:
prefixes = vlan_prefixes;
break;
+ case SUBCOMMAND_HIF:
+ prefixes = hardif_prefixes;
+ break;
default:
prefixes = default_prefixes;
break;
@@ -133,6 +141,12 @@ static const struct command *find_command(struct state *state, const char *name)
if (state->vid < 0 && cmd->type == SUBCOMMAND_VID)
continue;
+ if (state->hif > 0 && cmd->type != SUBCOMMAND_HIF)
+ continue;
+
+ if (state->hif == 0 && cmd->type == SUBCOMMAND_HIF)
+ continue;
+
if (strcmp(cmd->name, name) == 0)
return cmd;
@@ -180,6 +194,18 @@ static int parse_dev_args(struct state *state, int argc, char *argv[])
state->arg_iface = argv[1];
translate_mesh_iface(state);
+ return 2;
+ } else if (strcmp(argv[0], "hardif") == 0) {
+ state->hif = if_nametoindex(argv[1]);
+ if (state->hif == 0) {
+ fprintf(stderr, "Error - hard interface not found\n");
+ return -ENODEV;
+ }
+
+ snprintf(state->hard_iface, sizeof(state->hard_iface), "%s",
+ argv[1]);
+
+ translate_mesh_iface(state);
return 2;
} else {
/* parse vlan as part of -m parameter */
@@ -193,6 +219,7 @@ int main(int argc, char **argv)
const struct command *cmd;
struct state state = {
.arg_iface = mesh_dfl_iface,
+ .hif = 0,
.cmd = NULL,
};
int dev_arguments;
diff --git a/main.h b/main.h
index 1d952610aefb8367bd52e24bea8c04c3d70b94ea..a27d8486ef689206b27b1b50cb017b1b740e91c9 100644
--- a/main.h
+++ b/main.h
@@ -59,6 +59,7 @@ enum command_flags {
enum command_type {
SUBCOMMAND,
SUBCOMMAND_VID,
+ SUBCOMMAND_HIF,
DEBUGTABLE,
};
@@ -66,6 +67,8 @@ struct state {
char *arg_iface;
char mesh_iface[IF_NAMESIZE];
unsigned int mesh_ifindex;
+ char hard_iface[IF_NAMESIZE];
+ unsigned int hif;
int vid;
const struct command *cmd;
diff --git a/sys.c b/sys.c
index f19719cfad61f36f2a5c1078305de83eb5be142a..fd34b2fa3bcf168a32bd53fc0df3f35d5532433f 100644
--- a/sys.c
+++ b/sys.c
@@ -150,6 +150,10 @@ static void settings_usage(struct state *state)
"vid <vid> ",
NULL,
};
+ const char *hardif_prefixes[] = {
+ "hardif <netdev> ",
+ NULL,
+ };
const char *linestart = "Usage:";
const char **prefixes;
const char **prefix;
@@ -158,6 +162,9 @@ static void settings_usage(struct state *state)
case SUBCOMMAND_VID:
prefixes = vlan_prefixes;
break;
+ case SUBCOMMAND_HIF:
+ prefixes = hardif_prefixes;
+ break;
default:
prefixes = default_prefixes;
break;
@@ -259,15 +266,23 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
return EXIT_FAILURE;
}
- /* if the specified interface is a VLAN then change the path to point
- * to the proper "vlan%{vid}" subfolder in the sysfs tree.
- */
- if (state->vid >= 0)
+ if (state->hif > 0) {
+ /* if a hard interface was specified then change the path to
+ * point to the proper ${hardif}/batman-adv path in the sysfs
+ * tree.
+ */
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_HARDIF_PATH,
+ state->hard_iface);
+ } else if (state->vid >= 0) {
+ /* if the specified interface is a VLAN then change the path to
+ * point to the proper "vlan%{vid}" subfolder in the sysfs tree.
+ */
snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
state->mesh_iface, state->vid);
- else
+ } else {
snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT,
state->mesh_iface);
+ }
if (argc == 1) {
res = sys_read_setting(state, path_buff, settings->sysfs_name);
diff --git a/sys.h b/sys.h
index d4f2fcf542bc66b2b1c6ec55a9ac16e10fdc5cac..b6f0f9043a9af8e3c4d4f8bf7e4af4cab0aa5df9 100644
--- a/sys.h
+++ b/sys.h
@@ -21,8 +21,9 @@
#define SYS_BATIF_PATH_FMT "/sys/class/net/%s/mesh/"
#define SYS_IFACE_PATH "/sys/class/net"
#define SYS_IFACE_DIR SYS_IFACE_PATH"/%s/"
-#define SYS_MESH_IFACE_FMT SYS_IFACE_PATH"/%s/batman_adv/mesh_iface"
-#define SYS_IFACE_STATUS_FMT SYS_IFACE_PATH"/%s/batman_adv/iface_status"
+#define SYS_HARDIF_PATH SYS_IFACE_DIR "batman_adv/"
+#define SYS_MESH_IFACE_FMT SYS_HARDIF_PATH "mesh_iface"
+#define SYS_IFACE_STATUS_FMT SYS_HARDIF_PATH "iface_status"
#define SYS_VLAN_PATH SYS_IFACE_PATH"/%s/mesh/vlan%d/"
#define SYS_ROUTING_ALGO_FMT SYS_IFACE_PATH"/%s/mesh/routing_algo"
#define VLAN_ID_MAX_LEN 4

View File

@ -1,183 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:16 +0200
Subject: batctl: Add elp_interval setting command
B.A.T.M.A.N. V introduced a hard interface specific setting called
elp_interval. It defines the interval in milliseconds in which batman-adv
emits probing packets for neighbor sensing (ELP).
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17949/
diff --git a/Makefile b/Makefile
index b7bd545e92963c62128efe60c0dc401bdd9fa023..f071da20f866bff6c162d697d2e43fa9d68ee08d 100755
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ $(eval $(call add_command,bridge_loop_avoidance,y))
$(eval $(call add_command,claimtable,y))
$(eval $(call add_command,dat_cache,y))
$(eval $(call add_command,distributed_arp_table,y))
+$(eval $(call add_command,elp_interval,y))
$(eval $(call add_command,event,y))
$(eval $(call add_command,fragmentation,y))
$(eval $(call add_command,gateways,y))
diff --git a/README.rst b/README.rst
index bc54412bc77dae1889d4f05298c34efc1966776b..92983aa6030e2a890283bca448b9203cd4d56b51 100644
--- a/README.rst
+++ b/README.rst
@@ -386,6 +386,22 @@ Example::
1000
+batctl elp interval
+===================
+
+display or modify the elp interval in ms for hard interface
+
+Usage::
+
+ batctl hardif $hardif elp_interval|et [interval]
+
+Example::
+
+ $ batctl hardif eth0 elp_interval 200
+ $ batctl hardif eth0 elp_interval
+ 200
+
+
batctl loglevel
===============
diff --git a/elp_interval.c b/elp_interval.c
new file mode 100644
index 0000000000000000000000000000000000000000..0a5e98923a622f52e523696b1ec1bfb856eeca9f
--- /dev/null
+++ b/elp_interval.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "main.h"
+#include "sys.h"
+
+static struct elp_interval_data {
+ uint32_t elp_interval;
+} elp_interval;
+
+static int parse_elp_interval(struct state *state, int argc, char *argv[])
+{
+ struct settings_data *settings = state->cmd->arg;
+ struct elp_interval_data *data = settings->data;
+ char *endptr;
+
+ if (argc != 2) {
+ fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
+ return -EINVAL;
+ }
+
+ data->elp_interval = strtoul(argv[1], &endptr, 0);
+ if (!endptr || *endptr != '\0') {
+ fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int print_elp_interval(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_ELP_INTERVAL])
+ return NL_OK;
+
+ printf("%u\n", nla_get_u32(attrs[BATADV_ATTR_ELP_INTERVAL]));
+
+ *result = 0;
+ return NL_STOP;
+}
+
+static int get_attrs_elp_interval(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
+
+ return 0;
+}
+
+static int get_elp_interval(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_GET_HARDIF,
+ get_attrs_elp_interval, print_elp_interval);
+}
+
+static int set_attrs_elp_interval(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+ struct settings_data *settings = state->cmd->arg;
+ struct elp_interval_data *data = settings->data;
+
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
+ nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, data->elp_interval);
+
+ return 0;
+}
+
+static int set_elp_interval(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_SET_HARDIF,
+ set_attrs_elp_interval, NULL);
+}
+
+static struct settings_data batctl_settings_elp_interval = {
+ .sysfs_name = "elp_interval",
+ .data = &elp_interval,
+ .parse = parse_elp_interval,
+ .netlink_get = get_elp_interval,
+ .netlink_set = set_elp_interval,
+};
+
+COMMAND_NAMED(SUBCOMMAND_HIF, elp_interval, "et", handle_sys_setting,
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+ &batctl_settings_elp_interval,
+ "[interval] \tdisplay or modify elp_interval setting");
diff --git a/man/batctl.8 b/man/batctl.8
index acb4288c4e6f59b322d20631ef8e3aee6f2215e5..690da023fd1ac6f51915a9167e92030a650fe1bd 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -93,6 +93,10 @@ the bonding mode.
batctl will monitor for events from the netlink kernel interface of batman-adv. The local timestamp of the event will be printed
when parameter \fB\-t\fP is specified. Parameter \fB\-r\fP will do the same but with relative timestamps.
.br
+.IP "\fBhardif <hardif>\fP \fBelp_interval\fP|\fBet\fP [\fBinterval\fP]"
+If no parameter is given the current ELP interval setting of the hard interface is displayed otherwise the parameter is used to set the
+ELP interval. The interval is in units of milliseconds.
+.br
.IP "\fBfragmentation\fP|\fBf\fP [\fB0\fP|\fB1\fP]"
If no parameter is given the current fragmentation mode setting is displayed. Otherwise the parameter is used to enable or
disable fragmentation.

View File

@ -1,189 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:17 +0200
Subject: batctl: Add throughput_override setting command
B.A.T.M.A.N. V introduced a hard interface specific setting called
throughput. It defines the throughput value to be used by B.A.T.M.A.N. V
when estimating the link throughput using this interface. If the value is
set to 0 then batman-adv will try to estimate the throughput by itself.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17950/
diff --git a/Makefile b/Makefile
index f071da20f866bff6c162d697d2e43fa9d68ee08d..e3747a2a28eb34323e34a1e22f5507dd1d7cd0f6 100755
--- a/Makefile
+++ b/Makefile
@@ -67,6 +67,7 @@ $(eval $(call add_command,ping,y))
$(eval $(call add_command,routing_algo,y))
$(eval $(call add_command,statistics,y))
$(eval $(call add_command,tcpdump,y))
+$(eval $(call add_command,throughput_override,y))
$(eval $(call add_command,throughputmeter,y))
$(eval $(call add_command,traceroute,y))
$(eval $(call add_command,transglobal,y))
diff --git a/README.rst b/README.rst
index 92983aa6030e2a890283bca448b9203cd4d56b51..128f539852fa085d023fb6d26ae436e76b617bb6 100644
--- a/README.rst
+++ b/README.rst
@@ -402,6 +402,23 @@ Example::
200
+batctl throughput override
+==========================
+
+display or modify the throughput override in kbit/s for hard interface
+
+Usage::
+
+ batctl hardif $hardif throughput_override|to [kbit]
+
+Example::
+
+ $ batctl hardif eth0 throughput_override 15000
+ $ batctl hardif eth0 throughput_override 15mbit
+ $ batctl hardif eth0 throughput_override
+ 15.0 MBit
+
+
batctl loglevel
===============
diff --git a/man/batctl.8 b/man/batctl.8
index 690da023fd1ac6f51915a9167e92030a650fe1bd..b8218963712bbf0cc9470459896fc904cd393748 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -203,6 +203,12 @@ supported routing algorithms are displayed.
Otherwise the parameter is used to select the routing algorithm for the following
batX interface to be created.
.br
+.IP "\fBhardif <hardif>\fP \fBthroughput_override|to\fP [\fBbandwidth\fP]\fP"
+If no parameter is given the current througput override is displayed otherwise
+the parameter is used to set the throughput override for the specified hard
+interface.
+Just enter any number (optionally followed by "kbit" or "mbit").
+.br
.IP "\fBisolation_mark\fP|\fBmark\fP"
If no parameter is given the current isolation mark value is displayed.
Otherwise the parameter is used to set or unset the isolation mark used by the
diff --git a/throughput_override.c b/throughput_override.c
new file mode 100644
index 0000000000000000000000000000000000000000..28a6588b9417cca213ebde3545a3eb425592ad89
--- /dev/null
+++ b/throughput_override.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "functions.h"
+#include "main.h"
+#include "sys.h"
+
+static struct throughput_override_data {
+ uint32_t throughput_override;
+} throughput_override;
+
+static int parse_throughput_override(struct state *state, int argc, char *argv[])
+{
+ struct settings_data *settings = state->cmd->arg;
+ struct throughput_override_data *data = settings->data;
+ bool ret;
+
+ if (argc != 2) {
+ fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
+ return -EINVAL;
+ }
+
+ ret = parse_throughput(argv[1], "throughput override",
+ &data->throughput_override);
+ if (!ret)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int print_throughput_override(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;
+ uint32_t mbit;
+
+ 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_THROUGHPUT_OVERRIDE])
+ return NL_OK;
+
+ mbit = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]);
+ printf("%u.%u MBit\n", mbit / 10, mbit % 10);
+
+ *result = 0;
+ return NL_STOP;
+}
+
+static int get_attrs_elp_isolation(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
+
+ return 0;
+}
+
+static int get_throughput_override(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_GET_HARDIF,
+ get_attrs_elp_isolation, print_throughput_override);
+}
+
+static int set_attrs_throughput_override(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+ struct settings_data *settings = state->cmd->arg;
+ struct throughput_override_data *data = settings->data;
+
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, state->hif);
+ nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE, data->throughput_override);
+
+ return 0;
+}
+
+static int set_throughput_override(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_SET_HARDIF,
+ set_attrs_throughput_override, NULL);
+}
+
+static struct settings_data batctl_settings_throughput_override = {
+ .sysfs_name = "throughput_override",
+ .data = &throughput_override,
+ .parse = parse_throughput_override,
+ .netlink_get = get_throughput_override,
+ .netlink_set = set_throughput_override,
+};
+
+COMMAND_NAMED(SUBCOMMAND_HIF, throughput_override, "to", handle_sys_setting,
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+ &batctl_settings_throughput_override,
+ "[mbit] \tdisplay or modify throughput_override setting");