From: Mat Martineau <mathew.j.martineau@linux.intel.com>
To: Paolo Abeni <pabeni@redhat.com>
Cc: mptcp@lists.linux.dev
Subject: Re: [PATCH v3 mptcp-next 3/3] mptcp: strict local address ID selection.
Date: Fri, 11 Feb 2022 15:04:47 -0800 (PST) [thread overview]
Message-ID: <b46e2ccf-8fbb-a835-2daf-6bdff87ca90@linux.intel.com> (raw)
In-Reply-To: <246389435f6d9660fee8f8c01a6544e4089f8708.1644518737.git.pabeni@redhat.com>
On Thu, 10 Feb 2022, Paolo Abeni wrote:
> The address ID selection for MPJ subflows created in response
> to incoming ADD_ADDR option is currently unreliable: it happens
> at MPJ socket creation time, when the local address could be
> unknown.
>
> Additionally, if the no local endpoint is available for the local
> address, a new dummy endpoint is created, confusing the user-land.
>
> This change refactor the code to move the address ID seleciton inside
> the rebuild_header() helper, when the local address eventually
> selected by the route lookup is finally known. If the address used
> is not mapped by any endpoint - and thus can't be advertised/removed
> pick the id 0 instead of allocate a new endpoint.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> v2 -> v3:
> - keep creating dummy endpoint
>
> v1 -> v2:
> - hopefully fix build issue with ipv6 disabled
> - avoid looking-up multiple times the local_id for req sockets
> - factor-out an helper for local_id initialization
>
> RFC -> v1:
> - don't bail if ID lookup fails, use 0 instead
> ---
> net/mptcp/pm_netlink.c | 15 +---------
> net/mptcp/protocol.c | 3 ++
> net/mptcp/protocol.h | 3 +-
> net/mptcp/subflow.c | 67 ++++++++++++++++++++++++++++++++++++------
> 4 files changed, 64 insertions(+), 24 deletions(-)
>
> diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
> index 928ebe4949e9..ca0fb2ab1204 100644
> --- a/net/mptcp/pm_netlink.c
> +++ b/net/mptcp/pm_netlink.c
> @@ -83,16 +83,6 @@ static bool addresses_equal(const struct mptcp_addr_info *a,
> return a->port == b->port;
> }
>
> -static bool address_zero(const struct mptcp_addr_info *addr)
> -{
> - struct mptcp_addr_info zero;
> -
> - memset(&zero, 0, sizeof(zero));
> - zero.family = addr->family;
> -
> - return addresses_equal(addr, &zero, true);
> -}
> -
> static void local_address(const struct sock_common *skc,
> struct mptcp_addr_info *addr)
> {
> @@ -998,7 +988,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
> struct mptcp_addr_info skc_local;
> struct mptcp_addr_info msk_local;
> struct pm_nl_pernet *pernet;
> - int ret = -1;
> + int ret = 0;
With this line changed, ret is never negative after the rcu_read_unlock()
in this function, so the dummy record creation code at the end is all dead
code. I'm guessing this needs to stay "ret = -1" for the dummy allocation
to work as expected.
-Mat
>
> if (WARN_ON_ONCE(!msk))
> return -1;
> @@ -1011,9 +1001,6 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
> if (addresses_equal(&msk_local, &skc_local, false))
> return 0;
>
> - if (address_zero(&skc_local))
> - return 0;
> -
> pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
>
> rcu_read_lock();
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 3324e1c61576..57caf470e500 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -117,6 +117,9 @@ static int __mptcp_socket_create(struct mptcp_sock *msk)
> list_add(&subflow->node, &msk->conn_list);
> sock_hold(ssock->sk);
> subflow->request_mptcp = 1;
> +
> + /* This is the first subflow, always with id 0 */
> + subflow->local_id_valid = 1;
> mptcp_sock_graft(msk->first, sk->sk_socket);
>
> return 0;
> diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
> index a1ce1fd005ab..663b8d83154e 100644
> --- a/net/mptcp/protocol.h
> +++ b/net/mptcp/protocol.h
> @@ -453,7 +453,8 @@ struct mptcp_subflow_context {
> rx_eof : 1,
> can_ack : 1, /* only after processing the remote a key */
> disposable : 1, /* ctx can be free at ulp release time */
> - stale : 1; /* unable to snd/rcv data, do not use for xmit */
> + stale : 1, /* unable to snd/rcv data, do not use for xmit */
> + local_id_valid : 1; /* local_id is correctly initialized */
> enum mptcp_data_avail data_avail;
> u32 remote_nonce;
> u64 thmac;
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index b53b392dd280..283e5d57e003 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -481,6 +481,51 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
> mptcp_subflow_reset(sk);
> }
>
> +static void subflow_set_local_id(struct mptcp_subflow_context *subflow, int local_id)
> +{
> + subflow->local_id = local_id;
> + subflow->local_id_valid = 1;
> +}
> +
> +static int subflow_chk_local_id(struct sock *sk)
> +{
> + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
> + struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> + int err;
> +
> + if (likely(subflow->local_id_valid))
> + return 0;
> +
> + err = mptcp_pm_get_local_id(msk, (struct sock_common *)sk);
> + if (err < 0)
> + return err;
> +
> + subflow_set_local_id(subflow, err);
> + return 0;
> +}
> +
> +static int subflow_rebuild_header(struct sock *sk)
> +{
> + int err = subflow_chk_local_id(sk);
> +
> + if (unlikely(err < 0))
> + return err;
> +
> + return inet_sk_rebuild_header(sk);
> +}
> +
> +#if IS_ENABLED(CONFIG_MPTCP_IPV6)
> +static int subflow_v6_rebuild_header(struct sock *sk)
> +{
> + int err = subflow_chk_local_id(sk);
> +
> + if (unlikely(err < 0))
> + return err;
> +
> + return inet6_sk_rebuild_header(sk);
> +}
> +#endif
> +
> struct request_sock_ops mptcp_subflow_request_sock_ops;
> static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
>
> @@ -1403,13 +1448,8 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
> get_random_bytes(&subflow->local_nonce, sizeof(u32));
> } while (!subflow->local_nonce);
>
> - if (!local_id) {
> - err = mptcp_pm_get_local_id(msk, (struct sock_common *)ssk);
> - if (err < 0)
> - goto failed;
> -
> - local_id = err;
> - }
> + if (local_id)
> + subflow_set_local_id(subflow, local_id);
>
> mptcp_pm_get_flags_and_ifindex_by_id(sock_net(sk), local_id,
> &flags, &ifindex);
> @@ -1434,7 +1474,6 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
> pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk,
> remote_token, local_id, remote_id);
> subflow->remote_token = remote_token;
> - subflow->local_id = local_id;
> subflow->remote_id = remote_id;
> subflow->request_join = 1;
> subflow->request_bkup = !!(flags & MPTCP_PM_ADDR_FLAG_BACKUP);
> @@ -1734,15 +1773,22 @@ static void subflow_ulp_clone(const struct request_sock *req,
> new_ctx->token = subflow_req->token;
> new_ctx->ssn_offset = subflow_req->ssn_offset;
> new_ctx->idsn = subflow_req->idsn;
> +
> + /* this is the first subflow, id is always 0 */
> + new_ctx->local_id_valid = 1;
> } else if (subflow_req->mp_join) {
> new_ctx->ssn_offset = subflow_req->ssn_offset;
> new_ctx->mp_join = 1;
> new_ctx->fully_established = 1;
> new_ctx->backup = subflow_req->backup;
> - new_ctx->local_id = subflow_req->local_id;
> new_ctx->remote_id = subflow_req->remote_id;
> new_ctx->token = subflow_req->token;
> new_ctx->thmac = subflow_req->thmac;
> +
> + /* the subflow req id is valid, fetched via subflow_check_req()
> + * and subflow_token_join_request()
> + */
> + subflow_set_local_id(new_ctx, subflow_req->local_id);
> }
> }
>
> @@ -1795,6 +1841,7 @@ void __init mptcp_subflow_init(void)
> subflow_specific.conn_request = subflow_v4_conn_request;
> subflow_specific.syn_recv_sock = subflow_syn_recv_sock;
> subflow_specific.sk_rx_dst_set = subflow_finish_connect;
> + subflow_specific.rebuild_header = subflow_rebuild_header;
>
> tcp_prot_override = tcp_prot;
> tcp_prot_override.release_cb = tcp_release_cb_override;
> @@ -1807,6 +1854,7 @@ void __init mptcp_subflow_init(void)
> subflow_v6_specific.conn_request = subflow_v6_conn_request;
> subflow_v6_specific.syn_recv_sock = subflow_syn_recv_sock;
> subflow_v6_specific.sk_rx_dst_set = subflow_finish_connect;
> + subflow_v6_specific.rebuild_header = subflow_v6_rebuild_header;
>
> subflow_v6m_specific = subflow_v6_specific;
> subflow_v6m_specific.queue_xmit = ipv4_specific.queue_xmit;
> @@ -1814,6 +1862,7 @@ void __init mptcp_subflow_init(void)
> subflow_v6m_specific.net_header_len = ipv4_specific.net_header_len;
> subflow_v6m_specific.mtu_reduced = ipv4_specific.mtu_reduced;
> subflow_v6m_specific.net_frag_header_len = 0;
> + subflow_v6m_specific.rebuild_header = subflow_rebuild_header;
>
> tcpv6_prot_override = tcpv6_prot;
> tcpv6_prot_override.release_cb = tcp_release_cb_override;
> --
> 2.34.1
>
>
>
--
Mat Martineau
Intel
next prev parent reply other threads:[~2022-02-11 23:04 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-10 18:49 [PATCH v3 mptcp-next 0/3] mptcp: more self-tests improvements Paolo Abeni
2022-02-10 18:49 ` [PATCH v3 mptcp-next 1/3] Squash-to: "mptcp: constify a bunch of of helpers" Paolo Abeni
2022-02-11 23:11 ` Mat Martineau
2022-02-10 18:49 ` [PATCH v3 mptcp-next 2/3] mptcp: more careful RM_ADDR generation Paolo Abeni
2022-02-11 23:10 ` Mat Martineau
2022-02-13 9:06 ` Paolo Abeni
2022-02-10 18:49 ` [PATCH v3 mptcp-next 3/3] mptcp: strict local address ID selection Paolo Abeni
2022-02-11 23:04 ` Mat Martineau [this message]
2022-02-11 10:33 ` [PATCH v3 mptcp-next 0/3] mptcp: more self-tests improvements Matthieu Baerts
2022-02-11 11:44 ` Paolo Abeni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b46e2ccf-8fbb-a835-2daf-6bdff87ca90@linux.intel.com \
--to=mathew.j.martineau@linux.intel.com \
--cc=mptcp@lists.linux.dev \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox