unl: add support for connecting to rtnl
authorFelix Fietkau <nbd@nbd.name>
Wed, 5 Aug 2020 15:11:50 +0000 (17:11 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 5 Aug 2020 15:45:17 +0000 (17:45 +0200)
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>
include/unl.h
unl.c

index 4fe7dc745d1bfdc4f54eec8678b24e1001274bee..0709818e209c06bbb981173299221579cee9fc5e 100644 (file)
@@ -16,14 +16,22 @@ struct unl {
 };
 
 int unl_genl_init(struct unl *unl, const char *family);
+int unl_rtnl_init(struct unl *unl);
 void unl_free(struct unl *unl);
 
 typedef int (*unl_cb)(struct nl_msg *, void *);
 
 struct nl_msg *unl_genl_msg(struct unl *unl, int cmd, bool dump);
-int unl_genl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg);
-int unl_genl_request_single(struct unl *unl, struct nl_msg *msg, struct nl_msg **dest);
-void unl_genl_loop(struct unl *unl, unl_cb handler, void *arg);
+struct nl_msg *unl_rtnl_msg(struct unl *unl, int cmd, bool dump);
+
+int unl_request(struct unl *unl, struct nl_msg *msg, unl_cb handler, void *arg);
+int unl_request_single(struct unl *unl, struct nl_msg *msg, struct nl_msg **dest);
+void unl_loop(struct unl *unl, unl_cb handler, void *arg);
+
+/* compat */
+#define unl_genl_request unl_request
+#define unl_genl_request_single unl_request_single
+#define unl_genl_loop unl_loop
 
 int unl_genl_multicast_id(struct unl *unl, const char *name);
 int unl_genl_subscribe(struct unl *unl, const char *name);
diff --git a/unl.c b/unl.c
index 33c020ea13f86090cf81fd504360d0a1b035104d..a5714f4c6209735bfd0b36743b38b9b061e841d4 100644 (file)
--- 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);