All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Juhee Kang <claudiajkang@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Kurt Kanzenbach <kurt@linutronix.de>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Subject: [PATCH net 5/5] hsr: Synchronize sequence number updates.
Date: Wed, 16 Nov 2022 17:59:43 +0100	[thread overview]
Message-ID: <20221116165943.1776754-6-bigeasy@linutronix.de> (raw)
In-Reply-To: <20221116165943.1776754-1-bigeasy@linutronix.de>

hsr_register_frame_out() compares new sequence_nr vs the old one
recorded in hsr_node::seq_out and if the new sequence_nr is higher then
it will be written to hsr_node::seq_out as the new value.

This operation isn't locked so it is possible that two frames with the
same sequence number arrive (via the two slave devices) and are fed to
hsr_register_frame_out() at the same time. Both will pass the check and
update the sequence counter later to the same value. As a result the
content of the same packet is fed into the stack twice.

This was noticed by running ping and observing DUP being reported from
time to time.

Instead of using the hsr_priv::seqnr_lock for the whole receive path (as
it is for sending in the master node) ensure that the id is only updated
based on the expected old value.

Use cmpxchg() to only update sequence number if it is the old value,
that was also used for comparison.

Fixes: f421436a591d3 ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 net/hsr/hsr_framereg.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index 9b8eaebce2549..7a9d4d36f114d 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -453,13 +453,19 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
 int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
 			   u16 sequence_nr)
 {
-	if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]) &&
+	u16 old_seq;
+again:
+	old_seq = READ_ONCE(node->seq_out[port->type]);
+
+	if (seq_nr_before_or_eq(sequence_nr, old_seq) &&
 	    time_is_after_jiffies(node->time_out[port->type] +
 	    msecs_to_jiffies(HSR_ENTRY_FORGET_TIME)))
 		return 1;
 
+	if (cmpxchg(&node->seq_out[port->type], old_seq, sequence_nr) != old_seq)
+		goto again;
+
 	node->time_out[port->type] = jiffies;
-	node->seq_out[port->type] = sequence_nr;
 	return 0;
 }
 
-- 
2.38.1


  parent reply	other threads:[~2022-11-16 17:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-16 16:59 [PATCH net 0/5] hsr: HSR send/recv fixes Sebastian Andrzej Siewior
2022-11-16 16:59 ` [PATCH net 1/5] Revert "net: hsr: use hlist_head instead of list_head for mac addresses" Sebastian Andrzej Siewior
2022-11-16 16:59 ` [PATCH net 2/5] hsr: Add a rcu-read lock to hsr_forward_skb() Sebastian Andrzej Siewior
2022-11-16 16:59 ` [PATCH net 3/5] hsr: Disable netpoll Sebastian Andrzej Siewior
2022-11-16 16:59 ` [PATCH net 4/5] hsr: Synchronize sending frames to have always incremented outgoing seq nr Sebastian Andrzej Siewior
2022-11-16 16:59 ` Sebastian Andrzej Siewior [this message]
2022-11-17 16:47   ` [PATCH net 5/5] hsr: Synchronize sequence number updates kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221116165943.1776754-6-bigeasy@linutronix.de \
    --to=bigeasy@linutronix.de \
    --cc=claudiajkang@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=kurt@linutronix.de \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.