From ea843ba835cf14391185c4de6415181d9875c7b9 Mon Sep 17 00:00:00 2001 From: Joris Guisson Date: Tue, 21 Nov 2023 07:54:06 +0100 Subject: [PATCH] Fix invalid rogue peer delay request error When linuxptp goes from LISTENING to UNCALIBRATED, it will flush the the peer delay. This means that linuxptp forgets it sent a peer delay request. However, if there is an outstanding peer delay request at this point in time, the subsequent response will be considered rogue, and linuxptp will go into a faulty state. Which causes it to do nothing for a while. To fix this, we keep track of wether a flush_peer_delay has occurred. And if we receive a response after one, we don't consider it rogue but just ignore it. Signed-off-by: Joris Guisson --- port.c | 9 +++++++++ port_private.h | 1 + 2 files changed, 10 insertions(+) diff --git a/port.c b/port.c index 5803cd35..0bcb72e4 100644 --- a/port.c +++ b/port.c @@ -1843,6 +1843,7 @@ static void flush_peer_delay(struct port *p) if (p->peer_delay_req) { msg_put(p->peer_delay_req); p->peer_delay_req = NULL; + p->peer_delay_req_flushed = 1; } if (p->peer_delay_resp) { msg_put(p->peer_delay_resp); @@ -2478,9 +2479,17 @@ int process_pdelay_resp(struct port *p, struct ptp_message *m) } } if (!p->peer_delay_req) { + if (p->peer_delay_req_flushed) { + pr_notice("%s: peer delay response ignored because of previous flush", p->log_name); + p->peer_delay_req_flushed = 0; + return 0; + } pr_err("%s: rogue peer delay response", p->log_name); return -1; + } else { + p->peer_delay_req_flushed = 0; } + if (p->peer_portid_valid) { if (!pid_eq(&p->peer_portid, &m->header.sourcePortIdentity)) { pr_err("%s: received pdelay_resp msg with " diff --git a/port_private.h b/port_private.h index 3b02d2fe..47dacccb 100644 --- a/port_private.h +++ b/port_private.h @@ -82,6 +82,7 @@ struct port { struct ptp_message *last_syncfup; TAILQ_HEAD(delay_req, ptp_message) delay_req; struct ptp_message *peer_delay_req; + unsigned int peer_delay_req_flushed; struct ptp_message *peer_delay_resp; struct ptp_message *peer_delay_fup; int peer_portid_valid;