b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] batctl: Use shared batadv genl socket for requests
@ 2021-05-10 19:49 Sven Eckelmann
  2021-05-10 19:49 ` [PATCH 1/6] batctl: Consume genl ACKs after setting reads Sven Eckelmann
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

It was noticed that quite a lot of functions create their own netlink
socket just to talk to batman-adv. This is related to the old sysfs
compat code which was removed in 2021.0. So restructure the code to
make use of the existing global information in the state object.

Kind regards,
	Sven

Sven Eckelmann (6):
  batctl: Consume genl ACKs after setting reads
  batctl: throughputmeter: Use global genl socket
  batctl: interface: List using shared genl socket
  batctl: Get meshif info using shared genl socket
  batctl: Use common genl socket for netlink_query_common
  batctl: routing_algo: List using shared genl socket

 functions.c       |  15 +++---
 functions.h       |   5 +-
 gateways.c        |   3 +-
 gw_mode.c         |   3 +-
 icmp_helper.c     |  14 +++---
 icmp_helper.h     |   2 +-
 interface.c       |  77 ++++++++++++-----------------
 mcast_flags.c     |   3 +-
 netlink.c         | 121 +++++++++++++++++-----------------------------
 netlink.h         |  12 ++---
 originators.c     |   3 +-
 ping.c            |   7 +--
 routing_algo.c    |  74 +++++++++++++---------------
 sys.c             |   8 ++-
 throughputmeter.c | 105 ++++++++--------------------------------
 traceroute.c      |   7 +--
 translate.c       |   5 +-
 17 files changed, 176 insertions(+), 288 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] batctl: Consume genl ACKs after setting reads
  2021-05-10 19:49 [PATCH 0/6] batctl: Use shared batadv genl socket for requests Sven Eckelmann
@ 2021-05-10 19:49 ` Sven Eckelmann
  2021-05-10 19:49 ` [PATCH 2/6] batctl: throughputmeter: Use global genl socket Sven Eckelmann
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

The kernel is sending an ACK after an successful read request via the
batadv genl socket. This ack must be consumed manually after the actual
message was processed. Otherwise, the next user of the socket can get
confused by the unexpected ACK in the socket queue.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 sys.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sys.c b/sys.c
index 6dd8c10..f1dc275 100644
--- a/sys.c
+++ b/sys.c
@@ -107,7 +107,13 @@ int sys_simple_nlquery(struct state *state, enum batadv_nl_commands nl_cmd,
 	nl_send_auto_complete(state->sock, msg);
 	nlmsg_free(msg);
 
-	nl_recvmsgs(state->sock, state->cb);
+	if (callback) {
+		ret = nl_recvmsgs(state->sock, state->cb);
+		if (ret < 0)
+			return ret;
+	}
+
+	nl_wait_for_ack(state->sock);
 
 	return result;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] batctl: throughputmeter: Use global genl socket
  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 ` Sven Eckelmann
  2021-05-10 19:49 ` [PATCH 3/6] batctl: interface: List using shared " Sven Eckelmann
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

The batctl framework can take care of creating the netlink socket and
gathering the data for a mesh interface. It is not necessary to duplicate
all the code to create, setup and destroy the batadv genl socket for a
standard socket.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 throughputmeter.c | 105 ++++++++++------------------------------------
 1 file changed, 21 insertions(+), 84 deletions(-)

diff --git a/throughputmeter.c b/throughputmeter.c
index f50f521..7f89651 100644
--- a/throughputmeter.c
+++ b/throughputmeter.c
@@ -34,7 +34,7 @@
 #include "netlink.h"
 
 static struct ether_addr *dst_mac;
-static char *tp_mesh_iface;
+static struct state *tp_state;
 
 struct tp_result {
 	int error;
@@ -151,62 +151,34 @@ static int tp_meter_cookie_callback(struct nl_msg *msg, void *arg)
 	return NL_OK;
 }
 
-static int tp_meter_start(char *mesh_iface, struct ether_addr *dst_mac,
+
+static int tp_meter_start(struct state *state, struct ether_addr *dst_mac,
 			  uint32_t time, struct tp_cookie *cookie)
 {
-	struct nl_sock *sock;
 	struct nl_msg *msg;
 	struct nl_cb *cb;
-	int ifindex;
-	int family;
-	int ret;
 	int err = 0;
 
-	sock = nl_socket_alloc();
-	if (!sock)
-		return -ENOMEM;
-
-	ret = genl_connect(sock);
-	if (ret < 0) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
-	if (family < 0) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	ifindex = if_nametoindex(mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", mesh_iface);
-		err = -ENODEV;
-		goto out;
-	}
-
 	cb = nl_cb_alloc(NL_CB_DEFAULT);
 	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, tp_meter_cookie_callback,
 		  cookie);
 	nl_cb_err(cb, NL_CB_CUSTOM, tpmeter_nl_print_error, cookie);
 
 	msg = nlmsg_alloc();
-	if (!msg) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!msg)
+		return -ENOMEM;
 
-	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0,
+	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family, 0,
 		    0, BATADV_CMD_TP_METER, 1);
 
-	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex);
+	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, state->mesh_ifindex);
 	nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst_mac);
 	nla_put_u32(msg, BATADV_ATTR_TPMETER_TEST_TIME, time);
 
-	nl_send_auto_complete(sock, msg);
+	nl_send_auto_complete(state->sock, msg);
 	nlmsg_free(msg);
 
-	nl_recvmsgs(sock, cb);
+	nl_recvmsgs(state->sock, cb);
 
 	nl_cb_put(cb);
 
@@ -215,9 +187,6 @@ static int tp_meter_start(char *mesh_iface, struct ether_addr *dst_mac,
 	else if (!cookie->found)
 		err= -EINVAL;
 
-out:
-	nl_socket_free(sock);
-
 	return err;
 }
 
@@ -251,57 +220,24 @@ static int tp_recv_result(struct nl_sock *sock, struct tp_result *result)
 	return err;
 }
 
-static int tp_meter_stop(char *mesh_iface, struct ether_addr *dst_mac)
+static int tp_meter_stop(struct state *state, struct ether_addr *dst_mac)
 {
-	struct nl_sock *sock;
 	struct nl_msg *msg;
-	int ifindex;
-	int family;
-	int ret;
-	int err = 0;
-
-	sock = nl_socket_alloc();
-	if (!sock)
-		return -ENOMEM;
-
-	ret = genl_connect(sock);
-	if (ret < 0) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
-	if (family < 0) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	ifindex = if_nametoindex(mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", mesh_iface);
-		err = -ENODEV;
-		goto out;
-	}
 
 	msg = nlmsg_alloc();
-	if (!msg) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!msg)
+		return -ENOMEM;
 
-	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0,
+	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family, 0,
 		    0, BATADV_CMD_TP_METER_CANCEL, 1);
 
-	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex);
+	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, state->mesh_ifindex);
 	nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, dst_mac);
 
-	nl_send_auto_complete(sock, msg);
+	nl_send_auto_complete(state->sock, msg);
 	nlmsg_free(msg);
 
-out:
-	nl_socket_free(sock);
-
-	return err;
+	return 0;
 }
 
 static struct nl_sock *tp_prepare_listening_sock(void)
@@ -358,7 +294,7 @@ void tp_sig_handler(int sig)
 	case SIGINT:
 	case SIGTERM:
 		fflush(stdout);
-		tp_meter_stop(tp_mesh_iface, dst_mac);
+		tp_meter_stop(tp_state, dst_mac);
 		break;
 	default:
 		break;
@@ -443,7 +379,7 @@ static int throughputmeter(struct state *state, int argc, char **argv)
 		dst_string = ether_ntoa_long(dst_mac);
 
 	/* for sighandler */
-	tp_mesh_iface = state->mesh_iface;
+	tp_state = state;
 	signal(SIGINT, tp_sig_handler);
 	signal(SIGTERM, tp_sig_handler);
 
@@ -451,7 +387,7 @@ static int throughputmeter(struct state *state, int argc, char **argv)
 	if (!listen_sock)
 		goto out;
 
-	ret = tp_meter_start(state->mesh_iface, dst_mac, time, &cookie);
+	ret = tp_meter_start(state, dst_mac, time, &cookie);
 	if (ret < 0) {
 		printf("Failed to send tp_meter request to kernel: %d\n", ret);
 		goto out;
@@ -529,5 +465,6 @@ static int throughputmeter(struct state *state, int argc, char **argv)
 	return ret;
 }
 
-COMMAND(SUBCOMMAND_MIF, throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, NULL,
+COMMAND(SUBCOMMAND_MIF, throughputmeter, "tp",
+	COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, NULL,
 	"<destination>     \tstart a throughput measurement");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] batctl: interface: List using shared genl socket
  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
  2021-05-10 19:49 ` [PATCH 4/6] batctl: Get meshif info " Sven Eckelmann
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] batctl: Get meshif info using shared genl socket
  2021-05-10 19:49 [PATCH 0/6] batctl: Use shared batadv genl socket for requests Sven Eckelmann
                   ` (2 preceding siblings ...)
  2021-05-10 19:49 ` [PATCH 3/6] batctl: interface: List using shared " Sven Eckelmann
