pl.count will make a timer that 'timeout' every after '10 * node timer
interval', where it does state transition in tipc_link_pl_send() and
sends probe in tipc_link_build_proto_msg().

For the details, see:

  https://lwn.net/Articles/860385/

Signed-off-by: Xin Long <lucien....@gmail.com>
---
 net/tipc/link.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 414f9cf543ff..3af6c04f82c2 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -292,6 +292,7 @@ static int tipc_link_advance_transmq(struct tipc_link *l, 
struct tipc_link *r,
                                     bool *retransmitted, int *rc);
 static void tipc_link_update_cwin(struct tipc_link *l, int released,
                                  bool retransmitted);
+static void tipc_link_pl_send(struct tipc_link *l);
 /*
  *  Simple non-static link routines (i.e. referenced outside this file)
  */
@@ -902,6 +903,14 @@ int tipc_link_timeout(struct tipc_link *l, struct 
sk_buff_head *xmitq)
        if (state || probe || setup)
                tipc_link_build_proto_msg(l, mtyp, PROBE_MSTATE, 0, 0, 0, 0, 
xmitq);
 
+       if (probe && tipc_link_is_up(l)) {
+               l->pl.count++;
+               if (!(l->pl.count % TIPC_PROBE_INTERVAL)) {
+                       tipc_link_pl_send(l);
+                       tipc_link_build_proto_msg(l, mtyp, PROBE_PLPMTU, 0, 0, 
0, 0, xmitq);
+               }
+       }
+
        return rc;
 }
 
@@ -3013,3 +3022,42 @@ int tipc_link_dump(struct tipc_link *l, u16 dqueues, 
char *buf)
 
        return i;
 }
+
+static void tipc_link_pl_send(struct tipc_link *l)
+{
+       pr_debug("%s: PLPMTUD: link: %p, state: %d, pmtu: %d, size: %d, high: 
%d\n",
+                __func__, l, l->pl.state, l->pl.pmtu, l->pl.probe_size, 
l->pl.probe_high);
+
+       if (l->pl.count <= TIPC_MAX_PROBES * TIPC_PROBE_INTERVAL)
+               return;
+
+       if (l->pl.state == TIPC_PL_BASE) {
+               if (l->pl.probe_size == TIPC_BASE_PLPMTU) { /* BASE_PLPMTU 
Confirmation Failed */
+                       l->pl.state = TIPC_PL_ERROR; /* Base -> Error */
+
+                       l->pl.pmtu = TIPC_MIN_PLPMTU;
+                       l->mtu = l->pl.pmtu;
+               }
+       } else if (l->pl.state == TIPC_PL_SEARCH) {
+               if (l->pl.pmtu == l->pl.probe_size) { /* Black Hole Detected */
+                       l->pl.state = TIPC_PL_BASE;  /* Search -> Base */
+                       l->pl.probe_size = TIPC_BASE_PLPMTU;
+                       l->pl.probe_high = 0;
+
+                       l->pl.pmtu = TIPC_BASE_PLPMTU;
+                       l->mtu = l->pl.pmtu;
+               } else { /* Normal probe failure. */
+                       l->pl.probe_high = l->pl.probe_size;
+                       l->pl.probe_size = l->pl.pmtu;
+               }
+       } else if (l->pl.state == TIPC_PL_COMPLETE) {
+               if (l->pl.pmtu == l->pl.probe_size) { /* Black Hole Detected */
+                       l->pl.state = TIPC_PL_BASE;  /* Search Complete -> Base 
*/
+                       l->pl.probe_size = TIPC_BASE_PLPMTU;
+
+                       l->pl.pmtu = TIPC_BASE_PLPMTU;
+                       l->mtu = l->pl.pmtu;
+               }
+       }
+       l->pl.count = TIPC_PROBE_INTERVAL;
+}
-- 
2.27.0



_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to