From 8c362e3bbf821372ff77084c01577bc651ca7d6c Mon Sep 17 00:00:00 2001
From: Jan Luebbe <sho@stratum0.net>
Date: Sun, 16 Apr 2023 17:44:09 +0200
Subject: [PATCH] gluon-radv-filterd: respondd: update to use netlink instead
 of sysfs

---
 package/gluon-radv-filterd/src/respondd.c | 72 +++++++++++++++++++----
 1 file changed, 62 insertions(+), 10 deletions(-)

diff --git a/package/gluon-radv-filterd/src/respondd.c b/package/gluon-radv-filterd/src/respondd.c
index 34b70222..4577730d 100644
--- a/package/gluon-radv-filterd/src/respondd.c
+++ b/package/gluon-radv-filterd/src/respondd.c
@@ -8,8 +8,57 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <batadv-genl.h>
+
 #include "mac.h"
 
+struct mode_netlink_opts {
+	bool is_server;
+	struct batadv_nlquery_opts query_opts;
+};
+
+static const enum batadv_nl_attrs mode_mandatory[] = {
+	BATADV_ATTR_GW_MODE,
+};
+
+static int parse_mode_netlink_cb(struct nl_msg *msg, void *arg)
+{
+	struct nlattr *attrs[BATADV_ATTR_MAX+1];
+	struct nlmsghdr *nlh = nlmsg_hdr(msg);
+	struct batadv_nlquery_opts *query_opts = arg;
+	struct genlmsghdr *ghdr;
+	struct mode_netlink_opts *opts;
+	uint8_t mode;
+
+	opts = batadv_container_of(query_opts, struct mode_netlink_opts,
+				   query_opts);
+
+	if (!genlmsg_valid_hdr(nlh, 0))
+		return NL_OK;
+
+	ghdr = nlmsg_data(nlh);
+
+	if (ghdr->cmd != BATADV_CMD_GET_MESH_INFO)
+		return NL_OK;
+
+	if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+	    genlmsg_len(ghdr), batadv_genl_policy))
+		return NL_OK;
+
+	if (batadv_genl_missing_attrs(attrs, mode_mandatory,
+	    BATADV_ARRAY_SIZE(mode_mandatory)))
+		return NL_OK;
+
+	mode = nla_get_u8(attrs[BATADV_ATTR_GW_MODE]);
+
+	opts->is_server = mode == BATADV_GW_MODE_SERVER;
+
+	return NL_OK;
+}
+
 static struct json_object * get_radv_filter() {
 	FILE *f = popen("exec ebtables-tiny -L RADV_FILTER", "r");
 	char *line = NULL;
@@ -40,16 +89,19 @@ static struct json_object * get_radv_filter() {
 
 static struct json_object * respondd_provider_statistics() {
 	struct json_object *ret = json_object_new_object();
-	char buf[6];
-	int fd = open("/sys/class/net/bat0/mesh/gw_mode", O_RDONLY);
-	if (fd == -1) {
-		perror("error opening gateway info file");
-		return ret;
-	}
-	memset(buf, 0, sizeof(buf));
-	read(fd, buf, sizeof(buf));
-	close(fd);
-	if (strncmp(buf, "server", 6) == 0) {
+
+	struct mode_netlink_opts opts = {
+                .is_server = false,
+                .query_opts = {
+                        .err = 0,
+                },
+        };
+
+        batadv_genl_query("bat0", BATADV_CMD_GET_MESH_INFO,
+                          parse_mode_netlink_cb, 0,
+                          &opts.query_opts);
+
+	if (opts.is_server) {
 		// We are a batman gateway, do not write gateway6
 		return ret;
 	}
-- 
GitLab