sctp: add the error cause for new encapsulation port restart
authorXin Long <lucien.xin@gmail.com>
Thu, 29 Oct 2020 07:05:08 +0000 (15:05 +0800)
committerJakub Kicinski <kuba@kernel.org>
Fri, 30 Oct 2020 22:24:40 +0000 (15:24 -0700)
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: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/sctp.h
include/net/sctp/sm.h
net/sctp/sm_make_chunk.c

index 7673123..bb19265 100644 (file)
@@ -482,11 +482,13 @@ enum sctp_error {
         *  11  Restart of an association with new addresses
         *  12  User Initiated Abort
         *  13  Protocol Violation
+        *  14  Restart of an Association with New Encapsulation Port
         */
 
        SCTP_ERROR_RESTART         = cpu_to_be16(0x0b),
        SCTP_ERROR_USER_ABORT      = cpu_to_be16(0x0c),
        SCTP_ERROR_PROTO_VIOLATION = cpu_to_be16(0x0d),
+       SCTP_ERROR_NEW_ENCAP_PORT  = cpu_to_be16(0x0e),
 
        /* ADDIP Section 3.3  New Error Causes
         *
@@ -793,4 +795,22 @@ enum {
        SCTP_FLOWLABEL_VAL_MASK = 0xfffff
 };
 
+/* UDP Encapsulation
+ * draft-tuexen-tsvwg-sctp-udp-encaps-cons-03.html#section-4-4
+ *
+ *   The error cause indicating an "Restart of an Association with
+ *   New Encapsulation Port"
+ *
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |        Cause Code = 14        |       Cause Length = 8        |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   Current Encapsulation Port  |     New Encapsulation Port    |
+ * +-------------------------------+-------------------------------+
+ */
+struct sctp_new_encap_port_hdr {
+       __be16 cur_port;
+       __be16 new_port;
+};
+
 #endif /* __LINUX_SCTP_H__ */
index a499341..fd223c9 100644 (file)
@@ -221,6 +221,9 @@ struct sctp_chunk *sctp_make_violation_paramlen(
 struct sctp_chunk *sctp_make_violation_max_retrans(
                                        const struct sctp_association *asoc,
                                        const struct sctp_chunk *chunk);
+struct sctp_chunk *sctp_make_new_encap_port(
+                                       const struct sctp_association *asoc,
+                                       const struct sctp_chunk *chunk);
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                       const struct sctp_transport *transport);
 struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
index 21d0ff1..f77484d 100644 (file)
@@ -1142,6 +1142,26 @@ nodata:
        return retval;
 }
 
+struct sctp_chunk *sctp_make_new_encap_port(const struct sctp_association *asoc,
+                                           const struct sctp_chunk *chunk)
+{
+       struct sctp_new_encap_port_hdr nep;
+       struct sctp_chunk *retval;
+
+       retval = sctp_make_abort(asoc, chunk,
+                                sizeof(struct sctp_errhdr) + sizeof(nep));
+       if (!retval)
+               goto nodata;
+
+       sctp_init_cause(retval, SCTP_ERROR_NEW_ENCAP_PORT, sizeof(nep));
+       nep.cur_port = SCTP_INPUT_CB(chunk->skb)->encap_port;
+       nep.new_port = chunk->transport->encap_port;
+       sctp_addto_chunk(retval, sizeof(nep), &nep);
+
+nodata:
+       return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                       const struct sctp_transport *transport)