@ 2021-05-10 19:49 ` 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
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

All subcommands which are using the netlink_get_info helper are already
creating state object with batadv genl socket. It is not necessary to
create a new one just to request data from the kernel.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 gateways.c    |  3 +--
 mcast_flags.c |  3 +--
 netlink.c     | 40 +++++++++++++---------------------------
 netlink.h     |  2 +-
 originators.c |  3 +--
 5 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/gateways.c b/gateways.c
index 7625bd8..bdd6795 100644
--- a/gateways.c
+++ b/gateways.c
@@ -122,8 +122,7 @@ static int netlink_print_gateways(struct state *state, char *orig_iface,
 
 	/* only parse routing algorithm name */
 	last_err = -EINVAL;
-	info_header = netlink_get_info(state->mesh_ifindex,
-				       BATADV_CMD_GET_ORIGINATORS, NULL);
+	info_header = netlink_get_info(state, BATADV_CMD_GET_ORIGINATORS, NULL);
 	free(info_header);
 
 	if (strlen(algo_name_buf) == 0)
diff --git a/mcast_flags.c b/mcast_flags.c
index 721f549..44344e0 100644
--- a/mcast_flags.c
+++ b/mcast_flags.c
@@ -104,8 +104,7 @@ static int netlink_print_mcast_flags(struct state *state, char *orig_iface,
 	int ret;
 
 	/* only parse own multicast flags */
-	info_header = netlink_get_info(state->mesh_ifindex,
-				       BATADV_CMD_GET_MCAST_FLAGS, NULL);
+	info_header = netlink_get_info(state, BATADV_CMD_GET_MCAST_FLAGS, NULL);
 	free(info_header);
 
 	if (mcast_flags == -EOPNOTSUPP || mcast_flags_priv == -EOPNOTSUPP)
diff --git a/netlink.c b/netlink.c
index 31c9b01..e3a7b7c 100644
--- a/netlink.c
+++ b/netlink.c
@@ -339,60 +339,46 @@ static int info_callback(struct nl_msg *msg, void *arg)
 			opts->remaining_header = NULL;
 	}
 
-	return NL_STOP;
+	return NL_OK;
 }
 
-char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header)
+char *netlink_get_info(struct state *state, uint8_t nl_cmd, const char *header)
 {
-	struct nl_sock *sock;
 	struct nl_msg *msg;
 	struct nl_cb *cb;
-	int family;
 	struct print_opts opts = {
 		.read_opt = 0,
 		.nl_cmd = nl_cmd,
 		.remaining_header = NULL,
 		.static_header = header,
 	};
-
-	sock = nl_socket_alloc();
-	if (!sock)
-		return NULL;
-
-	genl_connect(sock);
-
-	family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
-	if (family < 0) {
-		nl_socket_free(sock);
-		return NULL;
-	}
+	int ret;
 
 	msg = nlmsg_alloc();
-	if (!msg) {
-		nl_socket_free(sock);
+	if (!msg)
 		return NULL;
-	}
 
-	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, 0,
+	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family, 0, 0,
 		    BATADV_CMD_GET_MESH_INFO, 1);
 
-	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex);
+	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, state->mesh_ifindex);
 
-	nl_send_auto_complete(sock, msg);
+	nl_send_auto_complete(state->sock, msg);
 
 	nlmsg_free(msg);
 
 	cb = nl_cb_alloc(NL_CB_DEFAULT);
 	if (!cb)
-		goto err_free_sock;
+		return NULL;
 
 	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, info_callback, &opts);
 	nl_cb_err(cb, NL_CB_CUSTOM, netlink_print_error, NULL);
 
-	nl_recvmsgs(sock, cb);
+	ret = nl_recvmsgs(state->sock, cb);
+	if (ret < 0)
+		return opts.remaining_header;
 
-err_free_sock:
-	nl_socket_free(sock);
+	nl_wait_for_ack(state->sock);
 
 	return opts.remaining_header;
 }
@@ -458,7 +444,7 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt,
 			printf("\033[2J\033[0;0f");
 
 		if (!(read_opt & SKIP_HEADER))
-			opts.remaining_header = netlink_get_info(state->mesh_ifindex,
+			opts.remaining_header = netlink_get_info(state,
 								 nl_cmd,
 								 header);
 
diff --git a/netlink.h b/netlink.h
index 4ee2f39..48a2a23 100644
--- a/netlink.h
+++ b/netlink.h
@@ -30,7 +30,7 @@ struct ether_addr;
 int netlink_create(struct state *state);
 void netlink_destroy(struct state *state);
 
-char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header);
+char *netlink_get_info(struct state *state, uint8_t nl_cmd, const char *header);
 int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
 			  struct ether_addr *mac_out);
 int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac,
diff --git a/originators.c b/originators.c
index 8a29dd7..a8b313e 100644
--- a/originators.c
+++ b/originators.c
@@ -174,8 +174,7 @@ static int netlink_print_originators(struct state *state, char *orig_iface,
 
 	/* only parse routing algorithm name */
 	last_err = -EINVAL;
-	info_header = netlink_get_info(state->mesh_ifindex,
-				       BATADV_CMD_GET_ORIGINATORS, NULL);
+	info_header = netlink_get_info(state, BATADV_CMD_GET_ORIGINATORS, NULL);
 	free(info_header);
 
 	if (strlen(algo_name_buf) == 0)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] batctl: Use common genl socket for netlink_query_common
  2021-05-10 19:49 [PATCH 0/6] batctl: Use shared batadv genl socket for requests Sven Eckelmann
                   ` (3 preceding siblings ...)
  2021-05-10 19:49 ` [PATCH 4/6] batctl: Get meshif info " Sven Eckelmann
@ 2021-05-10 19:49 ` Sven Eckelmann
  2021-05-10 19:49 ` [PATCH 6/6] batctl: routing_algo: List using shared genl socket Sven Eckelmann
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

All functions which use the netlink_query_common can be changed to provide
the socket for batadv genl operations in the state object. Either by
manually calling netlink_create or by simply using the
COMMAND_FLAG_NETLINK.

This makes is unnecessary to allocate a new netlink socket and resolve the
generic netlink family for each helper function call.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 functions.c    | 15 +++++-----
 functions.h    |  5 ++--
 gw_mode.c      |  3 +-
 icmp_helper.c  | 14 ++++-----
 icmp_helper.h  |  2 +-
 netlink.c      | 81 +++++++++++++++++++-------------------------------
 netlink.h      | 10 +++----
 ping.c         |  7 +++--
 routing_algo.c | 23 ++++++++++----
 traceroute.c   |  7 +++--
 translate.c    |  5 ++--
 11 files changed, 84 insertions(+), 88 deletions(-)

diff --git a/functions.c b/functions.c
index 0dbf2ed..617fc5b 100644
--- a/functions.c
+++ b/functions.c
@@ -171,7 +171,7 @@ int read_file(const char *full_path, int read_opt)
 	return res;
 }
 
-struct ether_addr *translate_mac(const char *mesh_iface,
+struct ether_addr *translate_mac(struct state *state,
 				 const struct ether_addr *mac)
 {
 	struct ether_addr in_mac;
@@ -188,14 +188,16 @@ struct ether_addr *translate_mac(const char *mesh_iface,
 	if (!ether_addr_valid(in_mac.ether_addr_octet))
 		return mac_result;
 
-	translate_mac_netlink(mesh_iface, &in_mac, mac_result);
+	translate_mac_netlink(state, &in_mac, mac_result);
 
 	return mac_result;
 }
 
-int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len)
+int get_algoname(struct state *state, unsigned int mesh_ifindex,
+		 char *algoname, size_t algoname_len)
 {
-	return get_algoname_netlink(mesh_iface, algoname, algoname_len);
+	return get_algoname_netlink(state, mesh_ifindex, algoname,
+				    algoname_len);
 }
 
 static int resolve_l3addr(int ai_family, const char *asc, void *l3addr)
@@ -340,10 +342,7 @@ static int resolve_mac_from_parse(struct nl_msg *msg, void *arg)
 	}
 
 err:
-	if (nl_arg->found)
-		return NL_STOP;
-	else
-		return NL_OK;
+	return NL_OK;
 }
 
 static struct ether_addr *resolve_mac_from_cache(int ai_family,
diff --git a/functions.h b/functions.h
index 3bb66f6..860d9f4 100644
--- a/functions.h
+++ b/functions.h
@@ -44,7 +44,7 @@ char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt);
 char *get_name_by_macstr(char *mac_str, int read_opt);
 int file_exists(const char *fpath);
 int read_file(const char *full_path, int read_opt);
-struct ether_addr *translate_mac(const char *mesh_iface,
+struct ether_addr *translate_mac(struct state *state,
 				 const struct ether_addr *mac);
 struct ether_addr *resolve_mac(const char *asc);
 int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
@@ -54,7 +54,8 @@ 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 guess_netdev_type(const char *netdev, enum selector_prefix *type);
-int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
+int get_algoname(struct state *state, unsigned int mesh_ifindex,
+		 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/gw_mode.c b/gw_mode.c
index 0bc99e2..93f255c 100644
--- a/gw_mode.c
+++ b/gw_mode.c
@@ -46,7 +46,8 @@ static bool is_throughput_select_class(struct state *state)
 	char algoname[32];
 	int ret;
 
-	ret = get_algoname(state->mesh_iface, algoname, sizeof(algoname));
+	ret = get_algoname(state, state->mesh_ifindex, algoname,
+			   sizeof(algoname));
 
 	/* no algo name -> assume that it is a pre-B.A.T.M.A.N. V version */
 	if (ret < 0)
diff --git a/icmp_helper.c b/icmp_helper.c
index 3aa49c0..cbb6122 100644
--- a/icmp_helper.c
+++ b/icmp_helper.c
@@ -314,13 +314,11 @@ static void icmp_interface_sweep(void)
 	}
 }
 
-static int icmp_interface_update(const char *mesh_iface)
+static int icmp_interface_update(struct state *state)
 {
 	struct icmp_interface_update_arg update_arg;
 
-	update_arg.ifindex = if_nametoindex(mesh_iface);
-	if (!update_arg.ifindex)
-		return -errno;
+	update_arg.ifindex = state->mesh_ifindex;
 
 	/* unmark current interface - will be marked again by query */
 	icmp_interface_unmark();
@@ -331,7 +329,7 @@ static int icmp_interface_update(const char *mesh_iface)
 	/* remove old interfaces */
 	icmp_interface_sweep();
 
-	get_primarymac_netlink(mesh_iface, primary_mac);
+	get_primarymac_netlink(state, primary_mac);
 
 	return 0;
 }
@@ -355,7 +353,7 @@ static int icmp_interface_send(struct batadv_icmp_header *icmp_packet,
 	return (int)writev(iface->sock, vector, 2);
 }
 
-int icmp_interface_write(const char *mesh_iface,
+int icmp_interface_write(struct state *state,
 			 struct batadv_icmp_header *icmp_packet, size_t len)
 {
 	struct batadv_icmp_packet_rr *icmp_packet_rr;
@@ -380,7 +378,7 @@ int icmp_interface_write(const char *mesh_iface,
 	if (icmp_packet->msg_type != BATADV_ECHO_REQUEST)
 		return -EINVAL;
 
-	icmp_interface_update(mesh_iface);
+	icmp_interface_update(state);
 
 	if (list_empty(&interface_list))
 		return -EFAULT;
@@ -388,7 +386,7 @@ int icmp_interface_write(const char *mesh_iface,
 	/* find best neighbor */
 	memcpy(&mac, icmp_packet->dst, ETH_ALEN);
 
-	ret = get_nexthop_netlink(mesh_iface, &mac, nexthop, ifname);
+	ret = get_nexthop_netlink(state, &mac, nexthop, ifname);
 	if (ret < 0)
 		goto dst_unreachable;
 
diff --git a/icmp_helper.h b/icmp_helper.h
index 6f84d34..5eed55e 100644
--- a/icmp_helper.h
+++ b/icmp_helper.h
@@ -35,7 +35,7 @@ struct icmp_interface {
 };
 
 int icmp_interfaces_init(void);
-int icmp_interface_write(const char *mesh_iface,
+int icmp_interface_write(struct state *state,
 			 struct batadv_icmp_header *icmp_packet, size_t len);
 void icmp_interfaces_clean(void);
 ssize_t icmp_interface_read(struct batadv_icmp_header *icmp_packet, size_t len,
diff --git a/netlink.c b/netlink.c
index e3a7b7c..b8bca30 100644
--- a/netlink.c
+++ b/netlink.c
@@ -503,46 +503,20 @@ static int nlquery_stop_cb(struct nl_msg *msg, void *arg)
 	return NL_STOP;
 }
 
-static int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd,
+static int netlink_query_common(struct state *state,
+				unsigned int mesh_ifindex, uint8_t nl_cmd,
 				nl_recvmsg_msg_cb_t callback, int flags,
 				struct nlquery_opts *query_opts)
 {
-	struct nl_sock *sock;
 	struct nl_msg *msg;
 	struct nl_cb *cb;
-	int ifindex;
-	int family;
 	int ret;
 
 	query_opts->err = 0;
 
-	sock = nl_socket_alloc();
-	if (!sock)
-		return -ENOMEM;
-
-	ret = genl_connect(sock);
-	if (ret < 0) {
-		query_opts->err = ret;
-		goto err_free_sock;
-	}
-
-	family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
-	if (family < 0) {
-		query_opts->err = -EOPNOTSUPP;
-		goto err_free_sock;
-	}
-
-	ifindex = if_nametoindex(mesh_iface);
-	if (!ifindex) {
-		query_opts->err = -ENODEV;
-		goto err_free_sock;
-	}
-
 	cb = nl_cb_alloc(NL_CB_DEFAULT);
-	if (!cb) {
-		query_opts->err = -ENOMEM;
-		goto err_free_sock;
-	}
+	if (!cb)
+		return -ENOMEM;
 
 	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, query_opts);
 	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nlquery_stop_cb, query_opts);
@@ -554,19 +528,24 @@ static int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd,
 		goto err_free_cb;
 	}
 
-	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, flags,
-		    nl_cmd, 1);
+	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family, 0,
+		    flags, nl_cmd, 1);
 
-	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex);
-	nl_send_auto_complete(sock, msg);
+	nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, mesh_ifindex);
+	nl_send_auto_complete(state->sock, msg);
 	nlmsg_free(msg);
 
-	nl_recvmsgs(sock, cb);
+	ret = nl_recvmsgs(state->sock, cb);
+	if (ret < 0) {
+		query_opts->err = ret;
+		goto err_free_cb;
+	}
+
+	if (!(flags & NLM_F_DUMP))
+		nl_wait_for_ack(state->sock);
 
 err_free_cb:
 	nl_cb_put(cb);
-err_free_sock:
-	nl_socket_free(sock);
 
 	return query_opts->err;
 }
@@ -625,10 +604,10 @@ static int translate_mac_netlink_cb(struct nl_msg *msg, void *arg)
 	opts->found = true;
 	opts->query_opts.err = 0;
 
-	return NL_STOP;
+	return NL_OK;
 }
 
-int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
+int translate_mac_netlink(struct state *state, const struct ether_addr *mac,
 			  struct ether_addr *mac_out)
 {
 	struct translate_mac_netlink_opts opts = {
@@ -641,7 +620,7 @@ int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
 
 	memcpy(&opts.mac, mac, ETH_ALEN);
 
-	ret = netlink_query_common(mesh_iface,
+	ret = netlink_query_common(state, state->mesh_ifindex,
 				   BATADV_CMD_GET_TRANSTABLE_GLOBAL,
 			           translate_mac_netlink_cb, NLM_F_DUMP,
 				   &opts.query_opts);
@@ -721,10 +700,10 @@ static int get_nexthop_netlink_cb(struct nl_msg *msg, void *arg)
 	opts->found = true;
 	opts->query_opts.err = 0;
 
-	return NL_STOP;
+	return NL_OK;
 }
 
-int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac,
+int get_nexthop_netlink(struct state *state, const struct ether_addr *mac,
 			uint8_t *nexthop, char *ifname)
 {
 	struct get_nexthop_netlink_opts opts = {
@@ -740,7 +719,8 @@ int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac,
 	opts.nexthop = nexthop;
 	opts.ifname = ifname;
 
-	ret = netlink_query_common(mesh_iface,  BATADV_CMD_GET_ORIGINATORS,
+	ret = netlink_query_common(state, state->mesh_ifindex,
+				   BATADV_CMD_GET_ORIGINATORS,
 			           get_nexthop_netlink_cb, NLM_F_DUMP,
 				   &opts.query_opts);
 	if (ret < 0)
@@ -799,10 +779,10 @@ static int get_primarymac_netlink_cb(struct nl_msg *msg, void *arg)
 	opts->found = true;
 	opts->query_opts.err = 0;
 
-	return NL_STOP;
+	return NL_OK;
 }
 
-int get_primarymac_netlink(const char *mesh_iface, uint8_t *primarymac)
+int get_primarymac_netlink(struct state *state, uint8_t *primarymac)
 {
 	struct get_primarymac_netlink_opts opts = {
 		.primarymac = 0,
@@ -815,7 +795,8 @@ int get_primarymac_netlink(const char *mesh_iface, uint8_t *primarymac)
 
 	opts.primarymac = primarymac;
 
-	ret = netlink_query_common(mesh_iface, BATADV_CMD_GET_MESH_INFO,
+	ret = netlink_query_common(state, state->mesh_ifindex,
+				   BATADV_CMD_GET_MESH_INFO,
 			           get_primarymac_netlink_cb, 0,
 				   &opts.query_opts);
 	if (ret < 0)
@@ -875,11 +856,11 @@ static int get_algoname_netlink_cb(struct nl_msg *msg, void *arg)
 	opts->found = true;
 	opts->query_opts.err = 0;
 
-	return NL_STOP;
+	return NL_OK;
 }
 
-int get_algoname_netlink(const char *mesh_iface, char *algoname,
-			 size_t algoname_len)
+int get_algoname_netlink(struct state *state, unsigned int mesh_ifindex,
+			 char *algoname, size_t algoname_len)
 {
 	struct get_algoname_netlink_opts opts = {
 		.algoname = algoname,
@@ -891,7 +872,7 @@ int get_algoname_netlink(const char *mesh_iface, char *algoname,
 	};
 	int ret;
 
-	ret = netlink_query_common(mesh_iface, BATADV_CMD_GET_MESH,
+	ret = netlink_query_common(state, mesh_ifindex, BATADV_CMD_GET_MESH,
 			           get_algoname_netlink_cb, 0,
 				   &opts.query_opts);
 	if (ret < 0)
diff --git a/netlink.h b/netlink.h
index 48a2a23..2cc5862 100644
--- a/netlink.h
+++ b/netlink.h
@@ -31,13 +31,13 @@ int netlink_create(struct state *state);
 void netlink_destroy(struct state *state);
 
 char *netlink_get_info(struct state *state, uint8_t nl_cmd, const char *header);
-int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
+int translate_mac_netlink(struct state *state, const struct ether_addr *mac,
 			  struct ether_addr *mac_out);
-int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac,
+int get_nexthop_netlink(struct state *state, const struct ether_addr *mac,
 			uint8_t *nexthop, char *ifname);
-int get_primarymac_netlink(const char *mesh_iface, uint8_t *primarymac);
-int get_algoname_netlink(const char *mesh_iface, char *algoname,
-			 size_t algoname_len);
+int get_primarymac_netlink(struct state *state, uint8_t *primarymac);
+int get_algoname_netlink(struct state *state, unsigned int mesh_ifindex,
+			 char *algoname, size_t algoname_len);
 
 extern struct nla_policy batadv_netlink_policy[];
 
diff --git a/ping.c b/ping.c
index a9f0913..7565dcd 100644
--- a/ping.c
+++ b/ping.c
@@ -136,7 +136,7 @@ static int ping(struct state *state, int argc, char **argv)
 	}
 
 	if (!disable_translate_mac)
-		dst_mac = translate_mac(state->mesh_iface, dst_mac);
+		dst_mac = translate_mac(state, dst_mac);
 
 	mac_string = ether_ntoa_long(dst_mac);
 	signal(SIGINT, sig_handler);
@@ -177,7 +177,7 @@ static int ping(struct state *state, int argc, char **argv)
 
 		icmp_packet_out.seqno = htons(++seq_counter);
 
-		res = icmp_interface_write(state->mesh_iface,
+		res = icmp_interface_write(state,
 					   (struct batadv_icmp_header *)&icmp_packet_out,
 					   packet_len);
 		if (res < 0) {
@@ -323,5 +323,6 @@ static int ping(struct state *state, int argc, char **argv)
 	return ret;
 }
 
-COMMAND(SUBCOMMAND_MIF, ping, "p", COMMAND_FLAG_MESH_IFACE, NULL,
+COMMAND(SUBCOMMAND_MIF, ping, "p",
+	COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, NULL,
 	"<destination>     \tping another batman adv host via layer 2");
diff --git a/routing_algo.c b/routing_algo.c
index 01376bc..8fb4fab 100644
--- a/routing_algo.c
+++ b/routing_algo.c
@@ -168,6 +168,7 @@ static struct nla_policy link_policy[IFLA_MAX + 1] = {
 
 struct print_ra_interfaces_rtnl_arg {
 	uint8_t header_shown:1;
+	struct state *state;
 };
 
 static int print_ra_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
@@ -190,7 +191,8 @@ static int print_ra_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
 
 	mesh_iface = nla_get_string(attrs[IFLA_IFNAME]);
 
-	ret = get_algoname_netlink(mesh_iface, algoname, sizeof(algoname));
+	ret = get_algoname_netlink(print_arg->state, ifm->ifi_index, algoname,
+				   sizeof(algoname));
 	if (ret < 0)
 		goto err;
 
@@ -205,9 +207,11 @@ static int print_ra_interfaces_rtnl_parse(struct nl_msg *msg, void *arg)
 	return NL_OK;
 }
 
-static int print_ra_interfaces(void)
+static int print_ra_interfaces(struct state *state)
 {
-	struct print_ra_interfaces_rtnl_arg print_arg = {};
+	struct print_ra_interfaces_rtnl_arg print_arg = {
+		.state = state,
+	};
 
 	struct ifinfomsg rt_hdr = {
 		.ifi_family = IFLA_UNSPEC,
@@ -282,10 +286,11 @@ static int print_ra_interfaces(void)
 	return err;
 }
 
-static int routing_algo(struct state *state __maybe_unused, int argc, char **argv)
+static int routing_algo(struct state *state, int argc, char **argv)
 {
 	int optchar;
 	int res = EXIT_FAILURE;
+	int ret;
 
 	while ((optchar = getopt(argc, argv, "h")) != -1) {
 		switch (optchar) {
@@ -303,7 +308,15 @@ static int routing_algo(struct state *state __maybe_unused, int argc, char **arg
 	if (argc == 2)
 		return write_default_ra(SYS_SELECTED_RA_PATH, argv[1]);
 
-	print_ra_interfaces();
+	/* duplicated code here from the main() because interface doesn't always
+	 * need COMMAND_FLAG_MESH_IFACE and COMMAND_FLAG_NETLINK
+	 */
+	ret = netlink_create(state);
+	if (ret < 0)
+		return EXIT_FAILURE;
+
+	print_ra_interfaces(state);
+	netlink_destroy(state);
 
 	res = read_file(SYS_SELECTED_RA_PATH, USE_READ_BUFF);
 	if (res != EXIT_SUCCESS)
diff --git a/traceroute.c b/traceroute.c
index 517962f..40e1e8f 100644
--- a/traceroute.c
+++ b/traceroute.c
@@ -97,7 +97,7 @@ static int traceroute(struct state *state, int argc, char **argv)
 	}
 
 	if (!disable_translate_mac)
-		dst_mac = translate_mac(state->mesh_iface, dst_mac);
+		dst_mac = translate_mac(state, dst_mac);
 
 	mac_string = ether_ntoa_long(dst_mac);
 
@@ -124,7 +124,7 @@ static int traceroute(struct state *state, int argc, char **argv)
 			icmp_packet_out.seqno = htons(++seq_counter);
 			time_delta[i] = 0.0;
 
-			res = icmp_interface_write(state->mesh_iface,
+			res = icmp_interface_write(state,
 					   (struct batadv_icmp_header *)&icmp_packet_out,
 					   sizeof(icmp_packet_out));
 			if (res < 0) {
@@ -209,5 +209,6 @@ static int traceroute(struct state *state, int argc, char **argv)
 	return ret;
 }
 
-COMMAND(SUBCOMMAND_MIF, traceroute, "tr", COMMAND_FLAG_MESH_IFACE, NULL,
+COMMAND(SUBCOMMAND_MIF, traceroute, "tr",
+	COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, NULL,
 	"<destination>     \ttraceroute another batman adv host via layer 2");
diff --git a/translate.c b/translate.c
index 6eef476..92451c9 100644
--- a/translate.c
+++ b/translate.c
@@ -50,7 +50,7 @@ static int translate(struct state *state, int argc, char **argv)
 		}
 	}
 
-	dst_mac = translate_mac(state->mesh_iface, dst_mac);
+	dst_mac = translate_mac(state, dst_mac);
 	if (dst_mac) {
 		mac_string = ether_ntoa_long(dst_mac);
 		printf("%s\n", mac_string);
@@ -64,5 +64,6 @@ static int translate(struct state *state, int argc, char **argv)
 	return ret;
 }
 
-COMMAND(SUBCOMMAND_MIF, translate, "t", COMMAND_FLAG_MESH_IFACE, NULL,
+COMMAND(SUBCOMMAND_MIF, translate, "t",
+	COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, NULL,
 	"<destination>     \ttranslate a destination to the originator responsible for it");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] batctl: routing_algo: List using shared genl socket
  2021-05-10 19:49 [PATCH 0/6] batctl: Use shared batadv genl socket for requests Sven Eckelmann
                   ` (4 preceding siblings ...)
  2021-05-10 19:49 ` [PATCH 5/6] batctl: Use common genl socket for netlink_query_common Sven Eckelmann
@ 2021-05-10 19:49 ` Sven Eckelmann
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2021-05-10 19:49 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

