Linux 2.6.32 (December 2009) introduced alternate netlink messages for setting and installing keys, deprecating the older ones. To allow hostapd/wpa_supplicant to use new features only provided via the new API this patch migrates all netlink messages to the current ones. Since the nl80211 driver was sometimes already using the new format this is only unifying the netlink API usage and not changing the minimal kernel requirement. The following netlink attributes have been retired for key installs: NL80211_ATTR_KEY_DATA NL80211_ATTR_KEY_TYPE NL80211_ATTR_KEY_SEQ NL80211_ATTR_KEY_IDX NL80211_ATTR_KEY_CIPHER NL80211_ATTR_KEY_DEFAULT NL80211_ATTR_KEY_DEFAULT_MGMT NL80211_ATTR_KEY_DEFAULT_TYPES And replaced by the following attributes nested in NL80211_ATTR_KEY: NL80211_KEY_DATA NL80211_KEY_TYPE NL80211_KEY_SEQ NL80211_KEY_IDX NL80211_KEY_CIPHER NL80211_KEY_DEFAULT NL80211_KEY_DEFAULT_MGMT NL80211_KEY_DEFAULT_TYPES When getting michael mic_failures notifications or querying a key sequence number the kernel continues to use the old attributes: NL80211_ATTR_KEY_TYPE NL80211_ATTR_KEY_SEQ NL80211_ATTR_KEY_IDX Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- There is not much to add to the commit log, most of it is straight forward. But I tried to keep the existing logic and therefore start an additional key netlink message which is then merged into the main one prior to sending the message. This allows to fill in the information with the existing logic and avoids the restructuring of everything to be able to use nla_nest_start(). src/drivers/driver_nl80211.c | 71 +++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index c7dad201b..9a4d8153a 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3011,7 +3011,8 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, { struct wpa_driver_nl80211_data *drv = bss->drv; int ifindex; - struct nl_msg *msg = NULL; + struct nl_msg *msg; + struct nl_msg *key_msg; int ret; int tdls = 0; @@ -3045,26 +3046,31 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X)) return nl80211_set_pmk(drv, key, key_len, addr); + key_msg = nlmsg_alloc(); + if (!key_msg) + return -ENOBUFS; + if (alg == WPA_ALG_NONE) { msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY); if (!msg) - return -ENOBUFS; + goto fail2; } else { u32 suite; suite = wpa_alg_to_cipher_suite(alg, key_len); if (!suite) - goto fail; + goto fail2; msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY); - if (!msg || - nla_put(msg, NL80211_ATTR_KEY_DATA, key_len, key) || - nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER, suite)) + if (!msg) + goto fail2; + if (nla_put(key_msg, NL80211_KEY_DATA, key_len, key) || + nla_put_u32(key_msg, NL80211_KEY_CIPHER, suite)) goto fail; wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len); } if (seq && seq_len) { - if (nla_put(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq)) + if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq)) goto fail; wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len); } @@ -3076,7 +3082,7 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, if (alg != WPA_ALG_WEP && key_idx && !set_tx) { wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK"); - if (nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, + if (nla_put_u32(key_msg, NL80211_KEY_TYPE, NL80211_KEYTYPE_GROUP)) goto fail; } @@ -3085,13 +3091,14 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, wpa_printf(MSG_DEBUG, " broadcast key"); - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } - if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx)) + if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) || + nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) goto fail; ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL); @@ -3111,34 +3118,43 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, !is_broadcast_ether_addr(addr)) return ret; + key_msg = nlmsg_alloc(); + if (!key_msg) + return -ENOBUFS; + msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY); - if (!msg || - nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) || - nla_put_flag(msg, (alg == WPA_ALG_IGTK || - alg == WPA_ALG_BIP_GMAC_128 || - alg == WPA_ALG_BIP_GMAC_256 || - alg == WPA_ALG_BIP_CMAC_256) ? - NL80211_ATTR_KEY_DEFAULT_MGMT : - NL80211_ATTR_KEY_DEFAULT)) + if (!msg) + goto fail2; + if (!key_msg || + nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) || + nla_put_flag(key_msg, (alg == WPA_ALG_IGTK || + alg == WPA_ALG_BIP_GMAC_128 || + alg == WPA_ALG_BIP_GMAC_256 || + alg == WPA_ALG_BIP_CMAC_256) ? + NL80211_KEY_DEFAULT_MGMT : + NL80211_KEY_DEFAULT)) goto fail; if (addr && is_broadcast_ether_addr(addr)) { struct nlattr *types; - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } else if (addr) { struct nlattr *types; - types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES); + types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || - nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST)) + nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_UNICAST)) goto fail; - nla_nest_end(msg, types); + nla_nest_end(key_msg, types); } + if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) + goto fail; + ret = send_and_recv_msgs(drv, msg, NULL, NULL); if (ret == -ENOENT) ret = 0; @@ -3150,6 +3166,9 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, fail: nl80211_nlmsg_clear(msg); nlmsg_free(msg); +fail2: + nl80211_nlmsg_clear(key_msg); + nlmsg_free(key_msg); return -ENOBUFS; } -- 2.23.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap