[Patch v8 05/15] nl80211: Migrate from set_tx to key_type API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Stop using set_tx and cleanup the driver.

Installing WEP and broadcast keys requires 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
based on set_tx to detect that.

The switch to key_type therefore also stops useless NL80211_CMD_SET_KEY
calls when installing unicast keys with wpa_supplicant.

Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx>
---

This simply is too big to for the patch migrating the other drivers to
use key_type. Nl80211 is the driver supporting the most features and
also using the strangest hacks...

So this patch is not only migrating to key_type, it's a general overhaul
of the key install logic.
The new logic works fine for all test cases and to my understanding all
dropped code pieces could not have had any function.  (Verified against
the kernel code.)

 src/drivers/driver_nl80211.c | 57 ++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e4829c84d..c6ed4caa8 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3014,8 +3014,9 @@ 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 skip_set_key = 1;
 	int ret;
-	int tdls = 0;
 
 	/* Ignore for P2P Device */
 	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
@@ -3023,13 +3024,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_type=%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_type);
 #ifdef CONFIG_TDLS
 	if (key_idx == -1) {
 		key_idx = 0;
-		tdls = 1;
 	}
 #endif /* CONFIG_TDLS */
 
@@ -3081,22 +3081,23 @@ 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 (alg != WPA_ALG_WEP && key_type == KEY_TYPE_BROADCAST) {
 			wpa_printf(MSG_DEBUG, "   RSN IBSS RX GTK");
 			if (nla_put_u32(key_msg, NL80211_KEY_TYPE,
 					NL80211_KEYTYPE_GROUP))
 				goto fail;
-		}
-	} else if (addr && is_broadcast_ether_addr(addr)) {
-		struct nlattr *types;
-
-		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))
+		} else if (key_type == KEY_TYPE_DEFAULT) {
+			/* We don't need or handle Pairwise Default Keys */
+			wpa_printf(MSG_ERROR,
+				   "Can't set a Pairwise key as default key.");
 			goto fail;
-		nla_nest_end(key_msg, types);
+		}
+	} else if (alg != WPA_ALG_NONE) {
+		/* Default (WEP, GTK or IGTK) key */
+		if (alg != WPA_ALG_WEP || key_type == KEY_TYPE_DEFAULT) {
+			wpa_printf(MSG_DEBUG, "   require SET_KEY");
+			skip_set_key = 0;
+		}
 	}
 	if (nla_put_u8(key_msg, NL80211_KEY_IDX, key_idx) ||
 	    nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
@@ -3113,13 +3114,10 @@ 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 || skip_set_key)
 		return ret;
 
 	key_msg = nlmsg_alloc();
@@ -3139,21 +3137,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, "   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);
-	} 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 default key");
+	} else {
+		wpa_printf(MSG_ERROR,
+			   "Unicast key when not expecting one, abort!");
+		goto fail;
 	}
 
 	if (nla_put_nested(msg, NL80211_ATTR_KEY, key_msg))
@@ -3163,8 +3158,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));
-- 
2.23.0


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux