]> git.baikalelectronics.ru Git - kernel.git/commitdiff
sctp: enable PLPMTUD when the transport is ready
authorXin Long <lucien.xin@gmail.com>
Tue, 22 Jun 2021 18:04:56 +0000 (14:04 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Jun 2021 18:28:52 +0000 (11:28 -0700)
sctp_transport_pl_reset() is called whenever any of these 3 members in
transport is changed:

  - probe_interval
  - param_flags & SPP_PMTUD_ENABLE
  - state == ACTIVE

If all are true, start the PLPMTUD when it's not yet started. If any of
these is false, stop the PLPMTUD when it's already running.

sctp_transport_pl_update() is called when the transport dst has changed.
It will restart the PLPMTUD probe. Again, the pathmtu won't change but
use the dst's mtu until the Search phase is done.

Note that after using PLPMTUD, the pathmtu is only initialized with the
dst mtu when the transport dst changes. At other time it is updated by
pl.pmtu. So sctp_transport_pmtu_check() will be called only when PLPMTUD
is disabled in sctp_packet_config().

After this patch, the PLPMTUD feature from RFC8899 will be activated
and can be used by users.

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>
net/sctp/associola.c
net/sctp/output.c
net/sctp/socket.c
net/sctp/transport.c

index e01895edd3a41056959359df106a320ab48da680..be29da09cc7ab08ec2fd9e24f7b5c53c407ea931 100644 (file)
@@ -716,6 +716,8 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
                return NULL;
        }
 
+       sctp_transport_pl_reset(peer);
+
        /* Attach the remote transport to our asoc.  */
        list_add_tail_rcu(&peer->transports, &asoc->peer.transport_addr_list);
        asoc->peer.transport_count++;
@@ -814,6 +816,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
                        spc_state = SCTP_ADDR_CONFIRMED;
 
                transport->state = SCTP_ACTIVE;
+               sctp_transport_pl_reset(transport);
                break;
 
        case SCTP_TRANSPORT_DOWN:
@@ -823,6 +826,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
                 */
                if (transport->state != SCTP_UNCONFIRMED) {
                        transport->state = SCTP_INACTIVE;
+                       sctp_transport_pl_reset(transport);
                        spc_state = SCTP_ADDR_UNREACHABLE;
                } else {
                        sctp_transport_dst_release(transport);
index ceefb0616d9dc14ae5a8582ce8e6e94d606f1842..9032ce60d50e81be8c6adfbf72df32f968a6a2fc 100644 (file)
@@ -103,7 +103,8 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
                sctp_transport_route(tp, NULL, sp);
                if (asoc->param_flags & SPP_PMTUD_ENABLE)
                        sctp_assoc_sync_pmtu(asoc);
-       } else if (!sctp_transport_pmtu_check(tp)) {
+       } else if (!sctp_transport_pl_enabled(tp) &&
+                  !sctp_transport_pmtu_check(tp)) {
                if (asoc->param_flags & SPP_PMTUD_ENABLE)
                        sctp_assoc_sync_pmtu(asoc);
        }
index aba576f534584e29111cf1035d6a8505ded62cc8..e64e01f61b117b8befe206d1eb4807d96aad09b4 100644 (file)
@@ -2496,6 +2496,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
                                sctp_transport_pmtu(trans, sctp_opt2sk(sp));
                                sctp_assoc_sync_pmtu(asoc);
                        }
+                       sctp_transport_pl_reset(trans);
                } else if (asoc) {
                        asoc->param_flags =
                                (asoc->param_flags & ~SPP_PMTUD) | pmtud_change;
@@ -4506,6 +4507,7 @@ static int sctp_setsockopt_probe_interval(struct sock *sk,
                        return -EINVAL;
 
                t->probe_interval = msecs_to_jiffies(probe_interval);
+               sctp_transport_pl_reset(t);
                return 0;
        }
 
@@ -4522,8 +4524,10 @@ static int sctp_setsockopt_probe_interval(struct sock *sk,
         * each transport.
         */
        if (asoc) {
-               list_for_each_entry(t, &asoc->peer.transport_addr_list, transports)
+               list_for_each_entry(t, &asoc->peer.transport_addr_list, transports) {
                        t->probe_interval = msecs_to_jiffies(probe_interval);
+                       sctp_transport_pl_reset(t);
+               }
 
                asoc->probe_interval = msecs_to_jiffies(probe_interval);
                return 0;
index 5cefb4eab8a04df9b6f3e6942cd9a32ddc8e3c29..f27b856ea8ceeb9c653695a5b19da12623716758 100644 (file)
@@ -259,6 +259,8 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
                transport->pathmtu = sctp_dst_mtu(transport->dst);
        else
                transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
+
+       sctp_transport_pl_update(transport);
 }
 
 void sctp_transport_pl_send(struct sctp_transport *t)