diff options
| author | Mark Brown <broonie@kernel.org> | 2020-05-20 16:09:02 +0100 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2020-05-20 16:09:02 +0100 | 
| commit | a24490e0170e4cc6d4fd1f37691f19a106b694ae (patch) | |
| tree | 20964ef269612a2ea33240274bc3422c74a02b15 /net/mptcp/subflow.c | |
| parent | 9bcbabafa19b9f27a283777eff32e7d66fcef09c (diff) | |
| parent | 7e73861eb40d591a98628592c6f0182fbf2f6c4d (diff) | |
Merge series "MAINTAINER entries for few ROHM power devices" from Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>:
Add maintainer entries to a few ROHM devices and Linear Ranges
Linear Ranges helpers were refactored out of regulator core to lib so
that other drivers could utilize them too. (I guess power/supply drivers
and possibly clk drivers can benefit from them). As regulators is
currently the main user it makes sense the changes to linear_ranges go
through Mark's tree.
During past two years few ROHM PMIC drivers have been added to
mainstream. They deserve a supporter from ROHM side too :)
Patch 1:
	Maintainer entries for few ROHM IC drivers
Patch 2:
	Maintainer entry for linear ranges helpers
---
Matti Vaittinen (2):
  MAINTAINERS: Add entry for ROHM power management ICs
  MAINTAINERS: Add maintainer entry for linear ranges helper
 MAINTAINERS | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
