forked from mirrors/linux
		
	mptcp: add the outgoing MP_PRIO support
This patch added the outgoing MP_PRIO logic: In mptcp_pm_nl_mp_prio_send_ack, find the related subflow and subsocket according to the input parameter addr. Save the input priority value to suflow's backup, then set subflow's send_mp_prio flag to true, and save the input priority value to suflow's request_bkup. Finally, send out a pure ACK on the related subsocket. In mptcp_established_options_mp_prio, check whether the subflow's send_mp_prio is set. If it is, this is the packet for sending MP_PRIO. So save subflow->request_bkup value to mptcp_out_options's backup, and change the option type to OPTION_MPTCP_PRIO. In mptcp_write_options, clear the send_mp_prio flag and send out the MP_PRIO suboption with mptcp_out_options's backup value. Signed-off-by: Geliang Tang <geliangtang@gmail.com> Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									dc8eb10e95
								
							
						
					
					
						commit
						067065422f
					
				
					 3 changed files with 79 additions and 0 deletions
				
			
		|  | @ -679,6 +679,28 @@ static bool mptcp_established_options_rm_addr(struct sock *sk, | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool mptcp_established_options_mp_prio(struct sock *sk, | ||||||
|  | 					      unsigned int *size, | ||||||
|  | 					      unsigned int remaining, | ||||||
|  | 					      struct mptcp_out_options *opts) | ||||||
|  | { | ||||||
|  | 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); | ||||||
|  | 
 | ||||||
|  | 	if (!subflow->send_mp_prio) | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	if (remaining < TCPOLEN_MPTCP_PRIO) | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	*size = TCPOLEN_MPTCP_PRIO; | ||||||
|  | 	opts->suboptions |= OPTION_MPTCP_PRIO; | ||||||
|  | 	opts->backup = subflow->request_bkup; | ||||||
|  | 
 | ||||||
|  | 	pr_debug("prio=%d", opts->backup); | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | ||||||
| 			       unsigned int *size, unsigned int remaining, | 			       unsigned int *size, unsigned int remaining, | ||||||
| 			       struct mptcp_out_options *opts) | 			       struct mptcp_out_options *opts) | ||||||
|  | @ -721,6 +743,12 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, | ||||||
| 		ret = true; | 		ret = true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (mptcp_established_options_mp_prio(sk, &opt_size, remaining, opts)) { | ||||||
|  | 		*size += opt_size; | ||||||
|  | 		remaining -= opt_size; | ||||||
|  | 		ret = true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1168,6 +1196,18 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, | ||||||
| 				      0, opts->rm_id); | 				      0, opts->rm_id); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (OPTION_MPTCP_PRIO & opts->suboptions) { | ||||||
|  | 		const struct sock *ssk = (const struct sock *)tp; | ||||||
|  | 		struct mptcp_subflow_context *subflow; | ||||||
|  | 
 | ||||||
|  | 		subflow = mptcp_subflow_ctx(ssk); | ||||||
|  | 		subflow->send_mp_prio = 0; | ||||||
|  | 
 | ||||||
|  | 		*ptr++ = mptcp_option(MPTCPOPT_MP_PRIO, | ||||||
|  | 				      TCPOLEN_MPTCP_PRIO, | ||||||
|  | 				      opts->backup, TCPOPT_NOP); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) { | 	if (OPTION_MPTCP_MPJ_SYN & opts->suboptions) { | ||||||
| 		*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN, | 		*ptr++ = mptcp_option(MPTCPOPT_MP_JOIN, | ||||||
| 				      TCPOLEN_MPTCP_MPJ_SYN, | 				      TCPOLEN_MPTCP_MPJ_SYN, | ||||||
|  |  | ||||||
|  | @ -442,6 +442,39 @@ void mptcp_pm_nl_add_addr_send_ack(struct mptcp_sock *msk) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, | ||||||
|  | 				 struct mptcp_addr_info *addr, | ||||||
|  | 				 u8 bkup) | ||||||
|  | { | ||||||
|  | 	struct mptcp_subflow_context *subflow; | ||||||
|  | 
 | ||||||
|  | 	pr_debug("bkup=%d", bkup); | ||||||
|  | 
 | ||||||
|  | 	mptcp_for_each_subflow(msk, subflow) { | ||||||
|  | 		struct sock *ssk = mptcp_subflow_tcp_sock(subflow); | ||||||
|  | 		struct mptcp_addr_info local; | ||||||
|  | 
 | ||||||
|  | 		local_address((struct sock_common *)ssk, &local); | ||||||
|  | 		if (!addresses_equal(&local, addr, addr->port)) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		subflow->backup = bkup; | ||||||
|  | 		subflow->send_mp_prio = 1; | ||||||
|  | 		subflow->request_bkup = bkup; | ||||||
|  | 
 | ||||||
|  | 		spin_unlock_bh(&msk->pm.lock); | ||||||
|  | 		pr_debug("send ack for mp_prio"); | ||||||
|  | 		lock_sock(ssk); | ||||||
|  | 		tcp_send_ack(ssk); | ||||||
|  | 		release_sock(ssk); | ||||||
|  | 		spin_lock_bh(&msk->pm.lock); | ||||||
|  | 
 | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return -EINVAL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk) | void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk) | ||||||
| { | { | ||||||
| 	struct mptcp_subflow_context *subflow, *tmp; | 	struct mptcp_subflow_context *subflow, *tmp; | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| #define OPTION_MPTCP_ADD_ADDR6	BIT(7) | #define OPTION_MPTCP_ADD_ADDR6	BIT(7) | ||||||
| #define OPTION_MPTCP_RM_ADDR	BIT(8) | #define OPTION_MPTCP_RM_ADDR	BIT(8) | ||||||
| #define OPTION_MPTCP_FASTCLOSE	BIT(9) | #define OPTION_MPTCP_FASTCLOSE	BIT(9) | ||||||
|  | #define OPTION_MPTCP_PRIO	BIT(10) | ||||||
| 
 | 
 | ||||||
| /* MPTCP option subtypes */ | /* MPTCP option subtypes */ | ||||||
| #define MPTCPOPT_MP_CAPABLE	0 | #define MPTCPOPT_MP_CAPABLE	0 | ||||||
|  | @ -59,6 +60,7 @@ | ||||||
| #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT	24 | #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT	24 | ||||||
| #define TCPOLEN_MPTCP_PORT_LEN		4 | #define TCPOLEN_MPTCP_PORT_LEN		4 | ||||||
| #define TCPOLEN_MPTCP_RM_ADDR_BASE	4 | #define TCPOLEN_MPTCP_RM_ADDR_BASE	4 | ||||||
|  | #define TCPOLEN_MPTCP_PRIO		4 | ||||||
| #define TCPOLEN_MPTCP_FASTCLOSE		12 | #define TCPOLEN_MPTCP_FASTCLOSE		12 | ||||||
| 
 | 
 | ||||||
| /* MPTCP MP_JOIN flags */ | /* MPTCP MP_JOIN flags */ | ||||||
|  | @ -396,6 +398,7 @@ struct mptcp_subflow_context { | ||||||
| 		map_valid : 1, | 		map_valid : 1, | ||||||
| 		mpc_map : 1, | 		mpc_map : 1, | ||||||
| 		backup : 1, | 		backup : 1, | ||||||
|  | 		send_mp_prio : 1, | ||||||
| 		rx_eof : 1, | 		rx_eof : 1, | ||||||
| 		can_ack : 1,        /* only after processing the remote a key */ | 		can_ack : 1,        /* only after processing the remote a key */ | ||||||
| 		disposable : 1;	    /* ctx can be free at ulp release time */ | 		disposable : 1;	    /* ctx can be free at ulp release time */ | ||||||
|  | @ -550,6 +553,9 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, | ||||||
| 				const struct mptcp_addr_info *addr); | 				const struct mptcp_addr_info *addr); | ||||||
| void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk); | void mptcp_pm_add_addr_send_ack(struct mptcp_sock *msk); | ||||||
| void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id); | void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id); | ||||||
|  | int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, | ||||||
|  | 				 struct mptcp_addr_info *addr, | ||||||
|  | 				 u8 bkup); | ||||||
| void mptcp_pm_free_anno_list(struct mptcp_sock *msk); | void mptcp_pm_free_anno_list(struct mptcp_sock *msk); | ||||||
| struct mptcp_pm_add_entry * | struct mptcp_pm_add_entry * | ||||||
| mptcp_pm_del_add_timer(struct mptcp_sock *msk, | mptcp_pm_del_add_timer(struct mptcp_sock *msk, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Geliang Tang
						Geliang Tang