@@ -62,65 +62,46 @@ static int get_iface_status_netlink_parse(struct nl_msg *msg, void *arg)
iface_status[IFACE_STATUS_LEN - 1] = '\0';
- return NL_STOP;
+ return NL_OK;
}
-static char *get_iface_status_netlink(unsigned int meshif, unsigned int hardif,
+static char *get_iface_status_netlink(struct state *state, 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,
+ nl_cb_set(state->cb, NL_CB_VALID, NL_CB_CUSTOM, get_iface_status_netlink_parse,
iface_status);
msg = nlmsg_alloc();
if (!msg)
- goto err_free_cb;
+ return NULL;
- genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, batadv_family,
+ genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family,
0, 0, BATADV_CMD_GET_HARDIF, 1);
- nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, meshif);
+ nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, state->mesh_ifindex);
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, hardif);
- ret = nl_send_auto_complete(sock, msg);
+ ret = nl_send_auto_complete(state->sock, msg);
+ if (ret < 0)
+ goto err_free_msg;
+
+ ret = nl_recvmsgs(state->sock, state->cb);
if (ret < 0)
goto err_free_msg;
- nl_recvmsgs(sock, cb);
+ nl_wait_for_ack(state->sock);
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;
}
@@ -130,20 +111,16 @@ static struct nla_policy link_policy[IFLA_MAX + 1] = {
[IFLA_MASTER] = { .type = NLA_U32 },
};
-struct print_interfaces_rtnl_arg {
- int ifindex;
-};
-
static int print_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
{
- struct print_interfaces_rtnl_arg *print_arg = arg;
char iface_status[IFACE_STATUS_LEN];
struct nlattr *attrs[IFLA_MAX + 1];
+ struct state *state = arg;
struct ifinfomsg *ifm;
+ unsigned int master;
char *ifname;
int ret;
const char *status;
- int master;
ifm = nlmsg_data(nlmsg_hdr(msg));
ret = nlmsg_parse(nlmsg_hdr(msg), sizeof(*ifm), attrs, IFLA_MAX,
@@ -161,10 +138,10 @@ static int print_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
master = nla_get_u32(attrs[IFLA_MASTER]);
/* required on older kernels which don't prefilter the results */
- if (master != print_arg->ifindex)
+ if (master != state->mesh_ifindex)
goto err;
- status = get_iface_status_netlink(master, ifm->ifi_index, iface_status);
+ status = get_iface_status_netlink(state, ifm->ifi_index, iface_status);
if (!status)
status = "<error reading status>\n";
@@ -174,21 +151,29 @@ static int print_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
return NL_OK;
}
-static int print_interfaces(char *mesh_iface)
+static int print_interfaces(struct state *state)
{
- struct print_interfaces_rtnl_arg print_arg;
+ int ret;
if (!file_exists(module_ver_path)) {
fprintf(stderr, "Error - batman-adv module has not been loaded\n");
return EXIT_FAILURE;
}
- print_arg.ifindex = if_nametoindex(mesh_iface);
- if (!print_arg.ifindex)
+ /* duplicated code here from the main() because interface doesn't always
+ * need COMMAND_FLAG_MESH_IFACE and COMMAND_FLAG_NETLINK
+ */
+ if (check_mesh_iface(state))
return EXIT_FAILURE;
- query_rtnl_link(print_arg.ifindex, print_interfaces_rtnl_parse,
- &print_arg);
+ ret = netlink_create(state);
+ if (ret < 0)
+ return EXIT_FAILURE;
+
+ query_rtnl_link(state->mesh_ifindex, print_interfaces_rtnl_parse,
+ state);
+
+ netlink_destroy(state);
return EXIT_SUCCESS;
}
@@ -452,7 +437,7 @@ static int interface(struct state *state, int argc, char **argv)
rest_argv = &argv[optind];
if (rest_argc == 0)
- return print_interfaces(state->mesh_iface);
+ return print_interfaces(state);
check_root_or_die("batctl interface");