base-commit: b9bbe6ed63b2b9f2c9ee5cbd0f2c946a2723f4ce
--
2.21.0
--
Matti Vaittinen, Linux device drivers
ROHM Semiconductors, Finland SWDC
Kiviharjunlenkki 1E
90220 OULU
FINLAND
~~~ "I don't think so," said Rene Descartes. Just then he vanished ~~~
Simon says - in Latin please.
~~~ "non cogito me" dixit Rene Descarte, deinde evanescavit ~~~
Thanks to Simon Glass for the translation =]
Diffstat (limited to 'net/mptcp/subflow.c')
| -rw-r--r-- | net/mptcp/subflow.c | 96 | 
1 files changed, 65 insertions, 31 deletions
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index fabd06f2ff45..4931a29a6f08 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -124,12 +124,11 @@ static void subflow_init_req(struct request_sock *req,  {  	struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener);  	struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); -	struct tcp_options_received rx_opt; +	struct mptcp_options_received mp_opt;  	pr_debug("subflow_req=%p, listener=%p", subflow_req, listener); -	memset(&rx_opt.mptcp, 0, sizeof(rx_opt.mptcp)); -	mptcp_get_options(skb, &rx_opt); +	mptcp_get_options(skb, &mp_opt);  	subflow_req->mp_capable = 0;  	subflow_req->mp_join = 0; @@ -142,16 +141,16 @@ static void subflow_init_req(struct request_sock *req,  		return;  #endif -	if (rx_opt.mptcp.mp_capable) { +	if (mp_opt.mp_capable) {  		SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE); -		if (rx_opt.mptcp.mp_join) +		if (mp_opt.mp_join)  			return; -	} else if (rx_opt.mptcp.mp_join) { +	} else if (mp_opt.mp_join) {  		SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX);  	} -	if (rx_opt.mptcp.mp_capable && listener->request_mptcp) { +	if (mp_opt.mp_capable && listener->request_mptcp) {  		int err;  		err = mptcp_token_new_request(req); @@ -159,13 +158,13 @@ static void subflow_init_req(struct request_sock *req,  			subflow_req->mp_capable = 1;  		subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq; -	} else if (rx_opt.mptcp.mp_join && listener->request_mptcp) { +	} else if (mp_opt.mp_join && listener->request_mptcp) {  		subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq;  		subflow_req->mp_join = 1; -		subflow_req->backup = rx_opt.mptcp.backup; -		subflow_req->remote_id = rx_opt.mptcp.join_id; -		subflow_req->token = rx_opt.mptcp.token; -		subflow_req->remote_nonce = rx_opt.mptcp.nonce; +		subflow_req->backup = mp_opt.backup; +		subflow_req->remote_id = mp_opt.join_id; +		subflow_req->token = mp_opt.token; +		subflow_req->remote_nonce = mp_opt.nonce;  		pr_debug("token=%u, remote_nonce=%u", subflow_req->token,  			 subflow_req->remote_nonce);  		if (!subflow_token_join_request(req, skb)) { @@ -221,23 +220,47 @@ static bool subflow_thmac_valid(struct mptcp_subflow_context *subflow)  static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)  {  	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); +	struct mptcp_options_received mp_opt;  	struct sock *parent = subflow->conn; +	struct tcp_sock *tp = tcp_sk(sk);  	subflow->icsk_af_ops->sk_rx_dst_set(sk, skb); -	if (inet_sk_state_load(parent) != TCP_ESTABLISHED) { +	if (inet_sk_state_load(parent) == TCP_SYN_SENT) {  		inet_sk_state_store(parent, TCP_ESTABLISHED);  		parent->sk_state_change(parent);  	} -	if (subflow->conn_finished || !tcp_sk(sk)->is_mptcp) +	/* be sure no special action on any packet other than syn-ack */ +	if (subflow->conn_finished) +		return; + +	subflow->conn_finished = 1; + +	mptcp_get_options(skb, &mp_opt); +	if (subflow->request_mptcp && mp_opt.mp_capable) { +		subflow->mp_capable = 1; +		subflow->can_ack = 1; +		subflow->remote_key = mp_opt.sndr_key; +		pr_debug("subflow=%p, remote_key=%llu", subflow, +			 subflow->remote_key); +	} else if (subflow->request_join && mp_opt.mp_join) { +		subflow->mp_join = 1; +		subflow->thmac = mp_opt.thmac; +		subflow->remote_nonce = mp_opt.nonce; +		pr_debug("subflow=%p, thmac=%llu, remote_nonce=%u", subflow, +			 subflow->thmac, subflow->remote_nonce); +	} else if (subflow->request_mptcp) { +		tp->is_mptcp = 0; +	} + +	if (!tp->is_mptcp)  		return;  	if (subflow->mp_capable) {  		pr_debug("subflow=%p, remote_key=%llu", mptcp_subflow_ctx(sk),  			 subflow->remote_key);  		mptcp_finish_connect(sk); -		subflow->conn_finished = 1;  		if (skb) {  			pr_debug("synack seq=%u", TCP_SKB_CB(skb)->seq); @@ -264,7 +287,6 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)  		if (!mptcp_finish_join(sk))  			goto do_reset; -		subflow->conn_finished = 1;  		MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX);  	} else {  do_reset: @@ -322,7 +344,7 @@ drop:  /* validate hmac received in third ACK */  static bool subflow_hmac_valid(const struct request_sock *req, -			       const struct tcp_options_received *rx_opt) +			       const struct mptcp_options_received *mp_opt)  {  	const struct mptcp_subflow_request_sock *subflow_req;  	u8 hmac[MPTCPOPT_HMAC_LEN]; @@ -339,7 +361,7 @@ static bool subflow_hmac_valid(const struct request_sock *req,  			      subflow_req->local_nonce, hmac);  	ret = true; -	if (crypto_memneq(hmac, rx_opt->mptcp.hmac, sizeof(hmac))) +	if (crypto_memneq(hmac, mp_opt->hmac, sizeof(hmac)))  		ret = false;  	sock_put((struct sock *)msk); @@ -395,7 +417,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,  {  	struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);  	struct mptcp_subflow_request_sock *subflow_req; -	struct tcp_options_received opt_rx; +	struct mptcp_options_received mp_opt;  	bool fallback_is_fatal = false;  	struct sock *new_msk = NULL;  	bool fallback = false; @@ -403,7 +425,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,  	pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn); -	opt_rx.mptcp.mp_capable = 0; +	/* we need later a valid 'mp_capable' value even when options are not +	 * parsed +	 */ +	mp_opt.mp_capable = 0;  	if (tcp_rsk(req)->is_mptcp == 0)  		goto create_child; @@ -418,22 +443,21 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,  			goto create_msk;  		} -		mptcp_get_options(skb, &opt_rx); -		if (!opt_rx.mptcp.mp_capable) { +		mptcp_get_options(skb, &mp_opt); +		if (!mp_opt.mp_capable) {  			fallback = true;  			goto create_child;  		}  create_msk: -		new_msk = mptcp_sk_clone(listener->conn, &opt_rx, req); +		new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req);  		if (!new_msk)  			fallback = true;  	} else if (subflow_req->mp_join) {  		fallback_is_fatal = true; -		opt_rx.mptcp.mp_join = 0; -		mptcp_get_options(skb, &opt_rx); -		if (!opt_rx.mptcp.mp_join || -		    !subflow_hmac_valid(req, &opt_rx)) { +		mptcp_get_options(skb, &mp_opt); +		if (!mp_opt.mp_join || +		    !subflow_hmac_valid(req, &mp_opt)) {  			SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);  			return NULL;  		} @@ -473,9 +497,9 @@ create_child:  			/* with OoO packets we can reach here without ingress  			 * mpc option  			 */ -			ctx->remote_key = opt_rx.mptcp.sndr_key; -			ctx->fully_established = opt_rx.mptcp.mp_capable; -			ctx->can_ack = opt_rx.mptcp.mp_capable; +			ctx->remote_key = mp_opt.sndr_key; +			ctx->fully_established = mp_opt.mp_capable; +			ctx->can_ack = mp_opt.mp_capable;  		} else if (ctx->mp_join) {  			struct mptcp_sock *owner; @@ -499,7 +523,7 @@ out:  	/* check for expected invariant - should never trigger, just help  	 * catching eariler subtle bugs  	 */ -	WARN_ON_ONCE(*own_req && child && tcp_sk(child)->is_mptcp && +	WARN_ON_ONCE(child && *own_req && tcp_sk(child)->is_mptcp &&  		     (!mptcp_subflow_ctx(child) ||  		      !mptcp_subflow_ctx(child)->conn));  	return child; @@ -988,6 +1012,16 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)  	if (err)  		return err; +	/* the newly created socket really belongs to the owning MPTCP master +	 * socket, even if for additional subflows the allocation is performed +	 * by a kernel workqueue. Adjust inode references, so that the +	 * procfs/diag interaces really show this one belonging to the correct +	 * user. +	 */ +	SOCK_INODE(sf)->i_ino = SOCK_INODE(sk->sk_socket)->i_ino; +	SOCK_INODE(sf)->i_uid = SOCK_INODE(sk->sk_socket)->i_uid; +	SOCK_INODE(sf)->i_gid = SOCK_INODE(sk->sk_socket)->i_gid; +  	subflow = mptcp_subflow_ctx(sf->sk);  	pr_debug("subflow=%p", subflow);  | 
