Merge pull request #496 from ecsv/batadv-for-19.07

openwrt-19.07: batman-adv: Merge bugfixes from 2019.3
This commit is contained in:
Simon Wunderlich 2019-08-02 09:53:13 +02:00 committed by GitHub
commit 784ae0e42d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 1033 additions and 705 deletions

View file

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=alfred
PKG_VERSION:=2019.2
PKG_RELEASE:=0
PKG_RELEASE:=1
PKG_HASH:=b656f0e9a97a99c7531b6d49ebfd663451c16cdd275bbf7d48ff8daed3880bf2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz

View file

@ -0,0 +1,242 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 19 Jun 2019 21:38:09 +0200
Subject: alfred: vis: Use rtnl to query list of hardifs of meshif
The normal way of network related programs to query the state of interfaces
is to use the rtnetlink. Most of these data can also be queried via sysfs
but it is better to use the same way for both retrieving the list of
interfaces and modifying the list of interfaces.
Also the sysfs files are deprecated and cause warnings when access:
batman_adv: [Deprecated]: batadv-vis (pid 832) Use of sysfs file "mesh_iface".
Use batadv genl family instead
In worst case, the file doesn't even exist when batman-adv was compiled
without sysfs support.
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/a34f044de561ce90f67b5760059f818bfb35b449
diff --git a/vis/vis.c b/vis/vis.c
index beaeca150bcac583e9506b9504fa026131f50d5d..37956b100fad72257f5bab2b9f49908da59520cc 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -372,70 +372,146 @@ static void clear_lists(struct globals *globals)
}
}
+static int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg)
+{
+ struct ifinfomsg rt_hdr = {
+ .ifi_family = IFLA_UNSPEC,
+ };
+ struct nl_sock *sock;
+ struct nl_msg *msg;
+ struct nl_cb *cb;
+ int err = 0;
+ int ret;
+
+ sock = nl_socket_alloc();
+ if (!sock)
+ return -ENOMEM;
+
+ ret = nl_connect(sock, NETLINK_ROUTE);
+ if (ret < 0) {
+ err = -ENOMEM;
+ goto err_free_sock;
+ }
+
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
+ if (!cb) {
+ err = -ENOMEM;
+ goto err_free_sock;
+ }
+
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, func, arg);
+
+ msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST | NLM_F_DUMP);
+ if (!msg) {
+ err = -ENOMEM;
+ goto err_free_cb;
+ }
+
+ ret = nlmsg_append(msg, &rt_hdr, sizeof(rt_hdr), NLMSG_ALIGNTO);
+ if (ret < 0) {
+ err = -ENOMEM;
+ goto err_free_msg;
+ }
+
+ ret = nla_put_u32(msg, IFLA_MASTER, ifindex);
+ if (ret < 0) {
+ err = -ENOMEM;
+ goto err_free_msg;
+ }
+
+ ret = nl_send_auto_complete(sock, msg);
+ if (ret < 0)
+ goto err_free_msg;
+
+ nl_recvmsgs(sock, cb);
+
+err_free_msg:
+ nlmsg_free(msg);
+err_free_cb:
+ nl_cb_put(cb);
+err_free_sock:
+ nl_socket_free(sock);
+
+ return err;
+}
+
+struct register_interfaces_rtnl_arg {
+ struct globals *globals;
+ int ifindex;
+};
+
+static struct nla_policy link_policy[IFLA_MAX + 1] = {
+ [IFLA_IFNAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
+ [IFLA_MASTER] = { .type = NLA_U32 },
+};
+
+static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
+{
+ struct register_interfaces_rtnl_arg *register_arg = arg;
+ struct nlattr *attrs[IFLA_MAX + 1];
+ char path_buff[PATH_BUFF_LEN];
+ struct ifinfomsg *ifm;
+ char *content_newline;
+ char *file_content;
+ char *ifname;
+ int master;
+ int ret;
+
+ ifm = nlmsg_data(nlmsg_hdr(msg));
+ ret = nlmsg_parse(nlmsg_hdr(msg), sizeof(*ifm), attrs, IFLA_MAX,
+ link_policy);
+ if (ret < 0)
+ goto err;
+
+ if (!attrs[IFLA_IFNAME])
+ goto err;
+
+ if (!attrs[IFLA_MASTER])
+ goto err;
+
+ ifname = nla_get_string(attrs[IFLA_IFNAME]);
+ master = nla_get_u32(attrs[IFLA_MASTER]);
+
+ /* required on older kernels which don't prefilter the results */
+ if (master != register_arg->ifindex)
+ goto err;
+
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, ifname);
+ file_content = read_file(path_buff);
+ if (!file_content)
+ goto free_file;
+
+ content_newline = strstr(file_content, "\n");
+ if (content_newline)
+ *content_newline = '\0';
+
+ if (strcmp(file_content, "active") != 0)
+ goto err;
+
+ get_if_index_byname(register_arg->globals, ifname);
+
+free_file:
+ free(file_content);
+ file_content = NULL;
+err:
+ return NL_OK;
+}
+
static int register_interfaces(struct globals *globals)
{
- DIR *iface_base_dir;
- struct dirent *iface_dir;
- char *path_buff, *file_content;
- char *content_newline;
+ struct register_interfaces_rtnl_arg register_arg = {
+ .globals = globals,
+ };
- path_buff = malloc(PATH_BUFF_LEN);
- if (!path_buff) {
- perror("Error - could not allocate path buffer");
- goto err;
- }
+ register_arg.ifindex = if_nametoindex(globals->interface);
+ if (!globals->interface)
+ return EXIT_FAILURE;
- iface_base_dir = opendir(SYS_IFACE_PATH);
- if (!iface_base_dir) {
- fprintf(stderr, "Error - the directory '%s' could not be read: %s\n",
- SYS_IFACE_PATH, strerror(errno));
- fprintf(stderr, "Is the batman-adv module loaded and sysfs mounted ?\n");
- goto err_buff;
- }
- while ((iface_dir = readdir(iface_base_dir)) != NULL) {
- snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, iface_dir->d_name);
- file_content = read_file(path_buff);
- if (!file_content)
- continue;
+ query_rtnl_link(register_arg.ifindex, register_interfaces_rtnl_parse,
+ &register_arg);
- if (file_content[strlen(file_content) - 1] == '\n')
- file_content[strlen(file_content) - 1] = '\0';
-
- if (strcmp(file_content, "none") == 0)
- goto free_line;
-
- if (strcmp(file_content, globals->interface) != 0)
- goto free_line;
-
- free(file_content);
- file_content = NULL;
-
- snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, iface_dir->d_name);
- file_content = read_file(path_buff);
- if (!file_content)
- continue;
-
- content_newline = strstr(file_content, "\n");
- if (content_newline)
- *content_newline = '\0';
-
- if (strcmp(file_content, "active") == 0)
- get_if_index_byname(globals, iface_dir->d_name);
-
-free_line:
- free(file_content);
- file_content = NULL;
- }
-
- free(path_buff);
- closedir(iface_base_dir);
return EXIT_SUCCESS;
-
-err_buff:
- free(path_buff);
-err:
- return EXIT_FAILURE;
}
static const int parse_orig_list_mandatory[] = {
diff --git a/vis/vis.h b/vis/vis.h
index 6870dd4ad8570135f4ab2edf0219d74778b7d061..b04a89351778806e84acae88ff3869cf68bcb1a3 100644
--- a/vis/vis.h
+++ b/vis/vis.h
@@ -25,7 +25,6 @@
#define SYS_IFACE_PATH "/sys/class/net"
#define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%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"

View file

@ -0,0 +1,201 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 19 Jun 2019 21:38:10 +0200
Subject: alfred: vis: Retrieve hardif status via generic netlink
The batman-adv kernel module can now be compiled without support for sysfs.
But the batadv-vis interface retriever can only get the status via the per
hardif sysfs file iface_status. To still have some information, use
BATADV_CMD_GET_HARDIF to retrieve the status and fall back to sysfs when
the status could not retrieved via generic netlink.
This also solved the warning about deprecated sysfs file access
batman_adv: [Deprecated]: batadv-vis (pid 1365) Use of sysfs file "iface_status".
Use batadv genl family instead
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/0fc6e6674428ce7085b07645895ef837604e18b5
diff --git a/vis/vis.c b/vis/vis.c
index 37956b100fad72257f5bab2b9f49908da59520cc..947456343125458845f26dc38b53f18d6fd42d75 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -27,6 +27,8 @@
#include "netlink.h"
#include "debugfs.h"
+#define IFACE_STATUS_LEN 256
+
static struct globals vis_globals;
struct vis_netlink_opts {
@@ -435,6 +437,131 @@ err_free_sock:
return err;
}
+static int get_iface_status_netlink_parse(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *attrs[NUM_BATADV_ATTR];
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ char *iface_status = arg;
+ struct genlmsghdr *ghdr;
+
+ if (!genlmsg_valid_hdr(nlh, 0))
+ return NL_OK;
+
+ ghdr = nlmsg_data(nlh);
+ if (ghdr->cmd != BATADV_CMD_GET_HARDIF)
+ return NL_OK;
+
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+ genlmsg_len(ghdr), batadv_netlink_policy))
+ return NL_OK;
+
+ if (attrs[BATADV_ATTR_ACTIVE])
+ strncpy(iface_status, "active\n", IFACE_STATUS_LEN);
+ else
+ strncpy(iface_status, "inactive\n", IFACE_STATUS_LEN);
+
+ iface_status[IFACE_STATUS_LEN - 1] = '\0';
+
+ return NL_STOP;
+}
+
+static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
+ char *iface_status)
+{
+ char *ret_status = NULL;
+ struct nl_sock *sock;
+ struct nl_msg *msg;
+ int batadv_family;
+ struct nl_cb *cb;
+ int ret;
+
+ iface_status[0] = '\0';
+
+ sock = nl_socket_alloc();
+ if (!sock)
+ return NULL;
+
+ ret = genl_connect(sock);
+ if (ret < 0)
+ goto err_free_sock;
+
+ batadv_family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
+ if (batadv_family < 0)
+ goto err_free_sock;
+
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
+ if (!cb)
+ goto err_free_sock;
+
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_iface_status_netlink_parse,
+ iface_status);
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ goto err_free_cb;
+
+ genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, batadv_family,
+ 0, 0, BATADV_CMD_GET_HARDIF, 1);
+
+ nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, meshif);
+ nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, hardif);
+
+ ret = nl_send_auto_complete(sock, msg);
+ if (ret < 0)
+ goto err_free_msg;
+
+ nl_recvmsgs(sock, cb);
+
+ if (strlen(iface_status) > 0)
+ ret_status = iface_status;
+
+err_free_msg:
+ nlmsg_free(msg);
+err_free_cb:
+ nl_cb_put(cb);
+err_free_sock:
+ nl_socket_free(sock);
+
+ return ret_status;
+}
+
+static bool interface_active(unsigned int meshif, unsigned int hardif,
+ const char *ifname)
+{
+ char iface_status[IFACE_STATUS_LEN];
+ char path_buff[PATH_BUFF_LEN];
+ char *file_content = NULL;
+ char *content_newline;
+ bool active = false;
+ char *status;
+
+ status = get_iface_status_netlink(meshif, hardif, iface_status);
+ if (!status) {
+ snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT,
+ ifname);
+ file_content = read_file(path_buff);
+ if (!file_content)
+ return false;
+
+ status = file_content;
+ }
+
+ content_newline = strstr(status, "\n");
+ if (content_newline)
+ *content_newline = '\0';
+
+ if (strcmp(status, "active") != 0)
+ goto free_file;
+
+ active = true;
+
+free_file:
+ free(file_content);
+ file_content = NULL;
+
+ return active;
+}
+
struct register_interfaces_rtnl_arg {
struct globals *globals;
int ifindex;
@@ -449,10 +576,7 @@ static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
{
struct register_interfaces_rtnl_arg *register_arg = arg;
struct nlattr *attrs[IFLA_MAX + 1];
- char path_buff[PATH_BUFF_LEN];
struct ifinfomsg *ifm;
- char *content_newline;
- char *file_content;
char *ifname;
int master;
int ret;
@@ -476,23 +600,11 @@ static int register_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
if (master != register_arg->ifindex)
goto err;
- snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_STATUS_FMT, ifname);
- file_content = read_file(path_buff);
- if (!file_content)
- goto free_file;
-
- content_newline = strstr(file_content, "\n");
- if (content_newline)
- *content_newline = '\0';
-
- if (strcmp(file_content, "active") != 0)
+ if (!interface_active(master, ifm->ifi_index, ifname))
goto err;
get_if_index_byname(register_arg->globals, ifname);
-free_file:
- free(file_content);
- file_content = NULL;
err:
return NL_OK;
}

View file

@ -0,0 +1,21 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 1 Aug 2019 15:54:32 +0200
Subject: alfred: vis: Add missing include for ifinfomsg
Fixes: 0fc6e6674428 ("alfred: vis: Retrieve hardif status via generic netlink")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/ce26453bd72829ac9561acd8d3a06a3937341687
diff --git a/vis/vis.c b/vis/vis.c
index 947456343125458845f26dc38b53f18d6fd42d75..8df3056612d5da3678603a6e6430923c0c86cde0 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -10,6 +10,7 @@
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
+#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/in.h>
#include <signal.h>

View file

@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batctl
PKG_VERSION:=2019.2
PKG_RELEASE:=1
PKG_RELEASE:=3
PKG_HASH:=fb656208ff7d4cd8b1b422f60c9e6d8747302a347cbf6c199d7afa9b80f80ea3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz

View file

@ -1,5 +1,5 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:14 +0200
Date: Tue, 9 Jul 2019 19:26:46 +0200
Subject: batctl: Make vlan setting explicit
The requirement to have a VLAN master device on top of the batadv mesh
@ -12,12 +12,48 @@ 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/
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/4704c5e05af7a4f6a397d80ff80f2f2c56fe8f2c
diff --git a/ap_isolation.c b/ap_isolation.c
index 71dcd00eac845d488c4969b17e1339f181c6c913..7c34649225dcc9cc557cc5bb4cbfa2343f8c0763 100644
index 71dcd00eac845d488c4969b17e1339f181c6c913..36fd4d607d03768251150951ebe450740501d446 100644
--- a/ap_isolation.c
+++ b/ap_isolation.c
@@ -28,7 +28,7 @@ static int get_attrs_ap_isolation(struct nl_msg *msg, void *arg)
{
struct state *state = arg;
- if (state->vid >= 0)
+ if (state->selector == SP_VLAN)
nla_put_u16(msg, BATADV_ATTR_VLANID, state->vid);
return 0;
@@ -38,7 +38,7 @@ static int get_ap_isolation(struct state *state)
{
enum batadv_nl_commands nl_cmd = BATADV_CMD_SET_MESH;
- if (state->vid >= 0)
+ if (state->selector == SP_VLAN)
nl_cmd = BATADV_CMD_GET_VLAN;
return sys_simple_nlquery(state, nl_cmd, get_attrs_ap_isolation,
@@ -53,7 +53,7 @@ static int set_attrs_ap_isolation(struct nl_msg *msg, void *arg)
nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION_ENABLED, data->val);
- if (state->vid >= 0)
+ if (state->selector == SP_VLAN)
nla_put_u16(msg, BATADV_ATTR_VLANID, state->vid);
return 0;
@@ -63,7 +63,7 @@ static int set_ap_isolation(struct state *state)
{
enum batadv_nl_commands nl_cmd = BATADV_CMD_SET_MESH;
- if (state->vid >= 0)
+ if (state->selector == SP_VLAN)
nl_cmd = BATADV_CMD_SET_VLAN;
return sys_simple_nlquery(state, nl_cmd, set_attrs_ap_isolation, NULL);
@@ -81,3 +81,8 @@ COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting,
COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
&batctl_settings_ap_isolation,
@ -27,8 +63,120 @@ index 71dcd00eac845d488c4969b17e1339f181c6c913..7c34649225dcc9cc557cc5bb4cbfa234
+ 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/functions.c b/functions.c
index aad6327a8f0fe6e512157e427d88dd0649acd052..61ea4879ebffbdadf8ef5bb12bb737c1ed7ff76f 100644
--- a/functions.c
+++ b/functions.c
@@ -919,32 +919,44 @@ static int query_rtnl_link_single(int mesh_ifindex,
return 0;
}
-int translate_mesh_iface(struct state *state)
+int translate_vlan_iface(struct state *state, const char *vlandev)
{
struct rtnl_link_iface_data link_data;
unsigned int arg_ifindex;
- arg_ifindex = if_nametoindex(state->arg_iface);
+ arg_ifindex = if_nametoindex(vlandev);
if (arg_ifindex == 0)
- goto fallback_meshif;
+ return -ENODEV;
query_rtnl_link_single(arg_ifindex, &link_data);
if (!link_data.vid_found)
- goto fallback_meshif;
+ return -ENODEV;
if (!link_data.link_found)
- goto fallback_meshif;
+ return -EINVAL;
if (!link_data.kind_found)
- goto fallback_meshif;
+ return -EINVAL;
if (strcmp(link_data.kind, "vlan") != 0)
- goto fallback_meshif;
+ return -EINVAL;
if (!if_indextoname(link_data.link, state->mesh_iface))
- goto fallback_meshif;
+ return -ENODEV;
state->vid = link_data.vid;
+ state->selector = SP_VLAN;
+
+ return 0;
+}
+
+int translate_mesh_iface_vlan(struct state *state, const char *vlandev)
+{
+ int ret;
+
+ ret = translate_vlan_iface(state, vlandev);
+ if (ret < 0)
+ goto fallback_meshif;
return 0;
@@ -952,9 +964,36 @@ int translate_mesh_iface(struct state *state)
/* if there is no vid then the argument must be the
* mesh interface
*/
- snprintf(state->mesh_iface, sizeof(state->mesh_iface), "%s",
- state->arg_iface);
- state->vid = -1;
+ snprintf(state->mesh_iface, sizeof(state->mesh_iface), "%s", vlandev);
+ state->selector = SP_NONE_OR_MESHIF;
+
+ return 0;
+}
+
+int translate_vid(struct state *state, const char *vidstr)
+{
+ unsigned long vid;
+ char *endptr;
+
+ if (vidstr[0] == '\0') {
+ fprintf(stderr, "Error - unparsable vid\n");
+ return -EINVAL;
+ }
+
+ vid = strtoul(vidstr, &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 */
+ state->vid = vid;
+ state->selector = SP_VLAN;
return 0;
}
diff --git a/functions.h b/functions.h
index d4a556879664eb5b4b11e6c638c22728db7a83a4..7474c40bbcdcb8fac8865def2e82514aede62b69 100644
--- a/functions.h
+++ b/functions.h
@@ -50,7 +50,9 @@ struct ether_addr *translate_mac(const char *mesh_iface,
struct ether_addr *resolve_mac(const char *asc);
int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
int netlink_simple_request(struct nl_msg *msg);
-int translate_mesh_iface(struct state *state);
+int translate_mesh_iface_vlan(struct state *state, const char *vlandev);
+int translate_vlan_iface(struct state *state, const char *vlandev);
+int translate_vid(struct state *state, const char *vidstr);
int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
int check_mesh_iface(struct state *state);
int check_mesh_iface_ownership(struct state *state, char *hard_iface);
diff --git a/main.c b/main.c
index 278683c6080e3ff4a9f3225931d0c5eb44f89595..6ca13ac0ec4c82ee969be04737a339fd702b52bd 100644
index 278683c6080e3ff4a9f3225931d0c5eb44f89595..309087799b839848029bd5cbec60cbe1213f9190 100644
--- a/main.c
+++ b/main.c
@@ -28,48 +28,75 @@ extern const struct command *__stop___command[];
@ -127,88 +275,150 @@ index 278683c6080e3ff4a9f3225931d0c5eb44f89595..6ca13ac0ec4c82ee969be04737a339fd
}
}
}
@@ -93,13 +120,19 @@ static void version(void)
@@ -93,13 +120,17 @@ 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)
+static const struct command *find_command_by_types(uint32_t types,
+ 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)
+ if (!(BIT(cmd->type) & types))
+ continue;
+
if (strcmp(cmd->name, name) == 0)
return cmd;
@@ -110,6 +143,51 @@ static const struct command *find_command(const char *name)
@@ -110,13 +141,123 @@ static const struct command *find_command(const char *name)
return NULL;
}
+static const struct command *find_command(struct state *state, const char *name)
+{
+ uint32_t types;
+
+ switch (state->selector) {
+ case SP_NONE_OR_MESHIF:
+ types = BIT(SUBCOMMAND) |
+ BIT(DEBUGTABLE);
+ break;
+ case SP_VLAN:
+ types = BIT(SUBCOMMAND_VID);
+ break;
+ default:
+ return NULL;
+ }
+
+ return find_command_by_types(types, name);
+}
+
+static int detect_selector_prefix(int argc, char *argv[],
+ enum selector_prefix *selector)
+{
+ /* not enough remaining arguments to detect anything */
+ if (argc < 2)
+ return -EINVAL;
+
+ /* only detect selector prefix which identifies meshif */
+ if (strcmp(argv[0], "vlan") == 0) {
+ *selector = SP_VLAN;
+ return 2;
+ }
+
+ return 0;
+}
+
+static int parse_meshif_args(struct state *state, int argc, char *argv[])
+{
+ enum selector_prefix selector;
+ int parsed_args;
+ char *dev_arg;
+ int ret;
+
+ parsed_args = detect_selector_prefix(argc, argv, &selector);
+ if (parsed_args < 1)
+ goto fallback_meshif_vlan;
+
+ dev_arg = argv[parsed_args - 1];
+
+ switch (selector) {
+ case SP_VLAN:
+ ret = translate_vlan_iface(state, dev_arg);
+ if (ret < 0) {
+ fprintf(stderr, "Error - invalid vlan device %s: %s\n",
+ dev_arg, strerror(-ret));
+ return ret;
+ }
+
+ return parsed_args;
+ case SP_NONE_OR_MESHIF:
+ /* not allowed - see detect_selector_prefix */
+ break;
+ }
+
+fallback_meshif_vlan:
+ /* parse vlan as part of -m parameter or mesh_dfl_iface */
+ translate_mesh_iface_vlan(state, state->arg_iface);
+ return 0;
+}
+
+static int parse_dev_args(struct state *state, int argc, char *argv[])
+{
+ unsigned long vid;
+ char *endptr;
+ int dev_arguments;
+ int ret;
+
+ /* not enough arguments to parse */
+ if (argc < 2) {
+ translate_mesh_iface(state);
+ return 0;
+ /* try to parse selector prefix which can be used to identify meshif */
+ dev_arguments = parse_meshif_args(state, argc, argv);
+ if (dev_arguments < 0)
+ return dev_arguments;
+
+ /* try to parse secondary prefix selectors which cannot be used to
+ * identify the meshif
+ */
+ argv += dev_arguments;
+ argc -= dev_arguments;
+
+ switch (state->selector) {
+ case SP_NONE_OR_MESHIF:
+ /* continue below */
+ break;
+ default:
+ return dev_arguments;
+ }
+
+ /* enough room for additional selectors? */
+ if (argc < 2)
+ return dev_arguments;
+
+ if (strcmp(argv[0], "vid") == 0) {
+ if (argv[1] == '\0') {
+ fprintf(stderr, "Error - unparsable vid\n");
+ return -EINVAL;
+ ret = translate_vid(state, argv[1]);
+ if (ret < 0)
+ return ret;
+
+ return dev_arguments + 2;
+ }
+
+ 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;
+ }
+ return dev_arguments;
+}
+
int main(int argc, char **argv)
{
const struct command *cmd;
@@ -117,6 +195,7 @@ int main(int argc, char **argv)
struct state state = {
.arg_iface = mesh_dfl_iface,
+ .selector = SP_NONE_OR_MESHIF,
.cmd = NULL,
};
+ int dev_arguments;
int opt;
int ret;
@@ -152,7 +231,15 @@ int main(int argc, char **argv)
@@ -152,7 +293,20 @@ int main(int argc, char **argv)
argc -= optind;
optind = 0;
@ -221,11 +431,16 @@ index 278683c6080e3ff4a9f3225931d0c5eb44f89595..6ca13ac0ec4c82ee969be04737a339fd
+ argv += dev_arguments;
+ argc -= dev_arguments;
+
+ if (argc == 0) {
+ fprintf(stderr, "Error - no command specified\n");
+ goto err;
+ }
+
+ 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)
@@ -162,8 +316,6 @@ int main(int argc, char **argv)
state.cmd = cmd;
@ -235,18 +450,31 @@ index 278683c6080e3ff4a9f3225931d0c5eb44f89595..6ca13ac0ec4c82ee969be04737a339fd
check_mesh_iface(&state) < 0) {
fprintf(stderr,
diff --git a/main.h b/main.h
index 1a4701513c49ad8974b9c9189619f5dde622acd4..1d952610aefb8367bd52e24bea8c04c3d70b94ea 100644
index 1a4701513c49ad8974b9c9189619f5dde622acd4..efc277c5465942d7b4dba284d29f653273b42dce 100644
--- a/main.h
+++ b/main.h
@@ -58,6 +58,7 @@ enum command_flags {
@@ -56,13 +56,20 @@ enum command_flags {
COMMAND_FLAG_INVERSE = BIT(2),
};
+enum selector_prefix {
+ SP_NONE_OR_MESHIF,
+ SP_VLAN,
+};
+
enum command_type {
SUBCOMMAND,
+ SUBCOMMAND_VID,
DEBUGTABLE,
};
@@ -84,7 +85,7 @@ struct command {
struct state {
char *arg_iface;
+ enum selector_prefix selector;
char mesh_iface[IF_NAMESIZE];
unsigned int mesh_ifindex;
int vid;
@@ -84,7 +91,7 @@ struct command {
};
#define COMMAND_NAMED(_type, _name, _abbr, _handler, _flags, _arg, _usage) \
@ -255,7 +483,7 @@ index 1a4701513c49ad8974b9c9189619f5dde622acd4..1d952610aefb8367bd52e24bea8c04c3
.type = (_type), \
.name = (#_name), \
.abbr = _abbr, \
@@ -93,8 +94,8 @@ struct command {
@@ -93,8 +100,8 @@ struct command {
.arg = (_arg), \
.usage = (_usage), \
}; \
@ -267,20 +495,33 @@ index 1a4701513c49ad8974b9c9189619f5dde622acd4..1d952610aefb8367bd52e24bea8c04c3
#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
index 0b430313075b5a7a4c796eba0867954e10061002..a5656cf9059bd82c1b85928c22e30d01c56e475f 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.
@@ -46,7 +46,7 @@ performances, is also included.
.SH OPTIONS
.TP
.I \fBoptions:
-\-m specify mesh interface or VLAN created on top of a mesh interface (default 'bat0')
+\-m specify mesh interface (default 'bat0')
.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]"
\-h print general batctl help
.br
@@ -70,7 +70,11 @@ originator interval. The interval is in units of milliseconds.
.br
.IP "\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.
-disable ap isolation. This command can be used in conjunction with "\-m" option to target per VLAN configurations.
+disable ap isolation.
+.br
+.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 for the specified VLAN is displayed. Otherwise the parameter is used to enable or
+disable ap isolation for the specified VLAN.
.br
.IP "\fBbridge_loop_avoidance\fP|\fBbl\fP [\fB0\fP|\fB1\fP]"
If no parameter is given the current bridge loop avoidance setting is displayed. Otherwise the parameter is used to enable
diff --git a/sys.c b/sys.c
index 39123db87d391b8898b7454eba7708515bfb3c78..f19719cfad61f36f2a5c1078305de83eb5be142a 100644
index 39123db87d391b8898b7454eba7708515bfb3c78..61a314d88010ef34507ec9dd6a77b53f318f63a8 100644
--- a/sys.c
+++ b/sys.c
@@ -141,9 +141,35 @@ int sys_simple_print_boolean(struct nl_msg *msg, void *arg,
@ -322,3 +563,30 @@ index 39123db87d391b8898b7454eba7708515bfb3c78..f19719cfad61f36f2a5c1078305de83e
fprintf(stderr, "parameters:\n");
fprintf(stderr, " \t -h print this help\n");
@@ -233,15 +259,19 @@ 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)
- snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
- state->mesh_iface, state->vid);
- else
+ switch (state->selector) {
+ case SP_NONE_OR_MESHIF:
snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT,
state->mesh_iface);
+ break;
+ case SP_VLAN:
+ /* 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);
+ break;
+ }
if (argc == 1) {
res = sys_read_setting(state, path_buff, settings->sysfs_name);

View file

@ -1,5 +1,5 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:15 +0200
Date: Tue, 9 Jul 2019 19:26:47 +0200
Subject: batctl: Integrate hardif setting framework
batctl currently supports settings which are either mesh interface or vlan
@ -9,14 +9,59 @@ hard (slave) interface specific.
To support these, an additional command prefix called hardif is implemented
for some sysfs commands:
$ batctl -m bat0 hardif eth0 ...
$ batctl hardif eth0 ...
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17948/
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6ed4dfc5459fd3b9ed221308075db592e538c92f
diff --git a/functions.c b/functions.c
index 61ea4879ebffbdadf8ef5bb12bb737c1ed7ff76f..4ffa86ca7830dea3ed2599656831b56f6fec9e33 100644
--- a/functions.c
+++ b/functions.c
@@ -998,6 +998,28 @@ int translate_vid(struct state *state, const char *vidstr)
return 0;
}
+int translate_hard_iface(struct state *state, const char *hardif)
+{
+ struct rtnl_link_iface_data link_data;
+ unsigned int arg_ifindex;
+
+ arg_ifindex = if_nametoindex(hardif);
+ if (arg_ifindex == 0)
+ return -ENODEV;
+
+ query_rtnl_link_single(arg_ifindex, &link_data);
+ if (!link_data.master_found)
+ return -ENOLINK;
+
+ if (!if_indextoname(link_data.master, state->mesh_iface))
+ return -ENOLINK;
+
+ state->hif = arg_ifindex;
+ state->selector = SP_HARDIF;
+
+ return 0;
+}
+
static int check_mesh_iface_netlink(struct state *state)
{
struct rtnl_link_iface_data link_data;
diff --git a/functions.h b/functions.h
index 7474c40bbcdcb8fac8865def2e82514aede62b69..0a08870cee651ee676e67d3e55677c53f59e41c4 100644
--- a/functions.h
+++ b/functions.h
@@ -53,6 +53,7 @@ int netlink_simple_request(struct nl_msg *msg);
int translate_mesh_iface_vlan(struct state *state, const char *vlandev);
int translate_vlan_iface(struct state *state, const char *vlandev);
int translate_vid(struct state *state, const char *vidstr);
+int translate_hard_iface(struct state *state, const char *hardif);
int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
int check_mesh_iface(struct state *state);
int check_mesh_iface_ownership(struct state *state, char *hard_iface);
diff --git a/main.c b/main.c
index 6ca13ac0ec4c82ee969be04737a339fd702b52bd..c806dbf4373fd082ff368cba391bdf14eebf4eae 100644
index 309087799b839848029bd5cbec60cbe1213f9190..3b3a16f4c1caffdd2be897e6bf2a00564e5580f8 100644
--- a/main.c
+++ b/main.c
@@ -35,7 +35,8 @@ static void print_usage(void)
@ -50,51 +95,55 @@ index 6ca13ac0ec4c82ee969be04737a339fd702b52bd..c806dbf4373fd082ff368cba391bdf14
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);
@@ -153,6 +161,9 @@ static const struct command *find_command(struct state *state, const char *name)
case SP_VLAN:
types = BIT(SUBCOMMAND_VID);
break;
+ case SP_HARDIF:
+ types = BIT(SUBCOMMAND_HIF);
+ break;
default:
return NULL;
}
@@ -171,6 +182,9 @@ static int detect_selector_prefix(int argc, char *argv[],
if (strcmp(argv[0], "vlan") == 0) {
*selector = SP_VLAN;
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;
+ } else if (strcmp(argv[0], "hardif") == 0) {
+ *selector = SP_HARDIF;
+ return 2;
}
return 0;
@@ -197,7 +211,17 @@ static int parse_meshif_args(struct state *state, int argc, char *argv[])
dev_arg, strerror(-ret));
return ret;
}
+ return parsed_args;
+ case SP_HARDIF:
+ ret = translate_hard_iface(state, dev_arg);
+ if (ret < 0) {
+ fprintf(stderr, "Error - invalid hardif %s: %s\n",
+ dev_arg, strerror(-ret));
+ return ret;
+ }
+ snprintf(state->hard_iface, sizeof(state->hard_iface), "%s",
+ dev_arg);
return parsed_args;
case SP_NONE_OR_MESHIF:
/* not allowed - see detect_selector_prefix */
diff --git a/main.h b/main.h
index 1d952610aefb8367bd52e24bea8c04c3d70b94ea..a27d8486ef689206b27b1b50cb017b1b740e91c9 100644
index efc277c5465942d7b4dba284d29f653273b42dce..a97b26fe7b969e01cbdb848e58824e36e3d236ab 100644
--- a/main.h
+++ b/main.h
@@ -59,6 +59,7 @@ enum command_flags {
@@ -59,11 +59,13 @@ enum command_flags {
enum selector_prefix {
SP_NONE_OR_MESHIF,
SP_VLAN,
+ SP_HARDIF,
};
enum command_type {
SUBCOMMAND,
SUBCOMMAND_VID,
@ -102,17 +151,21 @@ index 1d952610aefb8367bd52e24bea8c04c3d70b94ea..a27d8486ef689206b27b1b50cb017b1b
DEBUGTABLE,
};
@@ -66,6 +67,8 @@ struct state {
char *arg_iface;
@@ -72,7 +74,11 @@ struct state {
enum selector_prefix selector;
char mesh_iface[IF_NAMESIZE];
unsigned int mesh_ifindex;
- int vid;
+ char hard_iface[IF_NAMESIZE];
+ union {
+ unsigned int hif;
int vid;
+ int vid;
+ };
const struct command *cmd;
struct nl_sock *sock;
diff --git a/sys.c b/sys.c
index f19719cfad61f36f2a5c1078305de83eb5be142a..fd34b2fa3bcf168a32bd53fc0df3f35d5532433f 100644
index 61a314d88010ef34507ec9dd6a77b53f318f63a8..b9555ee484f89c1022c0b4e74e18154d18b7af6b 100644
--- a/sys.c
+++ b/sys.c
@@ -150,6 +150,10 @@ static void settings_usage(struct state *state)
@ -136,35 +189,21 @@ index f19719cfad61f36f2a5c1078305de83eb5be142a..fd34b2fa3bcf168a32bd53fc0df3f35d
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) {
@@ -271,6 +278,14 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
state->mesh_iface, state->vid);
break;
+ case SP_HARDIF:
+ /* 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);
+ }
+ break;
}
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

View file

@ -1,5 +1,5 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:16 +0200
Date: Tue, 9 Jul 2019 19:26:48 +0200
Subject: batctl: Add elp_interval setting command
B.A.T.M.A.N. V introduced a hard interface specific setting called
@ -8,7 +8,7 @@ emits probing packets for neighbor sensing (ELP).
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Forwarded: https://patchwork.open-mesh.org/patch/17949/
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/df5c452a446951c5f2fde265d08f3c2809ac2334
diff --git a/Makefile b/Makefile
index b7bd545e92963c62128efe60c0dc401bdd9fa023..f071da20f866bff6c162d697d2e43fa9d68ee08d 100755
@ -167,10 +167,10 @@ index 0000000000000000000000000000000000000000..0a5e98923a622f52e523696b1ec1bfb8
+ &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
index a5656cf9059bd82c1b85928c22e30d01c56e475f..eef7cd8f1246b83f03627cf307471abcade87cfc 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -93,6 +93,10 @@ the bonding mode.
@@ -97,6 +97,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

View file

@ -1,5 +1,5 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 13 Jun 2019 21:12:17 +0200
Date: Tue, 9 Jul 2019 19:26:49 +0200
Subject: batctl: Add throughput_override setting command
B.A.T.M.A.N. V introduced a hard interface specific setting called
@ -9,7 +9,7 @@ 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/
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/e5e6560df82813a9aad4a6c958be4d8ea012e909
diff --git a/Makefile b/Makefile
index f071da20f866bff6c162d697d2e43fa9d68ee08d..e3747a2a28eb34323e34a1e22f5507dd1d7cd0f6 100755
@ -52,10 +52,10 @@ index 92983aa6030e2a890283bca448b9203cd4d56b51..128f539852fa085d023fb6d26ae436e7
===============
diff --git a/man/batctl.8 b/man/batctl.8
index 690da023fd1ac6f51915a9167e92030a650fe1bd..b8218963712bbf0cc9470459896fc904cd393748 100644
index eef7cd8f1246b83f03627cf307471abcade87cfc..d42b6825dd3172009369e370e45ed6e7a9bf9d0d 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -203,6 +203,12 @@ supported routing algorithms are displayed.
@@ -207,6 +207,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

View file

@ -0,0 +1,90 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 19 Jun 2019 09:37:50 +0200
Subject: batctl: Prefer netlink hardif status retrieval over sysfs
The sysfs code in batman-adv was changed to print a deprecated warning when
sysfs files are accessed. The `batctl if` call would therefore cause
warnings like this in the kernel log:
batman_adv: [Deprecated]: batctl (pid 18540) Use of sysfs file "iface_status".
Use batadv genl family instead
It is now appropriate to try the generic netlink BATADV_CMD_GET_HARDIF
request first to get the status of the interface before falling back to
sysfs.
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/
diff --git a/interface.c b/interface.c
index 19e6670b45d1bd2dd65c8fbb47eb85361e8c4d26..c2bfc7402aece61be37a71730745c47ad56e2af4 100644
--- a/interface.c
+++ b/interface.c
@@ -67,18 +67,18 @@ static int get_iface_status_netlink_parse(struct nl_msg *msg, void *arg)
static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
char *iface_status)
{
+ char *ret_status = NULL;
struct nl_sock *sock;
struct nl_msg *msg;
int batadv_family;
struct nl_cb *cb;
int ret;
- strncpy(iface_status, "<error reading status>\n", IFACE_STATUS_LEN);
- iface_status[IFACE_STATUS_LEN - 1] = '\0';
+ iface_status[0] = '\0';
sock = nl_socket_alloc();
if (!sock)
- return iface_status;
+ return NULL;
ret = genl_connect(sock);
if (ret < 0)
@@ -111,6 +111,9 @@ static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
nl_recvmsgs(sock, cb);
+ if (strlen(iface_status) > 0)
+ ret_status = iface_status;
+
err_free_msg:
nlmsg_free(msg);
err_free_cb:
@@ -118,7 +121,7 @@ static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
err_free_sock:
nl_socket_free(sock);
- return iface_status;
+ return ret_status;
}
static struct nla_policy link_policy[IFLA_MAX + 1] = {
@@ -161,13 +164,17 @@ static int print_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
if (master != print_arg->ifindex)
goto err;
- snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT, ifname);
- ret = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0);
- if (ret != EXIT_SUCCESS)
- status = get_iface_status_netlink(master, ifm->ifi_index,
- iface_status);
- else
- status = line_ptr;
+ status = get_iface_status_netlink(master, ifm->ifi_index, iface_status);
+ if (!status) {
+ snprintf(path_buff, sizeof(path_buff), SYS_IFACE_STATUS_FMT,
+ ifname);
+ ret = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS,
+ 0, 0, 0);
+ if (ret != EXIT_SUCCESS)
+ status = "<error reading status>\n";
+ else
+ status = line_ptr;
+ }
printf("%s: %s", ifname, status);

View file

@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batman-adv
PKG_VERSION:=2019.2
PKG_RELEASE:=3
PKG_RELEASE:=4
PKG_HASH:=70c3f6a6cf88d2b25681a76768a52ed92d9fe992ba8e358368b6a8088757adc8
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz

View file

@ -1,55 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 23 May 2019 19:26:27 +0200
Subject: Revert "batman-adv: convert stream-like files from nonseekable_open -> stream_open"
OpenWrt's mac80211 package is not yet ready to support the generic netlink
API of Linux 5.2.
This reverts commit 337ae19a00d4455cf84afa58abfb432f78c882b9.
diff --git a/compat-include/linux/fs.h b/compat-include/linux/fs.h
index 480722f04ba7ddefc837d5e55a340271e0814b14..c52e0e8e87584d106ab64ef2c522e6ac1ff6e796 100644
--- a/compat-include/linux/fs.h
+++ b/compat-include/linux/fs.h
@@ -31,15 +31,4 @@ static inline struct dentry *batadv_file_dentry(const struct file *file)
#endif /* < KERNEL_VERSION(4, 6, 0) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
-
-static inline int batadv_stream_open(struct inode *inode, struct file *filp)
-{
- return nonseekable_open(inode, filp);
-}
-
-#define stream_open batadv_stream_open
-
-#endif /* < KERNEL_VERSION(5, 2, 0) */
-
#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_FS_H_ */
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index 0a91c8661357d4ddbea1ba20dcd0df67b8ba5a97..de81b5ecad91afd8d684edbf781c70a3bae38c60 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -65,7 +65,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
batadv_debugfs_deprecated(file, "");
- stream_open(inode, file);
+ nonseekable_open(inode, file);
socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
if (!socket_client) {
diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c
index f79ebd5b46e95b3b6de717c7ea1ecf44e5c96051..60ce11e16a905e790424a2d7aca81c1f945c1ec2 100644
--- a/net/batman-adv/log.c
+++ b/net/batman-adv/log.c
@@ -90,7 +90,7 @@ static int batadv_log_open(struct inode *inode, struct file *file)
batadv_debugfs_deprecated(file,
"Use tracepoint batadv:batadv_dbg instead\n");
- stream_open(inode, file);
+ nonseekable_open(inode, file);
file->private_data = inode->i_private;
return 0;
}

View file

@ -1,29 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 23 May 2019 19:26:36 +0200
Subject: Revert "batman-adv: compat: Drop support for genl_ops->start"
OpenWrt's mac80211 package is not yet ready to support the generic netlink
API of Linux 5.2.
This reverts commit 1d30dbe3917d0d6fdb8ba473dfdd6265ac46670b.
diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index ee5b82288be97193c1a8e8340a2ea7e0c7ce112c..fbfdb733a3dd63c251def43cae416c7fe32cadab 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -42,6 +42,7 @@ enum genl_validate_flags {
struct batadv_genl_ops {
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
+ int (*start)(struct netlink_callback *cb);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
@@ -104,6 +105,7 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family)
for (i = 0; i < family->family.n_ops; i++) {
ops[i].doit = family->ops[i].doit;
+ ops[i].start = family->ops[i].start;
ops[i].dumpit = family->ops[i].dumpit;
ops[i].done = family->ops[i].done;
ops[i].cmd = family->ops[i].cmd;

View file

@ -1,222 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 23 May 2019 19:26:45 +0200
Subject: Revert "batman-adv: genetlink: optionally validate strictly/dumps"
OpenWrt's mac80211 package is not yet ready to support the generic netlink
API of Linux 5.2.
This reverts commit 2ee47abaeb35ca62bb909830e10b0e973393b853.
diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index fbfdb733a3dd63c251def43cae416c7fe32cadab..7d17a705273650355f074788e9220fc4981b0db1 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -33,25 +33,6 @@ void batadv_genl_dump_check_consistent(struct netlink_callback *cb,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
-enum genl_validate_flags {
- GENL_DONT_VALIDATE_STRICT = BIT(0),
- GENL_DONT_VALIDATE_DUMP = BIT(1),
- GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
-};
-
-struct batadv_genl_ops {
- int (*doit)(struct sk_buff *skb,
- struct genl_info *info);
- int (*start)(struct netlink_callback *cb);
- int (*dumpit)(struct sk_buff *skb,
- struct netlink_callback *cb);
- int (*done)(struct netlink_callback *cb);
- u8 cmd;
- u8 internal_flags;
- u8 flags;
- u8 validate;
-};
-
struct batadv_genl_family {
/* data handled by the actual kernel */
struct genl_family family;
@@ -69,7 +50,7 @@ struct batadv_genl_family {
struct genl_info *info);
void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb,
struct genl_info *info);
- const struct batadv_genl_ops *ops;
+ const struct genl_ops *ops;
const struct genl_multicast_group *mcgrps;
unsigned int n_ops;
unsigned int n_mcgrps;
@@ -82,6 +63,8 @@ struct batadv_genl_family {
struct genl_ops *copy_ops;
};
+#define genl_family batadv_genl_family
+
static inline int batadv_genl_register_family(struct batadv_genl_family *family)
{
struct genl_ops *ops;
@@ -99,20 +82,12 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family)
family->family.n_mcgrps = family->n_mcgrps;
family->family.module = family->module;
- ops = kzalloc(sizeof(*ops) * family->n_ops, GFP_KERNEL);
+ ops = kmemdup(family->ops, sizeof(*ops) * family->n_ops, GFP_KERNEL);
if (!ops)
return -ENOMEM;
- for (i = 0; i < family->family.n_ops; i++) {
- ops[i].doit = family->ops[i].doit;
- ops[i].start = family->ops[i].start;
- ops[i].dumpit = family->ops[i].dumpit;
- ops[i].done = family->ops[i].done;
- ops[i].cmd = family->ops[i].cmd;
- ops[i].internal_flags = family->ops[i].internal_flags;
- ops[i].flags = family->ops[i].flags;
+ for (i = 0; i < family->family.n_ops; i++)
ops[i].policy = family->policy;
- }
family->family.ops = ops;
family->copy_ops = ops;
@@ -120,17 +95,6 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family)
return genl_register_family(&family->family);
}
-typedef struct genl_ops batadv_genl_ops_old;
-
-#define batadv_pre_doit(__x, __y, __z) \
- batadv_pre_doit(const batadv_genl_ops_old *ops, __y, __z)
-
-#define batadv_post_doit(__x, __y, __z) \
- batadv_post_doit(const batadv_genl_ops_old *ops, __y, __z)
-
-#define genl_ops batadv_genl_ops
-#define genl_family batadv_genl_family
-
#define genl_register_family(family) \
batadv_genl_register_family((family))
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index a67720fad46ca496c932c0306e2f7ec4ed496fc9..e7907308b331ddc3e4917ff7d648bca27a65536b 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1343,34 +1343,29 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_MESH,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_start,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER_CANCEL,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_cancel,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_algo_dump,
},
{
.cmd = BATADV_CMD_GET_HARDIF,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.dumpit = batadv_netlink_dump_hardif,
.doit = batadv_netlink_get_hardif,
@@ -1379,68 +1374,57 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_local_dump,
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_global_dump,
},
{
.cmd = BATADV_CMD_GET_ORIGINATORS,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_orig_dump,
},
{
.cmd = BATADV_CMD_GET_NEIGHBORS,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_hardif_neigh_dump,
},
{
.cmd = BATADV_CMD_GET_GATEWAYS,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_gw_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_CLAIM,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_claim_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_backbone_dump,
},
{
.cmd = BATADV_CMD_GET_DAT_CACHE,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_dat_cache_dump,
},
{
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_mcast_flags_dump,
},
{
.cmd = BATADV_CMD_SET_MESH,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_SET_HARDIF,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_hardif,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1448,7 +1432,6 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_VLAN,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1456,7 +1439,6 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_SET_VLAN,
- .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |

View file

@ -1,256 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 23 May 2019 19:26:58 +0200
Subject: Revert "batman-adv: genetlink: make policy common to family"
OpenWrt's mac80211 package is not yet ready to support the generic netlink
API of Linux 5.2.
This reverts commit acfc9a214d01695d1676313ca80cfd2d9309f633.
diff --git a/compat-include/linux/cache.h b/compat-include/linux/cache.h
index 9ddda31232ed4b58efcb57dc2ee99ae82d09d6e2..efe440d11d04a1c3999649ba52058ad82e4d6bea 100644
--- a/compat-include/linux/cache.h
+++ b/compat-include/linux/cache.h
@@ -13,8 +13,12 @@
#include <linux/version.h>
#include_next <linux/cache.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
+/* hack for netlink.c which marked the family ops as ro */
+#ifdef __ro_after_init
+#undef __ro_after_init
+#endif
#define __ro_after_init
#endif /* < KERNEL_VERSION(4, 6, 0) */
diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index 7d17a705273650355f074788e9220fc4981b0db1..58fc24d7147a7f79c2db1976b36351d294f2aa4c 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -30,92 +30,4 @@ void batadv_genl_dump_check_consistent(struct netlink_callback *cb,
#endif /* < KERNEL_VERSION(4, 15, 0) */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
-
-struct batadv_genl_family {
- /* data handled by the actual kernel */
- struct genl_family family;
-
- /* data which has to be copied to family by
- * batadv_genl_register_family
- */
- unsigned int hdrsize;
- char name[GENL_NAMSIZ];
- unsigned int version;
- unsigned int maxattr;
- const struct nla_policy *policy;
- bool netnsok;
- int (*pre_doit)(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info);
- void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb,
- struct genl_info *info);
- const struct genl_ops *ops;
- const struct genl_multicast_group *mcgrps;
- unsigned int n_ops;
- unsigned int n_mcgrps;
- struct module *module;
-
- /* allocated by batadv_genl_register_family and free'd by
- * batadv_genl_unregister_family. Used to modify the usually read-only
- * ops
- */
- struct genl_ops *copy_ops;
-};
-
-#define genl_family batadv_genl_family
-
-static inline int batadv_genl_register_family(struct batadv_genl_family *family)
-{
- struct genl_ops *ops;
- unsigned int i;
-
- family->family.hdrsize = family->hdrsize;
- strncpy(family->family.name, family->name, sizeof(family->family.name));
- family->family.version = family->version;
- family->family.maxattr = family->maxattr;
- family->family.netnsok = family->netnsok;
- family->family.pre_doit = family->pre_doit;
- family->family.post_doit = family->post_doit;
- family->family.mcgrps = family->mcgrps;
- family->family.n_ops = family->n_ops;
- family->family.n_mcgrps = family->n_mcgrps;
- family->family.module = family->module;
-
- ops = kmemdup(family->ops, sizeof(*ops) * family->n_ops, GFP_KERNEL);
- if (!ops)
- return -ENOMEM;
-
- for (i = 0; i < family->family.n_ops; i++)
- ops[i].policy = family->policy;
-
- family->family.ops = ops;
- family->copy_ops = ops;
-
- return genl_register_family(&family->family);
-}
-
-#define genl_register_family(family) \
- batadv_genl_register_family((family))
-
-static inline void
-batadv_genl_unregister_family(struct batadv_genl_family *family)
-{
-
- genl_unregister_family(&family->family);
- kfree(family->copy_ops);
-}
-
-#define genl_unregister_family(family) \
- batadv_genl_unregister_family((family))
-
-#define genlmsg_put(_skb, _pid, _seq, _family, _flags, _cmd) \
- genlmsg_put(_skb, _pid, _seq, &(_family)->family, _flags, _cmd)
-
-#define genlmsg_multicast_netns(_family, _net, _skb, _portid, _group, _flags) \
- genlmsg_multicast_netns(&(_family)->family, _net, _skb, _portid, \
- _group, _flags)
-
-#endif /* < KERNEL_VERSION(5, 2, 0) */
-
#endif /* _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ */
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf283d7686a3 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1344,29 +1344,34 @@ static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_MESH,
/* can be retrieved by unprivileged users */
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_get_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_tp_meter_start,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER_CANCEL,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_tp_meter_cancel,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_algo_dump,
},
{
.cmd = BATADV_CMD_GET_HARDIF,
/* can be retrieved by unprivileged users */
+ .policy = batadv_netlink_policy,
.dumpit = batadv_netlink_dump_hardif,
.doit = batadv_netlink_get_hardif,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1375,57 +1380,68 @@ static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_tt_local_dump,
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_tt_global_dump,
},
{
.cmd = BATADV_CMD_GET_ORIGINATORS,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_orig_dump,
},
{
.cmd = BATADV_CMD_GET_NEIGHBORS,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_hardif_neigh_dump,
},
{
.cmd = BATADV_CMD_GET_GATEWAYS,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_gw_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_CLAIM,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_bla_claim_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_bla_backbone_dump,
},
{
.cmd = BATADV_CMD_GET_DAT_CACHE,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_dat_cache_dump,
},
{
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.dumpit = batadv_mcast_flags_dump,
},
{
.cmd = BATADV_CMD_SET_MESH,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_set_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_SET_HARDIF,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_set_hardif,
.internal_flags = BATADV_FLAG_NEED_MESH |
BATADV_FLAG_NEED_HARDIF,
@@ -1433,6 +1449,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_VLAN,
/* can be retrieved by unprivileged users */
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_get_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
BATADV_FLAG_NEED_VLAN,
@@ -1440,6 +1457,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_SET_VLAN,
.flags = GENL_ADMIN_PERM,
+ .policy = batadv_netlink_policy,
.doit = batadv_netlink_set_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
BATADV_FLAG_NEED_VLAN,
@@ -1451,7 +1469,6 @@ struct genl_family batadv_netlink_family __ro_after_init = {
.name = BATADV_NL_NAME,
.version = 1,
.maxattr = BATADV_ATTR_MAX,
- .policy = batadv_netlink_policy,
.netnsok = true,
.pre_doit = batadv_pre_doit,
.post_doit = batadv_post_doit,

View file

@ -0,0 +1,29 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sun, 7 Jul 2019 22:19:22 +0200
Subject: batman-adv: Fix netlink dumping of all mcast_flags buckets
The bucket variable is only updated outside the loop over the mcast_flags
buckets. It will only be updated during a dumping run when the dumping has
to be interrupted and a new message has to be started.
This could result in repeated or missing entries when the multicast flags
are dumped to userspace.
Fixes: 06c82b7b15b1 ("batman-adv: Add inconsistent multicast netlink dump detection")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d1de7f7aa316d6f7b3268f61afa88f5d2c1a5db5
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index ec54e236e345432496df8f55b2e00fbad92f3444..50fe9dfb088b60a911756c8c22cac1db6ef10ca4 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -1653,7 +1653,7 @@ __batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid,
while (bucket_tmp < hash->size) {
if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash,
- *bucket, &idx_tmp))
+ bucket_tmp, &idx_tmp))
break;
bucket_tmp++;