linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/17] mac80211: fix off-by-one in llid check.
@ 2013-11-05 19:16 Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 02/17] mac80211: consolidate calls to plink_frame_tx Thomas Pedersen
                   ` (16 more replies)
  0 siblings, 17 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

According to IEEE 802.11-2012 (8.4.2.104), no peering
management element exists with length 7. This code is checking
to see if llid is present to ignore close frames with different
llid, which would be IEs with length 8.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 4301aa5..a8c75c1 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -825,7 +825,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 				event = CLS_ACPT;
 			else if (sta->plid != plid)
 				event = CLS_IGNR;
-			else if (ie_len == 7 && sta->llid != llid)
+			else if (ie_len == 8 && sta->llid != llid)
 				event = CLS_IGNR;
 			else
 				event = CLS_ACPT;
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/17] mac80211: consolidate calls to plink_frame_tx
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 03/17] mac80211: hold sta->lock across plink switch statements Thomas Pedersen
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

Do all frame transfers in one place at the end of the
big switch statements.  sta->plid and sta->reason can
be passed in any case, since they are only used for
the frames that need them.  Remove assignments to locals
for values already stored in the sta structure.

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 net/mac80211/mesh_plink.c | 72 +++++++++++++++++++----------------------------
 1 file changed, 29 insertions(+), 43 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index a8c75c1..d45826e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -533,6 +533,7 @@ static void mesh_plink_timer(unsigned long data)
 	__le16 llid, plid, reason;
 	struct ieee80211_sub_if_data *sdata;
 	struct mesh_config *mshcfg;
+	enum ieee80211_self_protected_actioncode action = 0;
 
 	/*
 	 * This STA is valid because sta_info_destroy() will
@@ -575,8 +576,7 @@ static void mesh_plink_timer(unsigned long data)
 			++sta->plink_retries;
 			mod_plink_timer(sta, sta->plink_timeout);
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
-					    sta->sta.addr, llid, 0, 0);
+			action = WLAN_SP_MESH_PEERING_OPEN;
 			break;
 		}
 		reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES);
@@ -588,8 +588,7 @@ static void mesh_plink_timer(unsigned long data)
 		sta->plink_state = NL80211_PLINK_HOLDING;
 		mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 		spin_unlock_bh(&sta->lock);
-		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-				    sta->sta.addr, llid, plid, reason);
+		action = WLAN_SP_MESH_PEERING_CLOSE;
 		break;
 	case NL80211_PLINK_HOLDING:
 		/* holding timer */
@@ -601,6 +600,9 @@ static void mesh_plink_timer(unsigned long data)
 		spin_unlock_bh(&sta->lock);
 		break;
 	}
+	if (action)
+		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
+				    llid, plid, reason);
 }
 
 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
@@ -662,6 +664,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_rx_status *rx_status)
 {
 	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+	enum ieee80211_self_protected_actioncode action = 0;
 	struct ieee802_11_elems elems;
 	struct sta_info *sta;
 	enum plink_event event;
@@ -872,12 +875,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			changed |= ieee80211_mps_local_status_update(sdata);
 
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_OPEN,
-					    sta->sta.addr, llid, 0, 0);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, llid, plid, 0);
+			action = WLAN_SP_MESH_PEERING_OPEN;
 			break;
 		default:
 			spin_unlock_bh(&sta->lock);
@@ -899,21 +897,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CLOSE,
-					    sta->sta.addr, llid, plid, reason);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
 			/* retry timer is left untouched */
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
 			sta->plid = plid;
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, llid, plid, 0);
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
 			sta->plink_state = NL80211_PLINK_CNF_RCVD;
@@ -943,17 +935,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-					    sta->sta.addr, llid, plid, reason);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, llid, plid, 0);
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
 			del_timer(&sta->plink_timer);
@@ -988,11 +975,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CLOSE,
-					    sta->sta.addr, llid, plid, reason);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
 			del_timer(&sta->plink_timer);
@@ -1003,9 +987,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			changed |= mesh_set_short_slot_time(sdata);
 			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
 				sta->sta.addr);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, llid, plid, 0);
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			ieee80211_mps_sta_status_update(sta);
 			changed |= ieee80211_mps_set_sta_local_pm(sta,
 							mshcfg->power_mode);
@@ -1023,20 +1005,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			sta->reason = reason;
 			changed |= __mesh_plink_deactivate(sta);
 			sta->plink_state = NL80211_PLINK_HOLDING;
-			llid = sta->llid;
 			mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 			spin_unlock_bh(&sta->lock);
 			changed |= mesh_set_ht_prot_mode(sdata);
 			changed |= mesh_set_short_slot_time(sdata);
-			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-					    sta->sta.addr, llid, plid, reason);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-			llid = sta->llid;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, llid, plid, 0);
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		default:
 			spin_unlock_bh(&sta->lock);
@@ -1055,11 +1032,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		case CNF_ACPT:
 		case OPN_RJCT:
 		case CNF_RJCT:
-			llid = sta->llid;
-			reason = sta->reason;
 			spin_unlock_bh(&sta->lock);
-			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-					    sta->sta.addr, llid, plid, reason);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		default:
 			spin_unlock_bh(&sta->lock);
@@ -1072,6 +1046,18 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		spin_unlock_bh(&sta->lock);
 		break;
 	}
+	if (action) {
+		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
+				    sta->llid, sta->plid, sta->reason);
+
+		/* also send confirm in open case */
+		if (action == WLAN_SP_MESH_PEERING_OPEN) {
+			mesh_plink_frame_tx(sdata,
+					    WLAN_SP_MESH_PEERING_CONFIRM,
+					    sta->sta.addr, sta->llid,
+					    sta->plid, 0);
+		}
+	}
 
 	rcu_read_unlock();
 
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/17] mac80211: hold sta->lock across plink switch statements
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 02/17] mac80211: consolidate calls to plink_frame_tx Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 04/17] mac80211: mesh: factor out common plink close/estab code Thomas Pedersen
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

Rather than unlock at the end of each case, do it once after
all is said and done.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 29 +++--------------------------
 1 file changed, 3 insertions(+), 26 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index d45826e..c3a3faf 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -575,7 +575,6 @@ static void mesh_plink_timer(unsigned long data)
 					     rand % sta->plink_timeout;
 			++sta->plink_retries;
 			mod_plink_timer(sta, sta->plink_timeout);
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_OPEN;
 			break;
 		}
@@ -587,19 +586,17 @@ static void mesh_plink_timer(unsigned long data)
 			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
 		sta->plink_state = NL80211_PLINK_HOLDING;
 		mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
-		spin_unlock_bh(&sta->lock);
 		action = WLAN_SP_MESH_PEERING_CLOSE;
 		break;
 	case NL80211_PLINK_HOLDING:
 		/* holding timer */
 		del_timer(&sta->plink_timer);
 		mesh_plink_fsm_restart(sta);
-		spin_unlock_bh(&sta->lock);
 		break;
 	default:
-		spin_unlock_bh(&sta->lock);
 		break;
 	}
+	spin_unlock_bh(&sta->lock);
 	if (action)
 		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
 				    llid, plid, reason);
@@ -856,12 +853,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	reason = 0;
 	spin_lock_bh(&sta->lock);
 	switch (sta->plink_state) {
-		/* spin_unlock as soon as state is updated at each case */
 	case NL80211_PLINK_LISTEN:
 		switch (event) {
 		case CLS_ACPT:
 			mesh_plink_fsm_restart(sta);
-			spin_unlock_bh(&sta->lock);
 			break;
 		case OPN_ACPT:
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
@@ -874,11 +869,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			/* set the non-peer mode to active during peering */
 			changed |= ieee80211_mps_local_status_update(sdata);
 
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_OPEN;
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
 			break;
 		}
 		break;
@@ -897,14 +890,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
 			/* retry timer is left untouched */
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
 			sta->plid = plid;
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
@@ -913,10 +904,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshConfirmTimeout))
 				sta->ignore_plink_timer = true;
 
-			spin_unlock_bh(&sta->lock);
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
 			break;
 		}
 		break;
@@ -935,17 +924,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
 			del_timer(&sta->plink_timer);
 			sta->plink_state = NL80211_PLINK_ESTAB;
-			spin_unlock_bh(&sta->lock);
 			changed |= mesh_plink_inc_estab_count(sdata);
 			changed |= mesh_set_ht_prot_mode(sdata);
 			changed |= mesh_set_short_slot_time(sdata);
@@ -956,7 +942,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 						       mshcfg->power_mode);
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
 			break;
 		}
 		break;
@@ -975,13 +960,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 					     mshcfg->dot11MeshHoldingTimeout))
 				sta->ignore_plink_timer = true;
 
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
 			del_timer(&sta->plink_timer);
 			sta->plink_state = NL80211_PLINK_ESTAB;
-			spin_unlock_bh(&sta->lock);
 			changed |= mesh_plink_inc_estab_count(sdata);
 			changed |= mesh_set_ht_prot_mode(sdata);
 			changed |= mesh_set_short_slot_time(sdata);
@@ -993,7 +976,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 							mshcfg->power_mode);
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
 			break;
 		}
 		break;
@@ -1006,17 +988,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			changed |= __mesh_plink_deactivate(sta);
 			sta->plink_state = NL80211_PLINK_HOLDING;
 			mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
-			spin_unlock_bh(&sta->lock);
 			changed |= mesh_set_ht_prot_mode(sdata);
 			changed |= mesh_set_short_slot_time(sdata);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
 			break;
 		}
 		break;
@@ -1026,26 +1005,24 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			if (del_timer(&sta->plink_timer))
 				sta->ignore_plink_timer = 1;
 			mesh_plink_fsm_restart(sta);
-			spin_unlock_bh(&sta->lock);
 			break;
 		case OPN_ACPT:
 		case CNF_ACPT:
 		case OPN_RJCT:
 		case CNF_RJCT:
-			spin_unlock_bh(&sta->lock);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		default:
-			spin_unlock_bh(&sta->lock);
+			break;
 		}
 		break;
 	default:
 		/* should not get here, PLINK_BLOCKED is dealt with at the
 		 * beginning of the function
 		 */
-		spin_unlock_bh(&sta->lock);
 		break;
 	}
+	spin_unlock_bh(&sta->lock);
 	if (action) {
 		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
 				    sta->llid, sta->plid, sta->reason);
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/17] mac80211: mesh: factor out common plink close/estab code
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 02/17] mac80211: consolidate calls to plink_frame_tx Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 03/17] mac80211: hold sta->lock across plink switch statements Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 05/17] mac80211: mesh_plink: group basic fitness checks Thomas Pedersen
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

Reject and accepted close events always put the host in the
holding state and compute a reason code based only on the
current state.  Likewise on establish we always do the same
setup.  Put these in functions to save some duplicated code.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 98 +++++++++++++++++++++--------------------------
 1 file changed, 43 insertions(+), 55 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index c3a3faf..3bab76f 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -655,6 +655,39 @@ u32 mesh_plink_block(struct sta_info *sta)
 	return changed;
 }
 
+static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
+			     struct sta_info *sta,
+			     enum plink_event event)
+{
+	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+
+	__le16 reason = (event == CLS_ACPT) ?
+		cpu_to_le16(WLAN_REASON_MESH_CLOSE) :
+		cpu_to_le16(WLAN_REASON_MESH_CONFIG);
+
+	sta->reason = reason;
+	sta->plink_state = NL80211_PLINK_HOLDING;
+	if (!mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout))
+		sta->ignore_plink_timer = true;
+}
+
+static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
+				struct sta_info *sta)
+{
+	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+	u32 changed = 0;
+
+	del_timer(&sta->plink_timer);
+	sta->plink_state = NL80211_PLINK_ESTAB;
+	changed |= mesh_plink_inc_estab_count(sdata);
+	changed |= mesh_set_ht_prot_mode(sdata);
+	changed |= mesh_set_short_slot_time(sdata);
+	mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
+	ieee80211_mps_sta_status_update(sta);
+	changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
+	return changed;
+}
+
 
 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_mgmt *mgmt, size_t len,
@@ -671,7 +704,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	u8 ie_len;
 	u8 *baseaddr;
 	u32 changed = 0;
-	__le16 plid, llid, reason;
+	__le16 plid, llid;
 
 	/* need action_code, aux */
 	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
@@ -782,10 +815,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 
 	if (!sta && !matches_local) {
 		rcu_read_unlock();
-		reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
 		llid = 0;
 		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-				    mgmt->sa, llid, plid, reason);
+				    mgmt->sa, llid, plid,
+				    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
 		return;
 	} else if (!sta) {
 		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
@@ -850,7 +883,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 
 	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
 		       mplstates[sta->plink_state], mplevents[event]);
-	reason = 0;
 	spin_lock_bh(&sta->lock);
 	switch (sta->plink_state) {
 	case NL80211_PLINK_LISTEN:
@@ -880,18 +912,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		switch (event) {
 		case OPN_RJCT:
 		case CNF_RJCT:
-			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
 		case CLS_ACPT:
-			if (!reason)
-				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-			sta->reason = reason;
-			sta->plink_state = NL80211_PLINK_HOLDING;
-			if (!mod_plink_timer(sta,
-					     mshcfg->dot11MeshHoldingTimeout))
-				sta->ignore_plink_timer = true;
-
+			mesh_plink_close(sdata, sta, event);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
+
 		case OPN_ACPT:
 			/* retry timer is left untouched */
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
@@ -914,32 +939,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		switch (event) {
 		case OPN_RJCT:
 		case CNF_RJCT:
-			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
 		case CLS_ACPT:
-			if (!reason)
-				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-			sta->reason = reason;
-			sta->plink_state = NL80211_PLINK_HOLDING;
-			if (!mod_plink_timer(sta,
-					     mshcfg->dot11MeshHoldingTimeout))
-				sta->ignore_plink_timer = true;
-
+			mesh_plink_close(sdata, sta, event);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
-			del_timer(&sta->plink_timer);
-			sta->plink_state = NL80211_PLINK_ESTAB;
-			changed |= mesh_plink_inc_estab_count(sdata);
-			changed |= mesh_set_ht_prot_mode(sdata);
-			changed |= mesh_set_short_slot_time(sdata);
-			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
-				sta->sta.addr);
-			ieee80211_mps_sta_status_update(sta);
-			changed |= ieee80211_mps_set_sta_local_pm(sta,
-						       mshcfg->power_mode);
+			changed |= mesh_plink_establish(sdata, sta);
 			break;
 		default:
 			break;
@@ -950,30 +958,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		switch (event) {
 		case OPN_RJCT:
 		case CNF_RJCT:
-			reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
 		case CLS_ACPT:
-			if (!reason)
-				reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-			sta->reason = reason;
-			sta->plink_state = NL80211_PLINK_HOLDING;
-			if (!mod_plink_timer(sta,
-					     mshcfg->dot11MeshHoldingTimeout))
-				sta->ignore_plink_timer = true;
-
+			mesh_plink_close(sdata, sta, event);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-			del_timer(&sta->plink_timer);
-			sta->plink_state = NL80211_PLINK_ESTAB;
-			changed |= mesh_plink_inc_estab_count(sdata);
-			changed |= mesh_set_ht_prot_mode(sdata);
-			changed |= mesh_set_short_slot_time(sdata);
-			mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
-				sta->sta.addr);
+			changed |= mesh_plink_establish(sdata, sta);
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
-			ieee80211_mps_sta_status_update(sta);
-			changed |= ieee80211_mps_set_sta_local_pm(sta,
-							mshcfg->power_mode);
 			break;
 		default:
 			break;
@@ -983,13 +974,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	case NL80211_PLINK_ESTAB:
 		switch (event) {
 		case CLS_ACPT:
-			reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
-			sta->reason = reason;
 			changed |= __mesh_plink_deactivate(sta);
-			sta->plink_state = NL80211_PLINK_HOLDING;
-			mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 			changed |= mesh_set_ht_prot_mode(sdata);
 			changed |= mesh_set_short_slot_time(sdata);
+			mesh_plink_close(sdata, sta, event);
 			action = WLAN_SP_MESH_PEERING_CLOSE;
 			break;
 		case OPN_ACPT:
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/17] mac80211: mesh_plink: group basic fitness checks
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (2 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 04/17] mac80211: mesh: factor out common plink close/estab code Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 06/17] mac80211: mesh: rewrite rssi_threshold_check in C Thomas Pedersen
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

The initial frame checks differ depending on whether this is
a new peer or not, but they were all intermixed with sta checks
as necessary.  Group them together so the two cases are clearer.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 70 +++++++++++++++++++++++++----------------------
 1 file changed, 37 insertions(+), 33 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 3bab76f..5048658 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -700,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	enum plink_event event;
 	enum ieee80211_self_protected_actioncode ftype;
 	size_t baselen;
-	bool matches_local = true;
+	bool matches_local;
 	u8 ie_len;
 	u8 *baseaddr;
 	u32 changed = 0;
@@ -771,11 +771,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	rcu_read_lock();
 
 	sta = sta_info_get(sdata, mgmt->sa);
-	if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
-		mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
-		rcu_read_unlock();
-		return;
-	}
+
+	matches_local = ftype == WLAN_SP_MESH_PEERING_CLOSE ||
+			mesh_matches_local(sdata, &elems);
 
 	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
 	    !rssi_threshold_check(sta, sdata)) {
@@ -785,22 +783,41 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		return;
 	}
 
-	if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
-		mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
-		rcu_read_unlock();
-		return;
-	}
-
-	if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
-		rcu_read_unlock();
-		return;
+	if (!sta) {
+		if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
+			mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
+			rcu_read_unlock();
+			return;
+		}
+		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
+		if (!mesh_plink_free_count(sdata)) {
+			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
+			rcu_read_unlock();
+			return;
+		}
+		/* deny open request from non-matching peer */
+		if (!matches_local) {
+			rcu_read_unlock();
+			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+					    mgmt->sa, 0, plid,
+					    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
+			return;
+		}
+	} else {
+		if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
+			mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
+			rcu_read_unlock();
+			return;
+		}
+		if (sta->plink_state == NL80211_PLINK_BLOCKED) {
+			rcu_read_unlock();
+			return;
+		}
 	}
 
 	/* Now we will figure out the appropriate event... */
 	event = PLINK_UNDEFINED;
-	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
-	    !mesh_matches_local(sdata, &elems)) {
-		matches_local = false;
+	if (!matches_local) {
 		switch (ftype) {
 		case WLAN_SP_MESH_PEERING_OPEN:
 			event = OPN_RJCT;
@@ -813,22 +830,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
-	if (!sta && !matches_local) {
-		rcu_read_unlock();
-		llid = 0;
-		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-				    mgmt->sa, llid, plid,
-				    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
-		return;
-	} else if (!sta) {
-		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
-		if (!mesh_plink_free_count(sdata)) {
-			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
-			rcu_read_unlock();
-			return;
-		}
+	if (!sta)
 		event = OPN_ACPT;
-	} else if (matches_local) {
+	else if (matches_local) {
 		switch (ftype) {
 		case WLAN_SP_MESH_PEERING_OPEN:
 			if (!mesh_plink_free_count(sdata) ||
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/17] mac80211: mesh: rewrite rssi_threshold_check in C
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (3 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 05/17] mac80211: mesh_plink: group basic fitness checks Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 07/17] mac80211: mesh_plink: collapse the two switch statements together Thomas Pedersen
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

Use C instead of cpp for type checking.  Also swap the arguments
into the usual sdata -> sta order.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 5048658..36b6cff 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,12 +19,6 @@
 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
 				jiffies + HZ * t / 1000))
 
-/* We only need a valid sta if user configured a minimum rssi_threshold. */
-#define rssi_threshold_check(sta, sdata) \
-		(sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
-		(sta && (s8) -ewma_read(&sta->avg_signal) > \
-		sdata->u.mesh.mshcfg.rssi_threshold))
-
 enum plink_event {
 	PLINK_UNDEFINED,
 	OPN_ACPT,
@@ -63,6 +57,16 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 			       enum ieee80211_self_protected_actioncode action,
 			       u8 *da, __le16 llid, __le16 plid, __le16 reason);
 
+
+/* We only need a valid sta if user configured a minimum rssi_threshold. */
+static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
+				 struct sta_info *sta)
+{
+	s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
+	return rssi_threshold == 0 ||
+	       (sta && (s8) -ewma_read(&sta->avg_signal) > rssi_threshold);
+}
+
 /**
  * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
  *
@@ -518,7 +522,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
 	    sta->plink_state == NL80211_PLINK_LISTEN &&
 	    sdata->u.mesh.accepting_plinks &&
 	    sdata->u.mesh.mshcfg.auto_open_plinks &&
-	    rssi_threshold_check(sta, sdata))
+	    rssi_threshold_check(sdata, sta))
 		changed = mesh_plink_open(sta);
 
 	ieee80211_mps_frame_release(sta, elems);
@@ -776,7 +780,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 			mesh_matches_local(sdata, &elems);
 
 	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
-	    !rssi_threshold_check(sta, sdata)) {
+	    !rssi_threshold_check(sdata, sta)) {
 		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
 			mgmt->sa);
 		rcu_read_unlock();
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/17] mac80211: mesh_plink: collapse the two switch statements together
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (4 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 06/17] mac80211: mesh: rewrite rssi_threshold_check in C Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 08/17] mac80211: mesh_plink: don't ignore holding timer Thomas Pedersen
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

The matches_local check can just be done when looking at the
individual action types.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 26 +++++++++-----------------
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 36b6cff..8e23395 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -821,33 +821,25 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 
 	/* Now we will figure out the appropriate event... */
 	event = PLINK_UNDEFINED;
-	if (!matches_local) {
-		switch (ftype) {
-		case WLAN_SP_MESH_PEERING_OPEN:
-			event = OPN_RJCT;
-			break;
-		case WLAN_SP_MESH_PEERING_CONFIRM:
-			event = CNF_RJCT;
-			break;
-		default:
-			break;
-		}
-	}
 
 	if (!sta)
 		event = OPN_ACPT;
-	else if (matches_local) {
+	else {
 		switch (ftype) {
 		case WLAN_SP_MESH_PEERING_OPEN:
-			if (!mesh_plink_free_count(sdata) ||
-			    (sta->plid && sta->plid != plid))
+			if (!matches_local)
+				event = OPN_RJCT;
+			else if (!mesh_plink_free_count(sdata) ||
+				 (sta->plid && sta->plid != plid))
 				event = OPN_IGNR;
 			else
 				event = OPN_ACPT;
 			break;
 		case WLAN_SP_MESH_PEERING_CONFIRM:
-			if (!mesh_plink_free_count(sdata) ||
-			    (sta->llid != llid || sta->plid != plid))
+			if (!matches_local)
+				event = CNF_RJCT;
+			else if (!mesh_plink_free_count(sdata) ||
+				 (sta->llid != llid || sta->plid != plid))
 				event = CNF_IGNR;
 			else
 				event = CNF_ACPT;
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/17] mac80211: mesh_plink: don't ignore holding timer
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (5 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 07/17] mac80211: mesh_plink: collapse the two switch statements together Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 09/17] mac80211: return -ENOMEM in mesh_plink_frame_tx Thomas Pedersen
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

The ignore_plink_timer flag is set when doing mod_timer() if
the timer was not previously active.  This is to avoid executing
the timeout if del_timer() was subsequently called.  However,
del_timer() only happens if we are moving to ESTAB state or
get a close frame while in HOLDING.

We cannot leave HOLDING and re-enter ESTAB unless we receive a
close frame (in which case ignore_plink_timer is already set) or
if the timeout expires, so there actually isn't a case where
this is needed on mod_timer().

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8e23395..550ebc1 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -671,8 +671,7 @@ static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
 
 	sta->reason = reason;
 	sta->plink_state = NL80211_PLINK_HOLDING;
-	if (!mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout))
-		sta->ignore_plink_timer = true;
+	mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
 }
 
 static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/17] mac80211: return -ENOMEM in mesh_plink_frame_tx
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (6 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 08/17] mac80211: mesh_plink: don't ignore holding timer Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 10/17] mac80211: remove unused mesh_mgmt_ies_add() prototype Thomas Pedersen
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

All other paths return an error code, do the same here.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh_plink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 550ebc1..429f692 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -283,7 +283,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 			    2 + 8 + /* peering IE */
 			    sdata->u.mesh.ie_len);
 	if (!skb)
-		return -1;
+		return err;
 	info = IEEE80211_SKB_CB(skb);
 	skb_reserve(skb, local->tx_headroom);
 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/17] mac80211: remove unused mesh_mgmt_ies_add() prototype
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (7 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 09/17] mac80211: return -ENOMEM in mesh_plink_frame_tx Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:16 ` [PATCH 11/17] mac80211: factor peering frame processing into own function Thomas Pedersen
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

