diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 13:43:21 -0700 | 
| commit | 06f4e926d256d902dd9a53dcb400fd74974ce087 (patch) | |
| tree | 0b438b67f5f0eff6fd617bc497a9dace6164a488 /net/mac80211/mesh_plink.c | |
| parent | 8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff) | |
| parent | d93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff) | |
| download | olio-linux-3.10-06f4e926d256d902dd9a53dcb400fd74974ce087.tar.xz olio-linux-3.10-06f4e926d256d902dd9a53dcb400fd74974ce087.zip  | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits)
  macvlan: fix panic if lowerdev in a bond
  tg3: Add braces around 5906 workaround.
  tg3: Fix NETIF_F_LOOPBACK error
  macvlan: remove one synchronize_rcu() call
  networking: NET_CLS_ROUTE4 depends on INET
  irda: Fix error propagation in ircomm_lmp_connect_response()
  irda: Kill set but unused variable 'bytes' in irlan_check_command_param()
  irda: Kill set but unused variable 'clen' in ircomm_connect_indication()
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport()
  be2net: Kill set but unused variable 'req' in lancer_fw_download()
  irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication()
  atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined.
  rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer().
  rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection()
  rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window()
  pkt_sched: Kill set but unused variable 'protocol' in tc_classify()
  isdn: capi: Use pr_debug() instead of ifdefs.
  tg3: Update version to 3.119
  tg3: Apply rx_discards fix to 5719/5720
  ...
Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c
as per Davem.
Diffstat (limited to 'net/mac80211/mesh_plink.c')
| -rw-r--r-- | net/mac80211/mesh_plink.c | 112 | 
1 files changed, 67 insertions, 45 deletions
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 44b53931ba5..f4adc091788 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -43,7 +43,7 @@  #define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)  enum plink_frame_type { -	PLINK_OPEN = 0, +	PLINK_OPEN = 1,  	PLINK_CONFIRM,  	PLINK_CLOSE  }; @@ -83,7 +83,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)   */  static inline void mesh_plink_fsm_restart(struct sta_info *sta)  { -	sta->plink_state = PLINK_LISTEN; +	sta->plink_state = NL80211_PLINK_LISTEN;  	sta->llid = sta->plid = sta->reason = 0;  	sta->plink_retries = 0;  } @@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,  	if (!sta)  		return NULL; -	sta->flags = WLAN_STA_AUTHORIZED; +	sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH;  	sta->sta.supp_rates[local->hw.conf.channel->band] = rates;  	rate_control_rate_init(sta); @@ -126,11 +126,11 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)  	struct ieee80211_sub_if_data *sdata = sta->sdata;  	bool deactivated = false; -	if (sta->plink_state == PLINK_ESTAB) { +	if (sta->plink_state == NL80211_PLINK_ESTAB) {  		mesh_plink_dec_estab_count(sdata);  		deactivated = true;  	} -	sta->plink_state = PLINK_BLOCKED; +	sta->plink_state = NL80211_PLINK_BLOCKED;  	mesh_path_flush_by_nexthop(sta);  	return deactivated; @@ -161,7 +161,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,  		__le16 reason) {  	struct ieee80211_local *local = sdata->local;  	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 + -			sdata->u.mesh.vendor_ie_len); +			sdata->u.mesh.ie_len);  	struct ieee80211_mgmt *mgmt;  	bool include_plid = false;  	static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; @@ -181,8 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,  					  IEEE80211_STYPE_ACTION);  	memcpy(mgmt->da, da, ETH_ALEN);  	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); -	/* BSSID is left zeroed, wildcard value */ -	mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK; +	memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); +	mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;  	mgmt->u.action.u.plink_action.action_code = action;  	if (action == PLINK_CLOSE) @@ -237,8 +237,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,  	return 0;  } -void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata, -			   bool peer_accepting_plinks) +void mesh_neighbour_update(u8 *hw_addr, u32 rates, +		struct ieee80211_sub_if_data *sdata, +		struct ieee802_11_elems *elems)  {  	struct ieee80211_local *local = sdata->local;  	struct sta_info *sta; @@ -248,8 +249,14 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data  	sta = sta_info_get(sdata, hw_addr);  	if (!sta) {  		rcu_read_unlock(); - -		sta = mesh_plink_alloc(sdata, hw_addr, rates); +		/* Userspace handles peer allocation when security is enabled +		 * */ +		if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) +			cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, +					elems->ie_start, elems->total_len, +					GFP_KERNEL); +		else +			sta = mesh_plink_alloc(sdata, hw_addr, rates);  		if (!sta)  			return;  		if (sta_info_insert_rcu(sta)) { @@ -260,7 +267,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data  	sta->last_rx = jiffies;  	sta->sta.supp_rates[local->hw.conf.channel->band] = rates; -	if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && +	if (mesh_peer_accepts_plinks(elems) && +			sta->plink_state == NL80211_PLINK_LISTEN &&  			sdata->u.mesh.accepting_plinks &&  			sdata->u.mesh.mshcfg.auto_open_plinks)  		mesh_plink_open(sta); @@ -300,8 +308,8 @@ static void mesh_plink_timer(unsigned long data)  	sdata = sta->sdata;  	switch (sta->plink_state) { -	case PLINK_OPN_RCVD: -	case PLINK_OPN_SNT: +	case NL80211_PLINK_OPN_RCVD: +	case NL80211_PLINK_OPN_SNT:  		/* retry timer */  		if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {  			u32 rand; @@ -320,17 +328,17 @@ static void mesh_plink_timer(unsigned long data)  		}  		reason = cpu_to_le16(MESH_MAX_RETRIES);  		/* fall through on else */ -	case PLINK_CNF_RCVD: +	case NL80211_PLINK_CNF_RCVD:  		/* confirm timer */  		if (!reason)  			reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); -		sta->plink_state = PLINK_HOLDING; +		sta->plink_state = NL80211_PLINK_HOLDING;  		mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));  		spin_unlock_bh(&sta->lock);  		mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,  				    reason);  		break; -	case PLINK_HOLDING: +	case NL80211_PLINK_HOLDING:  		/* holding timer */  		del_timer(&sta->plink_timer);  		mesh_plink_fsm_restart(sta); @@ -372,14 +380,17 @@ int mesh_plink_open(struct sta_info *sta)  	__le16 llid;  	struct ieee80211_sub_if_data *sdata = sta->sdata; +	if (!test_sta_flags(sta, WLAN_STA_AUTH)) +		return -EPERM; +  	spin_lock_bh(&sta->lock);  	get_random_bytes(&llid, 2);  	sta->llid = llid; -	if (sta->plink_state != PLINK_LISTEN) { +	if (sta->plink_state != NL80211_PLINK_LISTEN) {  		spin_unlock_bh(&sta->lock);  		return -EBUSY;  	} -	sta->plink_state = PLINK_OPN_SNT; +	sta->plink_state = NL80211_PLINK_OPN_SNT;  	mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));  	spin_unlock_bh(&sta->lock);  	mpl_dbg("Mesh plink: starting establishment with %pM\n", @@ -396,7 +407,7 @@ void mesh_plink_block(struct sta_info *sta)  	spin_lock_bh(&sta->lock);  	deactivated = __mesh_plink_deactivate(sta); -	sta->plink_state = PLINK_BLOCKED; +	sta->plink_state = NL80211_PLINK_BLOCKED;  	spin_unlock_bh(&sta->lock);  	if (deactivated) @@ -419,13 +430,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  	__le16 plid, llid, reason;  #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG  	static const char *mplstates[] = { -		[PLINK_LISTEN] = "LISTEN", -		[PLINK_OPN_SNT] = "OPN-SNT", -		[PLINK_OPN_RCVD] = "OPN-RCVD", -		[PLINK_CNF_RCVD] = "CNF_RCVD", -		[PLINK_ESTAB] = "ESTAB", -		[PLINK_HOLDING] = "HOLDING", -		[PLINK_BLOCKED] = "BLOCKED" +		[NL80211_PLINK_LISTEN] = "LISTEN", +		[NL80211_PLINK_OPN_SNT] = "OPN-SNT", +		[NL80211_PLINK_OPN_RCVD] = "OPN-RCVD", +		[NL80211_PLINK_CNF_RCVD] = "CNF_RCVD", +		[NL80211_PLINK_ESTAB] = "ESTAB", +		[NL80211_PLINK_HOLDING] = "HOLDING", +		[NL80211_PLINK_BLOCKED] = "BLOCKED"  	};  #endif @@ -449,6 +460,11 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		mpl_dbg("Mesh plink: missing necessary peer link ie\n");  		return;  	} +	if (elems.rsn_len && +			sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { +		mpl_dbg("Mesh plink: can't establish link with secure peer\n"); +		return; +	}  	ftype = mgmt->u.action.u.plink_action.action_code;  	ie_len = elems.peer_link_len; @@ -480,7 +496,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		return;  	} -	if (sta && sta->plink_state == PLINK_BLOCKED) { +	if (sta && !test_sta_flags(sta, WLAN_STA_AUTH)) { +		mpl_dbg("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;  	} @@ -550,7 +572,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  				event = CNF_ACPT;  			break;  		case PLINK_CLOSE: -			if (sta->plink_state == PLINK_ESTAB) +			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 @@ -585,14 +607,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  	reason = 0;  	switch (sta->plink_state) {  		/* spin_unlock as soon as state is updated at each case */ -	case PLINK_LISTEN: +	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 = PLINK_OPN_RCVD; +			sta->plink_state = NL80211_PLINK_OPN_RCVD;  			sta->plid = plid;  			get_random_bytes(&llid, 2);  			sta->llid = llid; @@ -609,7 +631,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		}  		break; -	case PLINK_OPN_SNT: +	case NL80211_PLINK_OPN_SNT:  		switch (event) {  		case OPN_RJCT:  		case CNF_RJCT: @@ -618,7 +640,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			if (!reason)  				reason = cpu_to_le16(MESH_CLOSE_RCVD);  			sta->reason = reason; -			sta->plink_state = PLINK_HOLDING; +			sta->plink_state = NL80211_PLINK_HOLDING;  			if (!mod_plink_timer(sta,  					     dot11MeshHoldingTimeout(sdata)))  				sta->ignore_plink_timer = true; @@ -630,7 +652,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			break;  		case OPN_ACPT:  			/* retry timer is left untouched */ -			sta->plink_state = PLINK_OPN_RCVD; +			sta->plink_state = NL80211_PLINK_OPN_RCVD;  			sta->plid = plid;  			llid = sta->llid;  			spin_unlock_bh(&sta->lock); @@ -638,7 +660,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  					    plid, 0);  			break;  		case CNF_ACPT: -			sta->plink_state = PLINK_CNF_RCVD; +			sta->plink_state = NL80211_PLINK_CNF_RCVD;  			if (!mod_plink_timer(sta,  					     dot11MeshConfirmTimeout(sdata)))  				sta->ignore_plink_timer = true; @@ -651,7 +673,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		}  		break; -	case PLINK_OPN_RCVD: +	case NL80211_PLINK_OPN_RCVD:  		switch (event) {  		case OPN_RJCT:  		case CNF_RJCT: @@ -660,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			if (!reason)  				reason = cpu_to_le16(MESH_CLOSE_RCVD);  			sta->reason = reason; -			sta->plink_state = PLINK_HOLDING; +			sta->plink_state = NL80211_PLINK_HOLDING;  			if (!mod_plink_timer(sta,  					     dot11MeshHoldingTimeout(sdata)))  				sta->ignore_plink_timer = true; @@ -678,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			break;  		case CNF_ACPT:  			del_timer(&sta->plink_timer); -			sta->plink_state = PLINK_ESTAB; +			sta->plink_state = NL80211_PLINK_ESTAB;  			spin_unlock_bh(&sta->lock);  			mesh_plink_inc_estab_count(sdata);  			ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -691,7 +713,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		}  		break; -	case PLINK_CNF_RCVD: +	case NL80211_PLINK_CNF_RCVD:  		switch (event) {  		case OPN_RJCT:  		case CNF_RJCT: @@ -700,7 +722,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			if (!reason)  				reason = cpu_to_le16(MESH_CLOSE_RCVD);  			sta->reason = reason; -			sta->plink_state = PLINK_HOLDING; +			sta->plink_state = NL80211_PLINK_HOLDING;  			if (!mod_plink_timer(sta,  					     dot11MeshHoldingTimeout(sdata)))  				sta->ignore_plink_timer = true; @@ -712,7 +734,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			break;  		case OPN_ACPT:  			del_timer(&sta->plink_timer); -			sta->plink_state = PLINK_ESTAB; +			sta->plink_state = NL80211_PLINK_ESTAB;  			spin_unlock_bh(&sta->lock);  			mesh_plink_inc_estab_count(sdata);  			ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -727,13 +749,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  		}  		break; -	case PLINK_ESTAB: +	case NL80211_PLINK_ESTAB:  		switch (event) {  		case CLS_ACPT:  			reason = cpu_to_le16(MESH_CLOSE_RCVD);  			sta->reason = reason;  			deactivated = __mesh_plink_deactivate(sta); -			sta->plink_state = PLINK_HOLDING; +			sta->plink_state = NL80211_PLINK_HOLDING;  			llid = sta->llid;  			mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));  			spin_unlock_bh(&sta->lock); @@ -753,7 +775,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m  			break;  		}  		break; -	case PLINK_HOLDING: +	case NL80211_PLINK_HOLDING:  		switch (event) {  		case CLS_ACPT:  			if (del_timer(&sta->plink_timer))  |