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 --- vis/vis.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 128 insertions(+), 16 deletions(-)
diff --git a/vis/vis.c b/vis/vis.c index 37956b1..9474563 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; }