The interface subcommand doesn't need to allocate a new netlink socket to
get the list of interfaces. There is already a netlink socket available
which was used to query the routing algorithm of each interface.
Just use this batadv genl socket to also dump the list of all available
routing algorithms.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 routing_algo.c | 53 ++++++++++++++++----------------------------------
 1 file changed, 17 insertions(+), 36 deletions(-)

diff --git a/routing_algo.c b/routing_algo.c
index 8fb4fab..0adf32f 100644
--- a/routing_algo.c
+++ b/routing_algo.c
@@ -79,58 +79,35 @@ static int routing_algos_callback(struct nl_msg *msg, void *arg __maybe_unused)
 	return NL_OK;
 }
 
-static int print_routing_algos(void)
+static int print_routing_algos(struct state *state)
 {
-	struct nl_sock *sock;
 	struct nl_msg *msg;
 	struct nl_cb *cb;
-	int family;
 	struct print_opts opts = {
 		.callback = routing_algos_callback,
 	};
 
-	sock = nl_socket_alloc();
-	if (!sock)
-		return -ENOMEM;
-
-	genl_connect(sock);
-
-	family = genl_ctrl_resolve(sock, BATADV_NL_NAME);
-	if (family < 0) {
-		last_err = -EOPNOTSUPP;
-		goto err_free_sock;
-	}
-
 	msg = nlmsg_alloc();
-	if (!msg) {
-		last_err = -ENOMEM;
-		goto err_free_sock;
-	}
-
-	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_DUMP,
-		    BATADV_CMD_GET_ROUTING_ALGOS, 1);
-
-	nl_send_auto_complete(sock, msg);
+	if (!msg)
+		return -ENOMEM;
 
+	genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family, 0,
+		    NLM_F_DUMP, BATADV_CMD_GET_ROUTING_ALGOS, 1);
+	nl_send_auto_complete(state->sock, msg);
 	nlmsg_free(msg);
 
 	opts.remaining_header = strdup("Available routing algorithms:\n");
 
 	cb = nl_cb_alloc(NL_CB_DEFAULT);
-	if (!cb) {
-		last_err = -ENOMEM;
-		goto err_free_sock;
-	}
+	if (!cb)
+		return -ENOMEM;
 
 	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb,
 		  &opts);
 	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, netlink_stop_callback, NULL);
 	nl_cb_err(cb, NL_CB_CUSTOM, netlink_print_error, NULL);
 
-	nl_recvmsgs(sock, cb);
-
-err_free_sock:
-	nl_socket_free(sock);
+	nl_recvmsgs(state->sock, cb);
 
 	if (!last_err)
 		netlink_print_remaining_header(&opts);
@@ -316,19 +293,23 @@ static int routing_algo(struct state *state, int argc, char **argv)
 		return EXIT_FAILURE;
 
 	print_ra_interfaces(state);
-	netlink_destroy(state);
 
 	res = read_file(SYS_SELECTED_RA_PATH, USE_READ_BUFF);
 	if (res != EXIT_SUCCESS)
-		return EXIT_FAILURE;
+		goto err_free_netlink;
 
 	printf("Selected routing algorithm (used when next batX interface is created):\n");
 	printf(" => %s\n", line_ptr);
 	free(line_ptr);
 	line_ptr = NULL;
 
-	print_routing_algos();
-	return EXIT_SUCCESS;
+	print_routing_algos(state);
+	res = EXIT_SUCCESS;
+
+err_free_netlink:
+	netlink_destroy(state);
+
+	return res;
 }
 
 COMMAND(SUBCOMMAND, routing_algo, "ra", 0, NULL,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-05-10 19:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 3/6] batctl: interface: List using shared " Sven Eckelmann
2021-05-10 19:49 ` [PATCH 4/6] batctl: Get meshif info " 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

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).