aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Maurer <fmaurer@redhat.com>2025-11-11 17:29:33 +0100
committerPaolo Abeni <pabeni@redhat.com>2025-11-13 15:55:04 +0100
commitb2c26c82f7a94ec4da096f370e3612ee14424450 (patch)
treefd2415dc87c869a8bdb7f9fb9b87437167990c3c
parent96a3a03abf3d8cc38cd9cb0d280235fbcf7c3f7f (diff)
downloadlinux-b2c26c82f7a94ec4da096f370e3612ee14424450.tar.gz
hsr: Follow standard for HSRv0 supervision frames
For HSRv0, the path_id has the following meaning: - 0000: PRP supervision frame - 0001-1001: HSR ring identifier - 1010-1011: Frames from PRP network (A/B, with RedBoxes) - 1111: HSR supervision frame Follow the IEC 62439-3:2010 standard more closely by setting the right path_id for HSRv0 supervision frames (actually, it is correctly set when the frame is constructed, but hsr_set_path_id() overwrites it) and set a fixed HSR ring identifier of 1. The ring identifier seems to be generally unused and we ignore it anyways on reception, but some fixed identifier is definitely better than using one identifier in one direction and a wrong identifier in the other. This was also the behavior before commit f266a683a480 ("net/hsr: Better frame dispatch") which introduced the alternating path_id. This was later moved to hsr_set_path_id() in commit 451d8123f897 ("net: prp: add packet handling support"). The IEC 62439-3:2010 also contains 6 unused bytes after the MacAddressA in the HSRv0 supervision frames. Adjust a TODO comment accordingly. Fixes: f266a683a480 ("net/hsr: Better frame dispatch") Fixes: 451d8123f897 ("net: prp: add packet handling support") Signed-off-by: Felix Maurer <fmaurer@redhat.com> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/ea0d5133cd593856b2fa673d6e2067bf1d4d1794.1762876095.git.fmaurer@redhat.com Tested-by: Hangbin Liu <liuhangbin@gmail.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--net/hsr/hsr_device.c2
-rw-r--r--net/hsr/hsr_forward.c22
2 files changed, 16 insertions, 8 deletions
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 1235abb2d79fa8..492cbc78ab75a0 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -337,7 +337,7 @@ static void send_hsr_supervision_frame(struct hsr_port *port,
}
hsr_stag->tlv.HSR_TLV_type = type;
- /* TODO: Why 12 in HSRv0? */
+ /* HSRv0 has 6 unused bytes after the MAC */
hsr_stag->tlv.HSR_TLV_length = hsr->prot_version ?
sizeof(struct hsr_sup_payload) : 12;
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index c67c0d35921de0..339f0d22021294 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -262,15 +262,23 @@ static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
return skb;
}
-static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr,
+static void hsr_set_path_id(struct hsr_frame_info *frame,
+ struct hsr_ethhdr *hsr_ethhdr,
struct hsr_port *port)
{
int path_id;
- if (port->type == HSR_PT_SLAVE_A)
- path_id = 0;
- else
- path_id = 1;
+ if (port->hsr->prot_version) {
+ if (port->type == HSR_PT_SLAVE_A)
+ path_id = 0;
+ else
+ path_id = 1;
+ } else {
+ if (frame->is_supervision)
+ path_id = 0xf;
+ else
+ path_id = 1;
+ }
set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id);
}
@@ -304,7 +312,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
else
hsr_ethhdr = (struct hsr_ethhdr *)pc;
- hsr_set_path_id(hsr_ethhdr, port);
+ hsr_set_path_id(frame, hsr_ethhdr, port);
set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr);
hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
@@ -330,7 +338,7 @@ struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
(struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr);
/* set the lane id properly */
- hsr_set_path_id(hsr_ethhdr, port);
+ hsr_set_path_id(frame, hsr_ethhdr, port);
return skb_clone(frame->skb_hsr, GFP_ATOMIC);
} else if (port->dev->features & NETIF_F_HW_HSR_TAG_INS) {
return skb_clone(frame->skb_std, GFP_ATOMIC);