1. 31 Oct, 2020 32 commits
  2. 30 Oct, 2020 8 commits
    • Jakub Kicinski's avatar
      Merge branch 'sctp-implement-rfc6951-udp-encapsulation-of-sctp' · be25f43a
      Jakub Kicinski authored
      Xin Long says:
      
      ====================
      sctp: Implement RFC6951: UDP Encapsulation of SCTP
      
      Description From the RFC:
      
         The Main Reasons:
      
         o  To allow SCTP traffic to pass through legacy NATs, which do not
            provide native SCTP support as specified in [BEHAVE] and
            [NATSUPP].
      
         o  To allow SCTP to be implemented on hosts that do not provide
            direct access to the IP layer.  In particular, applications can
            use their own SCTP implementation if the operating system does not
            provide one.
      
         Implementation Notes:
      
         UDP-encapsulated SCTP is normally communicated between SCTP stacks
         using the IANA-assigned UDP port number 9899 (sctp-tunneling) on both
         ends.  There are circumstances where other ports may be used on
         either end, and it might be required to use ports other than the
         registered port.
      
         Each SCTP stack uses a single local UDP encapsulation port number as
         the destination port for all its incoming SCTP packets, this greatly
         simplifies implementation design.
      
         An SCTP implementation supporting UDP encapsulation MUST maintain a
         remote UDP encapsulation port number per destination address for each
         SCTP association.  Again, because the remote stack may be using ports
         other than the well-known port, each port may be different from each
         stack.  However, because of remapping of ports by NATs, the remote
         ports associated with different remote IP addresses may not be
         identical, even if they are associated with the same stack.
      
         Because the well-known port might not be used, implementations need
         to allow other port numbers to be specified as a local or remote UDP
         encapsulation port number through APIs.
      
      Patches:
      
         This patchset is using the udp4/6 tunnel APIs to implement the UDP
         Encapsulation of SCTP with not much change in SCTP protocol stack
         and with all current SCTP features keeped in Linux Kernel.
      
         1 - 4: Fix some UDP issues that may be triggered by SCTP over UDP.
         5 - 7: Process incoming UDP encapsulated packets and ICMP packets.
         8 -10: Remote encap port's update by sysctl, sockopt and packets.
         11-14: Process outgoing pakects with UDP encapsulated and its GSO.
         15-16: Add the part from draft-tuexen-tsvwg-sctp-udp-encaps-cons-03.
            17: Enable this feature.
      
      Tests:
      
        - lksctp-tools/src/func_tests with UDP Encapsulation enabled/disabled:
      
            Both make v4test and v6test passed.
      
        - sctp-tests with UDP Encapsulation enabled/disabled:
      
            repeatability/procdumps/sctpdiag/gsomtuchange/extoverflow/
            sctphashtable passed. Others failed as expected due to those
            "iptables -p sctp" rules.
      
        - netperf on lo/netns/virtio_net, with gso enabled/disabled and
          with ip_checksum enabled/disabled, with UDP Encapsulation
          enabled/disabled:
      
            No clear performance dropped.
      
      v1->v2:
        - Fix some incorrect code in the patches 5,6,8,10,11,13,14,17, suggested
          by Marcelo.
        - Append two patches 15-16 to add the Additional Considerations for UDP
          Encapsulation of SCTP from draft-tuexen-tsvwg-sctp-udp-encaps-cons-03.
      v2->v3:
        - remove the cleanup code in patch 2, suggested by Willem.
        - remove the patch 3 and fix the checksum in the new patch 3 after
          talking with Paolo, Marcelo and Guillaume.
        - add 'select NET_UDP_TUNNEL' in patch 4 to solve a compiling error.
        - fix __be16 type cast warning in patch 8.
        - fix the wrong endian orders when setting values in 14,16.
      v3->v4:
        - add entries in ip-sysctl.rst in patch 7,16, as Marcelo Suggested.
        - not create udp socks when udp_port is set to 0 in patch 16, as
          Marcelo noticed.
      v4->v5:
        - improve the description for udp_port and encap_port entries in patch
          7, 16.
        - use 0 as the default udp_port.
      ====================
      
      Link: https://lore.kernel.org/r/cover.1603955040.git.lucien.xin@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      be25f43a
    • Xin Long's avatar
      sctp: enable udp tunneling socks · 046c052b
      Xin Long authored
      This patch is to enable udp tunneling socks by calling
      sctp_udp_sock_start() in sctp_ctrlsock_init(), and
      sctp_udp_sock_stop() in sctp_ctrlsock_exit().
      
      Also add sysctl udp_port to allow changing the listening
      sock's port by users.
      
      Wit this patch, the whole sctp over udp feature can be
      enabled and used.
      
      v1->v2:
        - Also update ctl_sock udp_port in proc_sctp_do_udp_port()
          where netns udp_port gets changed.
      v2->v3:
        - Call htons() when setting sk udp_port from netns udp_port.
      v3->v4:
        - Not call sctp_udp_sock_start() when new_value is 0.
        - Add udp_port entry in ip-sysctl.rst.
      v4->v5:
        - Not call sctp_udp_sock_start/stop() in sctp_ctrlsock_init/exit().
        - Improve the description of udp_port in ip-sysctl.rst.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      046c052b
    • Xin Long's avatar
      sctp: handle the init chunk matching an existing asoc · 1c16a186
      Xin Long authored
      This is from Section 4 of draft-tuexen-tsvwg-sctp-udp-encaps-cons-03,
      and it requires responding with an abort chunk with an error cause
      when the udp source port of the received init chunk doesn't match the
      encap port of the transport.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      1c16a186
    • Xin Long's avatar
      sctp: add the error cause for new encapsulation port restart · e38d86b3
      Xin Long authored
      This patch is to add the function to make the abort chunk with
      the error cause for new encapsulation port restart, defined
      on Section 4.4 in draft-tuexen-tsvwg-sctp-udp-encaps-cons-03.
      
      v1->v2:
        - no change.
      v2->v3:
        - no need to call htons() when setting nep.cur_port/new_port.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      e38d86b3
    • Xin Long's avatar
      sctp: support for sending packet over udp6 sock · 259db53b
      Xin Long authored
      This one basically does the similar things in sctp_v6_xmit as does for
      udp4 sock in the last patch, just note that:
      
        1. label needs to be calculated, as it's the param of
           udp_tunnel6_xmit_skb().
      
        2. The 'nocheck' param of udp_tunnel6_xmit_skb() is false, as
           required by RFC.
      
      v1->v2:
        - Use sp->udp_port instead in sctp_v6_xmit(), which is more safe.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      259db53b
    • Xin Long's avatar
      sctp: support for sending packet over udp4 sock · 600af7fd
      Xin Long authored
      This patch does what the rfc6951#section-5.3 says for ipv4:
      
        "Within the UDP header, the source port MUST be the local UDP
         encapsulation port number of the SCTP stack, and the destination port
         MUST be the remote UDP encapsulation port number maintained for the
         association and the destination address to which the packet is sent
         (see Section 5.1).
      
         Because the SCTP packet is the UDP payload, the length of the UDP
         packet MUST be the length of the SCTP packet plus the size of the UDP
         header.
      
         The SCTP checksum MUST be computed for IPv4 and IPv6, and the UDP
         checksum SHOULD be computed for IPv4 and IPv6."
      
      Some places need to be adjusted in sctp_packet_transmit():
      
        1. For non-gso packets, when transport's encap_port is set, sctp
           checksum has to be done in sctp_packet_pack(), as the outer
           udp will use ip_summed = CHECKSUM_PARTIAL to do the offload
           setting for checksum.
      
        2. Delay calling dst_clone() and skb_dst_set() for non-udp packets
           until sctp_v4_xmit(), as for udp packets, skb_dst_set() is not
           needed before calling udp_tunnel_xmit_skb().
      
      then in sctp_v4_xmit():
      
        1. Go to udp_tunnel_xmit_skb() only when transport->encap_port and
           net->sctp.udp_port both are set, as these are one for dst port
           and another for src port.
      
        2. For gso packet, SKB_GSO_UDP_TUNNEL_CSUM is set for gso_type, and
           with this udp checksum can be done in __skb_udp_tunnel_segment()
           for each segments after the sctp gso.
      
        3. inner_mac_header and inner_transport_header are set, as these
           will be needed in __skb_udp_tunnel_segment() to find the right
           headers.
      
        4. df and ttl are calculated, as these are the required params by
           udp_tunnel_xmit_skb().
      
        5. nocheck param has to be false, as "the UDP checksum SHOULD be
           computed for IPv4 and IPv6", says in rfc6951#section-5.3.
      
      v1->v2:
        - Use sp->udp_port instead in sctp_v4_xmit(), which is more safe.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      600af7fd
    • Xin Long's avatar
      sctp: call sk_setup_caps in sctp_packet_transmit instead · bcd623d8
      Xin Long authored
      sk_setup_caps() was originally called in Commit 90017acc ("sctp:
      Add GSO support"), as:
      
        "We have to refresh this in case we are xmiting to more than one
         transport at a time"
      
      This actually happens in the loop of sctp_outq_flush_transports(),
      and it shouldn't be tied to gso, so move it out of gso part and
      before sctp_packet_pack().
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      bcd623d8
    • Xin Long's avatar
      sctp: add udphdr to overhead when udp_port is set · f1bfe8b5
      Xin Long authored
      sctp_mtu_payload() is for calculating the frag size before making
      chunks from a msg. So we should only add udphdr size to overhead
      when udp socks are listening, as only then sctp can handle the
      incoming sctp over udp packets and outgoing sctp over udp packets
      will be possible.
      
      Note that we can't do this according to transport->encap_port, as
      different transports may be set to different values, while the
      chunks were made before choosing the transport, we could not be
      able to meet all rfc6951#section-5.6 recommends.
      
      v1->v2:
        - Add udp_port for sctp_sock to avoid a potential race issue, it
          will be used in xmit path in the next patch.
      Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
      Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
      f1bfe8b5