summaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2020-10-29 08:05:03 +0100
committerJakub Kicinski <kuba@kernel.org>2020-10-30 23:24:16 +0100
commita1dd2cf2f1aedabc2ca9bb4f90231a521c52d8eb (patch)
treea6cc1c86ee8e727cfe28c96d63350d7c45f9391d /net/sctp/protocol.c
parentsctp: add SCTP_REMOTE_UDP_ENCAPS_PORT sockopt (diff)
downloadlinux-a1dd2cf2f1aedabc2ca9bb4f90231a521c52d8eb.tar.xz
linux-a1dd2cf2f1aedabc2ca9bb4f90231a521c52d8eb.zip
sctp: allow changing transport encap_port by peer packets
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 <lucien.xin@gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 89dfd313e113..f3de8c03a15e 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,