summaryrefslogtreecommitdiff
path: root/unl.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2020-08-05 17:11:50 +0200
committerrofl0r <rofl0r@users.noreply.github.com>2022-09-16 01:32:26 +0000
commitaae09e27c30ee63c4a555e4f7fdf06448b4eced4 (patch)
tree05e6c30b199729857edb4d54ade34616ce9a3435 /unl.c
parentf74511ed4608f9dd2d1ced612b0d6a3e65db5da4 (diff)
downloadlibnl-tiny-aae09e27c30ee63c4a555e4f7fdf06448b4eced4.tar.gz
unl: add support for connecting to rtnl
The API is almost the same and some unl_genl_* functions are renamed to unl_* with compat #define in place The only thing different between genl and rtnl is the init function and the function for allocating a message Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'unl.c')
-rw-r--r--unl.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/unl.c b/unl.c
index 33c020e..a5714f4 100644
--- a/unl.c
+++ b/unl.c
@@ -13,6 +13,8 @@
static int unl_init(struct unl *unl)
{
+ memset(unl, 0, sizeof(*unl));
+
unl->sock = nl_socket_alloc();
if (!unl->sock)
return -1;
@@ -22,8 +24,6 @@ static int unl_init(struct unl *unl)
int unl_genl_init(struct unl *unl, const char *family)
{
- memset(unl, 0, sizeof(*unl));
-
if (unl_init(unl))
goto error_out;
@@ -50,6 +50,23 @@ error_out:
return -1;
}
+int unl_rtnl_init(struct unl *unl)
+{
+ if (unl_init(unl))
+ goto error_out;
+
+ unl->hdrlen = 0;
+ if (nl_connect(unl->sock, NETLINK_ROUTE))
+ goto error;
+
+ return 0;
+
+error:
+ unl_free(unl);
+error_out:
+ return -1;
+}
+
void unl_free(struct unl *unl)
{
if (unl->family_name)
@@ -107,7 +124,25 @@ out:
return msg;
}
-int unl_genl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg)
+struct nl_msg *unl_rtnl_msg(struct unl *unl, int cmd, bool dump)
+{
+ struct nl_msg *msg;
+ int flags = 0;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ goto out;
+
+ if (dump)
+ flags |= NLM_F_DUMP;
+
+ nlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, cmd, 0, flags);
+
+out:
+ return msg;
+}
+
+int unl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg)
{
struct nl_cb *cb;
int err;
@@ -144,10 +179,10 @@ static int request_single_cb(struct nl_msg *msg, void *arg)
return NL_SKIP;
}
-int unl_genl_request_single(struct unl *unl, struct nl_msg *msg, struct nl_msg **dest)
+int unl_request_single(struct unl *unl, struct nl_msg *msg, struct nl_msg **dest)
{
*dest = NULL;
- return unl_genl_request(unl, msg, request_single_cb, dest);
+ return unl_request(unl, msg, request_single_cb, dest);
}
static int no_seq_check(struct nl_msg *msg, void *arg)
@@ -155,7 +190,7 @@ static int no_seq_check(struct nl_msg *msg, void *arg)
return NL_OK;
}
-void unl_genl_loop(struct unl *unl, unl_cb handler, void *arg)
+void unl_loop(struct unl *unl, unl_cb handler, void *arg)
{
struct nl_cb *cb;
@@ -186,7 +221,7 @@ int unl_genl_multicast_id(struct unl *unl, const char *name)
ctrlid = genl_ctrl_resolve(unl->sock, "nlctrl");
genlmsg_put(msg, 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, unl->family_name);
- unl_genl_request_single(unl, msg, &msg);
+ unl_request_single(unl, msg, &msg);
if (!msg)
return -1;
@@ -270,7 +305,7 @@ int unl_nl80211_wdev_to_phy(struct unl *unl, int wdev)
return -1;
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev);
- if (unl_genl_request_single(unl, msg, &msg) < 0)
+ if (unl_request_single(unl, msg, &msg) < 0)
return -1;
attr = unl_find_attr(unl, msg, NL80211_ATTR_WIPHY);