From: Felix Fietkau Date: Wed, 5 Aug 2020 15:11:50 +0000 (+0200) Subject: unl: add support for connecting to rtnl X-Git-Url: http://git.openwrt.org/ubox.git?a=commitdiff_plain;h=c291088f631d1694f7ba0444b59677b194348da8;p=project%2Flibnl-tiny.git 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 --- diff --git a/include/unl.h b/include/unl.h index 4fe7dc7..0709818 100644 --- a/include/unl.h +++ b/include/unl.h @@ -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 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);