AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/18 00:37 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "HSR"
  ],
  "FocusSymbols": [
    "send_prp_supervision_frame",
    "prp_drop_frame",
    "hsr_drop_frame",
    "fill_frame_info",
    "hsr_add_node",
    "hsr_get_node",
    "hsr_handle_sup_frame",
    "prp_register_frame_out",
    "hsr_newlink"
  ],
  "Reasoning": "The patch introduces functional changes to the HSR (High-availability Seamless Redundancy) driver, specifically adding support for PRP (Parallel Redundancy Protocol) RedBox (interlink). This involves modifications to packet forwarding, dropping logic, node management, and supervision frame handling, which are reachable via network traffic and netlink configuration.",
  "WorthFuzzing": true
}

1/1 2026/07/18 00:37 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 350bd00e1b5cbce692f79f15f47288c3f8aca5d0\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sat Jul 18 00:37:24 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..7734a521a96c23 100644\n--- a/net/hsr/hsr_forward.c\n+++ b/net/hsr/hsr_forward.c\n@@ -440,12 +440,34 @@ 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(enum hsr_port_type rx, struct hsr_port *port)\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(rx, 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 +475,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-\u003eport_rcv-\u003etype, port);\n \n \t/* RedBox specific frames dropping policies\n \t *\n@@ -466,7 +488,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-\u003eport_rcv-\u003etype, 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 +728,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..53e95bae0ee276 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\t\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/18 00:37 agent patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": [
    "HSR"
  ],
  "FocusSymbols": [
    "send_prp_supervision_frame",
    "prp_drop_frame",
    "hsr_drop_frame",
    "fill_frame_info",
    "hsr_add_node",
    "hsr_get_node",
    "hsr_handle_sup_frame",
    "prp_register_frame_out",
    "hsr_newlink"
  ],
  "Reasoning": "The patch introduces functional changes to the HSR (High-availability Seamless Redundancy) driver, specifically adding support for PRP (Parallel Redundancy Protocol) RedBox (interlink). This involves modifications to packet forwarding, dropping logic, node management, and supervision frame handling, which are reachable via network traffic and netlink configuration.",
  "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 350bd00e1b5cbce692f79f15f47288c3f8aca5d0
Author: syz-cluster <triage@syzkaller.com>
Date:   Sat Jul 18 00:37:24 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..7734a521a96c23 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -440,12 +440,34 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port,
 	return dev_queue_xmit(skb);
 }
 
+static bool prp_is_lan_dup(enum hsr_port_type rx, struct hsr_port *port)
+{
+	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(rx, 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 +475,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_rcv->type, port);
 
 	/* RedBox specific frames dropping policies
 	 *
@@ -466,7 +488,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_rcv->type, 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 +728,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..53e95bae0ee276 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/18 00:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8029
							output: 28
							thoughts: 339
						

Thoughts:
**My Assessment of the HSR PRP RedBox Patch**

Okay, so I've got a patch here that's making changes to the HSR driver within the Linux kernel, specifically adding support for PRP RedBox interlinking. I see it's touching `hsr_device.c`, `hsr_forward.c`, `hsr_framereg.c`, and `hsr_netlink.c`, which is the typical area for network driver modifications, and includes a selftest. My initial impression is that this is definitely targeting a critical part of the network stack related to high availability. Given that it deals with adding PRP RedBox functionality, it's pretty clear that this patch is changing the core packet processing logic. Functions like `hsr_xmit`, `hsr_handle_sup_frame`, and `prp_drop_frame` are going to be affected.

The first thing that comes to mind is that this demands a thorough fuzzing campaign. This is exactly the kind of change that has the potential to introduce subtle, exploitable vulnerabilities, especially in the context of network packet handling.

I need to nail down the most critical functions for the fuzzing campaign. I'm focusing my attention on functions that are likely to be handling incoming or outgoing frames, or where PRP protocol logic is implemented:

*   `send_prp_supervision_frame`
*   `hsr_dev_finalize`
*   `prp_drop_frame`
*   `hsr_drop_frame`
*   `fill_frame_info`
*   `hsr_add_node`
*   `hsr_get_node`
*   `hsr_handle_sup_frame`
*   `prp_register_frame_out`
*   `hsr_newlink`

Before I get too deep into fuzzing, I'm going to quickly check the Kconfig options to verify that HSR is enabled and to see if any new configuration options specific to PRP have been introduced. I'll use `grepper` to look for `CONFIG_HSR` and any related options. This will help me understand the build environment and if there are any conditional dependencies.



4/2 2026/07/18 00:37 tool grepper
0m Args:
{
  "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/18 00:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8935
							output: 27
							thoughts: 18
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Diving into the HSR Configuration Landscape**

Alright, time to get my hands dirty. I'm taking a look at `net/hsr/Kconfig`. This means I'm trying to figure out the current configuration options and dependencies for the High-availability Seamless Redundancy (HSR) protocol support within this specific network subsystem. I need to understand what's been implemented, what knobs are available to fine-tune its behavior, and how it all fits together.

I'm thinking about the structure of the Kconfig file itself. I'll be looking for `config` entries, `menuconfig`, `depends on` statements, `select` statements, and of course, the actual definitions and help text. I'll be keeping an eye out for any potential conflicts or areas where upstream and downstream changes might require special consideration. I'm also thinking about whether this is a core HSR implementation or an extension, and how it might interact with other networking features (e.g., VLANs, bridging, QoS) and hardware platforms. I need to ensure a correct build.



6/2 2026/07/18 00:37 tool grepper
0m Args:
{
  "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/18 00:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9379
							output: 34
							thoughts: 173
						

Thoughts:
**Analyzing the HSR Configuration**

Okay, so the `HSR` configuration is the central piece here. I need to get a handle on the key functions involved, so let's start with those. I've got to focus on the following: `send_prp_supervision_frame`, `prp_drop_frame`, `hsr_drop_frame`, `fill_frame_info`, `hsr_add_node`, `hsr_get_node`, `hsr_handle_sup_frame`, `prp_register_frame_out`, and `hsr_newlink`. I need to ensure there aren't any other functions that are relevant, but it seems there's a new static function, `prp_is_lan_dup`, and a modified function, `hsr_dev_finalize`, that I need to factor in.

Now, I'll switch my focus to `net/hsr/hsr_device.c` to examine `send_prp_supervision_frame` in detail.



8/2 2026/07/18 00:37 tool grepper
0m Args:
{
  "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/18 00:37 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10045
							output: 187
							thoughts: 486
						

Thoughts:
**Analyzing the PRP RedBox Patch and Identifying Fuzzing Targets**

Okay, let's break this down. My initial assessment centers on identifying key functions related to this PRP RedBox implementation, specifically within the HSR driver. My immediate goal is to map out the functional changes and pinpoint the best areas for fuzzing.

My primary functions of interest, based on the code analysis so far, are: `send_prp_supervision_frame`, `prp_drop_frame`, `hsr_drop_frame`, `fill_frame_info`, `hsr_add_node`, `hsr_get_node`, `hsr_handle_sup_frame`, `prp_register_frame_out`, and `hsr_newlink`. I'll want to revisit those, especially considering the HSR config.

I need to confirm the inlining status of `prp_is_lan_dup`, although I think I can avoid it by just using the `prp_drop_frame` and `hsr_drop_frame` functions.

This patch fundamentally adds support for PRP RedBox interlink functionality, which is a significant change to how the HSR driver interacts with the network stack. Therefore, it's absolutely crucial to fuzz this implementation.

Now, let's refine this list. `hsr_newlink` appears to be the netlink entry point for interface creation. `send_prp_supervision_frame` seems to be called periodically or triggered on demand.  `prp_drop_frame` and `hsr_drop_frame` are critical for packet reception and forwarding. `fill_frame_info` is also directly related to reception. The `hsr_add_node` and `hsr_get_node` functions are involved in the management of the node table, during packet reception. Finally, `hsr_handle_sup_frame` handles the supervision frame and `prp_register_frame_out` is called on transmission.

Yes, this is a solid list of targets. I'm confident that this covers the most critical areas for fuzzing this new functionality. Time to set these results and proceed.



10/2 2026/07/18 00:37 tool set-results
0m Args:
{
  "EnableConfigs": [
    "HSR"
  ],
  "FocusSymbols": [
    "send_prp_supervision_frame",
    "prp_drop_frame",
    "hsr_drop_frame",
    "fill_frame_info",
    "hsr_add_node",
    "hsr_get_node",
    "hsr_handle_sup_frame",
    "prp_register_frame_out",
    "hsr_newlink"
  ],
  "Reasoning": "The patch introduces functional changes to the HSR (High-availability Seamless Redundancy) driver, specifically adding support for PRP (Parallel Redundancy Protocol) RedBox (interlink). This involves modifications to packet forwarding, dropping logic, node management, and supervision frame handling, which are reachable via network traffic and netlink configuration.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "HSR"
  ],
  "FocusSymbols": [
    "send_prp_supervision_frame",
    "prp_drop_frame",
    "hsr_drop_frame",
    "fill_frame_info",
    "hsr_add_node",
    "hsr_get_node",
    "hsr_handle_sup_frame",
    "prp_register_frame_out",
    "hsr_newlink"
  ],
  "Reasoning": "The patch introduces functional changes to the HSR (High-availability Seamless Redundancy) driver, specifically adding support for PRP (Parallel Redundancy Protocol) RedBox (interlink). This involves modifications to packet forwarding, dropping logic, node management, and supervision frame handling, which are reachable via network traffic and netlink configuration.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)