From patchwork Tue Oct 13 07:27:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 288509 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7E1BC433E7 for ; Tue, 13 Oct 2020 07:29:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 775E720872 for ; Tue, 13 Oct 2020 07:29:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="vROqWLGr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390226AbgJMH26 (ORCPT ); Tue, 13 Oct 2020 03:28:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390091AbgJMH24 (ORCPT ); Tue, 13 Oct 2020 03:28:56 -0400 Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 718F3C0613D0; Tue, 13 Oct 2020 00:28:56 -0700 (PDT) Received: by mail-pf1-x431.google.com with SMTP id j18so3634653pfa.0; Tue, 13 Oct 2020 00:28: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=iNzHGEAnbQnBSq+cqEMlnX9SeC26Mbv1uc1rY7stx/g=; b=vROqWLGrxp7jTopMSR7eQyOdSPqKJzS4zvQmCd9ulkGl3pGGiU2ounCv9yDwKAcupz MXEjVoKsI6Ac/vYw1/krcETcIgGKTWIteNwBRwjR2xsgeeGq4kTPSZNaWIXdoJzYSuYA UNQyRs1LDECHGQzxcqiBkMCewsjeA0Qi/E3HCQ3P/HNMX9rx/Yn4MNRKr8TO2tz+AwkK /42inAduZVCpyNL5ShUQmj189/F6/noQNcPqcfqfIGXFQzO7RIv3DNJ/Qjz2UZrLgVWt Y5YBHv4tkgvAVpvTBm4JbZl85e+2xFNKc+7d+cQqufkL0hDrylDLgN1E73yqrdR5dmbl rwQw== 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=iNzHGEAnbQnBSq+cqEMlnX9SeC26Mbv1uc1rY7stx/g=; b=gw0uVljfksonH0fsQmtlqlKr/J7uKQdfH9YGgWjWwNUv48ASAHTWYw7exop5t25jt2 gX6S0wpfV1xSTOy3A6uEK+EgMRIf6OAwwwlRuB4x1uLX5ADhqjHVno7ooQD6avd6T52/ jLCBTra0HBkv5tIg2WuGGHJ2mWTQfU/WePI6vyCZ7W0vOvpuorzPqF+oobbLxrKGdpx4 xWCh6/ZEB+1LcODXG6HA/DUyfH9cYUJnexJiIY5gQvJVkGMgIYRrCyL21C7do5ph5AKz TzBUaHR13d0K2lw0QsJFBgl+2LMTahNbatEMJ3WCgEcitHcDo32JzczQeerjhAOiokDP n3lQ== X-Gm-Message-State: AOAM532ST2adbS84HIB6hqGjyXLi5CnVqIC4QjgxpJuoX6VeFPEbJlky 3ImM5N/tj+/m2lS5/Bv8uIbg9eAboY8= X-Google-Smtp-Source: ABdhPJxoXTWzZVMweftDLitdPKPOGdpgPKUXrDV5iCTn/vXRFtseCfHLzWMVYbfED7fL7Pc1PfZydQ== X-Received: by 2002:a65:5ace:: with SMTP id d14mr16170961pgt.323.1602574135582; Tue, 13 Oct 2020 00:28:55 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id x29sm15309450pfp.152.2020.10.13.00.28.54 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Oct 2020 00:28:55 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: Marcelo Ricardo Leitner , Neil Horman , Michael Tuexen , davem@davemloft.net, gnault@redhat.com, pabeni@redhat.com, willemdebruijn.kernel@gmail.com Subject: [PATCHv3 net-next 09/16] sctp: allow changing transport encap_port by peer packets Date: Tue, 13 Oct 2020 15:27:34 +0800 Message-Id: <732baa9aef67a1b0d0b4d69f47149b41a49bbd76.1602574012.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <08854ecf72eee34d3e98e30def6940d94f97fdef.1602574012.git.lucien.xin@gmail.com> References: <7159fb58f44f9ff00ca5b3b8a26ee3aa2fd1bf8a.1602574012.git.lucien.xin@gmail.com> <37e9f70ffb9dea1572025b8e1c4b1f1c6e6b3da5.1602574012.git.lucien.xin@gmail.com> <08854ecf72eee34d3e98e30def6940d94f97fdef.1602574012.git.lucien.xin@gmail.com> In-Reply-To: References: Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As rfc6951#section-5.4 says: "After finding the SCTP association (which includes checking the verification tag), the UDP source port MUST be stored as the encapsulation port for the destination address the SCTP packet is received from (see Section 5.1). When a non-encapsulated SCTP packet is received by the SCTP stack, the encapsulation of outgoing packets belonging to the same association and the corresponding destination address MUST be disabled." transport encap_port should be updated by a validated incoming packet's udp src port. We save the udp src port in sctp_input_cb->encap_port, and then update the transport in two places: 1. right after vtag is verified, which is required by RFC, and this allows the existent transports to be updated by the chunks that can only be processed on an asoc. 2. right before processing the 'init' where the transports are added, and this allows building a sctp over udp connection by client with the server not knowing the remote encap port. 3. when processing ootb_pkt and creating the temporary transport for the reply pkt. Note that sctp_input_cb->header is removed, as it's not used any more in sctp. v1->v2: - Change encap_port as __be16 for sctp_input_cb. Signed-off-by: Xin Long --- include/net/sctp/sm.h | 1 + include/net/sctp/structs.h | 7 +------ net/sctp/ipv6.c | 1 + net/sctp/protocol.c | 11 ++++++++++- net/sctp/sm_make_chunk.c | 1 + net/sctp/sm_statefuns.c | 2 ++ 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 5c491a3..a499341 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -380,6 +380,7 @@ sctp_vtag_verify(const struct sctp_chunk *chunk, if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) return 1; + chunk->transport->encap_port = SCTP_INPUT_CB(chunk->skb)->encap_port; return 0; } diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index aa98e7e..81464ae 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1120,14 +1120,9 @@ static inline void sctp_outq_cork(struct sctp_outq *q) * sctp_input_cb is currently used on rx and sock rx queue */ struct sctp_input_cb { - union { - struct inet_skb_parm h4; -#if IS_ENABLED(CONFIG_IPV6) - struct inet6_skb_parm h6; -#endif - } header; struct sctp_chunk *chunk; struct sctp_af *af; + __be16 encap_port; }; #define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0])) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 8a58f42..a064bf2 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -1053,6 +1053,7 @@ static struct inet_protosw sctpv6_stream_protosw = { static int sctp6_rcv(struct sk_buff *skb) { + memset(skb->cb, 0, sizeof(skb->cb)); return sctp_rcv(skb) ? -1 : 0; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5b74187..0d16e5e 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -843,6 +843,9 @@ static int sctp_ctl_sock_init(struct net *net) static int sctp_udp_rcv(struct sock *sk, struct sk_buff *skb) { + memset(skb->cb, 0, sizeof(skb->cb)); + SCTP_INPUT_CB(skb)->encap_port = udp_hdr(skb)->source; + skb_set_transport_header(skb, sizeof(struct udphdr)); sctp_rcv(skb); return 0; @@ -1139,9 +1142,15 @@ static struct inet_protosw sctp_stream_protosw = { .flags = SCTP_PROTOSW_FLAG }; +static int sctp4_rcv(struct sk_buff *skb) +{ + memset(skb->cb, 0, sizeof(skb->cb)); + return sctp_rcv(skb); +} + /* Register with IP layer. */ static const struct net_protocol sctp_protocol = { - .handler = sctp_rcv, + .handler = sctp4_rcv, .err_handler = sctp_v4_err, .no_policy = 1, .netns_ok = 1, diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 9a56ae2..21d0ff1 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2321,6 +2321,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, * added as the primary transport. The source address seems to * be a better choice than any of the embedded addresses. */ + asoc->encap_port = SCTP_INPUT_CB(chunk->skb)->encap_port; if (!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) goto nomem; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c669f8b..8edab15 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -6268,6 +6268,8 @@ static struct sctp_packet *sctp_ootb_pkt_new( if (!transport) goto nomem; + transport->encap_port = SCTP_INPUT_CB(chunk->skb)->encap_port; + /* Cache a route for the transport with the chunk's destination as * the source address. */