| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/06 19:57 | flow | patch-triage |
3mArgs:null Results: {
"EnableConfigs": [
"HSR"
],
"FocusSymbols": [
"send_prp_supervision_frame",
"hsr_handle_sup_frame",
"hsr_newlink",
"prp_drop_frame",
"prp_register_frame_out"
],
"Reasoning": "The patch adds support for PRP RedBox (PRP-SAN) in the HSR/PRP subsystem. It modifies supervision frame generation, frame forwarding logic (dropping and registering), and node sequence handling to support the new feature. It also removes the restriction that interlink only works with HSR in netlink setup. This is a functional change to the network stack that should be fuzzed.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/06 19:57 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 3eb9967cf101085283f9b383f982e84ed19c5a83\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jul 6 19:57:35 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c\nindex 5555b71ab19b59..0973f9a94f4d48 100644\n--- a/net/hsr/hsr_device.c\n+++ b/net/hsr/hsr_device.c\n@@ -372,10 +372,21 @@ static void send_prp_supervision_frame(struct hsr_port *master,\n {\n \tstruct hsr_priv *hsr = master-\u003ehsr;\n \tstruct hsr_sup_payload *hsr_sp;\n+\tstruct hsr_sup_tlv *hsr_stlv;\n \tstruct hsr_sup_tag *hsr_stag;\n \tstruct sk_buff *skb;\n+\tbool redbox_proxy;\n+\tint extra = 0;\n \n-\tskb = hsr_init_skb(master, 0);\n+\tredbox_proxy = hsr-\u003eredbox \u0026\u0026 master-\u003etype == HSR_PT_INTERLINK;\n+\n+\t/* A proxy-announce carries a RedBox-MAC TLV and an EOT marker. */\n+\tif (redbox_proxy)\n+\t\textra = sizeof(struct hsr_sup_tlv) +\n+\t\t\tsizeof(struct hsr_sup_payload) +\n+\t\t\tsizeof(struct hsr_sup_tlv);\n+\n+\tskb = hsr_init_skb(master, extra);\n \tif (!skb) {\n \t\tnetdev_warn_once(master-\u003edev, \"PRP: Could not send supervision frame\\n\");\n \t\treturn;\n@@ -393,9 +404,25 @@ static void send_prp_supervision_frame(struct hsr_port *master,\n \thsr_stag-\u003etlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;\n \thsr_stag-\u003etlv.HSR_TLV_length = sizeof(struct hsr_sup_payload);\n \n-\t/* Payload: MacAddressA */\n+\t/* Payload: MacAddressA, the announced node. */\n \thsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));\n-\tether_addr_copy(hsr_sp-\u003emacaddress_A, master-\u003edev-\u003edev_addr);\n+\tether_addr_copy(hsr_sp-\u003emacaddress_A, addr);\n+\n+\t/* Proxy-announce: append the RedBox-MAC TLV (Type 30) and an explicit\n+\t * EOT to terminate the TLV chain before zero padding.\n+\t */\n+\tif (redbox_proxy) {\n+\t\thsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));\n+\t\thsr_stlv-\u003eHSR_TLV_type = PRP_TLV_REDBOX_MAC;\n+\t\thsr_stlv-\u003eHSR_TLV_length = sizeof(struct hsr_sup_payload);\n+\n+\t\thsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));\n+\t\tether_addr_copy(hsr_sp-\u003emacaddress_A, hsr-\u003emacaddress_redbox);\n+\n+\t\thsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));\n+\t\thsr_stlv-\u003eHSR_TLV_type = HSR_TLV_EOT;\n+\t\thsr_stlv-\u003eHSR_TLV_length = 0;\n+\t}\n \n \tif (skb_put_padto(skb, ETH_ZLEN)) {\n \t\tspin_unlock_bh(\u0026hsr-\u003eseqnr_lock);\n@@ -768,6 +795,15 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],\n \t/* Make sure the 1st call to netif_carrier_on() gets through */\n \tnetif_carrier_off(hsr_dev);\n \n+\t/* Publish the RedBox state before any port is attached: the rx\n+\t * handlers are live from hsr_add_port() on, and hsr_add_node()\n+\t * sizes each node's per-port sequence state from hsr-\u003eredbox.\n+\t */\n+\tif (interlink) {\n+\t\thsr-\u003eredbox = true;\n+\t\tether_addr_copy(hsr-\u003emacaddress_redbox, interlink-\u003edev_addr);\n+\t}\n+\n \tres = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER, extack);\n \tif (res)\n \t\tgoto err_add_master;\n@@ -805,8 +841,6 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],\n \t\tif (res)\n \t\t\tgoto err_unregister;\n \n-\t\thsr-\u003eredbox = true;\n-\t\tether_addr_copy(hsr-\u003emacaddress_redbox, interlink-\u003edev_addr);\n \t\tmod_timer(\u0026hsr-\u003eprune_proxy_timer,\n \t\t\t jiffies + msecs_to_jiffies(PRUNE_PROXY_PERIOD));\n \t}\ndiff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c\nindex 0774981a65c164..efcd0acef38c8b 100644\n--- a/net/hsr/hsr_forward.c\n+++ b/net/hsr/hsr_forward.c\n@@ -440,12 +440,37 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,\n \treturn dev_queue_xmit(skb);\n }\n \n+static bool prp_is_lan_dup(struct hsr_frame_info *frame,\n+\t\t\t struct hsr_port *port)\n+{\n+\tenum hsr_port_type rx = frame-\u003eport_rcv-\u003etype;\n+\n+\treturn (rx == HSR_PT_SLAVE_A \u0026\u0026 port-\u003etype == HSR_PT_SLAVE_B) ||\n+\t (rx == HSR_PT_SLAVE_B \u0026\u0026 port-\u003etype == HSR_PT_SLAVE_A);\n+}\n+\n bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\n {\n-\treturn ((frame-\u003eport_rcv-\u003etype == HSR_PT_SLAVE_A \u0026\u0026\n-\t\t port-\u003etype == HSR_PT_SLAVE_B) ||\n-\t\t(frame-\u003eport_rcv-\u003etype == HSR_PT_SLAVE_B \u0026\u0026\n-\t\t port-\u003etype == HSR_PT_SLAVE_A));\n+\tenum hsr_port_type rx = frame-\u003eport_rcv-\u003etype;\n+\n+\t/* Supervision frames are not delivered to a SAN on the interlink. */\n+\tif (frame-\u003eis_supervision \u0026\u0026 port-\u003etype == HSR_PT_INTERLINK)\n+\t\treturn true;\n+\n+\tif (prp_is_lan_dup(frame, port))\n+\t\treturn true;\n+\n+\t/* LAN to interlink: keep PRP-network unicast off the SAN segment. */\n+\tif ((rx == HSR_PT_SLAVE_A || rx == HSR_PT_SLAVE_B) \u0026\u0026\n+\t port-\u003etype == HSR_PT_INTERLINK)\n+\t\treturn frame-\u003edst_in_node_db;\n+\n+\t/* Interlink to LAN: keep SAN-to-SAN unicast local. */\n+\tif ((port-\u003etype == HSR_PT_SLAVE_A || port-\u003etype == HSR_PT_SLAVE_B) \u0026\u0026\n+\t rx == HSR_PT_INTERLINK)\n+\t\treturn frame-\u003edst_in_proxy_node_db;\n+\n+\treturn false;\n }\n \n bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\n@@ -453,7 +478,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\n \tstruct sk_buff *skb;\n \n \tif (port-\u003edev-\u003efeatures \u0026 NETIF_F_HW_HSR_FWD)\n-\t\treturn prp_drop_frame(frame, port);\n+\t\treturn prp_is_lan_dup(frame, port);\n \n \t/* RedBox specific frames dropping policies\n \t *\n@@ -466,7 +491,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\n \t * are addressed to interlink port (and are in the ProxyNodeTable).\n \t */\n \tskb = frame-\u003eskb_hsr;\n-\tif (skb \u0026\u0026 prp_drop_frame(frame, port) \u0026\u0026\n+\tif (skb \u0026\u0026 prp_is_lan_dup(frame, port) \u0026\u0026\n \t is_unicast_ether_addr(eth_hdr(skb)-\u003eh_dest) \u0026\u0026\n \t hsr_is_node_in_db(\u0026port-\u003ehsr-\u003eproxy_node_db,\n \t\t\t eth_hdr(skb)-\u003eh_dest)) {\n@@ -706,6 +731,18 @@ static int fill_frame_info(struct hsr_frame_info *frame,\n \tframe-\u003eis_vlan = false;\n \tproto = ethhdr-\u003eh_proto;\n \n+\t/* PRP RedBox only: classify the unicast destination once so the\n+\t * per-egress-port decision in prp_drop_frame() stays O(1). HSR RedBox\n+\t * does its own classification and must not pay these node-table walks.\n+\t */\n+\tif (hsr-\u003eprot_version == PRP_V1 \u0026\u0026 hsr-\u003eredbox \u0026\u0026\n+\t is_unicast_ether_addr(ethhdr-\u003eh_dest)) {\n+\t\tframe-\u003edst_in_node_db =\n+\t\t\thsr_is_node_in_db(\u0026hsr-\u003enode_db, ethhdr-\u003eh_dest);\n+\t\tframe-\u003edst_in_proxy_node_db =\n+\t\t\thsr_is_node_in_db(\u0026hsr-\u003eproxy_node_db, ethhdr-\u003eh_dest);\n+\t}\n+\n \tif (proto == htons(ETH_P_8021Q))\n \t\tframe-\u003eis_vlan = true;\n \ndiff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c\nindex e4492987127445..b3b106be692eaf 100644\n--- a/net/hsr/hsr_framereg.c\n+++ b/net/hsr/hsr_framereg.c\n@@ -199,7 +199,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,\n \tspin_lock_init(\u0026new_node-\u003eseq_out_lock);\n \n \tif (hsr-\u003eprot_version == PRP_V1)\n-\t\tnew_node-\u003eseq_port_cnt = 1;\n+\t\tnew_node-\u003eseq_port_cnt = hsr-\u003eredbox ? 2 : 1;\n \telse\n \t\tnew_node-\u003eseq_port_cnt = HSR_PT_PORTS - 1;\n \n@@ -293,8 +293,17 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,\n \t */\n \tif (ethhdr-\u003eh_proto == htons(ETH_P_PRP) ||\n \t ethhdr-\u003eh_proto == htons(ETH_P_HSR)) {\n-\t\t/* Check if skb contains hsr_ethhdr */\n-\t\tif (skb-\u003emac_len \u003c sizeof(struct hsr_ethhdr))\n+\t\tbool prp_sup;\n+\n+\t\t/* A PRP supervision frame is an untagged ETH_P_PRP frame\n+\t\t * (mac_len == ETH_HLEN); its RCT is appended only on egress.\n+\t\t * HSR (ETH_P_HSR) supervision is front-tagged and still must\n+\t\t * contain a struct hsr_ethhdr.\n+\t\t */\n+\t\tprp_sup = hsr-\u003eprot_version == PRP_V1 \u0026\u0026\n+\t\t\t ethhdr-\u003eh_proto == htons(ETH_P_PRP) \u0026\u0026 is_sup;\n+\n+\t\tif (!prp_sup \u0026\u0026 skb-\u003emac_len \u003c sizeof(struct hsr_ethhdr))\n \t\t\treturn NULL;\n \t} else {\n \t\trct = skb_get_PRP_rct(skb);\n@@ -381,6 +390,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)\n \tstruct ethhdr *ethhdr;\n \tunsigned int total_pull_size = 0;\n \tunsigned int pull_size = 0;\n+\tunsigned int seq_port_cnt;\n \tunsigned long idx;\n \tint i;\n \n@@ -474,6 +484,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)\n \t\t}\n \t}\n \n+\tseq_port_cnt = min(node_real-\u003eseq_port_cnt, node_curr-\u003eseq_port_cnt);\n \txa_for_each(\u0026node_curr-\u003eseq_blocks, idx, src_blk) {\n \t\tif (hsr_seq_block_is_old(src_blk))\n \t\t\tcontinue;\n@@ -482,7 +493,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)\n \t\tif (!merge_blk)\n \t\t\tcontinue;\n \t\tmerge_blk-\u003etime = min(merge_blk-\u003etime, src_blk-\u003etime);\n-\t\tfor (i = 0; i \u003c node_real-\u003eseq_port_cnt; i++) {\n+\t\tfor (i = 0; i \u003c seq_port_cnt; i++) {\n \t\t\tbitmap_or(merge_blk-\u003eseq_nrs[i], merge_blk-\u003eseq_nrs[i],\n \t\t\t\t src_blk-\u003eseq_nrs[i], HSR_SEQ_BLOCK_SIZE);\n \t\t}\n@@ -649,9 +660,13 @@ int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame)\n \tif (frame-\u003eport_rcv-\u003etype == HSR_PT_MASTER)\n \t\treturn 0;\n \n-\t/* for PRP we should only forward frames from the slave ports\n-\t * to the master port\n+\t/* RedBox: forward LAN frames out the interlink to a SAN, deduping the\n+\t * two LAN copies on a dedicated slot.\n \t */\n+\tif (port-\u003etype == HSR_PT_INTERLINK)\n+\t\treturn hsr_check_duplicate(frame, 1);\n+\n+\t/* For PRP only slave-to-master frames are forwarded. */\n \tif (port-\u003etype != HSR_PT_MASTER)\n \t\treturn 1;\n \ndiff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h\nindex c65ecb92573489..127a3fb64d5f03 100644\n--- a/net/hsr/hsr_framereg.h\n+++ b/net/hsr/hsr_framereg.h\n@@ -27,6 +27,8 @@ struct hsr_frame_info {\n \tbool is_local_dest;\n \tbool is_local_exclusive;\n \tbool is_from_san;\n+\tbool dst_in_node_db;\n+\tbool dst_in_proxy_node_db;\n };\n \n void hsr_del_self_node(struct hsr_priv *hsr);\ndiff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h\nindex 134e4f3fff6036..c27cfdd9ca3fa8 100644\n--- a/net/hsr/hsr_main.h\n+++ b/net/hsr/hsr_main.h\n@@ -211,7 +211,7 @@ struct hsr_priv {\n \t\t\t\t */\n \tbool fwd_offloaded;\t/* Forwarding offloaded to HW */\n \tbool redbox; /* Device supports HSR RedBox */\n-\tunsigned char\t\tmacaddress_redbox[ETH_ALEN];\n+\tunsigned char\tmacaddress_redbox[ETH_ALEN] __aligned(sizeof(u16));\n \tunsigned char\t\tsup_multicast_addr[ETH_ALEN] __aligned(sizeof(u16));\n \t\t\t\t/* Align to u16 boundary to avoid unaligned access\n \t\t\t\t * in ether_addr_equal\ndiff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c\nindex 8099f2069a748e..88940e8014b24f 100644\n--- a/net/hsr/hsr_netlink.c\n+++ b/net/hsr/hsr_netlink.c\n@@ -121,14 +121,8 @@ static int hsr_newlink(struct net_device *dev,\n \t\t}\n \t}\n \n-\tif (proto == HSR_PROTOCOL_PRP) {\n+\tif (proto == HSR_PROTOCOL_PRP)\n \t\tproto_version = PRP_V1;\n-\t\tif (interlink) {\n-\t\t\tNL_SET_ERR_MSG_MOD(extack,\n-\t\t\t\t\t \"Interlink only works with HSR\");\n-\t\t\treturn -EINVAL;\n-\t\t}\n-\t}\n \n \treturn hsr_dev_finalize(dev, link, interlink, multicast_spec,\n \t\t\t\tproto_version, extack);\ndiff --git a/tools/testing/selftests/net/hsr/Makefile b/tools/testing/selftests/net/hsr/Makefile\nindex 31fb9326cf533d..2150e487ac7d7f 100644\n--- a/tools/testing/selftests/net/hsr/Makefile\n+++ b/tools/testing/selftests/net/hsr/Makefile\n@@ -4,6 +4,7 @@ top_srcdir = ../../../../..\n \n TEST_PROGS := \\\n \thsr_ping.sh \\\n+\thsr_prp_redbox.sh \\\n \thsr_redbox.sh \\\n \tlink_faults.sh \\\n \tprp_ping.sh \\\ndiff --git a/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh b/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh\nnew file mode 100755\nindex 00000000000000..479c892225b1f3\n--- /dev/null\n+++ b/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh\n@@ -0,0 +1,99 @@\n+#!/bin/bash\n+# SPDX-License-Identifier: GPL-2.0\n+#\n+# Test a PRP RedBox (PRP-SAN): a SAN that sits behind the interlink port must\n+# reach, and be reached by, a peer DANP on the PRP network with its own MAC\n+# preserved on the wire, and the RedBox must announce the SAN with a RedBox-MAC\n+# TLV (terminated by an EOT marker) in its PRP supervision frames.\n+#\n+# RB PRP RedBox: prp0 over rb_a/rb_b (LAN A/B) + interlink rb_il\n+# PEER peer DANP : prp0 over pe_a/pe_b, 100.64.0.2\n+# SAN SAN : san_il, own MAC, 100.64.0.51 (behind the interlink)\n+\n+ipv6=false\n+\n+source ./hsr_common.sh\n+\n+check_prerequisites\n+\n+if ! command -v tcpdump \u003e/dev/null 2\u003e\u00261; then\n+\techo \"SKIP: This test requires tcpdump\"\n+\texit $ksft_skip\n+fi\n+\n+if ! ip link help hsr 2\u003e\u00261 | grep -q interlink; then\n+\techo \"SKIP: iproute2 too old (no hsr interlink support)\"\n+\texit $ksft_skip\n+fi\n+\n+setup_ns RB PEER SAN\n+trap 'cleanup_ns \"$RB\" \"$PEER\" \"$SAN\"' EXIT\n+\n+ip link add rb_a netns \"$RB\" type veth peer name pe_a netns \"$PEER\"\n+ip link add rb_b netns \"$RB\" type veth peer name pe_b netns \"$PEER\"\n+ip link add rb_il netns \"$RB\" type veth peer name san_il netns \"$SAN\"\n+\n+ip -n \"$RB\" link set rb_a up\n+ip -n \"$RB\" link set rb_b up\n+ip -n \"$RB\" link set rb_il up\n+ip -n \"$PEER\" link set pe_a up\n+ip -n \"$PEER\" link set pe_b up\n+ip -n \"$SAN\" link set san_il up\n+ip -n \"$SAN\" addr add 100.64.0.51/24 dev san_il\n+\n+# Feature gate: PRP interlink (RedBox) creation. A kernel without PRP RedBox\n+# support rejects this with -EINVAL, so SKIP rather than FAIL.\n+if ! ip -n \"$RB\" link add name prp0 type hsr slave1 rb_a slave2 rb_b \\\n+ interlink rb_il proto 1 2\u003e/dev/null; then\n+\techo \"SKIP: kernel without PRP RedBox (interlink) support\"\n+\texit $ksft_skip\n+fi\n+ip -n \"$RB\" link set prp0 up\n+ip -n \"$PEER\" link add name prp0 type hsr slave1 pe_a slave2 pe_b proto 1\n+ip -n \"$PEER\" link set prp0 up\n+ip -n \"$PEER\" addr add 100.64.0.2/24 dev prp0\n+sleep 1\n+\n+san_mac=$(ip -n \"$SAN\" -br link show san_il | awk '{print $3}')\n+rb_mac=$(ip -n \"$RB\" -br link show rb_il | awk '{print $3}')\n+\n+# Bidirectional unicast across the interlink.\n+do_ping \"$PEER\" 100.64.0.51\n+do_ping \"$SAN\" 100.64.0.2\n+stop_if_error \"PRP RedBox bidirectional unicast failed\"\n+\n+# The SAN source MAC must be preserved on the PRP network, not laundered to the\n+# RedBox MAC: the peer resolves the SAN IP to the SAN's own MAC.\n+neigh=$(ip -n \"$PEER\" neigh show 100.64.0.51 | awk '{print $5}')\n+if [ \"$neigh\" != \"$san_mac\" ]; then\n+\techo \"SAN MAC preservation [ FAIL ]: peer resolved 100.64.0.51 to\" \\\n+\t \"'$neigh', expected $san_mac\" 1\u003e\u00262\n+\tret=1\n+fi\n+stop_if_error \"SAN MAC not preserved on the PRP network\"\n+\n+# The proxy-announce supervision frame must carry, in order, the life-check TLV\n+# (type 0x14, len 6) + MacAddressA == SAN MAC + the RedBox-MAC TLV (type 0x1e,\n+# len 6) + MacAddressRedBox == RedBox MAC + the EOT marker (0x0000).\n+ip netns exec \"$SAN\" ping -i 0.2 -q 100.64.0.2 \u003e/dev/null 2\u003e\u00261 \u0026\n+ping_pid=$!\n+cap=$(ip netns exec \"$PEER\" timeout 5 tcpdump -i pe_a -nn -x \\\n+\t\"ether proto 0x88fb and ether src $rb_mac\" 2\u003e/dev/null || true)\n+kill \"$ping_pid\" 2\u003e/dev/null || true\n+wait \"$ping_pid\" 2\u003e/dev/null || true\n+\n+san_hex=$(echo \"$san_mac\" | tr -d ':')\n+rb_hex=$(echo \"$rb_mac\" | tr -d ':')\n+# Reassemble contiguous frame hex: drop the \"0x0010:\" offset labels and spaces.\n+frame_hex=$(echo \"$cap\" | awk '/^[[:space:]]*0x[0-9a-f]+:/ {\n+\tsub(/^[[:space:]]*0x[0-9a-f]+:[[:space:]]*/, \"\");\n+\tgsub(/ /, \"\"); printf \"%s\", $0 }')\n+if ! echo \"$frame_hex\" | grep -q \"1406${san_hex}1e06${rb_hex}0000\"; then\n+\techo \"supervision RedBox-MAC TLV [ FAIL ]: missing SAN MAC, Type-30\" \\\n+\t \"payload, or EOT\" 1\u003e\u00262\n+\tret=1\n+fi\n+stop_if_error \"PRP RedBox supervision RedBox-MAC TLV/EOT check failed\"\n+\n+echo \"INFO: PRP RedBox (PRP-SAN) conformance checks passed\"\n+exit $ret\n"
} |
| 2/1 | 2026/07/06 19:57 | agent | patch-evaluator |
3mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"HSR"
],
"FocusSymbols": [
"send_prp_supervision_frame",
"hsr_handle_sup_frame",
"hsr_newlink",
"prp_drop_frame",
"prp_register_frame_out"
],
"Reasoning": "The patch adds support for PRP RedBox (PRP-SAN) in the HSR/PRP subsystem. It modifies supervision frame generation, frame forwarding logic (dropping and registering), and node sequence handling to support the new feature. It also removes the restriction that interlink only works with HSR in netlink setup. This is a functional change to the network stack that should be fuzzed.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 3eb9967cf101085283f9b383f982e84ed19c5a83
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jul 6 19:57:35 2026 +0000
syz-cluster: applied patch under review
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
index 5555b71ab19b59..0973f9a94f4d48 100644
--- a/net/hsr/hsr_device.c
+++ b/net/hsr/hsr_device.c
@@ -372,10 +372,21 @@ static void send_prp_supervision_frame(struct hsr_port *master,
{
struct hsr_priv *hsr = master->hsr;
struct hsr_sup_payload *hsr_sp;
+ struct hsr_sup_tlv *hsr_stlv;
struct hsr_sup_tag *hsr_stag;
struct sk_buff *skb;
+ bool redbox_proxy;
+ int extra = 0;
- skb = hsr_init_skb(master, 0);
+ redbox_proxy = hsr->redbox && master->type == HSR_PT_INTERLINK;
+
+ /* A proxy-announce carries a RedBox-MAC TLV and an EOT marker. */
+ if (redbox_proxy)
+ extra = sizeof(struct hsr_sup_tlv) +
+ sizeof(struct hsr_sup_payload) +
+ sizeof(struct hsr_sup_tlv);
+
+ skb = hsr_init_skb(master, extra);
if (!skb) {
netdev_warn_once(master->dev, "PRP: Could not send supervision frame\n");
return;
@@ -393,9 +404,25 @@ static void send_prp_supervision_frame(struct hsr_port *master,
hsr_stag->tlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
hsr_stag->tlv.HSR_TLV_length = sizeof(struct hsr_sup_payload);
- /* Payload: MacAddressA */
+ /* Payload: MacAddressA, the announced node. */
hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
- ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+ ether_addr_copy(hsr_sp->macaddress_A, addr);
+
+ /* Proxy-announce: append the RedBox-MAC TLV (Type 30) and an explicit
+ * EOT to terminate the TLV chain before zero padding.
+ */
+ if (redbox_proxy) {
+ hsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));
+ hsr_stlv->HSR_TLV_type = PRP_TLV_REDBOX_MAC;
+ hsr_stlv->HSR_TLV_length = sizeof(struct hsr_sup_payload);
+
+ hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+ ether_addr_copy(hsr_sp->macaddress_A, hsr->macaddress_redbox);
+
+ hsr_stlv = skb_put(skb, sizeof(struct hsr_sup_tlv));
+ hsr_stlv->HSR_TLV_type = HSR_TLV_EOT;
+ hsr_stlv->HSR_TLV_length = 0;
+ }
if (skb_put_padto(skb, ETH_ZLEN)) {
spin_unlock_bh(&hsr->seqnr_lock);
@@ -768,6 +795,15 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
/* Make sure the 1st call to netif_carrier_on() gets through */
netif_carrier_off(hsr_dev);
+ /* Publish the RedBox state before any port is attached: the rx
+ * handlers are live from hsr_add_port() on, and hsr_add_node()
+ * sizes each node's per-port sequence state from hsr->redbox.
+ */
+ if (interlink) {
+ hsr->redbox = true;
+ ether_addr_copy(hsr->macaddress_redbox, interlink->dev_addr);
+ }
+
res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER, extack);
if (res)
goto err_add_master;
@@ -805,8 +841,6 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
if (res)
goto err_unregister;
- hsr->redbox = true;
- ether_addr_copy(hsr->macaddress_redbox, interlink->dev_addr);
mod_timer(&hsr->prune_proxy_timer,
jiffies + msecs_to_jiffies(PRUNE_PROXY_PERIOD));
}
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index 0774981a65c164..efcd0acef38c8b 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -440,12 +440,37 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,
return dev_queue_xmit(skb);
}
+static bool prp_is_lan_dup(struct hsr_frame_info *frame,
+ struct hsr_port *port)
+{
+ enum hsr_port_type rx = frame->port_rcv->type;
+
+ return (rx == HSR_PT_SLAVE_A && port->type == HSR_PT_SLAVE_B) ||
+ (rx == HSR_PT_SLAVE_B && port->type == HSR_PT_SLAVE_A);
+}
+
bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
{
- return ((frame->port_rcv->type == HSR_PT_SLAVE_A &&
- port->type == HSR_PT_SLAVE_B) ||
- (frame->port_rcv->type == HSR_PT_SLAVE_B &&
- port->type == HSR_PT_SLAVE_A));
+ enum hsr_port_type rx = frame->port_rcv->type;
+
+ /* Supervision frames are not delivered to a SAN on the interlink. */
+ if (frame->is_supervision && port->type == HSR_PT_INTERLINK)
+ return true;
+
+ if (prp_is_lan_dup(frame, port))
+ return true;
+
+ /* LAN to interlink: keep PRP-network unicast off the SAN segment. */
+ if ((rx == HSR_PT_SLAVE_A || rx == HSR_PT_SLAVE_B) &&
+ port->type == HSR_PT_INTERLINK)
+ return frame->dst_in_node_db;
+
+ /* Interlink to LAN: keep SAN-to-SAN unicast local. */
+ if ((port->type == HSR_PT_SLAVE_A || port->type == HSR_PT_SLAVE_B) &&
+ rx == HSR_PT_INTERLINK)
+ return frame->dst_in_proxy_node_db;
+
+ return false;
}
bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
@@ -453,7 +478,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
struct sk_buff *skb;
if (port->dev->features & NETIF_F_HW_HSR_FWD)
- return prp_drop_frame(frame, port);
+ return prp_is_lan_dup(frame, port);
/* RedBox specific frames dropping policies
*
@@ -466,7 +491,7 @@ bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)
* are addressed to interlink port (and are in the ProxyNodeTable).
*/
skb = frame->skb_hsr;
- if (skb && prp_drop_frame(frame, port) &&
+ if (skb && prp_is_lan_dup(frame, port) &&
is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
hsr_is_node_in_db(&port->hsr->proxy_node_db,
eth_hdr(skb)->h_dest)) {
@@ -706,6 +731,18 @@ static int fill_frame_info(struct hsr_frame_info *frame,
frame->is_vlan = false;
proto = ethhdr->h_proto;
+ /* PRP RedBox only: classify the unicast destination once so the
+ * per-egress-port decision in prp_drop_frame() stays O(1). HSR RedBox
+ * does its own classification and must not pay these node-table walks.
+ */
+ if (hsr->prot_version == PRP_V1 && hsr->redbox &&
+ is_unicast_ether_addr(ethhdr->h_dest)) {
+ frame->dst_in_node_db =
+ hsr_is_node_in_db(&hsr->node_db, ethhdr->h_dest);
+ frame->dst_in_proxy_node_db =
+ hsr_is_node_in_db(&hsr->proxy_node_db, ethhdr->h_dest);
+ }
+
if (proto == htons(ETH_P_8021Q))
frame->is_vlan = true;
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index e4492987127445..b3b106be692eaf 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -199,7 +199,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
spin_lock_init(&new_node->seq_out_lock);
if (hsr->prot_version == PRP_V1)
- new_node->seq_port_cnt = 1;
+ new_node->seq_port_cnt = hsr->redbox ? 2 : 1;
else
new_node->seq_port_cnt = HSR_PT_PORTS - 1;
@@ -293,8 +293,17 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
*/
if (ethhdr->h_proto == htons(ETH_P_PRP) ||
ethhdr->h_proto == htons(ETH_P_HSR)) {
- /* Check if skb contains hsr_ethhdr */
- if (skb->mac_len < sizeof(struct hsr_ethhdr))
+ bool prp_sup;
+
+ /* A PRP supervision frame is an untagged ETH_P_PRP frame
+ * (mac_len == ETH_HLEN); its RCT is appended only on egress.
+ * HSR (ETH_P_HSR) supervision is front-tagged and still must
+ * contain a struct hsr_ethhdr.
+ */
+ prp_sup = hsr->prot_version == PRP_V1 &&
+ ethhdr->h_proto == htons(ETH_P_PRP) && is_sup;
+
+ if (!prp_sup && skb->mac_len < sizeof(struct hsr_ethhdr))
return NULL;
} else {
rct = skb_get_PRP_rct(skb);
@@ -381,6 +390,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
struct ethhdr *ethhdr;
unsigned int total_pull_size = 0;
unsigned int pull_size = 0;
+ unsigned int seq_port_cnt;
unsigned long idx;
int i;
@@ -474,6 +484,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
}
}
+ seq_port_cnt = min(node_real->seq_port_cnt, node_curr->seq_port_cnt);
xa_for_each(&node_curr->seq_blocks, idx, src_blk) {
if (hsr_seq_block_is_old(src_blk))
continue;
@@ -482,7 +493,7 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
if (!merge_blk)
continue;
merge_blk->time = min(merge_blk->time, src_blk->time);
- for (i = 0; i < node_real->seq_port_cnt; i++) {
+ for (i = 0; i < seq_port_cnt; i++) {
bitmap_or(merge_blk->seq_nrs[i], merge_blk->seq_nrs[i],
src_blk->seq_nrs[i], HSR_SEQ_BLOCK_SIZE);
}
@@ -649,9 +660,13 @@ int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame)
if (frame->port_rcv->type == HSR_PT_MASTER)
return 0;
- /* for PRP we should only forward frames from the slave ports
- * to the master port
+ /* RedBox: forward LAN frames out the interlink to a SAN, deduping the
+ * two LAN copies on a dedicated slot.
*/
+ if (port->type == HSR_PT_INTERLINK)
+ return hsr_check_duplicate(frame, 1);
+
+ /* For PRP only slave-to-master frames are forwarded. */
if (port->type != HSR_PT_MASTER)
return 1;
diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
index c65ecb92573489..127a3fb64d5f03 100644
--- a/net/hsr/hsr_framereg.h
+++ b/net/hsr/hsr_framereg.h
@@ -27,6 +27,8 @@ struct hsr_frame_info {
bool is_local_dest;
bool is_local_exclusive;
bool is_from_san;
+ bool dst_in_node_db;
+ bool dst_in_proxy_node_db;
};
void hsr_del_self_node(struct hsr_priv *hsr);
diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
index 134e4f3fff6036..c27cfdd9ca3fa8 100644
--- a/net/hsr/hsr_main.h
+++ b/net/hsr/hsr_main.h
@@ -211,7 +211,7 @@ struct hsr_priv {
*/
bool fwd_offloaded; /* Forwarding offloaded to HW */
bool redbox; /* Device supports HSR RedBox */
- unsigned char macaddress_redbox[ETH_ALEN];
+ unsigned char macaddress_redbox[ETH_ALEN] __aligned(sizeof(u16));
unsigned char sup_multicast_addr[ETH_ALEN] __aligned(sizeof(u16));
/* Align to u16 boundary to avoid unaligned access
* in ether_addr_equal
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 8099f2069a748e..88940e8014b24f 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -121,14 +121,8 @@ static int hsr_newlink(struct net_device *dev,
}
}
- if (proto == HSR_PROTOCOL_PRP) {
+ if (proto == HSR_PROTOCOL_PRP)
proto_version = PRP_V1;
- if (interlink) {
- NL_SET_ERR_MSG_MOD(extack,
- "Interlink only works with HSR");
- return -EINVAL;
- }
- }
return hsr_dev_finalize(dev, link, interlink, multicast_spec,
proto_version, extack);
diff --git a/tools/testing/selftests/net/hsr/Makefile b/tools/testing/selftests/net/hsr/Makefile
index 31fb9326cf533d..2150e487ac7d7f 100644
--- a/tools/testing/selftests/net/hsr/Makefile
+++ b/tools/testing/selftests/net/hsr/Makefile
@@ -4,6 +4,7 @@ top_srcdir = ../../../../..
TEST_PROGS := \
hsr_ping.sh \
+ hsr_prp_redbox.sh \
hsr_redbox.sh \
link_faults.sh \
prp_ping.sh \
diff --git a/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh b/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh
new file mode 100755
index 00000000000000..479c892225b1f3
--- /dev/null
+++ b/tools/testing/selftests/net/hsr/hsr_prp_redbox.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test a PRP RedBox (PRP-SAN): a SAN that sits behind the interlink port must
+# reach, and be reached by, a peer DANP on the PRP network with its own MAC
+# preserved on the wire, and the RedBox must announce the SAN with a RedBox-MAC
+# TLV (terminated by an EOT marker) in its PRP supervision frames.
+#
+# RB PRP RedBox: prp0 over rb_a/rb_b (LAN A/B) + interlink rb_il
+# PEER peer DANP : prp0 over pe_a/pe_b, 100.64.0.2
+# SAN SAN : san_il, own MAC, 100.64.0.51 (behind the interlink)
+
+ipv6=false
+
+source ./hsr_common.sh
+
+check_prerequisites
+
+if ! command -v tcpdump >/dev/null 2>&1; then
+ echo "SKIP: This test requires tcpdump"
+ exit $ksft_skip
+fi
+
+if ! ip link help hsr 2>&1 | grep -q interlink; then
+ echo "SKIP: iproute2 too old (no hsr interlink support)"
+ exit $ksft_skip
+fi
+
+setup_ns RB PEER SAN
+trap 'cleanup_ns "$RB" "$PEER" "$SAN"' EXIT
+
+ip link add rb_a netns "$RB" type veth peer name pe_a netns "$PEER"
+ip link add rb_b netns "$RB" type veth peer name pe_b netns "$PEER"
+ip link add rb_il netns "$RB" type veth peer name san_il netns "$SAN"
+
+ip -n "$RB" link set rb_a up
+ip -n "$RB" link set rb_b up
+ip -n "$RB" link set rb_il up
+ip -n "$PEER" link set pe_a up
+ip -n "$PEER" link set pe_b up
+ip -n "$SAN" link set san_il up
+ip -n "$SAN" addr add 100.64.0.51/24 dev san_il
+
+# Feature gate: PRP interlink (RedBox) creation. A kernel without PRP RedBox
+# support rejects this with -EINVAL, so SKIP rather than FAIL.
+if ! ip -n "$RB" link add name prp0 type hsr slave1 rb_a slave2 rb_b \
+ interlink rb_il proto 1 2>/dev/null; then
+ echo "SKIP: kernel without PRP RedBox (interlink) support"
+ exit $ksft_skip
+fi
+ip -n "$RB" link set prp0 up
+ip -n "$PEER" link add name prp0 type hsr slave1 pe_a slave2 pe_b proto 1
+ip -n "$PEER" link set prp0 up
+ip -n "$PEER" addr add 100.64.0.2/24 dev prp0
+sleep 1
+
+san_mac=$(ip -n "$SAN" -br link show san_il | awk '{print $3}')
+rb_mac=$(ip -n "$RB" -br link show rb_il | awk '{print $3}')
+
+# Bidirectional unicast across the interlink.
+do_ping "$PEER" 100.64.0.51
+do_ping "$SAN" 100.64.0.2
+stop_if_error "PRP RedBox bidirectional unicast failed"
+
+# The SAN source MAC must be preserved on the PRP network, not laundered to the
+# RedBox MAC: the peer resolves the SAN IP to the SAN's own MAC.
+neigh=$(ip -n "$PEER" neigh show 100.64.0.51 | awk '{print $5}')
+if [ "$neigh" != "$san_mac" ]; then
+ echo "SAN MAC preservation [ FAIL ]: peer resolved 100.64.0.51 to" \
+ "'$neigh', expected $san_mac" 1>&2
+ ret=1
+fi
+stop_if_error "SAN MAC not preserved on the PRP network"
+
+# The proxy-announce supervision frame must carry, in order, the life-check TLV
+# (type 0x14, len 6) + MacAddressA == SAN MAC + the RedBox-MAC TLV (type 0x1e,
+# len 6) + MacAddressRedBox == RedBox MAC + the EOT marker (0x0000).
+ip netns exec "$SAN" ping -i 0.2 -q 100.64.0.2 >/dev/null 2>&1 &
+ping_pid=$!
+cap=$(ip netns exec "$PEER" timeout 5 tcpdump -i pe_a -nn -x \
+ "ether proto 0x88fb and ether src $rb_mac" 2>/dev/null || true)
+kill "$ping_pid" 2>/dev/null || true
+wait "$ping_pid" 2>/dev/null || true
+
+san_hex=$(echo "$san_mac" | tr -d ':')
+rb_hex=$(echo "$rb_mac" | tr -d ':')
+# Reassemble contiguous frame hex: drop the "0x0010:" offset labels and spaces.
+frame_hex=$(echo "$cap" | awk '/^[[:space:]]*0x[0-9a-f]+:/ {
+ sub(/^[[:space:]]*0x[0-9a-f]+:[[:space:]]*/, "");
+ gsub(/ /, ""); printf "%s", $0 }')
+if ! echo "$frame_hex" | grep -q "1406${san_hex}1e06${rb_hex}0000"; then
+ echo "supervision RedBox-MAC TLV [ FAIL ]: missing SAN MAC, Type-30" \
+ "payload, or EOT" 1>&2
+ ret=1
+fi
+stop_if_error "PRP RedBox supervision RedBox-MAC TLV/EOT check failed"
+
+echo "INFO: PRP RedBox (PRP-SAN) conformance checks passed"
+exit $ret
|
| 3/2 | 2026/07/06 19:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8039 output: 28 thoughts: 732 Thoughts: **PRP RedBox Implementation Review** Okay, so we've got a patch here that's adding PRP RedBox support to the HSR/PRP subsystem. This looks like a significant functional change, enabling a SAN behind an interlink port to communicate with a peer DANP on the PRP network. The changes touch a decent chunk of the HSR code, modifying several files: `hsr_device.c`, `hsr_forward.c`, `hsr_framereg.c`, `hsr_framereg.h`, `hsr_main.h`, `hsr_netlink.c`, and adding a test script. Specifically, it looks like: * In `hsr_device.c`, the `send_prp_supervision_frame` function is being modified to include RedBox-MAC TLVs and EOT markers for proxy announcement, and `hsr_dev_finalize` now publishes the RedBox state prior to port attachment. This makes sense; RedBox needs to be initialized before anything else. * `hsr_forward.c` introduces logic within `prp_drop_frame` to handle supervision frames, LAN duplicates, and unicast frames, depending on their origin and destination. There is also a change to classify the destination for PRP RedBox in `fill_frame_info`. * `hsr_framereg.c` is being heavily modified. `hsr_add_node` now sets `seq_port_cnt` to 2 for PRP\_V1 if `hsr->redbox` is set. `hsr_get_node` will now check for the presence of the `hsr_ethhdr` for PRP supervision frames. Also, `hsr_handle_sup_frame` merges sequence blocks and `prp_register_frame_out` now forwards LAN frames out the interlink to a SAN, deduplicating the LAN copies. This is critical for the new functionality. * `hsr_netlink.c` has a simple change removing the restriction on interlink support and allowing PRP to function here. This warrants thorough testing, and based on the files and functions changed, this is definitely WorthFuzzing. I need to focus my fuzzing efforts on key functions to thoroughly evaluate this implementation. Looking at the diff, the main functions of concern seem to be: `send_prp_supervision_frame`, `prp_drop_frame`, `hsr_handle_sup_frame`, `prp_register_frame_out`, and `hsr_newlink`. I'll want to craft fuzzer inputs that specifically target these functions and the new PRP RedBox-specific logic. I can look in `net/hsr/Kconfig` or `net/Kconfig` for the relevant configuration options. Time to dig in and break this new functionality. |
| 4/2 | 2026/07/06 19:57 | tool | grepper |
0mArgs:{
"Expression": "config HSR",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/Kconfig-5-\nnet/hsr/Kconfig:6:config HSR\nnet/hsr/Kconfig-7-\ttristate \"High-availability Seamless Redundancy (HSR \u0026 PRP)\"\n"
} |
| 5/2 | 2026/07/06 19:57 | llm | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9478 output: 27 thoughts: 19 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Configuration Context Check** Alright, the core configuration setting is identified as `HSR`. My immediate response is to mentally flag that as the starting point for whatever analysis or task is at hand. Now, before I proceed, I need to confirm whether this is the ONLY relevant configuration. It's crucial to ensure this is a self-contained system. I need to quickly scan for any related, dependent, or conflicting configurations. I'm going to determine if the `HSR` setting is part of a larger, potentially more complex, configuration or if it can be examined in isolation. If there are other configurations I'll need to know about them, and how they interact. |
| 6/2 | 2026/07/06 19:59 | tool | grepper |
0mArgs:{
"Expression": "config ",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/Kconfig-5-\nnet/hsr/Kconfig:6:config HSR\nnet/hsr/Kconfig-7-\ttristate \"High-availability Seamless Redundancy (HSR \u0026 PRP)\"\n--\nnet/hsr/Kconfig=42=if HSR\nnet/hsr/Kconfig-43-\nnet/hsr/Kconfig:44:config PRP_DUP_DISCARD_KUNIT_TEST\nnet/hsr/Kconfig-45-\ttristate \"PRP duplicate discard KUnit tests\" if !KUNIT_ALL_TESTS\n"
} |
| 7/2 | 2026/07/06 19:59 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9838 output: 34 thoughts: 107 Thoughts: Here's my thought process, as if I were analyzing this code: **HSR Configuration Deep Dive** Okay, so I'm looking at this code and `HSR` appears to be the central configuration element. That's my starting point. Now, to really understand its impact, I need to zero in on the key functions involved. Let me quickly identify those: I'm seeing `send_prp_supervision_frame`, `prp_drop_frame`, `hsr_handle_sup_frame`, `prp_register_frame_out`, and `hsr_newlink`. These seem like the heavy lifters. Now, one of the crucial pieces is that `send_prp_supervision_frame`. I need to confirm its invocation chain and ensure it's not a dead end. I'm going to quickly check how this function is actually called. It feels like `hsr_announce` or a similar function is likely responsible, but I'll confirm that quickly. |
| 8/2 | 2026/07/06 19:59 | tool | grepper |
0mArgs:{
"Expression": "send_prp_supervision_frame",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_device.c=293=static void send_hsr_supervision_frame(struct hsr_port *port,\n--\nnet/hsr/hsr_device.c-368-\nnet/hsr/hsr_device.c:369:static void send_prp_supervision_frame(struct hsr_port *master,\nnet/hsr/hsr_device.c-370-\t\t\t\t unsigned long *interval,\n--\nnet/hsr/hsr_device.c=658=static const struct hsr_proto_ops prp_ops = {\nnet/hsr/hsr_device.c:659:\t.send_sv_frame = send_prp_supervision_frame,\nnet/hsr/hsr_device.c-660-\t.create_tagged_frame = prp_create_tagged_frame,\n"
} |
| 9/2 | 2026/07/06 19:59 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10427 output: 31 thoughts: 26 Thoughts: Okay, here's my summary, tailored as if I'm an expert in the field thinking through this: **Analyzing the Operation** Alright, right off the bat, I recognize that this is definitely something handled within the `prp_ops` framework. That narrows down the scope considerably; we're dealing with a specific set of operations, and the overall context is already established. Now, my next logical step is to dive directly into the `prp_drop_frame` function. That’s where the core logic related to handling frame drops would reside, and that's exactly what I'm looking for in order to understand how this function operates in practice. |
| 10/2 | 2026/07/06 19:59 | tool | grepper |
0mArgs:{
"Expression": "prp_drop_frame",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_device.c=658=static const struct hsr_proto_ops prp_ops = {\n--\nnet/hsr/hsr_device.c-661-\t.get_untagged_frame = prp_get_untagged_frame,\nnet/hsr/hsr_device.c:662:\t.drop_frame = prp_drop_frame,\nnet/hsr/hsr_device.c-663-\t.fill_frame_info = prp_fill_frame_info,\n--\nnet/hsr/hsr_forward.c=443=static bool prp_is_lan_dup(struct hsr_frame_info *frame,\n--\nnet/hsr/hsr_forward.c-451-\nnet/hsr/hsr_forward.c:452:bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\nnet/hsr/hsr_forward.c-453-{\n--\nnet/hsr/hsr_forward.c=701=static int fill_frame_info(struct hsr_frame_info *frame,\n--\nnet/hsr/hsr_forward.c-734-\t/* PRP RedBox only: classify the unicast destination once so the\nnet/hsr/hsr_forward.c:735:\t * per-egress-port decision in prp_drop_frame() stays O(1). HSR RedBox\nnet/hsr/hsr_forward.c-736-\t * does its own classification and must not pay these node-table walks.\n--\nnet/hsr/hsr_forward.h=23=struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame,\nnet/hsr/hsr_forward.h-24-\t\t\t\t struct hsr_port *port);\nnet/hsr/hsr_forward.h:25:bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port);\nnet/hsr/hsr_forward.h-26-bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port);\n"
} |
| 11/2 | 2026/07/06 19:59 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11193 output: 33 thoughts: 33 Thoughts: Here's my summary, as the thought process unfolds: **Connecting the Dots in the PRP Framework** Okay, so I'm digging into this `prp_drop_frame` function. I remember seeing that name pop up before. Wait, yes, it's also a component of the `prp_ops` structure. That's good to know; it puts it in a broader context within the PRP architecture. Let me make a mental note to keep that association in mind as I delve deeper. Now, where was I? Right, I should take a look at `hsr_handle_sup_frame` next. It sounds like this function might be related to the frame handling at a higher level, which is probably a critical piece of this puzzle and I suspect it will be relevant to how `prp_drop_frame` is used in a specific application. I want to see if this is handling super frames, and I'd like to understand what that entails. Let's see what that function reveals. |
| 12/2 | 2026/07/06 20:00 | tool | grepper |
0mArgs:{
"Expression": "hsr_handle_sup_frame",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_forward.c=544=static void hsr_forward_do(struct hsr_frame_info *frame)\n--\nnet/hsr/hsr_forward.c-579-\t\t !frame-\u003eis_proxy_supervision) {\nnet/hsr/hsr_forward.c:580:\t\t\thsr_handle_sup_frame(frame);\nnet/hsr/hsr_forward.c-581-\t\t\tcontinue;\n--\nnet/hsr/hsr_framereg.c=373=EXPORT_SYMBOL_IF_KUNIT(hsr_get_seq_block);\n--\nnet/hsr/hsr_framereg.c-378- */\nnet/hsr/hsr_framereg.c:379:void hsr_handle_sup_frame(struct hsr_frame_info *frame)\nnet/hsr/hsr_framereg.c-380-{\n--\nnet/hsr/hsr_framereg.h=36=struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,\n--\nnet/hsr/hsr_framereg.h-38-\t\t\t enum hsr_port_type rx_port);\nnet/hsr/hsr_framereg.h:39:void hsr_handle_sup_frame(struct hsr_frame_info *frame);\nnet/hsr/hsr_framereg.h-40-bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr);\n"
} |
| 13/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11878 output: 33 thoughts: 16 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person: **Targeting Optimal Output Frame Registration** Alright, thinking about output frame registration... `prp_register_frame_out` is definitely a strong contender, and maybe the best place to focus our efforts. This function seems like a central point, a logical place to hook in and optimize. I'm already visualizing how it handles the data flow, and I can start mentally mapping out the potential performance bottlenecks. I need to dig deeper into the code around that point, analyze its dependencies, and see if any quick wins are possible within that specific subroutine. I'm also considering the potential tradeoffs there - how much control do I want at this layer, versus pushing responsibility further down the line? This is definitely a solid starting point for our optimization efforts. |
| 14/2 | 2026/07/06 20:00 | tool | grepper |
0mArgs:{
"Expression": "prp_register_frame_out",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_device.c=658=static const struct hsr_proto_ops prp_ops = {\n--\nnet/hsr/hsr_device.c-665-\t.update_san_info = prp_update_san_info,\nnet/hsr/hsr_device.c:666:\t.register_frame_out = prp_register_frame_out,\nnet/hsr/hsr_device.c-667-};\n--\nnet/hsr/hsr_framereg.c=640=int hsr_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame)\n--\nnet/hsr/hsr_framereg.c-656- */\nnet/hsr/hsr_framereg.c:657:int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame)\nnet/hsr/hsr_framereg.c-658-{\n--\nnet/hsr/hsr_framereg.c-674-}\nnet/hsr/hsr_framereg.c:675:EXPORT_SYMBOL_IF_KUNIT(prp_register_frame_out);\nnet/hsr/hsr_framereg.c-676-\n--\nnet/hsr/hsr_framereg.h=74=bool hsr_is_node_in_db(struct list_head *node_db,\n--\nnet/hsr/hsr_framereg.h-76-\nnet/hsr/hsr_framereg.h:77:int prp_register_frame_out(struct hsr_port *port, struct hsr_frame_info *frame);\nnet/hsr/hsr_framereg.h-78-\n--\nnet/hsr/prp_dup_discard_test.c=69=static void prp_dup_discard_forward(struct kunit *test)\n--\nnet/hsr/prp_dup_discard_test.c-75-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:76:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-77-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c=80=static void prp_dup_discard_drop_duplicate(struct kunit *test)\n--\nnet/hsr/prp_dup_discard_test.c-85-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:86:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-87-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-89-\tKUNIT_EXPECT_EQ(test, 1,\nnet/hsr/prp_dup_discard_test.c:90:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-91-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c=94=static void prp_dup_discard_entry_timeout(struct kunit *test)\n--\nnet/hsr/prp_dup_discard_test.c-102-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:103:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-104-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-107-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:108:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-109-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-115-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:116:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-117-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c=121=static void prp_dup_discard_out_of_sequence(struct kunit *test)\n--\nnet/hsr/prp_dup_discard_test.c-128-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:129:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-130-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-134-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:135:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-136-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-141-\tKUNIT_EXPECT_EQ(test, 1,\nnet/hsr/prp_dup_discard_test.c:142:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-143-\n--\nnet/hsr/prp_dup_discard_test.c-147-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:148:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-149-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-154-\tKUNIT_EXPECT_EQ(test, 1,\nnet/hsr/prp_dup_discard_test.c:155:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-156-}\n--\nnet/hsr/prp_dup_discard_test.c=158=static void prp_dup_discard_lan_b_late(struct kunit *test)\n--\nnet/hsr/prp_dup_discard_test.c-164-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:165:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-166-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-169-\tKUNIT_EXPECT_EQ(test, 0,\nnet/hsr/prp_dup_discard_test.c:170:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-171-\tcheck_prp_frame_seen(test, data, data-\u003eframe.sequence_nr);\n--\nnet/hsr/prp_dup_discard_test.c-175-\tKUNIT_EXPECT_EQ(test, 1,\nnet/hsr/prp_dup_discard_test.c:176:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-177-\n--\nnet/hsr/prp_dup_discard_test.c-180-\tKUNIT_EXPECT_EQ(test, 1,\nnet/hsr/prp_dup_discard_test.c:181:\t\t\tprp_register_frame_out(\u0026data-\u003eport, \u0026data-\u003eframe));\nnet/hsr/prp_dup_discard_test.c-182-}\n"
} |
| 15/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14462 output: 30 thoughts: 34 Thoughts: Here's my analysis of the provided information, as if these were my internal thoughts: **Analyzing Reachability in the PRP Subsystem** Okay, so I see that `prp_register_frame_out` is connected to `prp_ops`, meaning it's reachable through that pathway as well. That's good to know, confirms my understanding of the PRP architecture. Now, let me shift gears and examine `hsr_newlink`. I want to understand how it interacts within this framework. My intuition tells me it likely touches the registration mechanism or a related data structure in some way. Time to dig into the code and see how it is working. |
| 16/2 | 2026/07/06 20:00 | tool | grepper |
0mArgs:{
"Expression": "hsr_newlink",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_netlink.c=18=static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = {\n--\nnet/hsr/hsr_netlink.c-31- */\nnet/hsr/hsr_netlink.c:32:static int hsr_newlink(struct net_device *dev,\nnet/hsr/hsr_netlink.c-33-\t\t struct rtnl_newlink_params *params,\n--\nnet/hsr/hsr_netlink.c=191=static struct rtnl_link_ops hsr_link_ops __read_mostly = {\n--\nnet/hsr/hsr_netlink.c-196-\t.setup\t\t= hsr_dev_setup,\nnet/hsr/hsr_netlink.c:197:\t.newlink\t= hsr_newlink,\nnet/hsr/hsr_netlink.c-198-\t.dellink\t= hsr_dellink,\n"
} |
| 17/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14935 output: 34 thoughts: 107 Thoughts: **My Netlink-Related HSR Investigation** Okay, so I've established that the `hsr_newlink` function is indeed reachable through netlink. That's good, that's what I needed to confirm. Now, I need to zoom in on the specific functions involved in the frame handling and HSR process as they relate to this connection. My immediate focus symbols are: `send_prp_supervision_frame`, `prp_drop_frame`, `hsr_handle_sup_frame`, `prp_register_frame_out`, and, of course, the key `hsr_newlink`. I need to understand how these pieces fit together in this netlink context. Before I go further, I want to confirm something that I thought I knew, but is worth a quick double-check for absolute certainty. Let me just open `net/hsr/Kconfig` again to make sure that `HSR` is the *only* configuration option in play here. I don't want to get sidetracked by related options if it's not the case. |
| 18/2 | 2026/07/06 20:00 | tool | read-file |
0mArgs:{
"File": "net/hsr/Kconfig",
"FirstLine": 1,
"LineCount": 100
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\t#\n 3:\t# IEC 62439-3 High-availability Seamless Redundancy\n 4:\t#\n 5:\t\n 6:\tconfig HSR\n 7:\t\ttristate \"High-availability Seamless Redundancy (HSR \u0026 PRP)\"\n 8:\t\thelp\n 9:\t\t This enables IEC 62439 defined High-availability Seamless\n 10:\t\t Redundancy (HSR) and Parallel Redundancy Protocol (PRP).\n 11:\t\n 12:\t\t If you say Y here, then your Linux box will be able to act as a\n 13:\t\t DANH (\"Doubly attached node implementing HSR\") or DANP (\"Doubly\n 14:\t\t attached node implementing PRP\"). For this to work, your Linux box\n 15:\t\t needs (at least) two physical Ethernet interfaces.\n 16:\t\n 17:\t\t For DANH, it must be connected as a node in a ring network together\n 18:\t\t with other HSR capable nodes. All Ethernet frames sent over the HSR\n 19:\t\t device will be sent in both directions on the ring (over both slave\n 20:\t\t ports), giving a redundant, instant fail-over network. Each HSR node\n 21:\t\t in the ring acts like a bridge for HSR frames, but filters frames\n 22:\t\t that have been forwarded earlier.\n 23:\t\n 24:\t\t For DANP, it must be connected as a node connecting to two\n 25:\t\t separate networks over the two slave interfaces. Like HSR, Ethernet\n 26:\t\t frames sent over the PRP device will be sent to both networks giving\n 27:\t\t a redundant, instant fail-over network. Unlike HSR, PRP networks\n 28:\t\t can have Singly Attached Nodes (SAN) such as PC, printer, bridges\n 29:\t\t etc and will be able to communicate with DANP nodes.\n 30:\t\n 31:\t\t This code is a \"best effort\" to comply with the HSR standard as\n 32:\t\t described in IEC 62439-3:2010 (HSRv0) and IEC 62439-3:2012 (HSRv1),\n 33:\t\t and PRP standard described in IEC 62439-4:2012 (PRP), but no\n 34:\t\t compliancy tests have been made. Use iproute2 to select the protocol\n 35:\t\t you would like to use.\n 36:\t\n 37:\t\t You need to perform any and all necessary tests yourself before\n 38:\t\t relying on this code in a safety critical system!\n 39:\t\n 40:\t\t If unsure, say N.\n 41:\t\n 42:\tif HSR\n 43:\t\n 44:\tconfig PRP_DUP_DISCARD_KUNIT_TEST\n 45:\t\ttristate \"PRP duplicate discard KUnit tests\" if !KUNIT_ALL_TESTS\n 46:\t\tdepends on KUNIT\n 47:\t\tdefault KUNIT_ALL_TESTS\n 48:\t\thelp\n 49:\t\t Covers the PRP duplicate discard algorithm.\n 50:\t\t Only useful for kernel devs running KUnit test harness and are not\n 51:\t\t for inclusion into a production build.\n 52:\t\n 53:\t\t For more information on KUnit and unit tests in general please refer\n 54:\t\t to the KUnit documentation in Documentation/dev-tools/kunit/.\n 55:\t\n 56:\t\t If unsure, say N.\n 57:\t\n 58:\tendif\n"
} |
| 19/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16248 output: 31 thoughts: 237 Thoughts: **My Fuzzing Strategy for HSR** Okay, so it looks like I only need the `HSR` configuration for this round. I need to make sure I don't miss anything, so I'll scan for any other potentially fuzzable functions. Right off the bat, I see that `hsr_dev_finalize` is called by `hsr_newlink`, and `hsr_add_node` is called by `hsr_get_node`. Further, `hsr_get_node` is a dependency of both `hsr_forward_do` and `hsr_handle_sup_frame`. This gets interesting. It looks like `fill_frame_info` is also called by `hsr_forward_do`, and so is `hsr_drop_frame`. Based on those call graphs, it's clear the primary entry points to fuzz are: * `hsr_newlink` * `hsr_forward_do` (which is a real rabbit hole, calling `hsr_drop_frame`, `fill_frame_info`, `hsr_handle_sup_frame`, `prp_drop_frame`, and `prp_register_frame_out`). I'll need to pay close attention to the `prp` functions too. * `send_prp_supervision_frame` Time to dig into `hsr_forward_do` and see what it expects. This looks like the main target for initial fuzzing. |
| 20/2 | 2026/07/06 20:00 | tool | grepper |
0mArgs:{
"Expression": "hsr_forward_do",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_forward.c=476=bool hsr_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port)\n--\nnet/hsr/hsr_forward.c-543- */\nnet/hsr/hsr_forward.c:544:static void hsr_forward_do(struct hsr_frame_info *frame)\nnet/hsr/hsr_forward.c-545-{\n--\nnet/hsr/hsr_forward.c=771=void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)\n--\nnet/hsr/hsr_forward.c-779-\thsr_register_frame_in(frame.node_src, port, frame.sequence_nr);\nnet/hsr/hsr_forward.c:780:\thsr_forward_do(\u0026frame);\nnet/hsr/hsr_forward.c-781-\trcu_read_unlock();\n"
} |
| 21/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17110 output: 32 thoughts: 17 Thoughts: Okay, here's my interpretation of that code snippet, delivered as if it's my own thought process: **Incoming Packet Processing: The `hsr_forward_skb` Perspective** Alright, so *this* is the entry point, the first place my attention lands when a packet comes knocking. `hsr_forward_skb`, that's the key. It's the first step in the whole process of receiving this thing. The code calls this function to kick everything off. I need to keep this function at the forefront of my mind, it's where my focus begins when handling new packets. This is ground zero. Everything funnels through here. |
| 22/2 | 2026/07/06 20:00 | tool | grepper |
0mArgs:{
"Expression": "hsr_forward_skb",
"PathPrefix": "net/hsr/"
}Results: {
"Output": "net/hsr/hsr_device.c=224=static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)\n--\nnet/hsr/hsr_device.c-235-\t\tspin_lock_bh(\u0026hsr-\u003eseqnr_lock);\nnet/hsr/hsr_device.c:236:\t\thsr_forward_skb(skb, master);\nnet/hsr/hsr_device.c-237-\t\tspin_unlock_bh(\u0026hsr-\u003eseqnr_lock);\n--\nnet/hsr/hsr_device.c=293=static void send_hsr_supervision_frame(struct hsr_port *port,\n--\nnet/hsr/hsr_device.c-363-\nnet/hsr/hsr_device.c:364:\thsr_forward_skb(skb, port);\nnet/hsr/hsr_device.c-365-\tspin_unlock_bh(\u0026hsr-\u003eseqnr_lock);\n--\nnet/hsr/hsr_device.c=369=static void send_prp_supervision_frame(struct hsr_port *master,\n--\nnet/hsr/hsr_device.c-431-\nnet/hsr/hsr_device.c:432:\thsr_forward_skb(skb, master);\nnet/hsr/hsr_device.c-433-\tspin_unlock_bh(\u0026hsr-\u003eseqnr_lock);\n--\nnet/hsr/hsr_forward.c=701=static int fill_frame_info(struct hsr_frame_info *frame,\n--\nnet/hsr/hsr_forward.c-770-/* Must be called holding rcu read lock (because of the port parameter) */\nnet/hsr/hsr_forward.c:771:void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)\nnet/hsr/hsr_forward.c-772-{\n--\nnet/hsr/hsr_forward.h-15-\nnet/hsr/hsr_forward.h:16:void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port);\nnet/hsr/hsr_forward.h-17-struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame,\n--\nnet/hsr/hsr_slave.c=24=static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)\n--\nnet/hsr/hsr_slave.c-80-\t\tspin_lock_bh(\u0026hsr-\u003eseqnr_lock);\nnet/hsr/hsr_slave.c:81:\t\thsr_forward_skb(skb, port);\nnet/hsr/hsr_slave.c-82-\t\tspin_unlock_bh(\u0026hsr-\u003eseqnr_lock);\nnet/hsr/hsr_slave.c-83-\t} else {\nnet/hsr/hsr_slave.c:84:\t\thsr_forward_skb(skb, port);\nnet/hsr/hsr_slave.c-85-\t}\n"
} |
| 23/2 | 2026/07/06 20:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 18135 output: 166 thoughts: 587 Thoughts: **My Assessment of the HSR/PRP PRP-SAN Patch** Okay, so I've been looking at this patch and here's my breakdown. From what I can see, `hsr_dev_xmit` and `hsr_handle_frame` are the key entry points for this whole thing. The core of this patch seems to be focused on enabling PRP RedBox functionality (PRP-SAN) within the existing HSR/PRP subsystem. I've pinpointed a few crucial functions that have been modified as a direct result. I'm focusing on these for my fuzzing strategy. I've zeroed in on the following functions: `send_prp_supervision_frame`, `hsr_handle_sup_frame`, `hsr_newlink`, `prp_drop_frame`, and `prp_register_frame_out`. I've included `hsr_newlink` because, while it calls `hsr_dev_finalize`, it represents a better point of entry. While `fill_frame_info` and `prp_register_frame_out` are technically hot-path, I've elected to include `prp_register_frame_out` as a focus symbol as the modification is specific to this patch. I've considered other functions as well, for example `fill_frame_info` which gets called by `hsr_forward_skb`, and is hot path. I decided against including this function, and `prp_drop_frame`, because the modification appears specific to this patch. Similarly, `hsr_handle_sup_frame` is only called for supervision frames, and `send_prp_supervision_frame` is based on a timer, so it's not hot-path. Essentially, the patch alters how supervision frames are generated, the core logic for forwarding frames, in particular, the dropping and registration, and also how node sequence is handled. This is all to accommodate this PRP-SAN feature. Additionally, it looks like there's been some flexibility added in how interlink works, removing a previous netlink setup restriction with HSR. This is a pretty significant functional change that has serious implications for the network stack, so fuzzing is definitely the way to go. The only relevant config that I can see is `HSR`. So, the key elements to target for fuzzing are: `send_prp_supervision_frame`, `hsr_handle_sup_frame`, `hsr_newlink`, `prp_drop_frame`, and `prp_register_frame_out`. Time to set the results! |
| 24/2 | 2026/07/06 20:00 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"HSR"
],
"FocusSymbols": [
"send_prp_supervision_frame",
"hsr_handle_sup_frame",
"hsr_newlink",
"prp_drop_frame",
"prp_register_frame_out"
],
"Reasoning": "The patch adds support for PRP RedBox (PRP-SAN) in the HSR/PRP subsystem. It modifies supervision frame generation, frame forwarding logic (dropping and registering), and node sequence handling to support the new feature. It also removes the restriction that interlink only works with HSR in netlink setup. This is a functional change to the network stack that should be fuzzed.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"HSR"
],
"FocusSymbols": [
"send_prp_supervision_frame",
"hsr_handle_sup_frame",
"hsr_newlink",
"prp_drop_frame",
"prp_register_frame_out"
],
"Reasoning": "The patch adds support for PRP RedBox (PRP-SAN) in the HSR/PRP subsystem. It modifies supervision frame generation, frame forwarding logic (dropping and registering), and node sequence handling to support the new feature. It also removes the restriction that interlink only works with HSR in netlink setup. This is a functional change to the network stack that should be fuzzed.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|