All of lore.kernel.org
 help / color / mirror / Atom feed
* [MPTCP] Re: [PATCH] mptcp: mptcp reset option
@ 2021-02-24  0:41 Mat Martineau
  0 siblings, 0 replies; 2+ messages in thread
From: Mat Martineau @ 2021-02-24  0:41 UTC (permalink / raw)
  To: mptcp 

[-- Attachment #1: Type: text/plain, Size: 7222 bytes --]

On Mon, 22 Feb 2021, Florian Westphal wrote:

> The MPTCP reset option allows to carry a mptcp-specific error code that
> provides more information on the nature of a connection reset.
>
> Reset option data received gets stored in the subflow context so it can
> be sent to userspace via the 'subflow closed' netlink event.
>
> When a subflow is closed, the desired error code that should be sent to
> the peer is also placed in the subflow context structure.
>
> If a reset is sent before subflow establishment could complete, e.g. on
> HMAC failure during an MP_JOIN operation, the mptcp skb extension is
> used to store the reset information.
>
> Signed-off-by: Florian Westphal <fw(a)strlen.de>
> ---
> include/net/mptcp.h        | 18 +++++++++--
> include/uapi/linux/mptcp.h |  2 ++
> net/ipv4/tcp_ipv4.c        | 21 ++++++++++--
> net/ipv6/tcp_ipv6.c        | 14 +++++++-
> net/mptcp/options.c        | 66 +++++++++++++++++++++++++++++++++++---
> net/mptcp/pm_netlink.c     | 12 +++++++
> net/mptcp/protocol.c       | 12 +++++--
> net/mptcp/protocol.h       | 22 ++++++++++++-
> net/mptcp/subflow.c        | 37 ++++++++++++++++++---
> 9 files changed, 185 insertions(+), 19 deletions(-)
>

> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 59ea64e5e914..e95bd8fa5e62 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -1648,9 +1648,21 @@ static int mptcp_event_sub_closed(struct sk_buff *skb,
> 				  const struct mptcp_sock *msk,
> 				  const struct sock *ssk)
> {
> +	const struct mptcp_subflow_context *sf;
> +
> 	if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
> 		return -EMSGSIZE;
>
> +	sf = mptcp_subflow_ctx(ssk);
> +	if (sf->reset_reason == 0)
> +		return 0;

From what I see in the RFC, the T flag can be set even if the reason code 
is 'unspecified', so I don't think MPTCP_ATTR_RESET_FLAGS should be 
skipped if reset_reason == 0.

I would suggest removing the above two lines and always including the 
reason & flags, but if it's worthwhile to optimize out either attribute 
then please explain.

> +
> +	if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
> +		return -EMSGSIZE;
> +
> +	if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
> +		return -EMSGSIZE;
> +
> 	return 0;
> }
>

> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index 593085610971..64ac8db5b673 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -26,6 +26,7 @@
> #define OPTION_MPTCP_RM_ADDR	BIT(8)
> #define OPTION_MPTCP_FASTCLOSE	BIT(9)
> #define OPTION_MPTCP_PRIO	BIT(10)
> +#define OPTION_MPTCP_RST	BIT(11)
>
> /* MPTCP option subtypes */
> #define MPTCPOPT_MP_CAPABLE	0
> @@ -36,6 +37,7 @@
> #define MPTCPOPT_MP_PRIO	5
> #define MPTCPOPT_MP_FAIL	6
> #define MPTCPOPT_MP_FASTCLOSE	7
> +#define MPTCPOPT_RST		8
>
> /* MPTCP suboption lengths */
> #define TCPOLEN_MPTCP_MPC_SYN		4
> @@ -64,6 +66,7 @@
> #define TCPOLEN_MPTCP_PRIO		3
> #define TCPOLEN_MPTCP_PRIO_ALIGN	4
> #define TCPOLEN_MPTCP_FASTCLOSE		12
> +#define TCPOLEN_MPTCP_RST		4
>
> /* MPTCP MP_JOIN flags */
> #define MPTCPOPT_BACKUP		BIT(0)
> @@ -93,6 +96,18 @@
> /* MPTCP MP_PRIO flags */
> #define MPTCP_PRIO_BKUP		BIT(0)
>
> +/* MPTCP TCPRST flags */
> +#define MPTCP_RST_TRANSIENT	BIT(0)
> +
> +/* MPTCP Reset reason codes, rfc8684 */
> +#define MPTCP_RST_EUNSPEC	0
> +#define MPTCP_RST_EMPTCP	1
> +#define MPTCP_RST_ERESOURCE	2
> +#define MPTCP_RST_EPROHIBIT	3
> +#define MPTCP_RST_EWQ2BIG	4
> +#define MPTCP_RST_EBADPERF	5
> +#define MPTCP_RST_EMIDDLEBOX	6
> +

The MSP_RST_* defines could be useful in include/uapi/linux/mptcp.h


> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index e411be079c44..a59dd71deb3e 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -187,8 +187,16 @@ static int subflow_check_req(struct request_sock *req,
> 		subflow_req->msk = subflow_token_join_request(req);
>
> 		/* Can't fall back to TCP in this case. */
> -		if (!subflow_req->msk)
> +		if (!subflow_req->msk) {


> +			struct mptcp_ext *mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
> +
> +			if (mpext) {
> +				memset(mpext, 0, sizeof(*mpext));
> +				mpext->reset_reason = MPTCP_RST_EMPTCP;
> +			}

This chunk of code (with slight variation in the first line) is used in 3 
places, worth adding a helper function in subflow.c?


Thanks,

Mat


> +
> 			return -EPERM;
> +		}
>
> 		if (subflow_use_different_sport(subflow_req->msk, sk_listener)) {
> 			pr_debug("syn inet_sport=%d %d",
> @@ -396,8 +404,10 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
> 	} else if (subflow->request_join) {
> 		u8 hmac[SHA256_DIGEST_SIZE];
>
> -		if (!mp_opt.mp_join)
> +		if (!mp_opt.mp_join) {
> +			subflow->reset_reason = MPTCP_RST_EMPTCP;
> 			goto do_reset;
> +		}
>
> 		subflow->thmac = mp_opt.thmac;
> 		subflow->remote_nonce = mp_opt.nonce;
> @@ -406,6 +416,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
>
> 		if (!subflow_thmac_valid(subflow)) {
> 			MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKMAC);
> +			subflow->reset_reason = MPTCP_RST_EMPTCP;
> 			goto do_reset;
> 		}
>
> @@ -434,6 +445,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
> 	return;
>
> do_reset:
> +	subflow->reset_transient = 0;
> 	mptcp_subflow_reset(sk);
> }
>
> @@ -586,6 +598,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> 	struct mptcp_options_received mp_opt;
> 	bool fallback, fallback_is_fatal;
> 	struct sock *new_msk = NULL;
> +	struct mptcp_ext *mpext;
> 	struct sock *child;
>
> 	pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
> @@ -645,8 +658,15 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> 		 * to reset the context to non MPTCP status.
> 		 */
> 		if (!ctx || fallback) {
> -			if (fallback_is_fatal)
> +			if (fallback_is_fatal) {
> +				mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
> +				if (mpext) {
> +					memset(mpext, 0, sizeof(*mpext));
> +					mpext->reset_reason = MPTCP_RST_EMPTCP;
> +				}
> +
> 				goto dispose_child;
> +			}
>
> 			subflow_drop_ctx(child);
> 			goto out;
> @@ -681,8 +701,15 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> 			struct mptcp_sock *owner;
>
> 			owner = subflow_req->msk;
> -			if (!owner)
> +			if (!owner) {
> +				mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
> +				if (mpext) {
> +					memset(mpext, 0, sizeof(*mpext));
> +					mpext->reset_reason = MPTCP_RST_EPROHIBIT;
> +				}
> +
> 				goto dispose_child;
> +			}
>
> 			/* move the msk reference ownership to the subflow */
> 			subflow_req->msk = NULL;
> @@ -1046,6 +1073,8 @@ static bool subflow_check_data_avail(struct sock *ssk)
> 	smp_wmb();
> 	ssk->sk_error_report(ssk);
> 	tcp_set_state(ssk, TCP_CLOSE);
> +	subflow->reset_transient = 0;
> +	subflow->reset_reason = MPTCP_RST_EMPTCP;
> 	tcp_send_active_reset(ssk, GFP_ATOMIC);
> 	subflow->data_avail = 0;
> 	return false;
> -- 
> 2.26.2

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [MPTCP] Re: [PATCH] mptcp: mptcp reset option
@ 2021-02-24 10:13 Florian Westphal
  0 siblings, 0 replies; 2+ messages in thread
From: Florian Westphal @ 2021-02-24 10:13 UTC (permalink / raw)
  To: mptcp 

[-- Attachment #1: Type: text/plain, Size: 2276 bytes --]

Mat Martineau <mathew.j.martineau(a)linux.intel.com> wrote:
> On Mon, 22 Feb 2021, Florian Westphal wrote:
> > diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> > index 59ea64e5e914..e95bd8fa5e62 100644
> > --- a/net/mptcp/pm_netlink.c
> > +++ b/net/mptcp/pm_netlink.c
> > @@ -1648,9 +1648,21 @@ static int mptcp_event_sub_closed(struct sk_buff *skb,
> > 				  const struct mptcp_sock *msk,
> > 				  const struct sock *ssk)
> > {
> > +	const struct mptcp_subflow_context *sf;
> > +
> > 	if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
> > 		return -EMSGSIZE;
> > 
> > +	sf = mptcp_subflow_ctx(ssk);
> > +	if (sf->reset_reason == 0)
> > +		return 0;
> 
> From what I see in the RFC, the T flag can be set even if the reason code is
> 'unspecified', so I don't think MPTCP_ATTR_RESET_FLAGS should be skipped if
> reset_reason == 0.

OK.

> I would suggest removing the above two lines and always including the reason
> & flags, but if it's worthwhile to optimize out either attribute then please
> explain.

Hmpf, yes, this isn't sufficient to do what I wanted.
The intention was to ONLY set any of these attributes in the nlmsg if
the subflow had been zapped via tcprst option.

as reset_reason can be 0 in the wire format (and hacks like 'lets store
v+1' are error prone), i will add another bit to signal the field is
valid instead.

> > +/* MPTCP Reset reason codes, rfc8684 */
> > +#define MPTCP_RST_EUNSPEC	0
> > +#define MPTCP_RST_EMPTCP	1
> > +#define MPTCP_RST_ERESOURCE	2
> > +#define MPTCP_RST_EPROHIBIT	3
> > +#define MPTCP_RST_EWQ2BIG	4
> > +#define MPTCP_RST_EBADPERF	5
> > +#define MPTCP_RST_EMIDDLEBOX	6
> > +
> 
> The MSP_RST_* defines could be useful in include/uapi/linux/mptcp.h

Okay, no problem. I was reluctant to place them there but
given those values are from the rfc i think it makes sense to have this
in a uapi header.

> > +			struct mptcp_ext *mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
> > +
> > +			if (mpext) {
> > +				memset(mpext, 0, sizeof(*mpext));
> > +				mpext->reset_reason = MPTCP_RST_EMPTCP;
> > +			}
> 
> This chunk of code (with slight variation in the first line) is used in 3
> places, worth adding a helper function in subflow.c?

Sure, will add one.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-02-24 10:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-24 10:13 [MPTCP] Re: [PATCH] mptcp: mptcp reset option Florian Westphal
  -- strict thread matches above, loose matches on Subject: below --
2021-02-24  0:41 Mat Martineau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.