From patchwork Thu Jul 30 11:06:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geliang Tang X-Patchwork-Id: 1338761 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.01.org (client-ip=198.145.21.10; helo=ml01.01.org; envelope-from=mptcp-bounces@lists.01.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=vAOPyETU; dkim-atps=neutral Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BHSVv3njZz9sR4 for ; Thu, 30 Jul 2020 21:15:02 +1000 (AEST) Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 0E7C912745C61; Thu, 30 Jul 2020 04:15:00 -0700 (PDT) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::641; helo=mail-pl1-x641.google.com; envelope-from=geliangtang@gmail.com; receiver= Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2C48D12732411 for ; Thu, 30 Jul 2020 04:14:56 -0700 (PDT) Received: by mail-pl1-x641.google.com with SMTP id m16so13778498pls.5 for ; Thu, 30 Jul 2020 04:14:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=BvsjW5682sEbWo7rX1ZrypsNkHQOnoSwf1pJMhlim9c=; b=vAOPyETUQz6DuahJiZr0ZbVBUL0h0oYJXmBrbAIlp9/ZlVswkPKpTjEajhQMc+aBOd 7KkvKOYRHoYVp1Gc8NosxrpetcKhN998rjQuPbSbDkWdaZdqPj3BTnQEp1WyTrQYlUQh DMVeT8axI+/QSqK0oNYW66qK0AJ3DFXqEc2KvnEPRNwhdR4I/qsP0zr6SwoQ+lIj1XrV 4hy1D+3RTc6tQwZApiZIF2jQ09f13jiSCFpBJDxDh5kcfTJq6evXkDB7NCPUo7HujUN9 GDAOslRKpk+f1nLEcNIp+TpINgKs/cZMnP4ri6UOjcsxS0Rp2aQCvewsZZucWNbVZuAy fVXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=BvsjW5682sEbWo7rX1ZrypsNkHQOnoSwf1pJMhlim9c=; b=ORFR4syi8gfzxIr7h5cEMvVT1KfPDQqGqPRPLibNHaPufL7mcBCAbimlXkaxYpD9yO m8ZG95kTidbfpbVZ2KAWZoaiQTLmlFkwXyHqsjepwlE2D8SjTaNcKY94XnQ+x+qHRrtP 9ohIRdFvlW0KgnJGD7YK5in919R9fZcjSGqeMZN+ZuMKawHCq6EvAnmKbz+InUpxjKMO 4Y7aOYNecZEMc2RzoEEOw2Qa+DNZ+cWnUjUs6AUBIBGp4lq6hwiWBP1p5YgLdXJp3P/Z 9reM38hcfmt7jG4dpiKU74bQnJx4saK7PltZYWgLlHONhexV8tDIBeYj5Ui18zNPhe0w 2guw== X-Gm-Message-State: AOAM533/vrRmZQkyA6xFt3fneeEOgB752YVlOItiTanalL1vdjcIPlBq ESISwwH94k1Q0Xl1mlKMyWBriUTFX/I= X-Google-Smtp-Source: ABdhPJxCdFi7ejW6DBQmg8cAYJAX3fD98BkF5yn8ZN4GV0yTyNeLcuC+shrEZrF76oD4fqt9nVN+pQ== X-Received: by 2002:a65:558d:: with SMTP id j13mr10955799pgs.48.1596107695369; Thu, 30 Jul 2020 04:14:55 -0700 (PDT) Received: from localhost ([43.224.245.180]) by smtp.gmail.com with ESMTPSA id l186sm5712108pfl.2.2020.07.30.04.14.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Jul 2020 04:14:55 -0700 (PDT) From: Geliang Tang To: mptcp@lists.01.org Date: Thu, 30 Jul 2020 19:06:01 +0800 Message-Id: X-Mailer: git-send-email 2.17.1 In-Reply-To: References: In-Reply-To: References: <259cb712f796f4b1e9c22e5d65de7ca15755dcd5.1596106606.git.geliangtang@gmail.com> Message-ID-Hash: K5PML5IQ6QKK377HQ4N764VBDFKVMMFV X-Message-ID-Hash: K5PML5IQ6QKK377HQ4N764VBDFKVMMFV X-MailFrom: geliangtang@gmail.com X-Mailman-Rule-Hits: member-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address CC: Geliang Tang X-Mailman-Version: 3.1.1 Precedence: list Subject: [MPTCP] [MPTCP][PATCH v4 mptcp-next 3/5] mptcp: add the incoming RM_ADDR support List-Id: Discussions regarding MPTCP upstreaming Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 Suggested-by: Paolo Abeni Suggested-by: Mat Martineau Signed-off-by: Geliang Tang --- net/mptcp/options.c | 5 +++++ net/mptcp/pm.c | 12 ++++++++++++ net/mptcp/pm_netlink.c | 33 ++++++++++++++++++++++++++++++++- net/mptcp/protocol.c | 12 ++++++++---- net/mptcp/protocol.h | 7 +++++++ net/mptcp/subflow.c | 1 + 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index bbc124876417..a52a05effac9 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -888,6 +888,11 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, 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) return; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 81b07ae213b9..558462d87eb3 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -149,6 +149,18 @@ void mptcp_pm_add_addr_received(struct mptcp_sock *msk, 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 */ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining, diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index c8820c4156e6..74a18e463c3d 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -173,7 +173,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) { struct sock *sk = (struct sock *)msk; struct mptcp_pm_addr_entry *local; - struct mptcp_addr_info remote; + struct mptcp_addr_info remote = { 0 }; struct pm_nl_pernet *pernet; pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id); @@ -261,6 +261,37 @@ void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) 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("rm_id %d", msk->pm.rm_id); + + if (!msk->pm.rm_id) + return; + + if (list_empty(&msk->conn_list)) + return; + + msk->pm.add_addr_accepted--; + msk->pm.subflows--; + WRITE_ONCE(msk->pm.accept_addr, true); + + 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) { + 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); + } + } +} + static bool address_use_port(struct mptcp_pm_addr_entry *entry) { return (entry->flags & diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index d3fe7296e1c9..2f43d0296951 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1336,9 +1336,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 * parent socket. */ -static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, - struct mptcp_subflow_context *subflow, - long timeout) +void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, + struct mptcp_subflow_context *subflow, + long timeout) { struct socket *sock = READ_ONCE(ssk->sk_socket); @@ -1369,6 +1369,10 @@ static void pm_work(struct mptcp_sock *msk) pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED); 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)) { pm->status &= ~BIT(MPTCP_PM_ESTABLISHED); mptcp_pm_nl_fully_established(msk); @@ -1528,7 +1532,7 @@ static void mptcp_cancel_work(struct sock *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); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index eefee58ca62d..717b3aee776c 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -150,6 +150,7 @@ struct mptcp_addr_info { enum mptcp_pm_status { MPTCP_PM_ADD_ADDR_RECEIVED, + MPTCP_PM_RM_ADDR_RECEIVED, MPTCP_PM_ESTABLISHED, MPTCP_PM_SUBFLOW_ESTABLISHED, }; @@ -350,6 +351,10 @@ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow, struct mptcp_options_received *mp_opt); bool mptcp_subflow_data_available(struct sock *sk); 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 */ int __mptcp_subflow_connect(struct sock *sk, int ifindex, @@ -422,6 +427,7 @@ void mptcp_pm_subflow_established(struct mptcp_sock *msk, void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id); void mptcp_pm_add_addr_received(struct mptcp_sock *msk, 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, const struct mptcp_addr_info *addr); @@ -456,6 +462,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_subflow_established(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); static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb) diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index 1c8482bc2ce5..8b4e6b9ec2ea 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1012,6 +1012,7 @@ int __mptcp_subflow_connect(struct sock *sk, int ifindex, subflow->remote_key = msk->remote_key; subflow->local_key = msk->local_key; subflow->token = msk->token; + subflow->remote_id = remote->id; mptcp_info2sockaddr(loc, &addr); addrlen = sizeof(struct sockaddr_in);