diff --git a/batctl/Makefile b/batctl/Makefile index 850375d..7cbb9bd 100644 --- a/batctl/Makefile +++ b/batctl/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batctl PKG_VERSION:=2019.2 -PKG_RELEASE:=0 +PKG_RELEASE:=1 PKG_HASH:=fb656208ff7d4cd8b1b422f60c9e6d8747302a347cbf6c199d7afa9b80f80ea3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz @@ -112,6 +112,7 @@ config-n := \ claimtable \ dat_cache \ distributed_arp_table \ + elp_interval \ event \ fragmentation \ gateways \ @@ -133,6 +134,7 @@ config-n := \ routing_algo \ statistics \ tcpdump \ + throughput_override \ throughputmeter \ traceroute \ transglobal \ @@ -145,6 +147,7 @@ config-settings := \ bonding \ bridge_loop_avoidance \ distributed_arp_table \ + elp_interval \ fragmentation \ gw_mode \ hop_penalty \ @@ -157,6 +160,7 @@ config-settings := \ network_coding \ orig_interval \ routing_algo \ + throughput_override \ config-tables := \ backbonetable \ diff --git a/batctl/patches/0001-batctl-Make-vlan-setting-explicit.patch b/batctl/patches/0001-batctl-Make-vlan-setting-explicit.patch new file mode 100644 index 0000000..e63c3dd --- /dev/null +++ b/batctl/patches/0001-batctl-Make-vlan-setting-explicit.patch @@ -0,0 +1,324 @@ +From: Sven Eckelmann +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 + +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 ", ++ "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 -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 \fP|\fBvid \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 ", ++ "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"); diff --git a/batctl/patches/0002-batctl-Integrate-hardif-setting-framework.patch b/batctl/patches/0002-batctl-Integrate-hardif-setting-framework.patch new file mode 100644 index 0000000..1224b5f --- /dev/null +++ b/batctl/patches/0002-batctl-Integrate-hardif-setting-framework.patch @@ -0,0 +1,183 @@ +From: Sven Eckelmann +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 + +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 ", + NULL, + }; ++ const char *hardif_prefixes[] = { ++ "hardif ", ++ 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 ", + NULL, + }; ++ const char *hardif_prefixes[] = { ++ "hardif ", ++ 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 diff --git a/batctl/patches/0003-batctl-Add-elp_interval-setting-command.patch b/batctl/patches/0003-batctl-Add-elp_interval-setting-command.patch new file mode 100644 index 0000000..bef7327 --- /dev/null +++ b/batctl/patches/0003-batctl-Add-elp_interval-setting-command.patch @@ -0,0 +1,183 @@ +From: Sven Eckelmann +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 + +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 ++ * ++ * License-Filename: LICENSES/preferred/GPL-2.0 ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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 \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. diff --git a/batctl/patches/0004-batctl-Add-throughput_override-setting-command.patch b/batctl/patches/0004-batctl-Add-throughput_override-setting-command.patch new file mode 100644 index 0000000..7982cef --- /dev/null +++ b/batctl/patches/0004-batctl-Add-throughput_override-setting-command.patch @@ -0,0 +1,189 @@ +From: Sven Eckelmann +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 + +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 \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 ++ * ++ * License-Filename: LICENSES/preferred/GPL-2.0 ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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");