b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: Sven Eckelmann <sven@narfation.org>
Subject: [PATCH 3/6] batctl: interface: List using shared genl socket
Date: Mon, 10 May 2021 21:49:42 +0200	[thread overview]
Message-ID: <20210510194945.103735-4-sven@narfation.org> (raw)
In-Reply-To: <20210510194945.103735-1-sven@narfation.org>

The interface subcommand doesn't need to allocate a new netlink socket to
query the state of a single interface. But it can also not use the socket
which is automatically pre-configured by COMMAND_FLAG_NETLINK because the
(main sub)command might also be started for interfaces which might not
exist yet.

Instead use the shared functions to pre-allocate the necessary state
information when calling the "list" sub-subcommand.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 interface.c | 77 +++++++++++++++++++++--------------------------------
 1 file changed, 31 insertions(+), 46 deletions(-)

diff --git a/interface.c b/interface.c
index cf9c0c3..a96a328 100644
--- a/interface.c
+++ b/interface.c
@@ -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");
 
-- 
2.30.2


  parent reply	other threads:[~2021-05-10 19:49 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-10 19:49 [PATCH 0/6] batctl: Use shared batadv genl socket for requests Sven Eckelmann
2021-05-10 19:49 ` [PATCH 1/6] batctl: Consume genl ACKs after setting reads Sven Eckelmann
2021-05-10 19:49 ` [PATCH 2/6] batctl: throughputmeter: Use global genl socket Sven Eckelmann
2021-05-10 19:49 ` Sven Eckelmann [this message]
2021-05-10 19:49 ` [PATCH 4/6] batctl: Get meshif info using shared " Sven Eckelmann
2021-05-10 19:49 ` [PATCH 5/6] batctl: Use common genl socket for netlink_query_common Sven Eckelmann
2021-05-10 19:49 ` [PATCH 6/6] batctl: routing_algo: List using shared genl socket Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210510194945.103735-4-sven@narfation.org \
    --to=sven@narfation.org \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).