Stop using set_tx and cleanup/restructure the key install logic. Group/broadcast default keys are needing an additional netlink call (NL80211_CMD_SET_KEY) after the key has been installed. The nl80211 driver used a overly complex and not always correct method - involving also set_tx - to decide if the additional netlink call was needed. Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- src/drivers/driver_nl80211.c | 62 +++++++++++++++++------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 64d16d1b4..992794ae6 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3022,8 +3022,8 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, int ifindex; struct nl_msg *msg; struct nl_msg *key_msg; + struct nlattr *types; int ret; - int tdls = 0; /* Ignore for P2P Device */ if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) @@ -3031,13 +3031,12 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, ifindex = if_nametoindex(ifname); wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d " - "set_tx=%d seq_len=%lu key_len=%lu", + "set_tx=%d seq_len=%lu key_len=%lu key_flag=%d", __func__, ifindex, ifname, alg, addr, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); + (unsigned long) seq_len, (unsigned long) key_len, key_flag); #ifdef CONFIG_TDLS if (key_idx == -1) { key_idx = 0; - tdls = 1; } #endif /* CONFIG_TDLS */ @@ -3089,22 +3088,25 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) goto fail; - if (alg != WPA_ALG_WEP && key_idx && !set_tx) { + if (key_flag == KEY_FLAG_GROUP_RX) { wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK"); if (nla_put_u32(key_msg, NL80211_KEY_TYPE, NL80211_KEYTYPE_GROUP)) goto fail; + } else if (key_flag & (KEY_FLAG_GROUP | KEY_FLAG_DEFAULT) || + !(key_flag & KEY_FLAG_PAIRWISE)) { + wpa_printf(MSG_ERROR, + "nl80211: Unhandled key type, abort"); + goto fail; + } else { + wpa_printf(MSG_DEBUG, " pairwise key"); } - } else if (addr && is_broadcast_ether_addr(addr)) { - struct nlattr *types; - + } else if (key_flag & KEY_FLAG_PAIRWISE || + !(key_flag & (KEY_FLAG_GROUP | KEY_FLAG_PMK))) { + wpa_printf(MSG_ERROR, "nl80211: Unhandled key type, abort"); + goto fail; + } else { wpa_printf(MSG_DEBUG, " broadcast key"); - - types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); - if (!types || - nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) - goto fail; - nla_nest_end(key_msg, types); } if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) || nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) @@ -3121,14 +3123,12 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, ret, strerror(-ret)); /* - * If we failed or don't need to set the default TX key (below), + * If we failed or don't need to set the key as default (below), * we're done here. */ - if (ret || !set_tx || alg == WPA_ALG_NONE || tdls) - return ret; - if (is_ap_interface(drv->nlmode) && addr && - !is_broadcast_ether_addr(addr)) + if (ret || !(key_flag & KEY_FLAG_DEFAULT)) return ret; + wpa_printf(MSG_DEBUG, " default key"); key_msg = nlmsg_alloc(); if (!key_msg) @@ -3147,21 +3147,18 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, NL80211_KEY_DEFAULT)) goto fail; if (addr && is_broadcast_ether_addr(addr)) { - struct nlattr *types; - + wpa_printf(MSG_DEBUG, " group key"); types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); if (!types || nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST)) goto fail; nla_nest_end(key_msg, types); - } else if (addr) { - struct nlattr *types; - - types = nla_nest_start(key_msg, NL80211_KEY_DEFAULT_TYPES); - if (!types || - nla_put_flag(key_msg, NL80211_KEY_DEFAULT_TYPE_UNICAST)) - goto fail; - nla_nest_end(key_msg, types); + } else if (!addr) { + wpa_printf(MSG_DEBUG, " WEP/WPA-NONE key"); + } else { + wpa_printf(MSG_ERROR, + "nl80211: Unicast key when not expecting one, abort!"); + goto fail; } if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg)) @@ -3171,8 +3168,6 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss, key_msg = NULL; ret = send_and_recv_msgs(drv, msg, NULL, NULL); - if (ret == -ENOENT) - ret = 0; if (ret) wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; " "err=%d %s)", ret, strerror(-ret)); @@ -3494,7 +3489,10 @@ retry: NULL, i, i == params->wep_tx_keyidx, NULL, 0, params->wep_key[i], - params->wep_key_len[i], 0); + params->wep_key_len[i], + i == params->wep_tx_keyidx ? + KEY_FLAG_GROUP_RX_TX_DEFAULT : + KEY_FLAG_GROUP_RX_TX); if (params->wep_tx_keyidx != i) continue; if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0, -- 2.24.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap