sctp: add probe_interval in sysctl and sock/asoc/transport
authorXin Long <lucien.xin@gmail.com>
Tue, 22 Jun 2021 18:04:48 +0000 (14:04 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Jun 2021 18:28:51 +0000 (11:28 -0700)
PLPMTUD can be enabled by doing 'sysctl -w net.sctp.probe_interval=n'.
'n' is the interval for PLPMTUD probe timer in milliseconds, and it
can't be less than 5000 if it's not 0.

All asoc/transport's PLPMTUD in a new socket will be enabled by default.

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>
Documentation/networking/ip-sysctl.rst
include/net/netns/sctp.h
include/net/sctp/constants.h
include/net/sctp/structs.h
net/sctp/associola.c
net/sctp/socket.c
net/sctp/sysctl.c

index b0436d3..8bff728 100644 (file)
@@ -2834,6 +2834,14 @@ encap_port - INTEGER
 
        Default: 0
 
+plpmtud_probe_interval - INTEGER
+        The time interval (in milliseconds) for sending PLPMTUD probe chunks.
+        These chunks are sent at the specified interval with a variable size
+        to probe the mtu of a given path between 2 endpoints. PLPMTUD will
+        be disabled when 0 is set, and other values for it must be >= 5000.
+
+       Default: 0
+
 
 ``/proc/sys/net/core/*``
 ========================
index a0f315e..4024072 100644 (file)
@@ -84,6 +84,9 @@ struct netns_sctp {
        /* HB.interval              - 30 seconds  */
        unsigned int hb_interval;
 
+       /* The interval for PLPMTUD probe timer */
+       unsigned int probe_interval;
+
        /* Association.Max.Retrans  - 10 attempts
         * Path.Max.Retrans         - 5  attempts (per destination address)
         * Max.Init.Retransmits     - 8  attempts
index 14a0d22..449cf9c 100644 (file)
@@ -424,4 +424,6 @@ enum {
  */
 #define SCTP_AUTH_RANDOM_LENGTH 32
 
+#define SCTP_PROBE_TIMER_MIN   5000
+
 #endif /* __sctp_constants_h__ */
index 1aa5852..bf5d22d 100644 (file)
@@ -177,6 +177,7 @@ struct sctp_sock {
         * will be inherited by all new associations.
         */
        __u32 hbinterval;
+       __u32 probe_interval;
 
        __be16 udp_port;
        __be16 encap_port;
@@ -858,6 +859,7 @@ struct sctp_transport {
         * the destination address every heartbeat interval.
         */
        unsigned long hbinterval;
+       unsigned long probe_interval;
 
        /* SACK delay timeout */
        unsigned long sackdelay;
@@ -1795,6 +1797,7 @@ struct sctp_association {
         * will be inherited by all new transports.
         */
        unsigned long hbinterval;
+       unsigned long probe_interval;
 
        __be16 encap_port;
 
index 336df4b..e01895e 100644 (file)
@@ -98,6 +98,7 @@ static struct sctp_association *sctp_association_init(
         * sock configured value.
         */
        asoc->hbinterval = msecs_to_jiffies(sp->hbinterval);
+       asoc->probe_interval = msecs_to_jiffies(sp->probe_interval);
 
        asoc->encap_port = sp->encap_port;
 
@@ -625,6 +626,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
         * association configured value.
         */
        peer->hbinterval = asoc->hbinterval;
+       peer->probe_interval = asoc->probe_interval;
 
        peer->encap_port = asoc->encap_port;
 
index a79d193..d2960ab 100644 (file)
@@ -4989,6 +4989,7 @@ static int sctp_init_sock(struct sock *sk)
        atomic_set(&sp->pd_mode, 0);
        skb_queue_head_init(&sp->pd_lobby);
        sp->frag_interleave = 0;
+       sp->probe_interval = net->sctp.probe_interval;
 
        /* Create a per socket endpoint structure.  Even if we
         * change the data structure relationships, this may still
index 55871b2..b46a416 100644 (file)
@@ -55,6 +55,8 @@ static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
                                   void *buffer, size_t *lenp, loff_t *ppos);
 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
                             void *buffer, size_t *lenp, loff_t *ppos);
+static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
+                                      void *buffer, size_t *lenp, loff_t *ppos);
 
 static struct ctl_table sctp_table[] = {
        {
@@ -293,6 +295,13 @@ static struct ctl_table sctp_net_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "plpmtud_probe_interval",
+               .data           = &init_net.sctp.probe_interval,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_sctp_do_probe_interval,
+       },
        {
                .procname       = "udp_port",
                .data           = &init_net.sctp.udp_port,
@@ -539,6 +548,32 @@ static int proc_sctp_do_udp_port(struct ctl_table *ctl, int write,
        return ret;
 }
 
+static int proc_sctp_do_probe_interval(struct ctl_table *ctl, int write,
+                                      void *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct net *net = current->nsproxy->net_ns;
+       struct ctl_table tbl;
+       int ret, new_value;
+
+       memset(&tbl, 0, sizeof(struct ctl_table));
+       tbl.maxlen = sizeof(unsigned int);
+
+       if (write)
+               tbl.data = &new_value;
+       else
+               tbl.data = &net->sctp.probe_interval;
+
+       ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+       if (write && ret == 0) {
+               if (new_value && new_value < SCTP_PROBE_TIMER_MIN)
+                       return -EINVAL;
+
+               net->sctp.probe_interval = new_value;
+       }
+
+       return ret;
+}
+
 int sctp_sysctl_net_register(struct net *net)
 {
        struct ctl_table *table;