mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-31 13:17:25 +01:00 
			
		
		
		
	ft: gate FT-over-DS with a wiphy work item
Queue the FT action just like we do with FT Authenticate which makes it able to be used the same way, i.e. call ft_action() then queue the ft_associate work right away. A timer was added to end the work item in case the target never responds.
This commit is contained in:
		
							parent
							
								
									59a0947c76
								
							
						
					
					
						commit
						6a616df125
					
				
							
								
								
									
										58
									
								
								src/ft.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/ft.c
									
									
									
									
									
								
							| @ -54,8 +54,12 @@ struct ft_info { | ||||
| 	uint8_t *authenticator_ie; | ||||
| 	uint8_t prev_bssid[6]; | ||||
| 	uint32_t frequency; | ||||
| 	uint32_t ds_frequency; | ||||
| 	uint32_t offchannel_id; | ||||
| 
 | ||||
| 	struct l_timeout *timeout; | ||||
| 	struct wiphy_radio_work_item work; | ||||
| 
 | ||||
| 	struct ie_ft_info ft_info; | ||||
| 
 | ||||
| 	bool parsed : 1; | ||||
| @ -830,6 +834,11 @@ void __ft_rx_action(uint32_t ifindex, const uint8_t *frame, size_t frame_len) | ||||
| 
 | ||||
| 	info->parsed = true; | ||||
| 
 | ||||
| 	l_timeout_remove(info->timeout); | ||||
| 	info->timeout = NULL; | ||||
| 
 | ||||
| 	wiphy_radio_work_done(netdev_get_wiphy(netdev), info->work.id); | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| ft_error: | ||||
| @ -868,6 +877,9 @@ static void ft_info_destroy(void *data) | ||||
| 	if (info->authenticator_ie) | ||||
| 		l_free(info->authenticator_ie); | ||||
| 
 | ||||
| 	if (info->timeout) | ||||
| 		l_timeout_remove(info->timeout); | ||||
| 
 | ||||
| 	l_free(info); | ||||
| } | ||||
| 
 | ||||
| @ -900,19 +912,17 @@ static void ft_prepare_handshake(struct ft_info *info, | ||||
| 	handshake_state_derive_ptk(hs); | ||||
| } | ||||
| 
 | ||||
| int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target) | ||||
| static bool ft_send_action(struct wiphy_radio_work_item *work) | ||||
| { | ||||
| 	struct netdev *netdev = netdev_find(ifindex); | ||||
| 	struct ft_info *info = l_container_of(work, struct ft_info, work); | ||||
| 	struct netdev *netdev = netdev_find(info->ifindex); | ||||
| 	struct handshake_state *hs = netdev_get_handshake(netdev); | ||||
| 	struct ft_info *info; | ||||
| 	uint8_t ft_req[14]; | ||||
| 	struct iovec iov[5]; | ||||
| 	uint8_t ies[512]; | ||||
| 	size_t len; | ||||
| 	int ret = -EINVAL; | ||||
| 
 | ||||
| 	info = ft_info_new(hs, target); | ||||
| 
 | ||||
| 	ft_req[0] = 6; /* FT category */ | ||||
| 	ft_req[1] = 1; /* FT Request action */ | ||||
| 	memcpy(ft_req + 2, info->spa, 6); | ||||
| @ -928,17 +938,47 @@ int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target) | ||||
| 	iov[1].iov_base = ies; | ||||
| 	iov[1].iov_len = len; | ||||
| 
 | ||||
| 	ret = tx_frame(hs->ifindex, 0x00d0, freq, hs->aa, iov, 2); | ||||
| 	ret = tx_frame(hs->ifindex, 0x00d0, info->ds_frequency, hs->aa, iov, 2); | ||||
| 	if (ret < 0) | ||||
| 		goto failed; | ||||
| 
 | ||||
| 	l_queue_push_tail(info_list, info); | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return false; | ||||
| 
 | ||||
| failed: | ||||
| 	l_free(info); | ||||
| 	return ret; | ||||
| 	l_debug("FT-over-DS action failed to "MAC, MAC_STR(hs->aa)); | ||||
| 
 | ||||
| 	ft_info_destroy(info); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| struct wiphy_radio_work_item_ops ft_ops = { | ||||
| 	.do_work = ft_send_action, | ||||
| }; | ||||
| 
 | ||||
| static void ft_ds_timeout(struct l_timeout *timeout, void *user_data) | ||||
| { | ||||
| 	struct ft_info *info = user_data; | ||||
| 	struct netdev *netdev = netdev_find(info->ifindex); | ||||
| 
 | ||||
| 	wiphy_radio_work_done(netdev_get_wiphy(netdev), info->work.id); | ||||
| } | ||||
| 
 | ||||
| int ft_action(uint32_t ifindex, uint32_t freq, const struct scan_bss *target) | ||||
| { | ||||
| 	struct netdev *netdev = netdev_find(ifindex); | ||||
| 	struct handshake_state *hs = netdev_get_handshake(netdev); | ||||
| 	struct ft_info *info; | ||||
| 
 | ||||
| 	info = ft_info_new(hs, target); | ||||
| 	info->ds_frequency = freq; | ||||
| 	info->timeout = l_timeout_create_ms(200, ft_ds_timeout, info, NULL); | ||||
| 
 | ||||
| 	wiphy_radio_work_insert(netdev_get_wiphy(netdev), &info->work, | ||||
| 				WIPHY_WORK_PRIORITY_FT, &ft_ops); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void __ft_rx_authenticate(uint32_t ifindex, const uint8_t *frame, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 James Prestwood
						James Prestwood