Merge tag 'leds-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel...
[linux-2.6-microblaze.git] / net / sctp / sm_statefuns.c
index 4f30388..09a8f23 100644 (file)
@@ -1004,7 +1004,7 @@ static enum sctp_disposition sctp_sf_heartbeat(
        struct sctp_chunk *reply;
 
        /* Send a heartbeat to our peer.  */
-       reply = sctp_make_heartbeat(asoc, transport);
+       reply = sctp_make_heartbeat(asoc, transport, 0);
        if (!reply)
                return SCTP_DISPOSITION_NOMEM;
 
@@ -1095,6 +1095,32 @@ enum sctp_disposition sctp_sf_send_reconf(struct net *net,
        return SCTP_DISPOSITION_CONSUME;
 }
 
+/* send hb chunk with padding for PLPMUTD.  */
+enum sctp_disposition sctp_sf_send_probe(struct net *net,
+                                        const struct sctp_endpoint *ep,
+                                        const struct sctp_association *asoc,
+                                        const union sctp_subtype type,
+                                        void *arg,
+                                        struct sctp_cmd_seq *commands)
+{
+       struct sctp_transport *transport = (struct sctp_transport *)arg;
+       struct sctp_chunk *reply;
+
+       if (!sctp_transport_pl_enabled(transport))
+               return SCTP_DISPOSITION_CONSUME;
+
+       sctp_transport_pl_send(transport);
+
+       reply = sctp_make_heartbeat(asoc, transport, transport->pl.probe_size);
+       if (!reply)
+               return SCTP_DISPOSITION_NOMEM;
+       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
+       sctp_add_cmd_sf(commands, SCTP_CMD_PROBE_TIMER_UPDATE,
+                       SCTP_TRANSPORT(transport));
+
+       return SCTP_DISPOSITION_CONSUME;
+}
+
 /*
  * Process an heartbeat request.
  *
@@ -1243,6 +1269,18 @@ enum sctp_disposition sctp_sf_backbeat_8_3(struct net *net,
        if (hbinfo->hb_nonce != link->hb_nonce)
                return SCTP_DISPOSITION_DISCARD;
 
+       if (hbinfo->probe_size) {
+               if (hbinfo->probe_size != link->pl.probe_size ||
+                   !sctp_transport_pl_enabled(link))
+                       return SCTP_DISPOSITION_DISCARD;
+
+               sctp_transport_pl_recv(link);
+               if (link->pl.state == SCTP_PL_COMPLETE)
+                       return SCTP_DISPOSITION_CONSUME;
+
+               return sctp_sf_send_probe(net, ep, asoc, type, link, commands);
+       }
+
        max_interval = link->hbinterval + link->rto;
 
        /* Check if the timestamp looks valid.  */