From: Bob Copeland <me@bobcopeland.com>

Said function was removed some time ago.

Signed-off-by: Bob Copeland <bob@cozybit.com>
---
 net/mac80211/mesh.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 2bc7fd2..3f867e5 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -215,8 +215,6 @@ int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
 bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
 			struct ieee802_11_elems *ie);
 void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
-void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata,
-		       struct sk_buff *skb);
 int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
 			 struct sk_buff *skb);
 int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata,
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/17] mac80211: factor peering frame processing into own function
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (8 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 10/17] mac80211: remove unused mesh_mgmt_ies_add() prototype Thomas Pedersen
@ 2013-11-05 19:16 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 12/17] mac80211: consolidate rcu unlocks in plink frame rx Thomas Pedersen
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:16 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 88 ++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 40 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 429f692..c234ddb 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -691,54 +691,29 @@ static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
 	return changed;
 }
 
-
-void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
-			 struct ieee80211_mgmt *mgmt, size_t len,
-			 struct ieee80211_rx_status *rx_status)
+static void
+mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
+			 struct ieee80211_mgmt *mgmt,
+			 struct ieee802_11_elems *elems)
 {
+
 	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
 	enum ieee80211_self_protected_actioncode action = 0;
-	struct ieee802_11_elems elems;
 	struct sta_info *sta;
 	enum plink_event event;
 	enum ieee80211_self_protected_actioncode ftype;
-	size_t baselen;
 	bool matches_local;
-	u8 ie_len;
-	u8 *baseaddr;
 	u32 changed = 0;
+	u8 ie_len;
 	__le16 plid, llid;
 
-	/* need action_code, aux */
-	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
-		return;
-
-	if (sdata->u.mesh.user_mpm)
-		/* userspace must register for these */
-		return;
-
-	if (is_multicast_ether_addr(mgmt->da)) {
-		mpl_dbg(sdata,
-			"Mesh plink: ignore frame from multicast address\n");
-		return;
-	}
-
-	baseaddr = mgmt->u.action.u.self_prot.variable;
-	baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
-	if (mgmt->u.action.u.self_prot.action_code ==
-						WLAN_SP_MESH_PEERING_CONFIRM) {
-		baseaddr += 4;
-		baselen += 4;
-	}
-	ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
-
-	if (!elems.peering) {
+	if (!elems->peering) {
 		mpl_dbg(sdata,
 			"Mesh plink: missing necessary peer link ie\n");
 		return;
 	}
 
-	if (elems.rsn_len &&
+	if (elems->rsn_len &&
 	    sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
 		mpl_dbg(sdata,
 			"Mesh plink: can't establish link with secure peer\n");
@@ -746,7 +721,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	}
 
 	ftype = mgmt->u.action.u.self_prot.action_code;
-	ie_len = elems.peering_len;
+	ie_len = elems->peering_len;
 	if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
 	    (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
 	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
@@ -758,25 +733,25 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	}
 
 	if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
-	    (!elems.mesh_id || !elems.mesh_config)) {
+	    (!elems->mesh_id || !elems->mesh_config)) {
 		mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
 		return;
 	}
 	/* Note the lines below are correct, the llid in the frame is the plid
 	 * from the point of view of this host.
 	 */
-	memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
+	memcpy(&plid, PLINK_GET_LLID(elems->peering), 2);
 	if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
 	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
-		memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
+		memcpy(&llid, PLINK_GET_PLID(elems->peering), 2);
 
 	/* WARNING: Only for sta pointer, is dropped & re-acquired */
 	rcu_read_lock();
 
 	sta = sta_info_get(sdata, mgmt->sa);
 
-	matches_local = ftype == WLAN_SP_MESH_PEERING_CLOSE ||
-			mesh_matches_local(sdata, &elems);
+	matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
+			 mesh_matches_local(sdata, elems));
 
 	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
 	    !rssi_threshold_check(sdata, sta)) {
@@ -872,7 +847,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	if (event == OPN_ACPT) {
 		rcu_read_unlock();
 		/* allocate sta entry if necessary and update info */
-		sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
+		sta = mesh_sta_info_get(sdata, mgmt->sa, elems);
 		if (!sta) {
 			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
 			rcu_read_unlock();
@@ -1028,3 +1003,36 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 	if (changed)
 		ieee80211_mbss_info_change_notify(sdata, changed);
 }
+
+void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
+			 struct ieee80211_mgmt *mgmt, size_t len,
+			 struct ieee80211_rx_status *rx_status)
+{
+	struct ieee802_11_elems elems;
+	size_t baselen;
+	u8 *baseaddr;
+
+	/* need action_code, aux */
+	if (len < IEEE80211_MIN_ACTION_SIZE + 3)
+		return;
+
+	if (sdata->u.mesh.user_mpm)
+		/* userspace must register for these */
+		return;
+
+	if (is_multicast_ether_addr(mgmt->da)) {
+		mpl_dbg(sdata,
+			"Mesh plink: ignore frame from multicast address\n");
+		return;
+	}
+
+	baseaddr = mgmt->u.action.u.self_prot.variable;
+	baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
+	if (mgmt->u.action.u.self_prot.action_code ==
+						WLAN_SP_MESH_PEERING_CONFIRM) {
+		baseaddr += 4;
+		baselen += 4;
+	}
+	ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
+	mesh_process_plink_frame(sdata, mgmt, &elems);
+}
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/17] mac80211: consolidate rcu unlocks in plink frame rx
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (9 preceding siblings ...)
  2013-11-05 19:16 ` [PATCH 11/17] mac80211: factor peering frame processing into own function Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 13/17] mac80211: assign sta plid early Thomas Pedersen
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 28 ++++++++++------------------
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index c234ddb..e70f490 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -757,40 +757,33 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 	    !rssi_threshold_check(sdata, sta)) {
 		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
 			mgmt->sa);
-		rcu_read_unlock();
-		return;
+		goto unlock_rcu;
 	}
 
 	if (!sta) {
 		if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
 			mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
-			rcu_read_unlock();
-			return;
+			goto unlock_rcu;
 		}
 		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
 		if (!mesh_plink_free_count(sdata)) {
 			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
-			rcu_read_unlock();
-			return;
+			goto unlock_rcu;
 		}
 		/* deny open request from non-matching peer */
 		if (!matches_local) {
-			rcu_read_unlock();
 			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
 					    mgmt->sa, 0, plid,
 					    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
-			return;
+			goto unlock_rcu;
 		}
 	} else {
 		if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
 			mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
-			rcu_read_unlock();
-			return;
-		}
-		if (sta->plink_state == NL80211_PLINK_BLOCKED) {
-			rcu_read_unlock();
-			return;
+			goto unlock_rcu;
 		}
+		if (sta->plink_state == NL80211_PLINK_BLOCKED)
+			goto unlock_rcu;
 	}
 
 	/* Now we will figure out the appropriate event... */
@@ -839,8 +832,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			break;
 		default:
 			mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
-			rcu_read_unlock();
-			return;
+			goto unlock_rcu;
 		}
 	}
 
@@ -850,8 +842,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 		sta = mesh_sta_info_get(sdata, mgmt->sa, elems);
 		if (!sta) {
 			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
-			rcu_read_unlock();
-			return;
+			goto unlock_rcu;
 		}
 	}
 
@@ -998,6 +989,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
+unlock_rcu:
 	rcu_read_unlock();
 
 	if (changed)
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 13/17] mac80211: assign sta plid early
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (10 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 12/17] mac80211: consolidate rcu unlocks in plink frame rx Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 14/17] mac80211: factor out peering FSM Thomas Pedersen
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

If we store the peer link ID right after initializing a
new neighbor, there is no need to do it later in the
peering FSM.

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index e70f490..fa86d35 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -844,6 +844,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
 			goto unlock_rcu;
 		}
+		sta->plid = plid;
 	}
 
 	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
@@ -857,7 +858,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			break;
 		case OPN_ACPT:
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
-			sta->plid = plid;
 			get_random_bytes(&llid, 2);
 			sta->llid = llid;
 			mesh_plink_timer_set(sta,
@@ -885,7 +885,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 		case OPN_ACPT:
 			/* retry timer is left untouched */
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
-			sta->plid = plid;
 			action = WLAN_SP_MESH_PEERING_CONFIRM;
 			break;
 		case CNF_ACPT:
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 14/17] mac80211: factor out peering FSM
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (11 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 13/17] mac80211: assign sta plid early Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 15/17] mac80211: factor out plink event gathering Thomas Pedersen
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 296 ++++++++++++++++++++++++----------------------
 1 file changed, 154 insertions(+), 142 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index fa86d35..e5d5c69 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -691,14 +691,165 @@ static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
 	return changed;
 }
 
+/**
+ * mesh_plink_fsm - step @sta MPM based on @event
+ *
+ * @sdata: interface
+ * @sta: mesh neighbor
+ * @event: peering event
+ *
+ * Return: changed MBSS flags
+ */
+static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
+			  struct sta_info *sta, enum plink_event event)
+{
+	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
+	enum ieee80211_self_protected_actioncode action = 0;
+	u32 changed = 0;
+
+	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
+		       mplstates[sta->plink_state], mplevents[event]);
+
+	spin_lock_bh(&sta->lock);
+	switch (sta->plink_state) {
+	case NL80211_PLINK_LISTEN:
+		switch (event) {
+		case CLS_ACPT:
+			mesh_plink_fsm_restart(sta);
+			break;
+		case OPN_ACPT:
+			sta->plink_state = NL80211_PLINK_OPN_RCVD;
+			get_random_bytes(&sta->llid, 2);
+			mesh_plink_timer_set(sta,
+					     mshcfg->dot11MeshRetryTimeout);
+
+			/* set the non-peer mode to active during peering */
+			changed |= ieee80211_mps_local_status_update(sdata);
+			action = WLAN_SP_MESH_PEERING_OPEN;
+			break;
+		default:
+			break;
+		}
+		break;
+	case NL80211_PLINK_OPN_SNT:
+		switch (event) {
+		case OPN_RJCT:
+		case CNF_RJCT:
+		case CLS_ACPT:
+			mesh_plink_close(sdata, sta, event);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
+			break;
+		case OPN_ACPT:
+			/* retry timer is left untouched */
+			sta->plink_state = NL80211_PLINK_OPN_RCVD;
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
+			break;
+		case CNF_ACPT:
+			sta->plink_state = NL80211_PLINK_CNF_RCVD;
+			if (!mod_plink_timer(sta,
+					     mshcfg->dot11MeshConfirmTimeout))
+				sta->ignore_plink_timer = true;
+			break;
+		default:
+			break;
+		}
+		break;
+	case NL80211_PLINK_OPN_RCVD:
+		switch (event) {
+		case OPN_RJCT:
+		case CNF_RJCT:
+		case CLS_ACPT:
+			mesh_plink_close(sdata, sta, event);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
+			break;
+		case OPN_ACPT:
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
+			break;
+		case CNF_ACPT:
+			changed |= mesh_plink_establish(sdata, sta);
+			break;
+		default:
+			break;
+		}
+		break;
+	case NL80211_PLINK_CNF_RCVD:
+		switch (event) {
+		case OPN_RJCT:
+		case CNF_RJCT:
+		case CLS_ACPT:
+			mesh_plink_close(sdata, sta, event);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
+			break;
+		case OPN_ACPT:
+			changed |= mesh_plink_establish(sdata, sta);
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
+			break;
+		default:
+			break;
+		}
+		break;
+	case NL80211_PLINK_ESTAB:
+		switch (event) {
+		case CLS_ACPT:
+			changed |= __mesh_plink_deactivate(sta);
+			changed |= mesh_set_ht_prot_mode(sdata);
+			changed |= mesh_set_short_slot_time(sdata);
+			mesh_plink_close(sdata, sta, event);
+			action = WLAN_SP_MESH_PEERING_CLOSE;
+			break;
+		case OPN_ACPT:
+			action = WLAN_SP_MESH_PEERING_CONFIRM;
+			break;
+		default:
+			break;
+		}
+		break;
+	case NL80211_PLINK_HOLDING:
+		switch (event) {
+		case CLS_ACPT:
+			if (del_timer(&sta->plink_timer))
+				sta->ignore_plink_timer = 1;
+			mesh_plink_fsm_restart(sta);
+			break;
+		case OPN_ACPT:
+		case CNF_ACPT:
+		case OPN_RJCT:
+		case CNF_RJCT:
+			action = WLAN_SP_MESH_PEERING_CLOSE;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		/* should not get here, PLINK_BLOCKED is dealt with at the
+		 * beginning of the function
+		 */
+		break;
+	}
+	spin_unlock_bh(&sta->lock);
+	if (action) {
+		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
+				    sta->llid, sta->plid, sta->reason);
+
+		/* also send confirm in open case */
+		if (action == WLAN_SP_MESH_PEERING_OPEN) {
+			mesh_plink_frame_tx(sdata,
+					    WLAN_SP_MESH_PEERING_CONFIRM,
+					    sta->sta.addr, sta->llid,
+					    sta->plid, 0);
+		}
+	}
+
+	return changed;
+}
+
 static void
 mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_mgmt *mgmt,
 			 struct ieee802_11_elems *elems)
 {
 
-	struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
-	enum ieee80211_self_protected_actioncode action = 0;
 	struct sta_info *sta;
 	enum plink_event event;
 	enum ieee80211_self_protected_actioncode ftype;
@@ -847,146 +998,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 		sta->plid = plid;
 	}
 
-	mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
-		       mplstates[sta->plink_state], mplevents[event]);
-	spin_lock_bh(&sta->lock);
-	switch (sta->plink_state) {
-	case NL80211_PLINK_LISTEN:
-		switch (event) {
-		case CLS_ACPT:
-			mesh_plink_fsm_restart(sta);
-			break;
-		case OPN_ACPT:
-			sta->plink_state = NL80211_PLINK_OPN_RCVD;
-			get_random_bytes(&llid, 2);
-			sta->llid = llid;
-			mesh_plink_timer_set(sta,
-					     mshcfg->dot11MeshRetryTimeout);
-
-			/* set the non-peer mode to active during peering */
-			changed |= ieee80211_mps_local_status_update(sdata);
-
-			action = WLAN_SP_MESH_PEERING_OPEN;
-			break;
-		default:
-			break;
-		}
-		break;
-
-	case NL80211_PLINK_OPN_SNT:
-		switch (event) {
-		case OPN_RJCT:
-		case CNF_RJCT:
-		case CLS_ACPT:
-			mesh_plink_close(sdata, sta, event);
-			action = WLAN_SP_MESH_PEERING_CLOSE;
-			break;
-
-		case OPN_ACPT:
-			/* retry timer is left untouched */
-			sta->plink_state = NL80211_PLINK_OPN_RCVD;
-			action = WLAN_SP_MESH_PEERING_CONFIRM;
-			break;
-		case CNF_ACPT:
-			sta->plink_state = NL80211_PLINK_CNF_RCVD;
-			if (!mod_plink_timer(sta,
-					     mshcfg->dot11MeshConfirmTimeout))
-				sta->ignore_plink_timer = true;
-
-			break;
-		default:
-			break;
-		}
-		break;
-
-	case NL80211_PLINK_OPN_RCVD:
-		switch (event) {
-		case OPN_RJCT:
-		case CNF_RJCT:
-		case CLS_ACPT:
-			mesh_plink_close(sdata, sta, event);
-			action = WLAN_SP_MESH_PEERING_CLOSE;
-			break;
-		case OPN_ACPT:
-			action = WLAN_SP_MESH_PEERING_CONFIRM;
-			break;
-		case CNF_ACPT:
-			changed |= mesh_plink_establish(sdata, sta);
-			break;
-		default:
-			break;
-		}
-		break;
-
-	case NL80211_PLINK_CNF_RCVD:
-		switch (event) {
-		case OPN_RJCT:
-		case CNF_RJCT:
-		case CLS_ACPT:
-			mesh_plink_close(sdata, sta, event);
-			action = WLAN_SP_MESH_PEERING_CLOSE;
-			break;
-		case OPN_ACPT:
-			changed |= mesh_plink_establish(sdata, sta);
-			action = WLAN_SP_MESH_PEERING_CONFIRM;
-			break;
-		default:
-			break;
-		}
-		break;
-
-	case NL80211_PLINK_ESTAB:
-		switch (event) {
-		case CLS_ACPT:
-			changed |= __mesh_plink_deactivate(sta);
-			changed |= mesh_set_ht_prot_mode(sdata);
-			changed |= mesh_set_short_slot_time(sdata);
-			mesh_plink_close(sdata, sta, event);
-			action = WLAN_SP_MESH_PEERING_CLOSE;
-			break;
-		case OPN_ACPT:
-			action = WLAN_SP_MESH_PEERING_CONFIRM;
-			break;
-		default:
-			break;
-		}
-		break;
-	case NL80211_PLINK_HOLDING:
-		switch (event) {
-		case CLS_ACPT:
-			if (del_timer(&sta->plink_timer))
-				sta->ignore_plink_timer = 1;
-			mesh_plink_fsm_restart(sta);
-			break;
-		case OPN_ACPT:
-		case CNF_ACPT:
-		case OPN_RJCT:
-		case CNF_RJCT:
-			action = WLAN_SP_MESH_PEERING_CLOSE;
-			break;
-		default:
-			break;
-		}
-		break;
-	default:
-		/* should not get here, PLINK_BLOCKED is dealt with at the
-		 * beginning of the function
-		 */
-		break;
-	}
-	spin_unlock_bh(&sta->lock);
-	if (action) {
-		mesh_plink_frame_tx(sdata, action, sta->sta.addr,
-				    sta->llid, sta->plid, sta->reason);
-
-		/* also send confirm in open case */
-		if (action == WLAN_SP_MESH_PEERING_OPEN) {
-			mesh_plink_frame_tx(sdata,
-					    WLAN_SP_MESH_PEERING_CONFIRM,
-					    sta->sta.addr, sta->llid,
-					    sta->plid, 0);
-		}
-	}
+	changed |= mesh_plink_fsm(sdata, sta, event);
 
 unlock_rcu:
 	rcu_read_unlock();
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 15/17] mac80211: factor out plink event gathering
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (12 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 14/17] mac80211: factor out peering FSM Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 16/17] mac80211: initialize llid Thomas Pedersen
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 195 +++++++++++++++++++++++++++-------------------
 1 file changed, 115 insertions(+), 80 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index e5d5c69..c6d0917 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -844,6 +844,111 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
 	return changed;
 }
 
+/*
+ * mesh_plink_get_event - get correct MPM event
+ *
+ * @sdata: interface
+ * @sta: peer, leave NULL if processing a frame from a new suitable peer
+ * @elems: peering management IEs
+ * @ftype: frame type
+ * @llid: peer's peer link ID
+ * @plid: peer's local link ID
+ *
+ * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as
+ * an error.
+ */
+static enum plink_event
+mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
+		     struct sta_info *sta,
+		     struct ieee802_11_elems *elems,
+		     enum ieee80211_self_protected_actioncode ftype,
+		     __le16 llid, __le16 plid)
+{
+	enum plink_event event = PLINK_UNDEFINED;
+	u8 ie_len = elems->peering_len;
+	bool matches_local;
+
+	matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
+			 mesh_matches_local(sdata, elems));
+
+	/* deny open request from non-matching peer */
+	if (!matches_local && !sta) {
+		event = OPN_RJCT;
+		goto out;
+	}
+
+	if (!sta) {
+		if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
+			mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
+			goto out;
+		}
+		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
+		if (!mesh_plink_free_count(sdata)) {
+			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
+			goto out;
+		}
+	} else {
+		if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
+			mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
+			goto out;
+		}
+		if (sta->plink_state == NL80211_PLINK_BLOCKED)
+			goto out;
+	}
+
+	/* new matching peer */
+	if (!sta) {
+		event = OPN_ACPT;
+		goto out;
+	}
+
+	switch (ftype) {
+	case WLAN_SP_MESH_PEERING_OPEN:
+		if (!matches_local)
+			event = OPN_RJCT;
+		if (!mesh_plink_free_count(sdata) ||
+		    (sta->plid && sta->plid != plid))
+			event = OPN_IGNR;
+		else
+			event = OPN_ACPT;
+		break;
+	case WLAN_SP_MESH_PEERING_CONFIRM:
+		if (!matches_local)
+			event = CNF_RJCT;
+		if (!mesh_plink_free_count(sdata) ||
+		    (sta->llid != llid || sta->plid != plid))
+			event = CNF_IGNR;
+		else
+			event = CNF_ACPT;
+		break;
+	case WLAN_SP_MESH_PEERING_CLOSE:
+		if (sta->plink_state == NL80211_PLINK_ESTAB)
+			/* Do not check for llid or plid. This does not
+			 * follow the standard but since multiple plinks
+			 * per sta are not supported, it is necessary in
+			 * order to avoid a livelock when MP A sees an
+			 * establish peer link to MP B but MP B does not
+			 * see it. This can be caused by a timeout in
+			 * B's peer link establishment or B beign
+			 * restarted.
+			 */
+			event = CLS_ACPT;
+		else if (sta->plid != plid)
+			event = CLS_IGNR;
+		else if (ie_len == 8 && sta->llid != llid)
+			event = CLS_IGNR;
+		else
+			event = CLS_ACPT;
+		break;
+	default:
+		mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
+		break;
+	}
+
+out:
+	return event;
+}
+
 static void
 mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_mgmt *mgmt,
@@ -853,9 +958,8 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 	struct sta_info *sta;
 	enum plink_event event;
 	enum ieee80211_self_protected_actioncode ftype;
-	bool matches_local;
 	u32 changed = 0;
-	u8 ie_len;
+	u8 ie_len = elems->peering_len;
 	__le16 plid, llid;
 
 	if (!elems->peering) {
@@ -872,7 +976,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 	}
 
 	ftype = mgmt->u.action.u.self_prot.action_code;
-	ie_len = elems->peering_len;
 	if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
 	    (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
 	    (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
@@ -901,9 +1004,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 
 	sta = sta_info_get(sdata, mgmt->sa);
 
-	matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
-			 mesh_matches_local(sdata, elems));
-
 	if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
 	    !rssi_threshold_check(sdata, sta)) {
 		mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
@@ -911,81 +1011,8 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 		goto unlock_rcu;
 	}
 
-	if (!sta) {
-		if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
-			mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
-			goto unlock_rcu;
-		}
-		/* ftype == WLAN_SP_MESH_PEERING_OPEN */
-		if (!mesh_plink_free_count(sdata)) {
-			mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
-			goto unlock_rcu;
-		}
-		/* deny open request from non-matching peer */
-		if (!matches_local) {
-			mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
-					    mgmt->sa, 0, plid,
-					    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
-			goto unlock_rcu;
-		}
-	} else {
-		if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
-			mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
-			goto unlock_rcu;
-		}
-		if (sta->plink_state == NL80211_PLINK_BLOCKED)
-			goto unlock_rcu;
-	}
-
 	/* Now we will figure out the appropriate event... */
-	event = PLINK_UNDEFINED;
-
-	if (!sta)
-		event = OPN_ACPT;
-	else {
-		switch (ftype) {
-		case WLAN_SP_MESH_PEERING_OPEN:
-			if (!matches_local)
-				event = OPN_RJCT;
-			else if (!mesh_plink_free_count(sdata) ||
-				 (sta->plid && sta->plid != plid))
-				event = OPN_IGNR;
-			else
-				event = OPN_ACPT;
-			break;
-		case WLAN_SP_MESH_PEERING_CONFIRM:
-			if (!matches_local)
-				event = CNF_RJCT;
-			else if (!mesh_plink_free_count(sdata) ||
-				 (sta->llid != llid || sta->plid != plid))
-				event = CNF_IGNR;
-			else
-				event = CNF_ACPT;
-			break;
-		case WLAN_SP_MESH_PEERING_CLOSE:
-			if (sta->plink_state == NL80211_PLINK_ESTAB)
-				/* Do not check for llid or plid. This does not
-				 * follow the standard but since multiple plinks
-				 * per sta are not supported, it is necessary in
-				 * order to avoid a livelock when MP A sees an
-				 * establish peer link to MP B but MP B does not
-				 * see it. This can be caused by a timeout in
-				 * B's peer link establishment or B beign
-				 * restarted.
-				 */
-				event = CLS_ACPT;
-			else if (sta->plid != plid)
-				event = CLS_IGNR;
-			else if (ie_len == 8 && sta->llid != llid)
-				event = CLS_IGNR;
-			else
-				event = CLS_ACPT;
-			break;
-		default:
-			mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
-			goto unlock_rcu;
-		}
-	}
+	event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid);
 
 	if (event == OPN_ACPT) {
 		rcu_read_unlock();
@@ -996,6 +1023,14 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 			goto unlock_rcu;
 		}
 		sta->plid = plid;
+	} else if (!sta && event == OPN_RJCT) {
+		mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+				    mgmt->sa, 0, plid,
+				    cpu_to_le16(WLAN_REASON_MESH_CONFIG));
+		goto unlock_rcu;
+	} else if (!sta || event == PLINK_UNDEFINED) {
+		/* something went wrong */
+		goto unlock_rcu;
 	}
 
 	changed |= mesh_plink_fsm(sdata, sta, event);
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 16/17] mac80211: initialize llid
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (13 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 15/17] mac80211: factor out plink event gathering Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-05 19:17 ` [PATCH 17/17] mac80211: clean up mesh local link ID generation Thomas Pedersen
  2013-11-06 10:35 ` [PATCH 01/17] mac80211: fix off-by-one in llid check Johannes Berg
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

If the peer doesn't have an llid for us, the event
gathering function won't use it anyway (based on
frametype), but initialize it so gcc and coverity don't
complain.

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index c6d0917..e0528b9 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -960,7 +960,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
 	enum ieee80211_self_protected_actioncode ftype;
 	u32 changed = 0;
 	u8 ie_len = elems->peering_len;
-	__le16 plid, llid;
+	__le16 plid, llid = 0;
 
 	if (!elems->peering) {
 		mpl_dbg(sdata,
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 17/17] mac80211: clean up mesh local link ID generation
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (14 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 16/17] mac80211: initialize llid Thomas Pedersen
@ 2013-11-05 19:17 ` Thomas Pedersen
  2013-11-06 10:35 ` [PATCH 01/17] mac80211: fix off-by-one in llid check Johannes Berg
  16 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-05 19:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s, Thomas Pedersen

802.11-2012 13.3.1 implicitly limits the mesh local link
ID range to that of AID, since for mesh PS the local link
ID must be indicated in the TIM IE, which only holds
IEEE80211_MAX_AID bits.

Also the code was allowing a local link ID of 0, but this
is not correct since that TIM bit is used for indicating
buffered mcast frames.

Generate a random, unique, link ID from 1 - 2007, and drop
a modulo conversion for the local link ID, but keep it for
the peer link ID in case he chose something > MAX_AID.

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
 net/mac80211/mesh_plink.c | 40 +++++++++++++++++++++++++++++++++++-----
 net/mac80211/mesh_ps.c    |  3 +--
 net/mac80211/sta_info.c   |  4 ++--
 3 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index e0528b9..4ea2f21 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -615,9 +615,40 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
 	add_timer(&sta->plink_timer);
 }
 
+static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
+			__le16 llid)
+{
+	struct ieee80211_local *local = sdata->local;
+	bool in_use = false;
+	struct sta_info *sta;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sta, &local->sta_list, list) {
+		if (!memcmp(&sta->llid, &llid, sizeof(llid))) {
+			in_use = true;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return in_use;
+}
+
+static __le16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
+{
+	u16 llid;
+
+	do {
+		get_random_bytes(&llid, sizeof(llid));
+		/* for mesh PS we still only have the AID range for TIM bits */
+		llid = (llid % IEEE80211_MAX_AID) + 1;
+	} while (llid_in_use(sdata, cpu_to_le16(llid)));
+
+	return cpu_to_le16(llid);
+}
+
 u32 mesh_plink_open(struct sta_info *sta)
 {
-	__le16 llid;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	u32 changed;
 
@@ -625,8 +656,7 @@ u32 mesh_plink_open(struct sta_info *sta)
 		return 0;
 
 	spin_lock_bh(&sta->lock);
-	get_random_bytes(&llid, 2);
-	sta->llid = llid;
+	sta->llid = mesh_get_new_llid(sdata);
 	if (sta->plink_state != NL80211_PLINK_LISTEN &&
 	    sta->plink_state != NL80211_PLINK_BLOCKED) {
 		spin_unlock_bh(&sta->lock);
@@ -643,7 +673,7 @@ u32 mesh_plink_open(struct sta_info *sta)
 	changed = ieee80211_mps_local_status_update(sdata);
 
 	mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
-			    sta->sta.addr, llid, 0, 0);
+			    sta->sta.addr, sta->llid, 0, 0);
 	return changed;
 }
 
@@ -719,7 +749,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
 			break;
 		case OPN_ACPT:
 			sta->plink_state = NL80211_PLINK_OPN_RCVD;
-			get_random_bytes(&sta->llid, 2);
+			sta->llid = mesh_get_new_llid(sdata);
 			mesh_plink_timer_set(sta,
 					     mshcfg->dot11MeshRetryTimeout);
 
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c
index 0f79b78..9493868 100644
--- a/net/mac80211/mesh_ps.c
+++ b/net/mac80211/mesh_ps.c
@@ -576,10 +576,9 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
 	int ac, buffer_local = 0;
 	bool has_buffered = false;
 
-	/* TIM map only for LLID <= IEEE80211_MAX_AID */
 	if (sta->plink_state == NL80211_PLINK_ESTAB)
 		has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len,
-				le16_to_cpu(sta->llid) % IEEE80211_MAX_AID);
+						   le16_to_cpu(sta->llid));
 
 	if (has_buffered)
 		mps_dbg(sta->sdata, "%pM indicates buffered frames\n",
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 1eb66e2..7a91515 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -630,8 +630,8 @@ void sta_info_recalc_tim(struct sta_info *sta)
 #ifdef CONFIG_MAC80211_MESH
 	} else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
 		ps = &sta->sdata->u.mesh.ps;
-		/* TIM map only for PLID <= IEEE80211_MAX_AID */
-		id = le16_to_cpu(sta->plid) % IEEE80211_MAX_AID;
+		/* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */
+		id = le16_to_cpu(sta->plid) % (IEEE80211_MAX_AID + 1);
 #endif
 	} else {
 		return;
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 01/17] mac80211: fix off-by-one in llid check.
  2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
                   ` (15 preceding siblings ...)
  2013-11-05 19:17 ` [PATCH 17/17] mac80211: clean up mesh local link ID generation Thomas Pedersen
@ 2013-11-06 10:35 ` Johannes Berg
  2013-11-06 15:14   ` Thomas Pedersen
  16 siblings, 1 reply; 19+ messages in thread
From: Johannes Berg @ 2013-11-06 10:35 UTC (permalink / raw)
  To: Thomas Pedersen; +Cc: Bob Copeland, linux-wireless, open80211s

Very nice. I've squashed the llid assignment into the patch that
introduced the warning.

johannes


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 01/17] mac80211: fix off-by-one in llid check.
  2013-11-06 10:35 ` [PATCH 01/17] mac80211: fix off-by-one in llid check Johannes Berg
