This patch is to receive and process the probe ack by checking msg_max_pkt() == l->pl.probe_size then does state transition in tipc_link_pl_recv().
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 3af6c04f82c2..241c9378e258 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -293,6 +293,7 @@ static int tipc_link_advance_transmq(struct tipc_link *l, struct tipc_link *r, static void tipc_link_update_cwin(struct tipc_link *l, int released, bool retransmitted); static void tipc_link_pl_send(struct tipc_link *l); +static void tipc_link_pl_recv(struct tipc_link *l); /* * Simple non-static link routines (i.e. referenced outside this file) */ @@ -2333,6 +2334,13 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, break; } + if (!reply && msg_max_pkt(hdr) == l->pl.probe_size) { + tipc_link_pl_recv(l); + if (l->pl.state == TIPC_PL_COMPLETE) + break; + tipc_link_build_proto_msg(l, STATE_MSG, PROBE_PLPMTU, 0, 0, 0, 0, xmitq); + } + /* Receive Gap ACK blocks from peer if any */ glen = tipc_get_gap_ack_blks(&ga, l, hdr, true); @@ -3061,3 +3069,43 @@ static void tipc_link_pl_send(struct tipc_link *l) } l->pl.count = TIPC_PROBE_INTERVAL; } + +static void tipc_link_pl_recv(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); + + l->pl.pmtu = l->pl.probe_size; + l->pl.count = 0; + if (l->pl.state == TIPC_PL_BASE) { + l->pl.state = TIPC_PL_SEARCH; /* Base -> Search */ + l->pl.probe_size += TIPC_PL_BIG_STEP; + } else if (l->pl.state == TIPC_PL_ERROR) { + l->pl.state = TIPC_PL_SEARCH; /* Error -> Search */ + + l->pl.pmtu = l->pl.probe_size; + l->mtu = l->pl.pmtu; + l->pl.probe_size += TIPC_PL_BIG_STEP; + } else if (l->pl.state == TIPC_PL_SEARCH) { + if (!l->pl.probe_high) { + l->pl.probe_size = min(l->pl.probe_size + TIPC_PL_BIG_STEP, + TIPC_MAX_PLPMTU); + return; + } + l->pl.probe_size += TIPC_PL_MIN_STEP; + if (l->pl.probe_size >= l->pl.probe_high) { + l->pl.probe_high = 0; + l->pl.raise = 0; + l->pl.state = TIPC_PL_COMPLETE; /* Search -> Search Complete */ + + l->pl.probe_size = l->pl.pmtu; + l->mtu = l->pl.pmtu; + } + } else if (l->pl.state == TIPC_PL_COMPLETE) { + l->pl.raise++; + if (l->pl.raise == 30) { + l->pl.state = TIPC_PL_SEARCH; /* Search Complete -> Search */ + l->pl.probe_size += TIPC_PL_MIN_STEP; + } + } +} -- 2.27.0 _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion