forked from mirrors/linux
		
	mptcp: add the incoming RM_ADDR support
This patch added the RM_ADDR option parsing logic: We parsed the incoming options to find if the rm_addr option is received, and called mptcp_pm_rm_addr_received to schedule PM work to a new status, named MPTCP_PM_RM_ADDR_RECEIVED. PM work got this status, and called mptcp_pm_nl_rm_addr_received to handle it. In mptcp_pm_nl_rm_addr_received, we closed the subflow matching the rm_id, and updated PM counter. Suggested-by: Matthieu Baerts <matthieu.baerts@tessares.net> Suggested-by: Paolo Abeni <pabeni@redhat.com> Suggested-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: Geliang Tang <geliangtang@gmail.com> Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									5cb104ae55
								
							
						
					
					
						commit
						d0876b2284
					
				
					 5 changed files with 66 additions and 4 deletions
				
			
		| 
						 | 
					@ -888,6 +888,11 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
 | 
				
			||||||
		mp_opt.add_addr = 0;
 | 
							mp_opt.add_addr = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mp_opt.rm_addr) {
 | 
				
			||||||
 | 
							mptcp_pm_rm_addr_received(msk, mp_opt.rm_id);
 | 
				
			||||||
 | 
							mp_opt.rm_addr = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mp_opt.dss)
 | 
						if (!mp_opt.dss)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +149,18 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
 | 
				
			||||||
	spin_unlock_bh(&pm->lock);
 | 
						spin_unlock_bh(&pm->lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, u8 rm_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mptcp_pm_data *pm = &msk->pm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_debug("msk=%p remote_id=%d", msk, rm_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_bh(&pm->lock);
 | 
				
			||||||
 | 
						mptcp_pm_schedule_work(msk, MPTCP_PM_RM_ADDR_RECEIVED);
 | 
				
			||||||
 | 
						pm->rm_id = rm_id;
 | 
				
			||||||
 | 
						spin_unlock_bh(&pm->lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* path manager helpers */
 | 
					/* path manager helpers */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 | 
					bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,6 +268,40 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
 | 
				
			||||||
	spin_lock_bh(&msk->pm.lock);
 | 
						spin_lock_bh(&msk->pm.lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mptcp_subflow_context *subflow, *tmp;
 | 
				
			||||||
 | 
						struct sock *sk = (struct sock *)msk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_debug("address rm_id %d", msk->pm.rm_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!msk->pm.rm_id)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (list_empty(&msk->conn_list))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) {
 | 
				
			||||||
 | 
							struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
 | 
				
			||||||
 | 
							int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
 | 
				
			||||||
 | 
							long timeout = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (msk->pm.rm_id != subflow->remote_id)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							spin_unlock_bh(&msk->pm.lock);
 | 
				
			||||||
 | 
							mptcp_subflow_shutdown(sk, ssk, how);
 | 
				
			||||||
 | 
							__mptcp_close_ssk(sk, ssk, subflow, timeout);
 | 
				
			||||||
 | 
							spin_lock_bh(&msk->pm.lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							msk->pm.add_addr_accepted--;
 | 
				
			||||||
 | 
							msk->pm.subflows--;
 | 
				
			||||||
 | 
							WRITE_ONCE(msk->pm.accept_addr, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool address_use_port(struct mptcp_pm_addr_entry *entry)
 | 
					static bool address_use_port(struct mptcp_pm_addr_entry *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (entry->addr.flags &
 | 
						return (entry->addr.flags &
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1652,9 +1652,9 @@ static struct sock *mptcp_subflow_get_retrans(const struct mptcp_sock *msk)
 | 
				
			||||||
 * so we need to use tcp_close() after detaching them from the mptcp
 | 
					 * so we need to use tcp_close() after detaching them from the mptcp
 | 
				
			||||||
 * parent socket.
 | 
					 * parent socket.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 | 
					void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 | 
				
			||||||
			      struct mptcp_subflow_context *subflow,
 | 
							       struct mptcp_subflow_context *subflow,
 | 
				
			||||||
			      long timeout)
 | 
							       long timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct socket *sock = READ_ONCE(ssk->sk_socket);
 | 
						struct socket *sock = READ_ONCE(ssk->sk_socket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1685,6 +1685,10 @@ static void pm_work(struct mptcp_sock *msk)
 | 
				
			||||||
		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
 | 
							pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
 | 
				
			||||||
		mptcp_pm_nl_add_addr_received(msk);
 | 
							mptcp_pm_nl_add_addr_received(msk);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) {
 | 
				
			||||||
 | 
							pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED);
 | 
				
			||||||
 | 
							mptcp_pm_nl_rm_addr_received(msk);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
 | 
						if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
 | 
				
			||||||
		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
 | 
							pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
 | 
				
			||||||
		mptcp_pm_nl_fully_established(msk);
 | 
							mptcp_pm_nl_fully_established(msk);
 | 
				
			||||||
| 
						 | 
					@ -1846,7 +1850,7 @@ static void mptcp_cancel_work(struct sock *sk)
 | 
				
			||||||
		sock_put(sk);
 | 
							sock_put(sk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
 | 
					void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lock_sock(ssk);
 | 
						lock_sock(ssk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,6 +152,7 @@ struct mptcp_addr_info {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum mptcp_pm_status {
 | 
					enum mptcp_pm_status {
 | 
				
			||||||
	MPTCP_PM_ADD_ADDR_RECEIVED,
 | 
						MPTCP_PM_ADD_ADDR_RECEIVED,
 | 
				
			||||||
 | 
						MPTCP_PM_RM_ADDR_RECEIVED,
 | 
				
			||||||
	MPTCP_PM_ESTABLISHED,
 | 
						MPTCP_PM_ESTABLISHED,
 | 
				
			||||||
	MPTCP_PM_SUBFLOW_ESTABLISHED,
 | 
						MPTCP_PM_SUBFLOW_ESTABLISHED,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -362,6 +363,10 @@ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
 | 
				
			||||||
				     struct mptcp_options_received *mp_opt);
 | 
									     struct mptcp_options_received *mp_opt);
 | 
				
			||||||
bool mptcp_subflow_data_available(struct sock *sk);
 | 
					bool mptcp_subflow_data_available(struct sock *sk);
 | 
				
			||||||
void __init mptcp_subflow_init(void);
 | 
					void __init mptcp_subflow_init(void);
 | 
				
			||||||
 | 
					void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how);
 | 
				
			||||||
 | 
					void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
 | 
				
			||||||
 | 
							       struct mptcp_subflow_context *subflow,
 | 
				
			||||||
 | 
							       long timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* called with sk socket lock held */
 | 
					/* called with sk socket lock held */
 | 
				
			||||||
int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
 | 
					int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
 | 
				
			||||||
| 
						 | 
					@ -434,6 +439,7 @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk,
 | 
				
			||||||
void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id);
 | 
					void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id);
 | 
				
			||||||
void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
 | 
					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_rm_addr_received(struct mptcp_sock *msk, u8 rm_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 | 
					int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 | 
				
			||||||
			   const struct mptcp_addr_info *addr);
 | 
								   const struct mptcp_addr_info *addr);
 | 
				
			||||||
| 
						 | 
					@ -468,6 +474,7 @@ void mptcp_pm_nl_data_init(struct mptcp_sock *msk);
 | 
				
			||||||
void mptcp_pm_nl_fully_established(struct mptcp_sock *msk);
 | 
					void mptcp_pm_nl_fully_established(struct mptcp_sock *msk);
 | 
				
			||||||
void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk);
 | 
					void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk);
 | 
				
			||||||
void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk);
 | 
					void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk);
 | 
				
			||||||
 | 
					void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk);
 | 
				
			||||||
int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 | 
					int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
 | 
					static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue