Move genl_ctrl_resolve out of the wifi code so it can be reused by other interfaces based on genetlink. --- src/platform/nm-netlink.c | 68 +++++++++++++++++++++++++++ src/platform/nm-netlink.h | 32 +++++++------ src/platform/wifi/wifi-utils-nl80211.c | 84 ++-------------------------------- 3 files changed, 88 insertions(+), 96 deletions(-)
diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c index f93577487..4cb19780b 100644 --- a/src/platform/nm-netlink.c +++ b/src/platform/nm-netlink.c @@ -783,6 +783,74 @@ genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], genlmsg_attrlen (ghdr, hdrlen), policy); } +static int +_genl_parse_getfamily (struct nl_msg *msg, void *arg) +{ + static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { + [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, + [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING, + .maxlen = GENL_NAMSIZ }, + [CTRL_ATTR_VERSION] = { .type = NLA_U32 }, + [CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 }, + [CTRL_ATTR_MAXATTR] = { .type = NLA_U32 }, + [CTRL_ATTR_OPS] = { .type = NLA_NESTED }, + [CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED }, + }; + struct nlattr *tb[CTRL_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr (msg); + gint32 *response_data = arg; + + if (genlmsg_parse (nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy)) + return NL_SKIP; + + if (tb[CTRL_ATTR_FAMILY_ID]) + *response_data = nla_get_u16 (tb[CTRL_ATTR_FAMILY_ID]); + + return NL_STOP; +} + +int +genl_ctrl_resolve (struct nl_sock *sk, const char *name) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int result = -ENOMEM; + gint32 response_data = -1; + const struct nl_cb cb = { + .valid_cb = _genl_parse_getfamily, + .valid_arg = &response_data, + }; + + msg = nlmsg_alloc (); + + if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, + 0, 0, CTRL_CMD_GETFAMILY, 1)) + goto out; + + if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0) + goto out; + + result = nl_send_auto (sk, msg); + if (result < 0) + goto out; + + result = nl_recvmsgs (sk, &cb); + if (result < 0) + goto out; + + /* If search was successful, request may be ACKed after data */ + result = nl_wait_for_ack (sk, NULL); + if (result < 0) + goto out; + + if (response_data > 0) + result = response_data; + else + result = -ENOENT; + +out: + return result; +} + /*****************************************************************************/ struct nl_sock * diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h index 1c89c1880..57b89e1e2 100644 --- a/src/platform/nm-netlink.h +++ b/src/platform/nm-netlink.h @@ -409,21 +409,6 @@ struct nlmsghdr *nlmsg_put (struct nl_msg *n, uint32_t pid, uint32_t seq, /*****************************************************************************/ -void *genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family, - int hdrlen, int flags, uint8_t cmd, uint8_t version); -void *genlmsg_data (const struct genlmsghdr *gnlh); -void *genlmsg_user_hdr (const struct genlmsghdr *gnlh); -struct genlmsghdr *genlmsg_hdr (struct nlmsghdr *nlh); -void *genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen); -struct nlattr *genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen); -int genlmsg_len (const struct genlmsghdr *gnlh); -int genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen); -int genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen); -int genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], - int maxtype, const struct nla_policy *policy); - -/*****************************************************************************/ - #define NL_AUTO_PORT 0 #define NL_AUTO_SEQ 0 @@ -506,4 +491,21 @@ int nl_socket_set_ext_ack (struct nl_sock *sk, gboolean enable); /*****************************************************************************/ +void *genlmsg_put (struct nl_msg *msg, uint32_t port, uint32_t seq, int family, + int hdrlen, int flags, uint8_t cmd, uint8_t version); +void *genlmsg_data (const struct genlmsghdr *gnlh); +void *genlmsg_user_hdr (const struct genlmsghdr *gnlh); +struct genlmsghdr *genlmsg_hdr (struct nlmsghdr *nlh); +void *genlmsg_user_data (const struct genlmsghdr *gnlh, const int hdrlen); +struct nlattr *genlmsg_attrdata (const struct genlmsghdr *gnlh, int hdrlen); +int genlmsg_len (const struct genlmsghdr *gnlh); +int genlmsg_attrlen (const struct genlmsghdr *gnlh, int hdrlen); +int genlmsg_valid_hdr (struct nlmsghdr *nlh, int hdrlen); +int genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], + int maxtype, const struct nla_policy *policy); + +int genl_ctrl_resolve (struct nl_sock *sk, const char *name); + +/*****************************************************************************/ + #endif /* __NM_NETLINK_H__ */ diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 769a2be48..db187a1fb 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -46,86 +46,6 @@ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } G_STMT_END -/***************************************************************************** - * Reimplementation of libnl3/genl functions: - *****************************************************************************/ - -static int -probe_response (struct nl_msg *msg, void *arg) -{ - static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { - [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, - [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING, - .maxlen = GENL_NAMSIZ }, - [CTRL_ATTR_VERSION] = { .type = NLA_U32 }, - [CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 }, - [CTRL_ATTR_MAXATTR] = { .type = NLA_U32 }, - [CTRL_ATTR_OPS] = { .type = NLA_NESTED }, - [CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED }, - }; - struct nlattr *tb[CTRL_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr (msg); - gint32 *response_data = arg; - - if (genlmsg_parse (nlh, 0, tb, CTRL_ATTR_MAX, ctrl_policy)) - return NL_SKIP; - - if (tb[CTRL_ATTR_FAMILY_ID]) - *response_data = nla_get_u16 (tb[CTRL_ATTR_FAMILY_ID]); - - return NL_STOP; -} - -static int -genl_ctrl_resolve (struct nl_sock *sk, const char *name) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - int result = -ENOMEM; - gint32 response_data = -1; - const struct nl_cb cb = { - .valid_cb = probe_response, - .valid_arg = &response_data, - }; - - msg = nlmsg_alloc (); - - if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, - 0, 0, CTRL_CMD_GETFAMILY, 1)) - goto out; - - if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0) - goto out; - - result = nl_send_auto (sk, msg); - if (result < 0) - goto out; - - result = nl_recvmsgs (sk, &cb); - if (result < 0) - goto out; - - /* If search was successful, request may be ACKed after data */ - result = nl_wait_for_ack (sk, NULL); - if (result < 0) - goto out; - - if (response_data > 0) - result = response_data; - else - result = -ENOENT; - -out: - if (result >= 0) - _LOGD (LOGD_WIFI, "genl_ctrl_resolve: resolved \"%s\" as 0x%x", name, result); - else - _LOGE (LOGD_WIFI, "genl_ctrl_resolve: failed resolve \"%s\"", name); - return result; -} - -/***************************************************************************** - * </libn-genl-3> - *****************************************************************************/ - typedef struct { WifiData parent; struct nl_sock *nl_sock; @@ -960,8 +880,10 @@ wifi_nl80211_init (int ifindex) goto error; nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); - if (nl80211->id < 0) + if (nl80211->id < 0) { + _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); goto error; + } nl80211->phy = -1; -- 2.16.2 _______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org https://mail.gnome.org/mailman/listinfo/networkmanager-list