]> git.baikalelectronics.ru Git - kernel.git/commitdiff
sctp: add the constants/variables and states and some APIs for transport
authorXin Long <lucien.xin@gmail.com>
Tue, 22 Jun 2021 18:04:50 +0000 (14:04 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Jun 2021 18:28:52 +0000 (11:28 -0700)
These are 4 constants described in rfc8899#section-5.1.2:

  MAX_PROBES, MIN_PLPMTU, MAX_PLPMTU, BASE_PLPMTU;

And 2 variables described in rfc8899#section-5.1.3:

  PROBED_SIZE, PROBE_COUNT;

And 5 states described in rfc8899#section-5.2:

  DISABLED, BASE, SEARCH, SEARCH_COMPLETE, ERROR;

And these 4 APIs are used to reset/update PLPMTUD, check if PLPMTUD is
enabled, and calculate the additional headers length for a transport.

Note the member 'probe_high' in transport will be set to the probe
size when a probe fails with this probe size in the next patches.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/constants.h
include/net/sctp/sctp.h
include/net/sctp/structs.h

index 449cf9cb428b1ce2b9ac26b1f545d5b97a82c130..85f6a105c59dd1126ad26635f947b8a376dd17f2 100644 (file)
@@ -200,6 +200,23 @@ enum sctp_sock_state {
        SCTP_SS_CLOSING        = TCP_CLOSE_WAIT,
 };
 
+enum sctp_plpmtud_state {
+       SCTP_PL_DISABLED,
+       SCTP_PL_BASE,
+       SCTP_PL_SEARCH,
+       SCTP_PL_COMPLETE,
+       SCTP_PL_ERROR,
+};
+
+#define        SCTP_BASE_PLPMTU        1200
+#define        SCTP_MAX_PLPMTU         9000
+#define        SCTP_MIN_PLPMTU         512
+
+#define        SCTP_MAX_PROBES         3
+
+#define SCTP_PL_BIG_STEP       32
+#define SCTP_PL_MIN_STEP       4
+
 /* These functions map various type to printable names.  */
 const char *sctp_cname(const union sctp_subtype id);   /* chunk types */
 const char *sctp_oname(const union sctp_subtype id);   /* other events */
index 86f74f2fe6deab9067cd3dcfab2fe152af9c3dba..08347d3f004f662cbed09703eedde0a4c772c517 100644 (file)
@@ -573,14 +573,15 @@ static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *
 /* Calculate max payload size given a MTU, or the total overhead if
  * given MTU is zero
  */
-static inline __u32 sctp_mtu_payload(const struct sctp_sock *sp,
-                                    __u32 mtu, __u32 extra)
+static inline __u32 __sctp_mtu_payload(const struct sctp_sock *sp,
+                                      const struct sctp_transport *t,
+                                      __u32 mtu, __u32 extra)
 {
        __u32 overhead = sizeof(struct sctphdr) + extra;
 
        if (sp) {
                overhead += sp->pf->af->net_header_len;
-               if (sp->udp_port)
+               if (sp->udp_port && (!t || t->encap_port))
                        overhead += sizeof(struct udphdr);
        } else {
                overhead += sizeof(struct ipv6hdr);
@@ -592,6 +593,12 @@ static inline __u32 sctp_mtu_payload(const struct sctp_sock *sp,
        return mtu ? mtu - overhead : overhead;
 }
 
+static inline __u32 sctp_mtu_payload(const struct sctp_sock *sp,
+                                    __u32 mtu, __u32 extra)
+{
+       return __sctp_mtu_payload(sp, NULL, mtu, extra);
+}
+
 static inline __u32 sctp_dst_mtu(const struct dst_entry *dst)
 {
        return SCTP_TRUNC4(max_t(__u32, dst_mtu(dst),
@@ -615,6 +622,41 @@ static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize)
        return sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, datasize);
 }
 
+static inline int sctp_transport_pl_hlen(struct sctp_transport *t)
+{
+       return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0);
+}
+
+static inline void sctp_transport_pl_reset(struct sctp_transport *t)
+{
+       if (t->probe_interval && (t->param_flags & SPP_PMTUD_ENABLE) &&
+           (t->state == SCTP_ACTIVE || t->state == SCTP_UNKNOWN)) {
+               if (t->pl.state == SCTP_PL_DISABLED) {
+                       t->pl.state = SCTP_PL_BASE;
+                       t->pl.pmtu = SCTP_BASE_PLPMTU;
+                       t->pl.probe_size = SCTP_BASE_PLPMTU;
+               }
+       } else {
+               if (t->pl.state != SCTP_PL_DISABLED)
+                       t->pl.state = SCTP_PL_DISABLED;
+       }
+}
+
+static inline void sctp_transport_pl_update(struct sctp_transport *t)
+{
+       if (t->pl.state == SCTP_PL_DISABLED)
+               return;
+
+       t->pl.state = SCTP_PL_BASE;
+       t->pl.pmtu = SCTP_BASE_PLPMTU;
+       t->pl.probe_size = SCTP_BASE_PLPMTU;
+}
+
+static inline bool sctp_transport_pl_enabled(struct sctp_transport *t)
+{
+       return t->pl.state != SCTP_PL_DISABLED;
+}
+
 static inline bool sctp_newsk_ready(const struct sock *sk)
 {
        return sock_flag(sk, SOCK_DEAD) || sk->sk_socket;
index bf5d22deaefbe1e373f36b6952ce4da116fd2946..85d3566c22276c8427d9ed76c0c54627fe73016e 100644 (file)
@@ -978,6 +978,14 @@ struct sctp_transport {
                char cacc_saw_newack;
        } cacc;
 
+       struct {
+               __u16 pmtu;
+               __u16 probe_size;
+               __u16 probe_high;
+               __u8 probe_count;
+               __u8 state;
+       } pl; /* plpmtud related */
+
        /* 64-bit random number sent with heartbeat. */
        __u64 hb_nonce;