@ 2013-11-06 15:14   ` Thomas Pedersen
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Pedersen @ 2013-11-06 15:14 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Bob Copeland, linux-wireless, open80211s

On Wed, Nov 6, 2013 at 2:35 AM, Johannes Berg <johannes@sipsolutions.net> wrote:
> Very nice. I've squashed the llid assignment into the patch that
> introduced the warning.

Hm, ok. Guess you can't get them all :)

Thanks!

-- 
Thomas

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2013-11-06 15:14 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-05 19:16 [PATCH 01/17] mac80211: fix off-by-one in llid check Thomas Pedersen
2013-11-05 19:16 ` [PATCH 02/17] mac80211: consolidate calls to plink_frame_tx Thomas Pedersen
2013-11-05 19:16 ` [PATCH 03/17] mac80211: hold sta->lock across plink switch statements Thomas Pedersen
2013-11-05 19:16 ` [PATCH 04/17] mac80211: mesh: factor out common plink close/estab code Thomas Pedersen
2013-11-05 19:16 ` [PATCH 05/17] mac80211: mesh_plink: group basic fitness checks Thomas Pedersen
2013-11-05 19:16 ` [PATCH 06/17] mac80211: mesh: rewrite rssi_threshold_check in C Thomas Pedersen
2013-11-05 19:16 ` [PATCH 07/17] mac80211: mesh_plink: collapse the two switch statements together Thomas Pedersen
2013-11-05 19:16 ` [PATCH 08/17] mac80211: mesh_plink: don't ignore holding timer Thomas Pedersen
2013-11-05 19:16 ` [PATCH 09/17] mac80211: return -ENOMEM in mesh_plink_frame_tx Thomas Pedersen
2013-11-05 19:16 ` [PATCH 10/17] mac80211: remove unused mesh_mgmt_ies_add() prototype Thomas Pedersen
2013-11-05 19:16 ` [PATCH 11/17] mac80211: factor peering frame processing into own function Thomas Pedersen
2013-11-05 19:17 ` [PATCH 12/17] mac80211: consolidate rcu unlocks in plink frame rx Thomas Pedersen
2013-11-05 19:17 ` [PATCH 13/17] mac80211: assign sta plid early Thomas Pedersen
2013-11-05 19:17 ` [PATCH 14/17] mac80211: factor out peering FSM Thomas Pedersen
2013-11-05 19:17 ` [PATCH 15/17] mac80211: factor out plink event gathering Thomas Pedersen
2013-11-05 19:17 ` [PATCH 16/17] mac80211: initialize llid Thomas Pedersen
2013-11-05 19:17 ` [PATCH 17/17] mac80211: clean up mesh local link ID generation Thomas Pedersen
2013-11-06 10:35 ` [PATCH 01/17] mac80211: fix off-by-one in llid check Johannes Berg
2013-11-06 15:14   ` Thomas Pedersen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).