diff mbox series

[5/6] batctl: Use common genl socket for netlink_query_common

Message ID 20210510194945.103735-6-sven@narfation.org
State Accepted, archived
Delegated to: Simon Wunderlich
Headers show
Series batctl: Use shared batadv genl socket for requests | expand

Commit Message

Sven Eckelmann May 10, 2021, 7:49 p.m. UTC
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 mbox series

Patch

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");