AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/21 04:38 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": [
    "IP_VS",
    "IP_VS_IPV6",
    "IP_VS_PROTO_TCP",
    "IP_VS_PROTO_UDP",
    "IP_VS_PROTO_SCTP"
  ],
  "FocusSymbols": [
    "ip_vs_in_icmp",
    "ip_vs_out_icmp",
    "ip_vs_in_icmp_v6",
    "ip_vs_out_icmp_v6",
    "ip_vs_forward_icmp",
    "ip_vs_icmp_xmit",
    "ip_vs_icmp_xmit_v6",
    "sctp_snat_handler",
    "sctp_dnat_handler",
    "tcp_snat_handler",
    "tcp_dnat_handler",
    "udp_snat_handler",
    "udp_dnat_handler",
    "ip_vs_nat_icmp",
    "ip_vs_nat_icmp_v6"
  ],
  "Reasoning": "The patch modifies core IPVS logic for handling checksums and NAT for ICMP, TCP, UDP, and SCTP packets. It introduces new checksum validation logic and alters packet mangling offsets. This is reachable core network functionality that should be fuzzed.",
  "WorthFuzzing": true
}

1/1 2026/07/21 04:38 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit cb4343b0810d96f39f5d0f7cc36ccb1a6f0bfcc1\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Tue Jul 21 04:38:29 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/include/net/ip_vs.h b/include/net/ip_vs.h\nindex 417ff51f62fc8e..c684a46ce15a54 100644\n--- a/include/net/ip_vs.h\n+++ b/include/net/ip_vs.h\n@@ -25,7 +25,9 @@\n #include \u003clinux/netfilter.h\u003e\t\t/* for union nf_inet_addr */\n #include \u003clinux/ip.h\u003e\n #include \u003clinux/ipv6.h\u003e\t\t\t/* for struct ipv6hdr */\n+#include \u003cnet/route.h\u003e\n #include \u003cnet/ipv6.h\u003e\n+#include \u003cnet/ip6_fib.h\u003e\n #if IS_ENABLED(CONFIG_NF_CONNTRACK)\n #include \u003cnet/netfilter/nf_conntrack.h\u003e\n #endif\n@@ -1972,8 +1974,9 @@ int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n int ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t\t  struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);\n int ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n-\t\t    struct ip_vs_protocol *pp, int offset,\n-\t\t    unsigned int hooknum, struct ip_vs_iphdr *iph);\n+\t\t    struct ip_vs_protocol *pp, unsigned int toff,\n+\t\t    unsigned int wlen, unsigned int hooknum,\n+\t\t    struct ip_vs_iphdr *ciph);\n void ip_vs_dest_dst_rcu_free(struct rcu_head *head);\n \n #ifdef CONFIG_IP_VS_IPV6\n@@ -1986,8 +1989,9 @@ int ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n int ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t\t     struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);\n int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n-\t\t       struct ip_vs_protocol *pp, int offset,\n-\t\t       unsigned int hooknum, struct ip_vs_iphdr *iph);\n+\t\t       struct ip_vs_protocol *pp, unsigned int toff,\n+\t\t       unsigned int wlen, unsigned int hooknum,\n+\t\t       struct ip_vs_iphdr *ciph);\n #endif\n \n #ifdef CONFIG_SYSCTL\n@@ -2059,15 +2063,14 @@ static inline bool ip_vs_conn_use_hash2(struct ip_vs_conn *cp)\n }\n \n void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\t    struct ip_vs_conn *cp, int dir);\n+\t\t    struct ip_vs_conn *cp, int dir, unsigned int toff);\n \n #ifdef CONFIG_IP_VS_IPV6\n void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\t       struct ip_vs_conn *cp, int dir);\n+\t\t       struct ip_vs_conn *cp, int dir, unsigned int toff,\n+\t\t       struct ip_vs_iphdr *ciph);\n #endif\n \n-__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset);\n-\n static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)\n {\n \t__be32 diff[2] = { ~old, new };\n@@ -2093,6 +2096,36 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)\n \treturn csum_partial(diff, sizeof(diff), oldsum);\n }\n \n+static inline bool ip_vs_checksum_needed(struct sk_buff *skb, int af)\n+{\n+\t/* Checksum unnecessary or already validated? */\n+\tif (skb_csum_unnecessary(skb))\n+\t\treturn false;\n+\t/* LOCAL_OUT ? */\n+\tif (!skb-\u003edev || skb-\u003edev-\u003eflags \u0026 IFF_LOOPBACK)\n+\t\treturn false;\n+\t/* !LOCAL_IN (FORWARD) ? */\n+\tif (af == AF_INET6) {\n+\t\tif (!(dst_rt6_info(skb_dst(skb))-\u003ert6i_flags \u0026 RTF_LOCAL))\n+\t\t\treturn false;\n+\t} else {\n+\t\tif (!(skb_rtable(skb)-\u003ert_flags \u0026 RTCF_LOCAL))\n+\t\t\treturn false;\n+\t}\n+\treturn true;\n+}\n+\n+/**\n+ * ip_vs_checksum_common_check - validate checksum for TCP/UDP/ICMP\n+ */\n+static inline bool ip_vs_checksum_common_check(struct sk_buff *skb,\n+\t\t\t\t\t       int offset, int proto, int af)\n+{\n+\tif (!ip_vs_checksum_needed(skb, af))\n+\t\treturn true;\n+\treturn !nf_checksum(skb, NF_INET_LOCAL_IN, offset, proto, af);\n+}\n+\n /* Forget current conntrack (unconfirmed) and attach notrack entry */\n static inline void ip_vs_notrack(struct sk_buff *skb)\n {\ndiff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c\nindex b0e00be85cb12c..11cbdbaf561daf 100644\n--- a/net/netfilter/ipvs/ip_vs_app.c\n+++ b/net/netfilter/ipvs/ip_vs_app.c\n@@ -367,7 +367,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb,\n \tif (skb_ensure_writable(skb, ipvsh-\u003elen + sizeof(*th)))\n \t\treturn 0;\n \n-\tth = (struct tcphdr *)(skb_network_header(skb) + ipvsh-\u003elen);\n+\tth = (struct tcphdr *)(skb-\u003edata + ipvsh-\u003elen);\n \n \t/*\n \t *\tRemember seq number in case this pkt gets resized\n@@ -443,7 +443,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb,\n \tif (skb_ensure_writable(skb, ipvsh-\u003elen + sizeof(*th)))\n \t\treturn 0;\n \n-\tth = (struct tcphdr *)(skb_network_header(skb) + ipvsh-\u003elen);\n+\tth = (struct tcphdr *)(skb-\u003edata + ipvsh-\u003elen);\n \n \t/*\n \t *\tRemember seq number in case this pkt gets resized\ndiff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c\nindex bafab93451d037..21db6af220eb09 100644\n--- a/net/netfilter/ipvs/ip_vs_core.c\n+++ b/net/netfilter/ipvs/ip_vs_core.c\n@@ -867,7 +867,7 @@ static int sysctl_nat_icmp_send(struct netns_ipvs *ipvs) { return 0; }\n \n #endif\n \n-__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)\n+static __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)\n {\n \treturn csum_fold(skb_checksum(skb, offset, skb-\u003elen - offset, 0));\n }\n@@ -924,13 +924,12 @@ static int ip_vs_route_me_harder(struct netns_ipvs *ipvs, int af,\n  * - inout: 1=in-\u003eout, 0=out-\u003ein\n  */\n void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\t    struct ip_vs_conn *cp, int inout)\n+\t\t    struct ip_vs_conn *cp, int inout, unsigned int toff)\n {\n \tstruct iphdr *iph\t = ip_hdr(skb);\n-\tunsigned int icmp_offset = iph-\u003eihl*4;\n-\tstruct icmphdr *icmph\t = (struct icmphdr *)(skb_network_header(skb) +\n-\t\t\t\t\t\t      icmp_offset);\n+\tstruct icmphdr *icmph\t = (struct icmphdr *)(skb-\u003edata + toff);\n \tstruct iphdr *ciph\t = (struct iphdr *)(icmph + 1);\n+\tunsigned int coff = toff + sizeof(struct icmphdr);\n \n \tif (inout) {\n \t\tiph-\u003esaddr = cp-\u003evaddr.ip;\n@@ -957,48 +956,45 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \n \t/* And finally the ICMP checksum */\n \ticmph-\u003echecksum = 0;\n-\ticmph-\u003echecksum = ip_vs_checksum_complete(skb, icmp_offset);\n+\ticmph-\u003echecksum = ip_vs_checksum_complete(skb, toff);\n \tskb-\u003eip_summed = CHECKSUM_UNNECESSARY;\n \n \tif (inout)\n-\t\tIP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,\n-\t\t\t\"Forwarding altered outgoing ICMP\");\n+\t\tIP_VS_DBG_PKT(11, AF_INET, pp, skb, coff,\n+\t\t\t      \"Forwarding altered outgoing ICMP\");\n \telse\n-\t\tIP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,\n-\t\t\t\"Forwarding altered incoming ICMP\");\n+\t\tIP_VS_DBG_PKT(11, AF_INET, pp, skb, coff,\n+\t\t\t      \"Forwarding altered incoming ICMP\");\n }\n \n #ifdef CONFIG_IP_VS_IPV6\n void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\t    struct ip_vs_conn *cp, int inout)\n+\t\t       struct ip_vs_conn *cp, int inout, unsigned int toff,\n+\t\t       struct ip_vs_iphdr *ciph)\n {\n \tstruct ipv6hdr *iph\t = ipv6_hdr(skb);\n-\tunsigned int icmp_offset = 0;\n-\tunsigned int offs\t = 0; /* header offset*/\n \tint protocol;\n \tstruct icmp6hdr *icmph;\n-\tstruct ipv6hdr *ciph;\n-\tunsigned short fragoffs;\n+\tstruct ipv6hdr *cih;\n \n-\tipv6_find_hdr(skb, \u0026icmp_offset, IPPROTO_ICMPV6, \u0026fragoffs, NULL);\n-\ticmph = (struct icmp6hdr *)(skb_network_header(skb) + icmp_offset);\n-\toffs = icmp_offset + sizeof(struct icmp6hdr);\n-\tciph = (struct ipv6hdr *)(skb_network_header(skb) + offs);\n+\ticmph = (struct icmp6hdr *)(skb-\u003edata + toff);\n+\tcih = (struct ipv6hdr *)(skb-\u003edata + ciph-\u003eoff);\n \n-\tprotocol = ipv6_find_hdr(skb, \u0026offs, -1, \u0026fragoffs, NULL);\n+\tprotocol = ciph-\u003eprotocol;\n \n \tif (inout) {\n \t\tiph-\u003esaddr = cp-\u003evaddr.in6;\n-\t\tciph-\u003edaddr = cp-\u003evaddr.in6;\n+\t\tcih-\u003edaddr = cp-\u003evaddr.in6;\n \t} else {\n \t\tiph-\u003edaddr = cp-\u003edaddr.in6;\n-\t\tciph-\u003esaddr = cp-\u003edaddr.in6;\n+\t\tcih-\u003esaddr = cp-\u003edaddr.in6;\n \t}\n \n \t/* the TCP/UDP/SCTP port */\n-\tif (!fragoffs \u0026\u0026 (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||\n-\t\t\t  IPPROTO_SCTP == protocol)) {\n-\t\t__be16 *ports = (void *)(skb_network_header(skb) + offs);\n+\tif (!ciph-\u003efragoffs \u0026\u0026\n+\t    (protocol == IPPROTO_TCP  || protocol == IPPROTO_UDP ||\n+\t     protocol == IPPROTO_SCTP)) {\n+\t\t__be16 *ports = (void *)(skb-\u003edata + ciph-\u003elen);\n \n \t\tIP_VS_DBG(11, \"%s() changed port %d to %d\\n\", __func__,\n \t\t\t      ntohs(inout ? ports[1] : ports[0]),\n@@ -1011,19 +1007,17 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \n \t/* And finally the ICMP checksum */\n \ticmph-\u003eicmp6_cksum = ~csum_ipv6_magic(\u0026iph-\u003esaddr, \u0026iph-\u003edaddr,\n-\t\t\t\t\t      skb-\u003elen - icmp_offset,\n+\t\t\t\t\t      skb-\u003elen - toff,\n \t\t\t\t\t      IPPROTO_ICMPV6, 0);\n-\tskb-\u003ecsum_start = skb_network_header(skb) - skb-\u003ehead + icmp_offset;\n+\tskb-\u003ecsum_start = skb_headroom(skb) + toff;\n \tskb-\u003ecsum_offset = offsetof(struct icmp6hdr, icmp6_cksum);\n \tskb-\u003eip_summed = CHECKSUM_PARTIAL;\n \n \tif (inout)\n-\t\tIP_VS_DBG_PKT(11, AF_INET6, pp, skb,\n-\t\t\t      (void *)ciph - (void *)iph,\n+\t\tIP_VS_DBG_PKT(11, AF_INET6, pp, skb, ciph-\u003eoff,\n \t\t\t      \"Forwarding altered outgoing ICMPv6\");\n \telse\n-\t\tIP_VS_DBG_PKT(11, AF_INET6, pp, skb,\n-\t\t\t      (void *)ciph - (void *)iph,\n+\t\tIP_VS_DBG_PKT(11, AF_INET6, pp, skb, ciph-\u003eoff,\n \t\t\t      \"Forwarding altered incoming ICMPv6\");\n }\n #endif\n@@ -1033,36 +1027,38 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,\n  */\n static int handle_response_icmp(int af, struct sk_buff *skb,\n \t\t\t\tunion nf_inet_addr *snet,\n-\t\t\t\t__u8 protocol, struct ip_vs_conn *cp,\n+\t\t\t\tstruct ip_vs_conn *cp,\n \t\t\t\tstruct ip_vs_protocol *pp,\n-\t\t\t\tunsigned int offset, unsigned int ihl,\n-\t\t\t\tunsigned int hooknum)\n+\t\t\t\tstruct ip_vs_iphdr *ciph,\n+\t\t\t\tunsigned int toff, unsigned int hooknum)\n {\n+\tint iproto = af == AF_INET6 ? IPPROTO_ICMPV6 : IPPROTO_ICMP;\n \tunsigned int verdict = NF_DROP;\n+\tunsigned int ctoff = ciph-\u003elen;\n \n \tif (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)\n \t\tgoto after_nat;\n \n \t/* Ensure the checksum is correct */\n-\tif (!skb_csum_unnecessary(skb) \u0026\u0026 ip_vs_checksum_complete(skb, ihl)) {\n+\tif (!ip_vs_checksum_common_check(skb, toff, iproto, af)) {\n \t\t/* Failed checksum! */\n \t\tIP_VS_DBG_BUF(1, \"Forward ICMP: failed checksum from %s!\\n\",\n \t\t\t      IP_VS_DBG_ADDR(af, snet));\n \t\tgoto out;\n \t}\n \n-\tif (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||\n-\t    IPPROTO_SCTP == protocol)\n-\t\toffset += 2 * sizeof(__u16);\n-\tif (skb_ensure_writable(skb, offset))\n+\tif (ciph-\u003eprotocol == IPPROTO_TCP || ciph-\u003eprotocol == IPPROTO_UDP ||\n+\t    ciph-\u003eprotocol == IPPROTO_SCTP)\n+\t\tctoff += 2 * sizeof(__u16);\n+\tif (skb_ensure_writable(skb, ctoff))\n \t\tgoto out;\n \n #ifdef CONFIG_IP_VS_IPV6\n \tif (af == AF_INET6)\n-\t\tip_vs_nat_icmp_v6(skb, pp, cp, 1);\n+\t\tip_vs_nat_icmp_v6(skb, pp, cp, 1, toff, ciph);\n \telse\n #endif\n-\t\tip_vs_nat_icmp(skb, pp, cp, 1);\n+\t\tip_vs_nat_icmp(skb, pp, cp, 1, toff);\n \n \tif (ip_vs_route_me_harder(cp-\u003eipvs, af, skb, hooknum))\n \t\tgoto out;\n@@ -1090,9 +1086,9 @@ static int handle_response_icmp(int af, struct sk_buff *skb,\n  *\tCurrently handles error types - unreachable, quench, ttl exceeded.\n  */\n static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,\n-\t\t\t  int *related, unsigned int hooknum)\n+\t\t\t  int *related, unsigned int hooknum,\n+\t\t\t  struct ip_vs_iphdr *ipvsh)\n {\n-\tstruct iphdr *iph;\n \tstruct icmphdr\t_icmph, *ic;\n \tstruct iphdr\t_ciph, *cih;\t/* The ip header contained within the ICMP */\n \tstruct ip_vs_iphdr ciph;\n@@ -1107,17 +1103,19 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \tif (ip_is_fragment(ip_hdr(skb))) {\n \t\tif (ip_vs_gather_frags(ipvs, skb, ip_vs_defrag_user(hooknum)))\n \t\t\treturn NF_STOLEN;\n+\t\tif (!ip_vs_fill_iph_skb(AF_INET, skb, false, ipvsh))\n+\t\t\treturn NF_ACCEPT;\n \t}\n \n-\tiph = ip_hdr(skb);\n-\toffset = ihl = iph-\u003eihl * 4;\n+\tihl = ipvsh-\u003elen;\n+\toffset = ipvsh-\u003elen;\n \tic = skb_header_pointer(skb, offset, sizeof(_icmph), \u0026_icmph);\n \tif (ic == NULL)\n \t\treturn NF_DROP;\n \n \tIP_VS_DBG(12, \"Outgoing ICMP (%d,%d) %pI4-\u003e%pI4\\n\",\n \t\t  ic-\u003etype, ntohs(icmp_id(ic)),\n-\t\t  \u0026iph-\u003esaddr, \u0026iph-\u003edaddr);\n+\t\t  \u0026ipvsh-\u003esaddr.ip, \u0026ipvsh-\u003edaddr.ip);\n \n \t/*\n \t * Work through seeing if this is for us.\n@@ -1136,7 +1134,7 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \t/* Now find the contained IP header */\n \toffset += sizeof(_icmph);\n \tcih = skb_header_pointer(skb, offset, sizeof(_ciph), \u0026_ciph);\n-\tif (cih == NULL)\n+\tif (!(cih \u0026\u0026 cih-\u003eversion == 4 \u0026\u0026 cih-\u003eihl \u003e= 5))\n \t\treturn NF_ACCEPT; /* The packet looks wrong, ignore */\n \n \tpp = ip_vs_proto_get(cih-\u003eprotocol);\n@@ -1159,9 +1157,9 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \tif (!cp)\n \t\treturn NF_ACCEPT;\n \n-\tsnet.ip = iph-\u003esaddr;\n-\treturn handle_response_icmp(AF_INET, skb, \u0026snet, cih-\u003eprotocol, cp,\n-\t\t\t\t    pp, ciph.len, ihl, hooknum);\n+\tsnet.ip = ipvsh-\u003esaddr.ip;\n+\treturn handle_response_icmp(AF_INET, skb, \u0026snet, cp, pp, \u0026ciph, ihl,\n+\t\t\t\t    hooknum);\n }\n \n #ifdef CONFIG_IP_VS_IPV6\n@@ -1174,7 +1172,6 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \tstruct ip_vs_conn *cp;\n \tstruct ip_vs_protocol *pp;\n \tunion nf_inet_addr snet;\n-\tunsigned int offset;\n \n \t*related = 1;\n \tic = frag_safe_skb_hp(skb, ipvsh-\u003elen, sizeof(_icmph), \u0026_icmph);\n@@ -1217,9 +1214,8 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \t\treturn NF_ACCEPT;\n \n \tsnet.in6 = ciph.saddr.in6;\n-\toffset = ciph.len;\n-\treturn handle_response_icmp(AF_INET6, skb, \u0026snet, ciph.protocol, cp,\n-\t\t\t\t    pp, offset, ipvsh-\u003elen, hooknum);\n+\treturn handle_response_icmp(AF_INET6, skb, \u0026snet, cp, pp, \u0026ciph,\n+\t\t\t\t    ipvsh-\u003elen, hooknum);\n }\n #endif\n \n@@ -1545,7 +1541,8 @@ ip_vs_out_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *stat\n #endif\n \t\tif (unlikely(iph.protocol == IPPROTO_ICMP)) {\n \t\t\tint related;\n-\t\t\tint verdict = ip_vs_out_icmp(ipvs, skb, \u0026related, hooknum);\n+\t\t\tint verdict = ip_vs_out_icmp(ipvs, skb, \u0026related,\n+\t\t\t\t\t\t     hooknum, \u0026iph);\n \n \t\t\tif (related)\n \t\t\t\treturn verdict;\n@@ -1753,9 +1750,8 @@ static int ipvs_gre_decap(struct netns_ipvs *ipvs, struct sk_buff *skb,\n  */\n static int\n ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n-\t      unsigned int hooknum)\n+\t      unsigned int hooknum, struct ip_vs_iphdr *iph)\n {\n-\tstruct iphdr *iph;\n \tstruct icmphdr\t_icmph, *ic;\n \tstruct iphdr\t_ciph, *cih;\t/* The ip header contained within the ICMP */\n \tstruct ip_vs_iphdr ciph;\n@@ -1775,17 +1771,19 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n \tif (ip_is_fragment(ip_hdr(skb))) {\n \t\tif (ip_vs_gather_frags(ipvs, skb, ip_vs_defrag_user(hooknum)))\n \t\t\treturn NF_STOLEN;\n+\t\tif (!ip_vs_fill_iph_skb(AF_INET, skb, false, iph))\n+\t\t\treturn NF_ACCEPT;\n \t}\n \n-\tiph = ip_hdr(skb);\n-\toffset = ihl = iph-\u003eihl * 4;\n+\tihl = iph-\u003elen;\n+\toffset = iph-\u003elen;\n \tic = skb_header_pointer(skb, offset, sizeof(_icmph), \u0026_icmph);\n \tif (ic == NULL)\n \t\treturn NF_DROP;\n \n \tIP_VS_DBG(12, \"Incoming ICMP (%d,%d) %pI4-\u003e%pI4\\n\",\n \t\t  ic-\u003etype, ntohs(icmp_id(ic)),\n-\t\t  \u0026iph-\u003esaddr, \u0026iph-\u003edaddr);\n+\t\t  \u0026iph-\u003esaddr.ip, \u0026iph-\u003edaddr.ip);\n \n \t/*\n \t * Work through seeing if this is for us.\n@@ -1898,10 +1896,11 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n \tverdict = NF_DROP;\n \n \t/* Ensure the checksum is correct */\n-\tif (!skb_csum_unnecessary(skb) \u0026\u0026 ip_vs_checksum_complete(skb, ihl)) {\n+\tif ((IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ || tunnel) \u0026\u0026\n+\t    !ip_vs_checksum_common_check(skb, ihl, IPPROTO_ICMP, AF_INET)) {\n \t\t/* Failed checksum! */\n \t\tIP_VS_DBG(1, \"Incoming ICMP: failed checksum from %pI4!\\n\",\n-\t\t\t  \u0026iph-\u003esaddr);\n+\t\t\t  \u0026iph-\u003esaddr.ip);\n \t\tgoto out;\n \t}\n \n@@ -1972,7 +1971,8 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n \tif (IPPROTO_TCP == cih-\u003eprotocol || IPPROTO_UDP == cih-\u003eprotocol ||\n \t    IPPROTO_SCTP == cih-\u003eprotocol)\n \t\toffset += 2 * sizeof(__u16);\n-\tverdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, \u0026ciph);\n+\tverdict = ip_vs_icmp_xmit(skb, cp, pp, iph-\u003elen, offset, hooknum,\n+\t\t\t\t  \u0026ciph);\n \n out:\n \tif (likely(!new_cp))\n@@ -2064,6 +2064,18 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \t\tgoto out;\n \t}\n \n+\tverdict = NF_DROP;\n+\n+\t/* Ensure the checksum is correct */\n+\tif (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ \u0026\u0026\n+\t    !ip_vs_checksum_common_check(skb, iph-\u003elen, IPPROTO_ICMPV6,\n+\t\t\t\t\t AF_INET6)) {\n+\t\t/* Failed checksum! */\n+\t\tIP_VS_DBG(1, \"Incoming ICMPv6: failed checksum from %pI6c!\\n\",\n+\t\t\t  \u0026iph-\u003esaddr);\n+\t\tgoto out;\n+\t}\n+\n \t/* do the statistics and put it back */\n \tip_vs_in_stats(cp, skb);\n \n@@ -2073,7 +2085,8 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n \t    IPPROTO_SCTP == ciph.protocol)\n \t\toffset += 2 * sizeof(__u16); /* Also mangle ports */\n \n-\tverdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum, \u0026ciph);\n+\tverdict = ip_vs_icmp_xmit_v6(skb, cp, pp, iph-\u003elen, offset, hooknum,\n+\t\t\t\t     \u0026ciph);\n \n out:\n \tif (likely(!new_cp))\n@@ -2152,7 +2165,7 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state\n \t\tif (unlikely(iph.protocol == IPPROTO_ICMP)) {\n \t\t\tint related;\n \t\t\tint verdict = ip_vs_in_icmp(ipvs, skb, \u0026related,\n-\t\t\t\t\t\t    hooknum);\n+\t\t\t\t\t\t    hooknum, \u0026iph);\n \n \t\t\tif (related)\n \t\t\t\treturn verdict;\n@@ -2288,6 +2301,7 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,\n \t\t   const struct nf_hook_state *state)\n {\n \tstruct netns_ipvs *ipvs = net_ipvs(state-\u003enet);\n+\tstruct ip_vs_iphdr iphdr;\n \tint r;\n \n \t/* ipvs enabled in this netns ? */\n@@ -2297,10 +2311,9 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,\n \tif (state-\u003epf == NFPROTO_IPV4) {\n \t\tif (ip_hdr(skb)-\u003eprotocol != IPPROTO_ICMP)\n \t\t\treturn NF_ACCEPT;\n+\t\tip_vs_fill_iph_skb(AF_INET, skb, false, \u0026iphdr);\n #ifdef CONFIG_IP_VS_IPV6\n \t} else {\n-\t\tstruct ip_vs_iphdr iphdr;\n-\n \t\tip_vs_fill_iph_skb(AF_INET6, skb, false, \u0026iphdr);\n \n \t\tif (iphdr.protocol != IPPROTO_ICMPV6)\n@@ -2310,7 +2323,7 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,\n #endif\n \t}\n \n-\treturn ip_vs_in_icmp(ipvs, skb, \u0026r, state-\u003ehook);\n+\treturn ip_vs_in_icmp(ipvs, skb, \u0026r, state-\u003ehook, \u0026iphdr);\n }\n \n static const struct nf_hook_ops ip_vs_ops4[] = {\ndiff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c\nindex c67317be17dfaf..3dbd3096e1637b 100644\n--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c\n+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c\n@@ -11,7 +11,7 @@\n \n static int\n sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\tunsigned int sctphoff);\n+\t\tstruct ip_vs_iphdr *iph);\n \n static int\n sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,\n@@ -109,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!sctp_csum_check(cp-\u003eaf, skb, pp, sctphoff))\n+\t\tif (!sctp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/* Call application helper if needed */\n@@ -121,7 +121,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\tsctph = (void *) skb_network_header(skb) + sctphoff;\n+\tsctph = (void *)skb-\u003edata + sctphoff;\n \n \t/* Only update csum if we really have to */\n \tif (sctph-\u003esource != cp-\u003evport || payload_csum ||\n@@ -157,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!sctp_csum_check(cp-\u003eaf, skb, pp, sctphoff))\n+\t\tif (!sctp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/* Call application helper if needed */\n@@ -169,7 +169,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\tsctph = (void *) skb_network_header(skb) + sctphoff;\n+\tsctph = (void *)skb-\u003edata + sctphoff;\n \n \t/* Only update csum if we really have to */\n \tif (sctph-\u003edest != cp-\u003edport || payload_csum ||\n@@ -187,19 +187,22 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \n static int\n sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t\tunsigned int sctphoff)\n+\t\tstruct ip_vs_iphdr *iph)\n {\n+\tunsigned int sctphoff = iph-\u003elen;\n \tstruct sctphdr *sh;\n \t__le32 cmp, val;\n \n+\tif (!ip_vs_checksum_needed(skb, af))\n+\t\treturn 1;\n \tsh = (struct sctphdr *)(skb-\u003edata + sctphoff);\n \tcmp = sh-\u003echecksum;\n \tval = sctp_compute_cksum(skb, sctphoff);\n \n \tif (val != cmp) {\n \t\t/* CRC failure, dump it. */\n-\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, 0,\n-\t\t\t\t\"Failed checksum for\");\n+\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, iph-\u003eoff,\n+\t\t\t\t \"Failed checksum for\");\n \t\treturn 0;\n \t}\n \treturn 1;\ndiff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c\nindex f86b763efcc4dc..99a286fdc90c65 100644\n--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c\n+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c\n@@ -29,7 +29,7 @@\n \n static int\n tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t       unsigned int tcphoff);\n+\t       struct ip_vs_iphdr *iph);\n \n static int\n tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,\n@@ -166,7 +166,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!tcp_csum_check(cp-\u003eaf, skb, pp, tcphoff))\n+\t\tif (!tcp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/* Call application helper if needed */\n@@ -179,7 +179,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\ttcph = (void *)skb_network_header(skb) + tcphoff;\n+\ttcph = (void *)skb-\u003edata + tcphoff;\n \ttcph-\u003esource = cp-\u003evport;\n \n \t/* Adjust TCP checksums */\n@@ -244,7 +244,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!tcp_csum_check(cp-\u003eaf, skb, pp, tcphoff))\n+\t\tif (!tcp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/*\n@@ -260,7 +260,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\ttcph = (void *)skb_network_header(skb) + tcphoff;\n+\ttcph = (void *)skb-\u003edata + tcphoff;\n \ttcph-\u003edest = cp-\u003edport;\n \n \t/*\n@@ -302,41 +302,13 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \n static int\n tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t       unsigned int tcphoff)\n+\t       struct ip_vs_iphdr *iph)\n {\n-\tswitch (skb-\u003eip_summed) {\n-\tcase CHECKSUM_NONE:\n-\t\tskb-\u003ecsum = skb_checksum(skb, tcphoff, skb-\u003elen - tcphoff, 0);\n-\t\tfallthrough;\n-\tcase CHECKSUM_COMPLETE:\n-#ifdef CONFIG_IP_VS_IPV6\n-\t\tif (af == AF_INET6) {\n-\t\t\tif (csum_ipv6_magic(\u0026ipv6_hdr(skb)-\u003esaddr,\n-\t\t\t\t\t    \u0026ipv6_hdr(skb)-\u003edaddr,\n-\t\t\t\t\t    skb-\u003elen - tcphoff,\n-\t\t\t\t\t    IPPROTO_TCP,\n-\t\t\t\t\t    skb-\u003ecsum)) {\n-\t\t\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, 0,\n-\t\t\t\t\t\t \"Failed checksum for\");\n-\t\t\t\treturn 0;\n-\t\t\t}\n-\t\t} else\n-#endif\n-\t\t\tif (csum_tcpudp_magic(ip_hdr(skb)-\u003esaddr,\n-\t\t\t\t\t      ip_hdr(skb)-\u003edaddr,\n-\t\t\t\t\t      skb-\u003elen - tcphoff,\n-\t\t\t\t\t      ip_hdr(skb)-\u003eprotocol,\n-\t\t\t\t\t      skb-\u003ecsum)) {\n-\t\t\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, 0,\n-\t\t\t\t\t\t \"Failed checksum for\");\n-\t\t\t\treturn 0;\n-\t\t\t}\n-\t\tbreak;\n-\tdefault:\n-\t\t/* No need to checksum. */\n-\t\tbreak;\n+\tif (!ip_vs_checksum_common_check(skb, iph-\u003elen, IPPROTO_TCP, af)) {\n+\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, iph-\u003eoff,\n+\t\t\t\t \"Failed checksum for\");\n+\t\treturn 0;\n \t}\n-\n \treturn 1;\n }\n \ndiff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c\nindex 58f9e255927e2e..f32785682402dd 100644\n--- a/net/netfilter/ipvs/ip_vs_proto_udp.c\n+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c\n@@ -25,7 +25,7 @@\n \n static int\n udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t       unsigned int udphoff);\n+\t       struct ip_vs_iphdr *iph);\n \n static int\n udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,\n@@ -155,7 +155,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!udp_csum_check(cp-\u003eaf, skb, pp, udphoff))\n+\t\tif (!udp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/*\n@@ -170,7 +170,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\tudph = (void *)skb_network_header(skb) + udphoff;\n+\tudph = (void *)skb-\u003edata + udphoff;\n \tudph-\u003esource = cp-\u003evport;\n \n \t/*\n@@ -238,7 +238,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\tint ret;\n \n \t\t/* Some checks before mangling */\n-\t\tif (!udp_csum_check(cp-\u003eaf, skb, pp, udphoff))\n+\t\tif (!udp_csum_check(cp-\u003eaf, skb, pp, iph))\n \t\t\treturn 0;\n \n \t\t/*\n@@ -254,7 +254,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \t\t\tpayload_csum = true;\n \t}\n \n-\tudph = (void *)skb_network_header(skb) + udphoff;\n+\tudph = (void *)skb-\u003edata + udphoff;\n \tudph-\u003edest = cp-\u003edport;\n \n \t/*\n@@ -298,48 +298,20 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n \n static int\n udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,\n-\t       unsigned int udphoff)\n+\t       struct ip_vs_iphdr *iph)\n {\n \tstruct udphdr _udph, *uh;\n \n-\tuh = skb_header_pointer(skb, udphoff, sizeof(_udph), \u0026_udph);\n+\tuh = skb_header_pointer(skb, iph-\u003elen, sizeof(_udph), \u0026_udph);\n \tif (uh == NULL)\n \t\treturn 0;\n \n-\tif (uh-\u003echeck != 0) {\n-\t\tswitch (skb-\u003eip_summed) {\n-\t\tcase CHECKSUM_NONE:\n-\t\t\tskb-\u003ecsum = skb_checksum(skb, udphoff,\n-\t\t\t\t\t\t skb-\u003elen - udphoff, 0);\n-\t\t\tfallthrough;\n-\t\tcase CHECKSUM_COMPLETE:\n-#ifdef CONFIG_IP_VS_IPV6\n-\t\t\tif (af == AF_INET6) {\n-\t\t\t\tif (csum_ipv6_magic(\u0026ipv6_hdr(skb)-\u003esaddr,\n-\t\t\t\t\t\t    \u0026ipv6_hdr(skb)-\u003edaddr,\n-\t\t\t\t\t\t    skb-\u003elen - udphoff,\n-\t\t\t\t\t\t    IPPROTO_UDP,\n-\t\t\t\t\t\t    skb-\u003ecsum)) {\n-\t\t\t\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, 0,\n-\t\t\t\t\t\t\t \"Failed checksum for\");\n-\t\t\t\t\treturn 0;\n-\t\t\t\t}\n-\t\t\t} else\n-#endif\n-\t\t\t\tif (csum_tcpudp_magic(ip_hdr(skb)-\u003esaddr,\n-\t\t\t\t\t\t      ip_hdr(skb)-\u003edaddr,\n-\t\t\t\t\t\t      skb-\u003elen - udphoff,\n-\t\t\t\t\t\t      ip_hdr(skb)-\u003eprotocol,\n-\t\t\t\t\t\t      skb-\u003ecsum)) {\n-\t\t\t\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, 0,\n-\t\t\t\t\t\t\t \"Failed checksum for\");\n-\t\t\t\t\treturn 0;\n-\t\t\t\t}\n-\t\t\tbreak;\n-\t\tdefault:\n-\t\t\t/* No need to checksum. */\n-\t\t\tbreak;\n-\t\t}\n+\tif (!uh-\u003echeck)\n+\t\treturn 1;\n+\tif (!ip_vs_checksum_common_check(skb, iph-\u003elen, IPPROTO_UDP, af)) {\n+\t\tIP_VS_DBG_RL_PKT(0, af, pp, skb, iph-\u003eoff,\n+\t\t\t\t \"Failed checksum for\");\n+\t\treturn 0;\n \t}\n \treturn 1;\n }\ndiff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c\nindex 9fef4335da13fd..c23401c789de32 100644\n--- a/net/netfilter/ipvs/ip_vs_xmit.c\n+++ b/net/netfilter/ipvs/ip_vs_xmit.c\n@@ -1502,8 +1502,9 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n  */\n int\n ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n-\t\tstruct ip_vs_protocol *pp, int offset, unsigned int hooknum,\n-\t\tstruct ip_vs_iphdr *iph)\n+\t\tstruct ip_vs_protocol *pp, unsigned int toff,\n+\t\tunsigned int wlen, unsigned int hooknum,\n+\t\tstruct ip_vs_iphdr *ciph)\n {\n \tstruct rtable\t*rt;\t/* Route to the other host */\n \tint rc;\n@@ -1515,7 +1516,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t   translate address/port back */\n \tif (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {\n \t\tif (cp-\u003epacket_xmit)\n-\t\t\trc = cp-\u003epacket_xmit(skb, cp, pp, iph);\n+\t\t\trc = cp-\u003epacket_xmit(skb, cp, pp, ciph);\n \t\telse\n \t\t\trc = NF_ACCEPT;\n \t\t/* do not touch skb anymore */\n@@ -1533,7 +1534,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t\t  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |\n \t\t  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;\n \tlocal = __ip_vs_get_out_rt(cp-\u003eipvs, cp-\u003eaf, skb, cp-\u003edest, cp-\u003edaddr.ip, rt_mode,\n-\t\t\t\t   NULL, iph);\n+\t\t\t\t   NULL, ciph);\n \tif (local \u003c 0)\n \t\tgoto tx_error;\n \trt = skb_rtable(skb);\n@@ -1565,13 +1566,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t}\n \n \t/* copy-on-write the packet before mangling it */\n-\tif (skb_ensure_writable(skb, offset))\n+\tif (skb_ensure_writable(skb, wlen))\n \t\tgoto tx_error;\n \n \tif (skb_cow(skb, rt-\u003edst.dev-\u003ehard_header_len))\n \t\tgoto tx_error;\n \n-\tip_vs_nat_icmp(skb, pp, cp, 0);\n+\tip_vs_nat_icmp(skb, pp, cp, 0, toff);\n \n \t/* Another hack: avoid icmp_send in ip_fragment */\n \tskb-\u003eignore_df = 1;\n@@ -1587,8 +1588,9 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n #ifdef CONFIG_IP_VS_IPV6\n int\n ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n-\t\tstruct ip_vs_protocol *pp, int offset, unsigned int hooknum,\n-\t\tstruct ip_vs_iphdr *ipvsh)\n+\t\tstruct ip_vs_protocol *pp, unsigned int toff,\n+\t\tunsigned int wlen, unsigned int hooknum,\n+\t\tstruct ip_vs_iphdr *ciph)\n {\n \tstruct rt6_info\t*rt;\t/* Route to the other host */\n \tint rc;\n@@ -1600,7 +1602,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t   translate address/port back */\n \tif (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {\n \t\tif (cp-\u003epacket_xmit)\n-\t\t\trc = cp-\u003epacket_xmit(skb, cp, pp, ipvsh);\n+\t\t\trc = cp-\u003epacket_xmit(skb, cp, pp, ciph);\n \t\telse\n \t\t\trc = NF_ACCEPT;\n \t\t/* do not touch skb anymore */\n@@ -1617,7 +1619,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t\t  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |\n \t\t  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;\n \tlocal = __ip_vs_get_out_rt_v6(cp-\u003eipvs, cp-\u003eaf, skb, cp-\u003edest,\n-\t\t\t\t      \u0026cp-\u003edaddr.in6, NULL, ipvsh, 0, rt_mode);\n+\t\t\t\t      \u0026cp-\u003edaddr.in6, NULL, ciph, 0, rt_mode);\n \tif (local \u003c 0)\n \t\tgoto tx_error;\n \trt = dst_rt6_info(skb_dst(skb));\n@@ -1649,13 +1651,13 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t}\n \n \t/* copy-on-write the packet before mangling it */\n-\tif (skb_ensure_writable(skb, offset))\n+\tif (skb_ensure_writable(skb, wlen))\n \t\tgoto tx_error;\n \n \tif (skb_cow(skb, rt-\u003edst.dev-\u003ehard_header_len))\n \t\tgoto tx_error;\n \n-\tip_vs_nat_icmp_v6(skb, pp, cp, 0);\n+\tip_vs_nat_icmp_v6(skb, pp, cp, 0, toff, ciph);\n \n \t/* Another hack: avoid icmp_send in ip_fragment */\n \tskb-\u003eignore_df = 1;\n"
}

2/1 2026/07/21 04:38 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "IP_VS",
    "IP_VS_IPV6",
    "IP_VS_PROTO_TCP",
    "IP_VS_PROTO_UDP",
    "IP_VS_PROTO_SCTP"
  ],
  "FocusSymbols": [
    "ip_vs_in_icmp",
    "ip_vs_out_icmp",
    "ip_vs_in_icmp_v6",
    "ip_vs_out_icmp_v6",
    "ip_vs_forward_icmp",
    "ip_vs_icmp_xmit",
    "ip_vs_icmp_xmit_v6",
    "sctp_snat_handler",
    "sctp_dnat_handler",
    "tcp_snat_handler",
    "tcp_dnat_handler",
    "udp_snat_handler",
    "udp_dnat_handler",
    "ip_vs_nat_icmp",
    "ip_vs_nat_icmp_v6"
  ],
  "Reasoning": "The patch modifies core IPVS logic for handling checksums and NAT for ICMP, TCP, UDP, and SCTP packets. It introduces new checksum validation logic and alters packet mangling offsets. This is reachable core network functionality 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 cb4343b0810d96f39f5d0f7cc36ccb1a6f0bfcc1
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Jul 21 04:38:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 417ff51f62fc8e..c684a46ce15a54 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -25,7 +25,9 @@
 #include <linux/netfilter.h>		/* for union nf_inet_addr */
 #include <linux/ip.h>
 #include <linux/ipv6.h>			/* for struct ipv6hdr */
+#include <net/route.h>
 #include <net/ipv6.h>
+#include <net/ip6_fib.h>
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
 #include <net/netfilter/nf_conntrack.h>
 #endif
@@ -1972,8 +1974,9 @@ int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 int ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 		  struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
 int ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
-		    struct ip_vs_protocol *pp, int offset,
-		    unsigned int hooknum, struct ip_vs_iphdr *iph);
+		    struct ip_vs_protocol *pp, unsigned int toff,
+		    unsigned int wlen, unsigned int hooknum,
+		    struct ip_vs_iphdr *ciph);
 void ip_vs_dest_dst_rcu_free(struct rcu_head *head);
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -1986,8 +1989,9 @@ int ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 int ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 		     struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph);
 int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
-		       struct ip_vs_protocol *pp, int offset,
-		       unsigned int hooknum, struct ip_vs_iphdr *iph);
+		       struct ip_vs_protocol *pp, unsigned int toff,
+		       unsigned int wlen, unsigned int hooknum,
+		       struct ip_vs_iphdr *ciph);
 #endif
 
 #ifdef CONFIG_SYSCTL
@@ -2059,15 +2063,14 @@ static inline bool ip_vs_conn_use_hash2(struct ip_vs_conn *cp)
 }
 
 void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
-		    struct ip_vs_conn *cp, int dir);
+		    struct ip_vs_conn *cp, int dir, unsigned int toff);
 
 #ifdef CONFIG_IP_VS_IPV6
 void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
-		       struct ip_vs_conn *cp, int dir);
+		       struct ip_vs_conn *cp, int dir, unsigned int toff,
+		       struct ip_vs_iphdr *ciph);
 #endif
 
-__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset);
-
 static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)
 {
 	__be32 diff[2] = { ~old, new };
@@ -2093,6 +2096,36 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
 	return csum_partial(diff, sizeof(diff), oldsum);
 }
 
+static inline bool ip_vs_checksum_needed(struct sk_buff *skb, int af)
+{
+	/* Checksum unnecessary or already validated? */
+	if (skb_csum_unnecessary(skb))
+		return false;
+	/* LOCAL_OUT ? */
+	if (!skb->dev || skb->dev->flags & IFF_LOOPBACK)
+		return false;
+	/* !LOCAL_IN (FORWARD) ? */
+	if (af == AF_INET6) {
+		if (!(dst_rt6_info(skb_dst(skb))->rt6i_flags & RTF_LOCAL))
+			return false;
+	} else {
+		if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL))
+			return false;
+	}
+	return true;
+}
+
+/**
+ * ip_vs_checksum_common_check - validate checksum for TCP/UDP/ICMP
+ */
+static inline bool ip_vs_checksum_common_check(struct sk_buff *skb,
+					       int offset, int proto, int af)
+{
+	if (!ip_vs_checksum_needed(skb, af))
+		return true;
+	return !nf_checksum(skb, NF_INET_LOCAL_IN, offset, proto, af);
+}
+
 /* Forget current conntrack (unconfirmed) and attach notrack entry */
 static inline void ip_vs_notrack(struct sk_buff *skb)
 {
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index b0e00be85cb12c..11cbdbaf561daf 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -367,7 +367,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb,
 	if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
 		return 0;
 
-	th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
+	th = (struct tcphdr *)(skb->data + ipvsh->len);
 
 	/*
 	 *	Remember seq number in case this pkt gets resized
@@ -443,7 +443,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb,
 	if (skb_ensure_writable(skb, ipvsh->len + sizeof(*th)))
 		return 0;
 
-	th = (struct tcphdr *)(skb_network_header(skb) + ipvsh->len);
+	th = (struct tcphdr *)(skb->data + ipvsh->len);
 
 	/*
 	 *	Remember seq number in case this pkt gets resized
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index bafab93451d037..21db6af220eb09 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -867,7 +867,7 @@ static int sysctl_nat_icmp_send(struct netns_ipvs *ipvs) { return 0; }
 
 #endif
 
-__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
+static __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
 {
 	return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
 }
@@ -924,13 +924,12 @@ static int ip_vs_route_me_harder(struct netns_ipvs *ipvs, int af,
  * - inout: 1=in->out, 0=out->in
  */
 void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
-		    struct ip_vs_conn *cp, int inout)
+		    struct ip_vs_conn *cp, int inout, unsigned int toff)
 {
 	struct iphdr *iph	 = ip_hdr(skb);
-	unsigned int icmp_offset = iph->ihl*4;
-	struct icmphdr *icmph	 = (struct icmphdr *)(skb_network_header(skb) +
-						      icmp_offset);
+	struct icmphdr *icmph	 = (struct icmphdr *)(skb->data + toff);
 	struct iphdr *ciph	 = (struct iphdr *)(icmph + 1);
+	unsigned int coff = toff + sizeof(struct icmphdr);
 
 	if (inout) {
 		iph->saddr = cp->vaddr.ip;
@@ -957,48 +956,45 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 	/* And finally the ICMP checksum */
 	icmph->checksum = 0;
-	icmph->checksum = ip_vs_checksum_complete(skb, icmp_offset);
+	icmph->checksum = ip_vs_checksum_complete(skb, toff);
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	if (inout)
-		IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
-			"Forwarding altered outgoing ICMP");
+		IP_VS_DBG_PKT(11, AF_INET, pp, skb, coff,
+			      "Forwarding altered outgoing ICMP");
 	else
-		IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
-			"Forwarding altered incoming ICMP");
+		IP_VS_DBG_PKT(11, AF_INET, pp, skb, coff,
+			      "Forwarding altered incoming ICMP");
 }
 
 #ifdef CONFIG_IP_VS_IPV6
 void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
-		    struct ip_vs_conn *cp, int inout)
+		       struct ip_vs_conn *cp, int inout, unsigned int toff,
+		       struct ip_vs_iphdr *ciph)
 {
 	struct ipv6hdr *iph	 = ipv6_hdr(skb);
-	unsigned int icmp_offset = 0;
-	unsigned int offs	 = 0; /* header offset*/
 	int protocol;
 	struct icmp6hdr *icmph;
-	struct ipv6hdr *ciph;
-	unsigned short fragoffs;
+	struct ipv6hdr *cih;
 
-	ipv6_find_hdr(skb, &icmp_offset, IPPROTO_ICMPV6, &fragoffs, NULL);
-	icmph = (struct icmp6hdr *)(skb_network_header(skb) + icmp_offset);
-	offs = icmp_offset + sizeof(struct icmp6hdr);
-	ciph = (struct ipv6hdr *)(skb_network_header(skb) + offs);
+	icmph = (struct icmp6hdr *)(skb->data + toff);
+	cih = (struct ipv6hdr *)(skb->data + ciph->off);
 
-	protocol = ipv6_find_hdr(skb, &offs, -1, &fragoffs, NULL);
+	protocol = ciph->protocol;
 
 	if (inout) {
 		iph->saddr = cp->vaddr.in6;
-		ciph->daddr = cp->vaddr.in6;
+		cih->daddr = cp->vaddr.in6;
 	} else {
 		iph->daddr = cp->daddr.in6;
-		ciph->saddr = cp->daddr.in6;
+		cih->saddr = cp->daddr.in6;
 	}
 
 	/* the TCP/UDP/SCTP port */
-	if (!fragoffs && (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||
-			  IPPROTO_SCTP == protocol)) {
-		__be16 *ports = (void *)(skb_network_header(skb) + offs);
+	if (!ciph->fragoffs &&
+	    (protocol == IPPROTO_TCP  || protocol == IPPROTO_UDP ||
+	     protocol == IPPROTO_SCTP)) {
+		__be16 *ports = (void *)(skb->data + ciph->len);
 
 		IP_VS_DBG(11, "%s() changed port %d to %d\n", __func__,
 			      ntohs(inout ? ports[1] : ports[0]),
@@ -1011,19 +1007,17 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 	/* And finally the ICMP checksum */
 	icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr,
-					      skb->len - icmp_offset,
+					      skb->len - toff,
 					      IPPROTO_ICMPV6, 0);
-	skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset;
+	skb->csum_start = skb_headroom(skb) + toff;
 	skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
 	skb->ip_summed = CHECKSUM_PARTIAL;
 
 	if (inout)
-		IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
-			      (void *)ciph - (void *)iph,
+		IP_VS_DBG_PKT(11, AF_INET6, pp, skb, ciph->off,
 			      "Forwarding altered outgoing ICMPv6");
 	else
-		IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
-			      (void *)ciph - (void *)iph,
+		IP_VS_DBG_PKT(11, AF_INET6, pp, skb, ciph->off,
 			      "Forwarding altered incoming ICMPv6");
 }
 #endif
@@ -1033,36 +1027,38 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
  */
 static int handle_response_icmp(int af, struct sk_buff *skb,
 				union nf_inet_addr *snet,
-				__u8 protocol, struct ip_vs_conn *cp,
+				struct ip_vs_conn *cp,
 				struct ip_vs_protocol *pp,
-				unsigned int offset, unsigned int ihl,
-				unsigned int hooknum)
+				struct ip_vs_iphdr *ciph,
+				unsigned int toff, unsigned int hooknum)
 {
+	int iproto = af == AF_INET6 ? IPPROTO_ICMPV6 : IPPROTO_ICMP;
 	unsigned int verdict = NF_DROP;
+	unsigned int ctoff = ciph->len;
 
 	if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
 		goto after_nat;
 
 	/* Ensure the checksum is correct */
-	if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
+	if (!ip_vs_checksum_common_check(skb, toff, iproto, af)) {
 		/* Failed checksum! */
 		IP_VS_DBG_BUF(1, "Forward ICMP: failed checksum from %s!\n",
 			      IP_VS_DBG_ADDR(af, snet));
 		goto out;
 	}
 
-	if (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||
-	    IPPROTO_SCTP == protocol)
-		offset += 2 * sizeof(__u16);
-	if (skb_ensure_writable(skb, offset))
+	if (ciph->protocol == IPPROTO_TCP || ciph->protocol == IPPROTO_UDP ||
+	    ciph->protocol == IPPROTO_SCTP)
+		ctoff += 2 * sizeof(__u16);
+	if (skb_ensure_writable(skb, ctoff))
 		goto out;
 
 #ifdef CONFIG_IP_VS_IPV6
 	if (af == AF_INET6)
-		ip_vs_nat_icmp_v6(skb, pp, cp, 1);
+		ip_vs_nat_icmp_v6(skb, pp, cp, 1, toff, ciph);
 	else
 #endif
-		ip_vs_nat_icmp(skb, pp, cp, 1);
+		ip_vs_nat_icmp(skb, pp, cp, 1, toff);
 
 	if (ip_vs_route_me_harder(cp->ipvs, af, skb, hooknum))
 		goto out;
@@ -1090,9 +1086,9 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
  *	Currently handles error types - unreachable, quench, ttl exceeded.
  */
 static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,
-			  int *related, unsigned int hooknum)
+			  int *related, unsigned int hooknum,
+			  struct ip_vs_iphdr *ipvsh)
 {
-	struct iphdr *iph;
 	struct icmphdr	_icmph, *ic;
 	struct iphdr	_ciph, *cih;	/* The ip header contained within the ICMP */
 	struct ip_vs_iphdr ciph;
@@ -1107,17 +1103,19 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,
 	if (ip_is_fragment(ip_hdr(skb))) {
 		if (ip_vs_gather_frags(ipvs, skb, ip_vs_defrag_user(hooknum)))
 			return NF_STOLEN;
+		if (!ip_vs_fill_iph_skb(AF_INET, skb, false, ipvsh))
+			return NF_ACCEPT;
 	}
 
-	iph = ip_hdr(skb);
-	offset = ihl = iph->ihl * 4;
+	ihl = ipvsh->len;
+	offset = ipvsh->len;
 	ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
 	if (ic == NULL)
 		return NF_DROP;
 
 	IP_VS_DBG(12, "Outgoing ICMP (%d,%d) %pI4->%pI4\n",
 		  ic->type, ntohs(icmp_id(ic)),
-		  &iph->saddr, &iph->daddr);
+		  &ipvsh->saddr.ip, &ipvsh->daddr.ip);
 
 	/*
 	 * Work through seeing if this is for us.
@@ -1136,7 +1134,7 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,
 	/* Now find the contained IP header */
 	offset += sizeof(_icmph);
 	cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
-	if (cih == NULL)
+	if (!(cih && cih->version == 4 && cih->ihl >= 5))
 		return NF_ACCEPT; /* The packet looks wrong, ignore */
 
 	pp = ip_vs_proto_get(cih->protocol);
@@ -1159,9 +1157,9 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,
 	if (!cp)
 		return NF_ACCEPT;
 
-	snet.ip = iph->saddr;
-	return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp,
-				    pp, ciph.len, ihl, hooknum);
+	snet.ip = ipvsh->saddr.ip;
+	return handle_response_icmp(AF_INET, skb, &snet, cp, pp, &ciph, ihl,
+				    hooknum);
 }
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -1174,7 +1172,6 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
 	struct ip_vs_conn *cp;
 	struct ip_vs_protocol *pp;
 	union nf_inet_addr snet;
-	unsigned int offset;
 
 	*related = 1;
 	ic = frag_safe_skb_hp(skb, ipvsh->len, sizeof(_icmph), &_icmph);
@@ -1217,9 +1214,8 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
 		return NF_ACCEPT;
 
 	snet.in6 = ciph.saddr.in6;
-	offset = ciph.len;
-	return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp,
-				    pp, offset, ipvsh->len, hooknum);
+	return handle_response_icmp(AF_INET6, skb, &snet, cp, pp, &ciph,
+				    ipvsh->len, hooknum);
 }
 #endif
 
@@ -1545,7 +1541,8 @@ ip_vs_out_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *stat
 #endif
 		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
 			int related;
-			int verdict = ip_vs_out_icmp(ipvs, skb, &related, hooknum);
+			int verdict = ip_vs_out_icmp(ipvs, skb, &related,
+						     hooknum, &iph);
 
 			if (related)
 				return verdict;
@@ -1753,9 +1750,8 @@ static int ipvs_gre_decap(struct netns_ipvs *ipvs, struct sk_buff *skb,
  */
 static int
 ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
-	      unsigned int hooknum)
+	      unsigned int hooknum, struct ip_vs_iphdr *iph)
 {
-	struct iphdr *iph;
 	struct icmphdr	_icmph, *ic;
 	struct iphdr	_ciph, *cih;	/* The ip header contained within the ICMP */
 	struct ip_vs_iphdr ciph;
@@ -1775,17 +1771,19 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
 	if (ip_is_fragment(ip_hdr(skb))) {
 		if (ip_vs_gather_frags(ipvs, skb, ip_vs_defrag_user(hooknum)))
 			return NF_STOLEN;
+		if (!ip_vs_fill_iph_skb(AF_INET, skb, false, iph))
+			return NF_ACCEPT;
 	}
 
-	iph = ip_hdr(skb);
-	offset = ihl = iph->ihl * 4;
+	ihl = iph->len;
+	offset = iph->len;
 	ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
 	if (ic == NULL)
 		return NF_DROP;
 
 	IP_VS_DBG(12, "Incoming ICMP (%d,%d) %pI4->%pI4\n",
 		  ic->type, ntohs(icmp_id(ic)),
-		  &iph->saddr, &iph->daddr);
+		  &iph->saddr.ip, &iph->daddr.ip);
 
 	/*
 	 * Work through seeing if this is for us.
@@ -1898,10 +1896,11 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
 	verdict = NF_DROP;
 
 	/* Ensure the checksum is correct */
-	if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
+	if ((IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ || tunnel) &&
+	    !ip_vs_checksum_common_check(skb, ihl, IPPROTO_ICMP, AF_INET)) {
 		/* Failed checksum! */
 		IP_VS_DBG(1, "Incoming ICMP: failed checksum from %pI4!\n",
-			  &iph->saddr);
+			  &iph->saddr.ip);
 		goto out;
 	}
 
@@ -1972,7 +1971,8 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
 	if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol ||
 	    IPPROTO_SCTP == cih->protocol)
 		offset += 2 * sizeof(__u16);
-	verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum, &ciph);
+	verdict = ip_vs_icmp_xmit(skb, cp, pp, iph->len, offset, hooknum,
+				  &ciph);
 
 out:
 	if (likely(!new_cp))
@@ -2064,6 +2064,18 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
 		goto out;
 	}
 
+	verdict = NF_DROP;
+
+	/* Ensure the checksum is correct */
+	if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ &&
+	    !ip_vs_checksum_common_check(skb, iph->len, IPPROTO_ICMPV6,
+					 AF_INET6)) {
+		/* Failed checksum! */
+		IP_VS_DBG(1, "Incoming ICMPv6: failed checksum from %pI6c!\n",
+			  &iph->saddr);
+		goto out;
+	}
+
 	/* do the statistics and put it back */
 	ip_vs_in_stats(cp, skb);
 
@@ -2073,7 +2085,8 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
 	    IPPROTO_SCTP == ciph.protocol)
 		offset += 2 * sizeof(__u16); /* Also mangle ports */
 
-	verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum, &ciph);
+	verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, iph->len, offset, hooknum,
+				     &ciph);
 
 out:
 	if (likely(!new_cp))
@@ -2152,7 +2165,7 @@ ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state
 		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
 			int related;
 			int verdict = ip_vs_in_icmp(ipvs, skb, &related,
-						    hooknum);
+						    hooknum, &iph);
 
 			if (related)
 				return verdict;
@@ -2288,6 +2301,7 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,
 		   const struct nf_hook_state *state)
 {
 	struct netns_ipvs *ipvs = net_ipvs(state->net);
+	struct ip_vs_iphdr iphdr;
 	int r;
 
 	/* ipvs enabled in this netns ? */
@@ -2297,10 +2311,9 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,
 	if (state->pf == NFPROTO_IPV4) {
 		if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
 			return NF_ACCEPT;
+		ip_vs_fill_iph_skb(AF_INET, skb, false, &iphdr);
 #ifdef CONFIG_IP_VS_IPV6
 	} else {
-		struct ip_vs_iphdr iphdr;
-
 		ip_vs_fill_iph_skb(AF_INET6, skb, false, &iphdr);
 
 		if (iphdr.protocol != IPPROTO_ICMPV6)
@@ -2310,7 +2323,7 @@ ip_vs_forward_icmp(void *priv, struct sk_buff *skb,
 #endif
 	}
 
-	return ip_vs_in_icmp(ipvs, skb, &r, state->hook);
+	return ip_vs_in_icmp(ipvs, skb, &r, state->hook, &iphdr);
 }
 
 static const struct nf_hook_ops ip_vs_ops4[] = {
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index c67317be17dfaf..3dbd3096e1637b 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -11,7 +11,7 @@
 
 static int
 sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-		unsigned int sctphoff);
+		struct ip_vs_iphdr *iph);
 
 static int
 sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
@@ -109,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!sctp_csum_check(cp->af, skb, pp, sctphoff))
+		if (!sctp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/* Call application helper if needed */
@@ -121,7 +121,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	sctph = (void *) skb_network_header(skb) + sctphoff;
+	sctph = (void *)skb->data + sctphoff;
 
 	/* Only update csum if we really have to */
 	if (sctph->source != cp->vport || payload_csum ||
@@ -157,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!sctp_csum_check(cp->af, skb, pp, sctphoff))
+		if (!sctp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/* Call application helper if needed */
@@ -169,7 +169,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	sctph = (void *) skb_network_header(skb) + sctphoff;
+	sctph = (void *)skb->data + sctphoff;
 
 	/* Only update csum if we really have to */
 	if (sctph->dest != cp->dport || payload_csum ||
@@ -187,19 +187,22 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 static int
 sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-		unsigned int sctphoff)
+		struct ip_vs_iphdr *iph)
 {
+	unsigned int sctphoff = iph->len;
 	struct sctphdr *sh;
 	__le32 cmp, val;
 
+	if (!ip_vs_checksum_needed(skb, af))
+		return 1;
 	sh = (struct sctphdr *)(skb->data + sctphoff);
 	cmp = sh->checksum;
 	val = sctp_compute_cksum(skb, sctphoff);
 
 	if (val != cmp) {
 		/* CRC failure, dump it. */
-		IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
-				"Failed checksum for");
+		IP_VS_DBG_RL_PKT(0, af, pp, skb, iph->off,
+				 "Failed checksum for");
 		return 0;
 	}
 	return 1;
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index f86b763efcc4dc..99a286fdc90c65 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -29,7 +29,7 @@
 
 static int
 tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-	       unsigned int tcphoff);
+	       struct ip_vs_iphdr *iph);
 
 static int
 tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
@@ -166,7 +166,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!tcp_csum_check(cp->af, skb, pp, tcphoff))
+		if (!tcp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/* Call application helper if needed */
@@ -179,7 +179,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	tcph = (void *)skb_network_header(skb) + tcphoff;
+	tcph = (void *)skb->data + tcphoff;
 	tcph->source = cp->vport;
 
 	/* Adjust TCP checksums */
@@ -244,7 +244,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!tcp_csum_check(cp->af, skb, pp, tcphoff))
+		if (!tcp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/*
@@ -260,7 +260,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	tcph = (void *)skb_network_header(skb) + tcphoff;
+	tcph = (void *)skb->data + tcphoff;
 	tcph->dest = cp->dport;
 
 	/*
@@ -302,41 +302,13 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 static int
 tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-	       unsigned int tcphoff)
+	       struct ip_vs_iphdr *iph)
 {
-	switch (skb->ip_summed) {
-	case CHECKSUM_NONE:
-		skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
-		fallthrough;
-	case CHECKSUM_COMPLETE:
-#ifdef CONFIG_IP_VS_IPV6
-		if (af == AF_INET6) {
-			if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-					    &ipv6_hdr(skb)->daddr,
-					    skb->len - tcphoff,
-					    IPPROTO_TCP,
-					    skb->csum)) {
-				IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
-						 "Failed checksum for");
-				return 0;
-			}
-		} else
-#endif
-			if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
-					      ip_hdr(skb)->daddr,
-					      skb->len - tcphoff,
-					      ip_hdr(skb)->protocol,
-					      skb->csum)) {
-				IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
-						 "Failed checksum for");
-				return 0;
-			}
-		break;
-	default:
-		/* No need to checksum. */
-		break;
+	if (!ip_vs_checksum_common_check(skb, iph->len, IPPROTO_TCP, af)) {
+		IP_VS_DBG_RL_PKT(0, af, pp, skb, iph->off,
+				 "Failed checksum for");
+		return 0;
 	}
-
 	return 1;
 }
 
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index 58f9e255927e2e..f32785682402dd 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -25,7 +25,7 @@
 
 static int
 udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-	       unsigned int udphoff);
+	       struct ip_vs_iphdr *iph);
 
 static int
 udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
@@ -155,7 +155,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!udp_csum_check(cp->af, skb, pp, udphoff))
+		if (!udp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/*
@@ -170,7 +170,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	udph = (void *)skb_network_header(skb) + udphoff;
+	udph = (void *)skb->data + udphoff;
 	udph->source = cp->vport;
 
 	/*
@@ -238,7 +238,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 		int ret;
 
 		/* Some checks before mangling */
-		if (!udp_csum_check(cp->af, skb, pp, udphoff))
+		if (!udp_csum_check(cp->af, skb, pp, iph))
 			return 0;
 
 		/*
@@ -254,7 +254,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 			payload_csum = true;
 	}
 
-	udph = (void *)skb_network_header(skb) + udphoff;
+	udph = (void *)skb->data + udphoff;
 	udph->dest = cp->dport;
 
 	/*
@@ -298,48 +298,20 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
 
 static int
 udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
-	       unsigned int udphoff)
+	       struct ip_vs_iphdr *iph)
 {
 	struct udphdr _udph, *uh;
 
-	uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph);
+	uh = skb_header_pointer(skb, iph->len, sizeof(_udph), &_udph);
 	if (uh == NULL)
 		return 0;
 
-	if (uh->check != 0) {
-		switch (skb->ip_summed) {
-		case CHECKSUM_NONE:
-			skb->csum = skb_checksum(skb, udphoff,
-						 skb->len - udphoff, 0);
-			fallthrough;
-		case CHECKSUM_COMPLETE:
-#ifdef CONFIG_IP_VS_IPV6
-			if (af == AF_INET6) {
-				if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-						    &ipv6_hdr(skb)->daddr,
-						    skb->len - udphoff,
-						    IPPROTO_UDP,
-						    skb->csum)) {
-					IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
-							 "Failed checksum for");
-					return 0;
-				}
-			} else
-#endif
-				if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
-						      ip_hdr(skb)->daddr,
-						      skb->len - udphoff,
-						      ip_hdr(skb)->protocol,
-						      skb->csum)) {
-					IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
-							 "Failed checksum for");
-					return 0;
-				}
-			break;
-		default:
-			/* No need to checksum. */
-			break;
-		}
+	if (!uh->check)
+		return 1;
+	if (!ip_vs_checksum_common_check(skb, iph->len, IPPROTO_UDP, af)) {
+		IP_VS_DBG_RL_PKT(0, af, pp, skb, iph->off,
+				 "Failed checksum for");
+		return 0;
 	}
 	return 1;
 }
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 9fef4335da13fd..c23401c789de32 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -1502,8 +1502,9 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
  */
 int
 ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
-		struct ip_vs_protocol *pp, int offset, unsigned int hooknum,
-		struct ip_vs_iphdr *iph)
+		struct ip_vs_protocol *pp, unsigned int toff,
+		unsigned int wlen, unsigned int hooknum,
+		struct ip_vs_iphdr *ciph)
 {
 	struct rtable	*rt;	/* Route to the other host */
 	int rc;
@@ -1515,7 +1516,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	   translate address/port back */
 	if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {
 		if (cp->packet_xmit)
-			rc = cp->packet_xmit(skb, cp, pp, iph);
+			rc = cp->packet_xmit(skb, cp, pp, ciph);
 		else
 			rc = NF_ACCEPT;
 		/* do not touch skb anymore */
@@ -1533,7 +1534,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 		  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
 		  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
 	local = __ip_vs_get_out_rt(cp->ipvs, cp->af, skb, cp->dest, cp->daddr.ip, rt_mode,
-				   NULL, iph);
+				   NULL, ciph);
 	if (local < 0)
 		goto tx_error;
 	rt = skb_rtable(skb);
@@ -1565,13 +1566,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	}
 
 	/* copy-on-write the packet before mangling it */
-	if (skb_ensure_writable(skb, offset))
+	if (skb_ensure_writable(skb, wlen))
 		goto tx_error;
 
 	if (skb_cow(skb, rt->dst.dev->hard_header_len))
 		goto tx_error;
 
-	ip_vs_nat_icmp(skb, pp, cp, 0);
+	ip_vs_nat_icmp(skb, pp, cp, 0, toff);
 
 	/* Another hack: avoid icmp_send in ip_fragment */
 	skb->ignore_df = 1;
@@ -1587,8 +1588,9 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 #ifdef CONFIG_IP_VS_IPV6
 int
 ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
-		struct ip_vs_protocol *pp, int offset, unsigned int hooknum,
-		struct ip_vs_iphdr *ipvsh)
+		struct ip_vs_protocol *pp, unsigned int toff,
+		unsigned int wlen, unsigned int hooknum,
+		struct ip_vs_iphdr *ciph)
 {
 	struct rt6_info	*rt;	/* Route to the other host */
 	int rc;
@@ -1600,7 +1602,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	   translate address/port back */
 	if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {
 		if (cp->packet_xmit)
-			rc = cp->packet_xmit(skb, cp, pp, ipvsh);
+			rc = cp->packet_xmit(skb, cp, pp, ciph);
 		else
 			rc = NF_ACCEPT;
 		/* do not touch skb anymore */
@@ -1617,7 +1619,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 		  IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
 		  IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
 	local = __ip_vs_get_out_rt_v6(cp->ipvs, cp->af, skb, cp->dest,
-				      &cp->daddr.in6, NULL, ipvsh, 0, rt_mode);
+				      &cp->daddr.in6, NULL, ciph, 0, rt_mode);
 	if (local < 0)
 		goto tx_error;
 	rt = dst_rt6_info(skb_dst(skb));
@@ -1649,13 +1651,13 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	}
 
 	/* copy-on-write the packet before mangling it */
-	if (skb_ensure_writable(skb, offset))
+	if (skb_ensure_writable(skb, wlen))
 		goto tx_error;
 
 	if (skb_cow(skb, rt->dst.dev->hard_header_len))
 		goto tx_error;
 
-	ip_vs_nat_icmp_v6(skb, pp, cp, 0);
+	ip_vs_nat_icmp_v6(skb, pp, cp, 0, toff, ciph);
 
 	/* Another hack: avoid icmp_send in ip_fragment */
 	skb->ignore_df = 1;

3/2 2026/07/21 04:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14860
							output: 34
							thoughts: 342
						

Thoughts:
**Checksum Validation Changes in IPVS: A Quick Assessment**

Okay, so I'm looking at this patch for IPVS and my initial impression is that this is focused work, definitely within reach of the kernel. It’s making changes to the checksum validation and update process within the IPVS code itself. Specifically, this patch seems to introduce functions like `ip_vs_checksum_needed` and `ip_vs_checksum_common_check`. Furthermore, it's modifying a bunch of crucial functions that handle ICMP, TCP, UDP, and SCTP packets – `ip_vs_nat_icmp`, `ip_vs_nat_icmp_v6`, `handle_response_icmp`, `ip_vs_out_icmp`, `ip_vs_in_icmp`, `ip_vs_in_icmp_v6`, `ip_vs_forward_icmp` and the various checksum check functions for sctp, tcp and udp. It also touches `ip_vs_icmp_xmit` and `ip_vs_icmp_xmit_v6`.

Knowing IPVS is a load balancer that sits on top of netfilter, this is clearly functional code and I think it's a good candidate for fuzzing. We have checksums here, that always warrants fuzzing.

My next step is to nail down the relevant configuration options. `CONFIG_IP_VS` obviously enables the core IPVS functionality. We’ve got `CONFIG_IP_VS_IPV6` for IPv6 support and `CONFIG_IP_VS_PROTO_SCTP` for SCTP. TCP and UDP are pretty much baked in if IPVS is enabled, which makes sense. I’m just wondering about NAT support. Is there a separate `CONFIG_IP_VS_NAT` or is it implicitly enabled when IPVS is enabled. I’ll need to check the kernel config options more closely on that point.



4/2 2026/07/21 04:38 tool grepper
0m Args:
{
  "Expression": "config IP_VS",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "Output": "net/netfilter/ipvs/Kconfig-4-#\nnet/netfilter/ipvs/Kconfig:5:menuconfig IP_VS\nnet/netfilter/ipvs/Kconfig-6-\ttristate \"IP virtual server support\"\n--\nnet/netfilter/ipvs/Kconfig=286=comment 'IPVS SH scheduler'\nnet/netfilter/ipvs/Kconfig-287-\nnet/netfilter/ipvs/Kconfig:288:config IP_VS_SH_TAB_BITS\nnet/netfilter/ipvs/Kconfig-289-\tint \"IPVS source hashing table size (the Nth power of 2)\"\n--\nnet/netfilter/ipvs/Kconfig=301=comment 'IPVS MH scheduler'\nnet/netfilter/ipvs/Kconfig-302-\nnet/netfilter/ipvs/Kconfig:303:config IP_VS_MH_TAB_INDEX\nnet/netfilter/ipvs/Kconfig-304-\tint \"IPVS maglev hashing table index of size (the prime numbers)\"\n"
}

5/2 2026/07/21 04:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 15911
							output: 34
							thoughts: 20
						

Thoughts:
Here's a summary of my thought process, as requested:

**Diving into the IPVS Kconfig**

Alright, let's see what we're dealing with in the `net/netfilter/ipvs/Kconfig` file. I need to get a clear picture of the configuration options available for IPVS. I'm thinking, by examining the `Kconfig` file, I can get a granular understanding of the configurable features and their dependencies. This will help me understand how to leverage it within my current work, or plan further development/troubleshooting. I expect to find definitions for all the different IPVS modules, features like connection tracking, scheduling algorithms, and any associated kernel parameters. Understanding the available options is the first, and arguably most important, step. I need a solid understanding of this foundational configuration before I proceed with any deeper analysis.



6/2 2026/07/21 04:38 tool grepper
0m Args:
{
  "Expression": "config IP_VS",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "Output": "net/netfilter/ipvs/Kconfig-4-#\nnet/netfilter/ipvs/Kconfig:5:menuconfig IP_VS\nnet/netfilter/ipvs/Kconfig-6-\ttristate \"IP virtual server support\"\n--\nnet/netfilter/ipvs/Kconfig=286=comment 'IPVS SH scheduler'\nnet/netfilter/ipvs/Kconfig-287-\nnet/netfilter/ipvs/Kconfig:288:config IP_VS_SH_TAB_BITS\nnet/netfilter/ipvs/Kconfig-289-\tint \"IPVS source hashing table size (the Nth power of 2)\"\n--\nnet/netfilter/ipvs/Kconfig=301=comment 'IPVS MH scheduler'\nnet/netfilter/ipvs/Kconfig-302-\nnet/netfilter/ipvs/Kconfig:303:config IP_VS_MH_TAB_INDEX\nnet/netfilter/ipvs/Kconfig-304-\tint \"IPVS maglev hashing table index of size (the prime numbers)\"\n"
}

7/2 2026/07/21 04:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16414
							output: 48
							thoughts: 25
						

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

**Examining Kernel Internals for Connection Tracking**

Alright, time to dive in. I need to refresh my memory on the IPv6 and SCTP connection tracking implementation within the kernel. Let's see... a quick `grep` for `IP_VS_IPV6` and `IP_VS_PROTO_SCTP` should pinpoint the relevant code. That will quickly bring up the key data structures, function calls, and any subtle differences in how IPv6 versus SCTP traffic is handled by the connection tracking module. I'm especially interested in whether the SCTP handling has the same level of granular control as TCP or UDP, considering the multi-homing aspect of SCTP. I'll be looking for any hints about how association identifiers are managed, and how they relate to the underlying flow data. This grep is a good initial scan to understand the basic architecture and quickly locate areas for deeper investigation.



8/2 2026/07/21 04:38 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config IP_VS_IPV6|config IP_VS_PROTO_SCTP",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "error": "no matches"
}

9/2 2026/07/21 04:38 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16707
							output: 35
							thoughts: 30
						

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

**Kernel Configuration Hunting**

Alright, let's cut to the chase. I need to figure out how `IP_VS` is configured within the kernel. Rather than meticulously sifting through the source, let's leverage the Kconfig system. A quick and dirty approach seems most efficient right now. I'll just grep for the string `config IP_VS` in the `net/netfilter/ipvs/Kconfig` file. I'm not overly concerned about an exact match initially; a broader search will hopefully quickly reveal the relevant configuration option, its dependencies, and perhaps some associated documentation within the Kconfig file. I'll filter out the irrelevant results later if needed.



10/2 2026/07/21 04:39 tool grepper
0m Args:
{
  "Expression": "^config IP_VS",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "Output": "net/netfilter/ipvs/Kconfig=286=comment 'IPVS SH scheduler'\nnet/netfilter/ipvs/Kconfig-287-\nnet/netfilter/ipvs/Kconfig:288:config IP_VS_SH_TAB_BITS\nnet/netfilter/ipvs/Kconfig-289-\tint \"IPVS source hashing table size (the Nth power of 2)\"\n--\nnet/netfilter/ipvs/Kconfig=301=comment 'IPVS MH scheduler'\nnet/netfilter/ipvs/Kconfig-302-\nnet/netfilter/ipvs/Kconfig:303:config IP_VS_MH_TAB_INDEX\nnet/netfilter/ipvs/Kconfig-304-\tint \"IPVS maglev hashing table index of size (the prime numbers)\"\n"
}

11/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 17144
							output: 33
							thoughts: 22
						

Thoughts:
Here's my take on those thoughts:

**Analyzing the IPVS Configuration Landscape**

Okay, time to dig into the `net/netfilter/ipvs/Kconfig` file. I need to get a clear picture of what configuration options are available for IPVS. Understanding the dependencies and features defined within this Kconfig is crucial for any IPVS-related project, be it optimization, debugging, or even just building a custom kernel. I need to see what knobs we have to tune performance, security, and behavior. This Kconfig file holds the keys to understanding the entire IPVS configuration ecosystem, so I'll be meticulously examining each symbol, its dependencies, and its default values. Let's see what gems are hidden in there!



12/2 2026/07/21 04:39 tool grepper
0m Args:
{
  "Expression": "^config ",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "Output": "net/netfilter/ipvs/Kconfig=100=config\tIP_VS_PROTO_AH\n--\nnet/netfilter/ipvs/Kconfig-105-\nnet/netfilter/ipvs/Kconfig:106:config  IP_VS_PROTO_SCTP\nnet/netfilter/ipvs/Kconfig-107-\tbool \"SCTP load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig=147=config\tIP_VS_WLC\n--\nnet/netfilter/ipvs/Kconfig-156-\nnet/netfilter/ipvs/Kconfig:157:config  IP_VS_FO\nnet/netfilter/ipvs/Kconfig-158-\t\ttristate \"weighted failover scheduling\"\n--\nnet/netfilter/ipvs/Kconfig-166-\nnet/netfilter/ipvs/Kconfig:167:config  IP_VS_OVF\nnet/netfilter/ipvs/Kconfig-168-\ttristate \"weighted overflow scheduling\"\n--\nnet/netfilter/ipvs/Kconfig=178=config\tIP_VS_LBLC\n--\nnet/netfilter/ipvs/Kconfig-191-\nnet/netfilter/ipvs/Kconfig:192:config  IP_VS_LBLCR\nnet/netfilter/ipvs/Kconfig-193-\ttristate \"locality-based least-connection with replication scheduling\"\n--\nnet/netfilter/ipvs/Kconfig=286=comment 'IPVS SH scheduler'\nnet/netfilter/ipvs/Kconfig-287-\nnet/netfilter/ipvs/Kconfig:288:config IP_VS_SH_TAB_BITS\nnet/netfilter/ipvs/Kconfig-289-\tint \"IPVS source hashing table size (the Nth power of 2)\"\n--\nnet/netfilter/ipvs/Kconfig=301=comment 'IPVS MH scheduler'\nnet/netfilter/ipvs/Kconfig-302-\nnet/netfilter/ipvs/Kconfig:303:config IP_VS_MH_TAB_INDEX\nnet/netfilter/ipvs/Kconfig-304-\tint \"IPVS maglev hashing table index of size (the prime numbers)\"\n--\nnet/netfilter/ipvs/Kconfig=345=config\tIP_VS_PE_SIP\n--\nnet/netfilter/ipvs/Kconfig-351-\nnet/netfilter/ipvs/Kconfig:352:config GCOV_PROFILE_IPVS\nnet/netfilter/ipvs/Kconfig-353-\tbool \"Enable GCOV profiling for IPVS\"\n"
}

13/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 18021
							output: 34
							thoughts: 14
						

Thoughts:
Here's my thought process, as if I were considering this myself:

**Debugging a Network Configuration**

Okay, hold on a second. I'm looking at this code, and I see a reference to `IP_VS_IPV6`. Now, where in the world is that constant defined? I need to track down where this macro or variable is declared. It could be in a header file, a configuration file, or even dynamically generated. I need to understand its value to comprehend what's happening in this particular function or section of the program. Is it a flag, a numerical constant? This has big implications for how IPV6 is being handled. I need to find the definition to ensure the code is behaving as expected, and that the appropriate IPv6 behavior is triggered. If I can't find it, I'm going to have to do some deeper digging to track down this critical piece of information.



14/2 2026/07/21 04:39 tool grepper
0m Args:
{
  "Expression": "IP_VS_IPV6",
  "PathPrefix": "net/netfilter/ipvs/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 507 lines.\nUse more precise expression if possible.\n\nnet/netfilter/ipvs/Kconfig=27=if IP_VS\nnet/netfilter/ipvs/Kconfig-28-\nnet/netfilter/ipvs/Kconfig:29:config\tIP_VS_IPV6\nnet/netfilter/ipvs/Kconfig-30-\tbool \"IPv6 support for IPVS\"\n--\nnet/netfilter/ipvs/ip_vs_conn.c=54=static struct kmem_cache *ip_vs_conn_cachep __read_mostly;\n--\nnet/netfilter/ipvs/ip_vs_conn.c-56-/* We need an addrstrlen that works with or without v6 */\nnet/netfilter/ipvs/ip_vs_conn.c:57:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-58-#define IP_VS_ADDRSTRLEN INET6_ADDRSTRLEN\n--\nnet/netfilter/ipvs/ip_vs_conn.c=166=static u32 ip_vs_conn_hashkey(struct ip_vs_rht *t, int af, unsigned int proto,\n--\nnet/netfilter/ipvs/ip_vs_conn.c-172-\nnet/netfilter/ipvs/ip_vs_conn.c:173:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-174-\tif (af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_conn.c=927=static inline void ip_vs_bind_xmit(struct ip_vs_conn *cp)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-934-\tcase IP_VS_CONN_F_TUNNEL:\nnet/netfilter/ipvs/ip_vs_conn.c:935:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-936-\t\tif (cp-\u003edaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-956-\nnet/netfilter/ipvs/ip_vs_conn.c:957:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-958-static inline void ip_vs_bind_xmit_v6(struct ip_vs_conn *cp)\n--\nnet/netfilter/ipvs/ip_vs_conn.c=1066=void ip_vs_try_bind_dest(struct ip_vs_conn *cp)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1099-\t\tcp-\u003epacket_xmit = NULL;\nnet/netfilter/ipvs/ip_vs_conn.c:1100:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1101-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c=1353=ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1442-\t/* Bind its packet transmitter */\nnet/netfilter/ipvs/ip_vs_conn.c:1443:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1444-\tif (p-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c=1583=static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1605-\nnet/netfilter/ipvs/ip_vs_conn.c:1606:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1607-\t\tif (cp-\u003edaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1613-\nnet/netfilter/ipvs/ip_vs_conn.c:1614:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1615-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c=1658=static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1667-\nnet/netfilter/ipvs/ip_vs_conn.c:1668:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1669-\t\tif (cp-\u003edaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_conn.c-1675-\nnet/netfilter/ipvs/ip_vs_conn.c:1676:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_conn.c-1677-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c-44-\nnet/netfilter/ipvs/ip_vs_core.c:45:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-46-#include \u003cnet/ipv6.h\u003e\n--\nnet/netfilter/ipvs/ip_vs_core.c=89=const char *ip_vs_proto_name(unsigned int proto)\n--\nnet/netfilter/ipvs/ip_vs_core.c-103-\t\treturn \"ICMP\";\nnet/netfilter/ipvs/ip_vs_core.c:104:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-105-\tcase IPPROTO_ICMPV6:\n--\nnet/netfilter/ipvs/ip_vs_core.c=284=u32 ip_vs_rht_hash_linfo(struct ip_vs_rht *t, int af,\n--\nnet/netfilter/ipvs/ip_vs_core.c-288-\nnet/netfilter/ipvs/ip_vs_core.c:289:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-290-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=431=ip_vs_sched_persist(struct ip_vs_service *svc,\n--\nnet/netfilter/ipvs/ip_vs_core.c-455-\t/* Mask saddr with the netmask to adjust template granularity */\nnet/netfilter/ipvs/ip_vs_core.c:456:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-457-\tif (svc-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=748=static inline int ip_vs_addr_is_unicast(struct net *net, int af,\n--\nnet/netfilter/ipvs/ip_vs_core.c-750-{\nnet/netfilter/ipvs/ip_vs_core.c:751:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-752-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=763=int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c-838-\t */\nnet/netfilter/ipvs/ip_vs_core.c:839:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-840-\tif (svc-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_core.c=898=static int ip_vs_route_me_harder(struct netns_ipvs *ipvs, int af,\n--\nnet/netfilter/ipvs/ip_vs_core.c-905-\t\treturn 0;\nnet/netfilter/ipvs/ip_vs_core.c:906:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-907-\tif (af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_core.c=926=void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_core.c-969-\nnet/netfilter/ipvs/ip_vs_core.c:970:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-971-void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_core.c=1028=static int handle_response_icmp(int af, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1055-\nnet/netfilter/ipvs/ip_vs_core.c:1056:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1057-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=1088=static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1164-\nnet/netfilter/ipvs/ip_vs_core.c:1165:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1166-static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c=1302=struct ip_vs_conn *ip_vs_new_conn_out(struct ip_vs_service *svc,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1329-\t\t/* apply netmask the same way ingress-side does */\nnet/netfilter/ipvs/ip_vs_core.c:1330:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1331-\t\tif (svc-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=1431=handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1449-\nnet/netfilter/ipvs/ip_vs_core.c:1450:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1451-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_core.c=1502=ip_vs_out_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)\n--\nnet/netfilter/ipvs/ip_vs_core.c-1529-\tip_vs_fill_iph_skb(af, skb, false, \u0026iph);\nnet/netfilter/ipvs/ip_vs_core.c:1530:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1531-\tif (af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_core.c-1556-\t/* reassemble IP fragments */\nnet/netfilter/ipvs/ip_vs_core.c:1557:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1558-\tif (af == AF_INET)\n--\nnet/netfilter/ipvs/ip_vs_core.c-1615-\t\t\t\t\t\tiph.len)))) {\nnet/netfilter/ipvs/ip_vs_core.c:1616:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1617-\t\t\t\tif (af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_core.c=1752=ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1985-\nnet/netfilter/ipvs/ip_vs_core.c:1986:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-1987-static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c=2107=ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)\n--\nnet/netfilter/ipvs/ip_vs_core.c-2152-\nnet/netfilter/ipvs/ip_vs_core.c:2153:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-2154-\tif (af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_core.c=2300=ip_vs_forward_icmp(void *priv, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2314-\t\tip_vs_fill_iph_skb(AF_INET, skb, false, \u0026iphdr);\nnet/netfilter/ipvs/ip_vs_core.c:2315:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-2316-\t} else {\n--\nnet/netfilter/ipvs/ip_vs_core.c=2329=static const struct nf_hook_ops ip_vs_ops4[] = {\n--\nnet/netfilter/ipvs/ip_vs_core.c-2376-\nnet/netfilter/ipvs/ip_vs_core.c:2377:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-2378-static const struct nf_hook_ops ip_vs_ops6[] = {\n--\nnet/netfilter/ipvs/ip_vs_core.c=2427=int ip_vs_register_hooks(struct netns_ipvs *ipvs, unsigned int af)\n--\nnet/netfilter/ipvs/ip_vs_core.c-2434-\tif (af == AF_INET6) {\nnet/netfilter/ipvs/ip_vs_core.c:2435:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-2436-\t\tops = ip_vs_ops6;\n--\nnet/netfilter/ipvs/ip_vs_core.c=2456=void ip_vs_unregister_hooks(struct netns_ipvs *ipvs, unsigned int af)\n--\nnet/netfilter/ipvs/ip_vs_core.c-2462-\tif (af == AF_INET6) {\nnet/netfilter/ipvs/ip_vs_core.c:2463:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_core.c-2464-\t\tops = ip_vs_ops6;\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-36-#include \u003cnet/ip.h\u003e\nnet/netfilter/ipvs/ip_vs_ctl.c:37:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-38-#include \u003cnet/ipv6.h\u003e\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=67=static void __ip_vs_del_service(struct ip_vs_service *svc, bool cleanup);\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-69-\nnet/netfilter/ipvs/ip_vs_ctl.c:70:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-71-/* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=868=static inline unsigned int ip_vs_rs_hashkey(int af,\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-874-\nnet/netfilter/ipvs/ip_vs_ctl.c:875:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-876-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=1402=ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-1407-\nnet/netfilter/ipvs/ip_vs_ctl.c:1408:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-1409-\tif (udest-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=1709=ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-1746-\nnet/netfilter/ipvs/ip_vs_ctl.c:1747:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-1748-\tif (u-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=1918=ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-1950-\nnet/netfilter/ipvs/ip_vs_ctl.c:1951:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-1952-\tif (u-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=2975=static int ip_vs_info_seq_show(struct seq_file *seq, void *v)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-2994-\t\tif (!svc-\u003efwmark) {\nnet/netfilter/ipvs/ip_vs_ctl.c:2995:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-2996-\t\t\tif (svc-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-3023-\t\tlist_for_each_entry_rcu(dest, \u0026svc-\u003edestinations, n_list) {\nnet/netfilter/ipvs/ip_vs_ctl.c:3024:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-3025-\t\t\tif (dest-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=4157=static bool ip_vs_is_af_valid(int af)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-4160-\t\treturn true;\nnet/netfilter/ipvs/ip_vs_ctl.c:4161:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-4162-\tif (af == AF_INET6 \u0026\u0026 ipv6_mod_enabled())\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=4430=static int ip_vs_genl_fill_daemon(struct sk_buff *skb, __u32 state,\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-4445-\t\tgoto nla_put_failure;\nnet/netfilter/ipvs/ip_vs_ctl.c:4446:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-4447-\tif (c-\u003emcast_af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=4517=static int ip_vs_genl_new_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs)\n--\nnet/netfilter/ipvs/ip_vs_ctl.c-4544-\t\tif (a) {\nnet/netfilter/ipvs/ip_vs_ctl.c:4545:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-4546-\t\t\tint addr_type;\n--\nnet/netfilter/ipvs/ip_vs_ctl.c=5172=static struct notifier_block ip_vs_dst_notifier = {\nnet/netfilter/ipvs/ip_vs_ctl.c-5173-\t.notifier_call = ip_vs_dst_event,\nnet/netfilter/ipvs/ip_vs_ctl.c:5174:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ctl.c-5175-\t.priority = ADDRCONF_NOTIFY_PRIORITY + 5,\n--\nnet/netfilter/ipvs/ip_vs_dh.c=70=static inline unsigned int ip_vs_dh_hashkey(int af, const union nf_inet_addr *addr)\n--\nnet/netfilter/ipvs/ip_vs_dh.c-73-\nnet/netfilter/ipvs/ip_vs_dh.c:74:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_dh.c-75-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_ftp.c=418=static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,\n--\nnet/netfilter/ipvs/ip_vs_ftp.c-463-\nnet/netfilter/ipvs/ip_vs_ftp.c:464:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_ftp.c-465-\t\t\t\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 proto == '2') {\n--\nnet/netfilter/ipvs/ip_vs_lblc.c=148=ip_vs_lblc_hashkey(int af, const union nf_inet_addr *addr)\n--\nnet/netfilter/ipvs/ip_vs_lblc.c-151-\nnet/netfilter/ipvs/ip_vs_lblc.c:152:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_lblc.c-153-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_lblcr.c=311=ip_vs_lblcr_hashkey(int af, const union nf_inet_addr *addr)\n--\nnet/netfilter/ipvs/ip_vs_lblcr.c-314-\nnet/netfilter/ipvs/ip_vs_lblcr.c:315:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_lblcr.c-316-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_mh.c=88=ip_vs_mh_hashkey(int af, const union nf_inet_addr *addr,\n--\nnet/netfilter/ipvs/ip_vs_mh.c-93-\nnet/netfilter/ipvs/ip_vs_mh.c:94:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_mh.c-95-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto.c=214=ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto.c-243-\nnet/netfilter/ipvs/ip_vs_proto.c:244:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto.c-245-static void\n--\nnet/netfilter/ipvs/ip_vs_proto.c=279=ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto.c-283-{\nnet/netfilter/ipvs/ip_vs_proto.c:284:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto.c-285-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c=92=sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-98-\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:99:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-100-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c=140=sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-146-\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:147:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-148-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=105=tcp_fast_csum_update(int af, struct tcphdr *tcph,\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-109-{\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:110:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-111-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=126=tcp_partial_csum_update(int af, struct tcphdr *tcph,\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-130-{\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:131:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-132-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=147=tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-154-\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:155:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-156-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-200-\t\tskb-\u003ecsum = skb_checksum(skb, tcphoff, skb-\u003elen - tcphoff, 0);\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:201:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-202-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=225=tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-232-\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:233:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-234-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-283-\t\tskb-\u003ecsum = skb_checksum(skb, tcphoff, skb-\u003elen - tcphoff, 0);\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:284:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-285-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=93=udp_fast_csum_update(int af, struct udphdr *uhdr,\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-97-{\nnet/netfilter/ipvs/ip_vs_proto_udp.c:98:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-99-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=115=udp_partial_csum_update(int af, struct udphdr *uhdr,\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-119-{\nnet/netfilter/ipvs/ip_vs_proto_udp.c:120:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-121-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=136=udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-143-\nnet/netfilter/ipvs/ip_vs_proto_udp.c:144:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-145-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-193-\t\tskb-\u003ecsum = skb_checksum(skb, udphoff, skb-\u003elen - udphoff, 0);\nnet/netfilter/ipvs/ip_vs_proto_udp.c:194:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-195-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=219=udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-226-\nnet/netfilter/ipvs/ip_vs_proto_udp.c:227:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-228-\tif (cp-\u003eaf == AF_INET6 \u0026\u0026 iph-\u003efragoffs)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-277-\t\tskb-\u003ecsum = skb_checksum(skb, udphoff, skb-\u003elen - udphoff, 0);\nnet/netfilter/ipvs/ip_vs_proto_udp.c:278:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_proto_udp.c-279-\t\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_sched.c=142=void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg)\n--\nnet/netfilter/ipvs/ip_vs_sched.c-149-\t\t\t     sched_name, svc-\u003efwmark, svc-\u003efwmark, msg);\nnet/netfilter/ipvs/ip_vs_sched.c:150:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sched.c-151-\t} else if (svc-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sh.c=83=ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr,\n--\nnet/netfilter/ipvs/ip_vs_sh.c-87-\nnet/netfilter/ipvs/ip_vs_sh.c:88:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sh.c-89-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_sync.c=629=void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-669-\nnet/netfilter/ipvs/ip_vs_sync.c:670:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-671-\tif (cp-\u003eaf == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-732-\nnet/netfilter/ipvs/ip_vs_sync.c:733:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-734-\tif (cp-\u003eaf == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sync.c=788=ip_vs_conn_fill_param_sync(struct netns_ipvs *ipvs, int af, union ip_vs_sync_conn *sc,\n--\nnet/netfilter/ipvs/ip_vs_sync.c-792-{\nnet/netfilter/ipvs/ip_vs_sync.c:793:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-794-\tif (af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1069=static inline int ip_vs_proc_sync_conn(struct netns_ipvs *ipvs, __u8 *p, __u8 *msg_end)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1083-\tif (s-\u003ev6.type \u0026 STYPE_F_INET6) {\nnet/netfilter/ipvs/ip_vs_sync.c:1084:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1085-\t\taf = AF_INET6;\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1181-\t\t\t\t);\nnet/netfilter/ipvs/ip_vs_sync.c:1182:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1183-\telse\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1297=static void set_mcast_loop(struct sock *sk, u_char loop)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1300-\tinet_assign_bit(MC_LOOP, sk, loop);\nnet/netfilter/ipvs/ip_vs_sync.c:1301:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1302-\tif (READ_ONCE(sk-\u003esk_family) == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1312=static void set_mcast_ttl(struct sock *sk, u_char ttl)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1318-\tWRITE_ONCE(inet-\u003emc_ttl, ttl);\nnet/netfilter/ipvs/ip_vs_sync.c:1319:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1320-\tif (sk-\u003esk_family == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1331=static void set_mcast_pmtudisc(struct sock *sk, int val)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1337-\tWRITE_ONCE(inet-\u003epmtudisc, val);\nnet/netfilter/ipvs/ip_vs_sync.c:1338:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1339-\tif (sk-\u003esk_family == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1352=static int set_mcast_if(struct sock *sk, struct net_device *dev)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1361-\t/*  inet-\u003emc_addr  = 0; */\nnet/netfilter/ipvs/ip_vs_sync.c:1362:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1363-\tif (sk-\u003esk_family == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1382=join_mcast_group(struct sock *sk, struct in_addr *addr, struct net_device *dev)\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1401-\nnet/netfilter/ipvs/ip_vs_sync.c:1402:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1403-static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,\n--\nnet/netfilter/ipvs/ip_vs_sync.c=1520=static int make_receive_sock(struct netns_ipvs *ipvs, int id,\n--\nnet/netfilter/ipvs/ip_vs_sync.c-1550-\t/* join the multicast group */\nnet/netfilter/ipvs/ip_vs_sync.c:1551:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_sync.c-1552-\tif (ipvs-\u003ebcfg.mcast_af == AF_INET6)\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=133=static struct rtable *do_output_route4(struct net *net, __be32 daddr,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-160-\nnet/netfilter/ipvs/ip_vs_xmit.c:161:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-162-static inline int __ip_vs_is_local_route6(struct rt6_info *rt)\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=168=static inline bool crosses_local_route_boundary(int skb_af, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-177-\nnet/netfilter/ipvs/ip_vs_xmit.c:178:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-179-\tif (skb_af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=217=static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-221-{\nnet/netfilter/ipvs/ip_vs_xmit.c:222:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-223-\tif (skb_af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=259=static inline bool decrement_ttl(struct netns_ipvs *ipvs,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-264-\nnet/netfilter/ipvs/ip_vs_xmit.c:265:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-266-\tif (skb_af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=316=__ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-446-\nnet/netfilter/ipvs/ip_vs_xmit.c:447:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-448-static struct dst_entry *\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=736=ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-756-\nnet/netfilter/ipvs/ip_vs_xmit.c:757:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-758-int\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=787=ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-868-\nnet/netfilter/ipvs/ip_vs_xmit.c:869:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-870-int\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=961=ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-968-\t__u8 old_dsfield;\nnet/netfilter/ipvs/ip_vs_xmit.c:969:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-970-\tstruct ipv6hdr *old_ipv6h = NULL;\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-984-\nnet/netfilter/ipvs/ip_vs_xmit.c:985:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-986-\tif (skb_af == AF_INET6) {\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=1147=ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-1289-\nnet/netfilter/ipvs/ip_vs_xmit.c:1290:#ifdef CONFIG_IP_VS_IPV6\nnet/netfilter/ipvs/ip_vs_xmit.c-1291-int\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=1439=ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c-1466-\nnet/netfilter/ipvs/ip_vs_xmit.c:1467:#ifdef CONFIG_IP_VS_IPV6\n\n"
}

15/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30200
							output: 36
							thoughts: 116
						

Thoughts:
**Examining IPVS Configuration Options**

Okay, so I'm diving into these IPVS configurations. I see `IP_VS_IPV6` and `IP_VS_PROTO_SCTP` are the key ones to focus on. Let me just confirm where `IP_VS_IPV6` is defined, ah yes, it's right there in `net/netfilter/ipvs/Kconfig`. And, just to be sure, I'll double-check `IP_VS_PROTO_SCTP` again, yep, still there, all good. Now, I need to consider NAT. Is there a dedicated config option for Network Address Translation in IPVS? I'll quickly check the `net/netfilter/ipvs/Kconfig` file and search for the `NAT` configuration.



16/2 2026/07/21 04:39 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config IP_VS_NAT",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "error": "no matches"
}

17/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30540
							output: 128
							thoughts: 639
						

Thoughts:
**Fuzzing Focus for IPVS NAT**

Okay, so I'm thinking about fuzzing the IPVS NAT implementation. First, I need to remind myself that IPVS NAT is inherently built-in when IPVS is enabled. Good. Now, let's analyze the relevant code.

I see that several functions have been modified: `ip_vs_nat_icmp`, `ip_vs_nat_icmp_v6`, `handle_response_icmp`, `ip_vs_out_icmp`, `ip_vs_out_icmp_v6`, `ip_vs_in_icmp`, `ip_vs_in_icmp_v6`, `ip_vs_forward_icmp`, `sctp_csum_check`, `tcp_csum_check`, `udp_csum_check`, `ip_vs_icmp_xmit`, and `ip_vs_icmp_xmit_v6`. These are all core IPVS functions, so that's where I need to focus.

Initially, I thought to prioritize: `ip_vs_in_icmp`, `ip_vs_in_icmp_v6`, `ip_vs_out_icmp`, `ip_vs_out_icmp_v6`, `ip_vs_forward_icmp`, `ip_vs_icmp_xmit`, `ip_vs_icmp_xmit_v6`, `sctp_csum_check`, `tcp_csum_check`, and `udp_csum_check`. But wait a minute... the csum checks are static functions. They're not directly exported, so I need to see *where* they're called. Ah, they're called from `sctp_snat_handler`, `sctp_dnat_handler`, etc. That changes things.

I'm now thinking I should be primarily focused on the handlers, which are the interesting points to attack. The handlers include: `sctp_snat_handler`, `sctp_dnat_handler`, `tcp_snat_handler`, `tcp_dnat_handler`, `udp_snat_handler`, and `udp_dnat_handler`.

Alright, back to those initial core functions. I need to make sure I understand the call graph correctly. `ip_vs_in_icmp` is static. It's called from `ip_vs_in_hook` and `ip_vs_forward_icmp`. Likewise, `ip_vs_out_icmp` is static, called only from `ip_vs_out_hook`. Okay, that clarifies things.

So, the updated priority for fuzzing should be: `ip_vs_in_hook`, `ip_vs_out_hook`, `ip_vs_forward_icmp`, `ip_vs_icmp_xmit`, `ip_vs_icmp_xmit_v6`, `sctp_snat_handler`, `sctp_dnat_handler`, `tcp_snat_handler`, `tcp_dnat_handler`, `udp_snat_handler`, and `udp_dnat_handler`. It's essential to verify these function names before moving on.



18/2 2026/07/21 04:39 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "^(static )?(int|void) (ip_vs_in_hook|ip_vs_out_hook|ip_vs_forward_icmp|ip_vs_icmp_xmit|ip_vs_icmp_xmit_v6|sctp_snat_handler|sctp_dnat_handler|tcp_snat_handler|tcp_dnat_handler|udp_snat_handler|udp_dnat_handler)",
  "PathPrefix": "net/netfilter/ipvs/"
}

Results:
{
  "error": "no matches"
}

19/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 32013
							output: 118
							thoughts: 18
						

Thoughts:
Okay, here's my summary, tailored for an expert audience, as if it were my thought process:

**Refining the Approach**

Alright, that initial regular expression… it's proving a bit too restrictive for the task at hand. I can see I'm getting bogged down in its precision, when a simpler solution might be more effective and less prone to edge-case errors. It's time to step back and re-evaluate. I'm going to shift my focus and start with a more straightforward approach. Instead of trying to force a perfect match based on the context, I will directly search for the core element: the names themselves. This will streamline the process and hopefully deliver the data with less complexity.



20/2 2026/07/21 04:39 tool grepper
0m Args:
{
  "Expression": "ip_vs_in_hook|ip_vs_out_hook|ip_vs_forward_icmp|ip_vs_icmp_xmit|ip_vs_icmp_xmit_v6|sctp_snat_handler|sctp_dnat_handler|tcp_snat_handler|tcp_dnat_handler|udp_snat_handler|udp_dnat_handler",
  "PathPrefix": "net/netfilter/ipvs/"
}

Results:
{
  "Output": "net/netfilter/ipvs/ip_vs_core.c=68=EXPORT_SYMBOL(ip_vs_new_conn_out);\n--\nnet/netfilter/ipvs/ip_vs_core.c-71-#define SNAT_CALL(f, ...) \\\nnet/netfilter/ipvs/ip_vs_core.c:72:\tINDIRECT_CALL_2(f, tcp_snat_handler, udp_snat_handler, __VA_ARGS__)\nnet/netfilter/ipvs/ip_vs_core.c-73-#elif defined(CONFIG_IP_VS_PROTO_TCP)\nnet/netfilter/ipvs/ip_vs_core.c:74:#define SNAT_CALL(f, ...) INDIRECT_CALL_1(f, tcp_snat_handler, __VA_ARGS__)\nnet/netfilter/ipvs/ip_vs_core.c-75-#elif defined(CONFIG_IP_VS_PROTO_UDP)\nnet/netfilter/ipvs/ip_vs_core.c:76:#define SNAT_CALL(f, ...) INDIRECT_CALL_1(f, udp_snat_handler, __VA_ARGS__)\nnet/netfilter/ipvs/ip_vs_core.c-77-#else\n--\nnet/netfilter/ipvs/ip_vs_core.c=1501=static unsigned int\nnet/netfilter/ipvs/ip_vs_core.c:1502:ip_vs_out_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)\nnet/netfilter/ipvs/ip_vs_core.c-1503-{\n--\nnet/netfilter/ipvs/ip_vs_core.c=1752=ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,\n--\nnet/netfilter/ipvs/ip_vs_core.c-1973-\t\toffset += 2 * sizeof(__u16);\nnet/netfilter/ipvs/ip_vs_core.c:1974:\tverdict = ip_vs_icmp_xmit(skb, cp, pp, iph-\u003elen, offset, hooknum,\nnet/netfilter/ipvs/ip_vs_core.c-1975-\t\t\t\t  \u0026ciph);\n--\nnet/netfilter/ipvs/ip_vs_core.c=1987=static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2087-\nnet/netfilter/ipvs/ip_vs_core.c:2088:\tverdict = ip_vs_icmp_xmit_v6(skb, cp, pp, iph-\u003elen, offset, hooknum,\nnet/netfilter/ipvs/ip_vs_core.c-2089-\t\t\t\t     \u0026ciph);\n--\nnet/netfilter/ipvs/ip_vs_core.c=2106=static unsigned int\nnet/netfilter/ipvs/ip_vs_core.c:2107:ip_vs_in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)\nnet/netfilter/ipvs/ip_vs_core.c-2108-{\n--\nnet/netfilter/ipvs/ip_vs_core.c=2299=static unsigned int\nnet/netfilter/ipvs/ip_vs_core.c:2300:ip_vs_forward_icmp(void *priv, struct sk_buff *skb,\nnet/netfilter/ipvs/ip_vs_core.c-2301-\t\t   const struct nf_hook_state *state)\n--\nnet/netfilter/ipvs/ip_vs_core.c=2329=static const struct nf_hook_ops ip_vs_ops4[] = {\n--\nnet/netfilter/ipvs/ip_vs_core.c-2331-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2332:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2333-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2340-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2341:\t\t.hook\t\t= ip_vs_in_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2342-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2347-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2348:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2349-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2354-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2355:\t\t.hook\t\t= ip_vs_in_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2356-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2362-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2363:\t\t.hook\t\t= ip_vs_forward_icmp,\nnet/netfilter/ipvs/ip_vs_core.c-2364-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2369-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2370:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2371-\t\t.pf\t\t= NFPROTO_IPV4,\n--\nnet/netfilter/ipvs/ip_vs_core.c=2378=static const struct nf_hook_ops ip_vs_ops6[] = {\n--\nnet/netfilter/ipvs/ip_vs_core.c-2380-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2381:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2382-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2389-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2390:\t\t.hook\t\t= ip_vs_in_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2391-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2396-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2397:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2398-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2403-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2404:\t\t.hook\t\t= ip_vs_in_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2405-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2411-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2412:\t\t.hook\t\t= ip_vs_forward_icmp,\nnet/netfilter/ipvs/ip_vs_core.c-2413-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_core.c-2418-\t{\nnet/netfilter/ipvs/ip_vs_core.c:2419:\t\t.hook\t\t= ip_vs_out_hook,\nnet/netfilter/ipvs/ip_vs_core.c-2420-\t\t.pf\t\t= NFPROTO_IPV6,\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c=91=static int\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:92:sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-93-\t\t  struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c=139=static int\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:140:sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-141-\t\t  struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c=569=struct ip_vs_protocol ip_vs_protocol_sctp = {\n--\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-582-\t.conn_out_get\t= ip_vs_conn_out_get_proto,\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:583:\t.snat_handler\t= sctp_snat_handler,\nnet/netfilter/ipvs/ip_vs_proto_sctp.c:584:\t.dnat_handler\t= sctp_dnat_handler,\nnet/netfilter/ipvs/ip_vs_proto_sctp.c-585-\t.state_name\t= sctp_state_name,\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=146=INDIRECT_CALLABLE_SCOPE int\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:147:tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-148-\t\t struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=224=static int\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:225:tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-226-\t\t struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c=684=struct ip_vs_protocol ip_vs_protocol_tcp = {\n--\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-697-\t.conn_out_get =\t\tip_vs_conn_out_get_proto,\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:698:\t.snat_handler =\t\ttcp_snat_handler,\nnet/netfilter/ipvs/ip_vs_proto_tcp.c:699:\t.dnat_handler =\t\ttcp_dnat_handler,\nnet/netfilter/ipvs/ip_vs_proto_tcp.c-700-\t.state_name =\t\ttcp_state_name,\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=135=INDIRECT_CALLABLE_SCOPE int\nnet/netfilter/ipvs/ip_vs_proto_udp.c:136:udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_udp.c-137-\t\t struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=218=static int\nnet/netfilter/ipvs/ip_vs_proto_udp.c:219:udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,\nnet/netfilter/ipvs/ip_vs_proto_udp.c-220-\t\t struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c=448=struct ip_vs_protocol ip_vs_protocol_udp = {\n--\nnet/netfilter/ipvs/ip_vs_proto_udp.c-459-\t.conn_out_get =\t\tip_vs_conn_out_get_proto,\nnet/netfilter/ipvs/ip_vs_proto_udp.c:460:\t.snat_handler =\t\tudp_snat_handler,\nnet/netfilter/ipvs/ip_vs_proto_udp.c:461:\t.dnat_handler =\t\tudp_dnat_handler,\nnet/netfilter/ipvs/ip_vs_proto_udp.c-462-\t.state_transition =\tudp_state_transition,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=1503=int\nnet/netfilter/ipvs/ip_vs_xmit.c:1504:ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,\nnet/netfilter/ipvs/ip_vs_xmit.c-1505-\t\tstruct ip_vs_protocol *pp, unsigned int toff,\n--\nnet/netfilter/ipvs/ip_vs_xmit.c=1589=int\nnet/netfilter/ipvs/ip_vs_xmit.c:1590:ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,\nnet/netfilter/ipvs/ip_vs_xmit.c-1591-\t\tstruct ip_vs_protocol *pp, unsigned int toff,\n"
}

21/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 36028
							output: 38
							thoughts: 580
						

Thoughts:
**Focusing on ICMP and Connection Tracking in the IPVS Implementation**

Okay, so I'm thinking about the most relevant functions for fuzzing within the IPVS code. My initial thought was to focus on a few key entry points: `ip_vs_in_hook`, `ip_vs_out_hook`, `ip_vs_forward_icmp`, `ip_vs_icmp_xmit`, `ip_vs_icmp_xmit_v6`, and the NAT handlers for various protocols like SCTP, TCP, and UDP. `sctp_snat_handler`, `sctp_dnat_handler`, `tcp_snat_handler`, `tcp_dnat_handler`, `udp_snat_handler`, `udp_dnat_handler`.

But then, considering the architecture, the hooks `ip_vs_in_hook` and `ip_vs_out_hook` are called for *every* packet. They're on the hot path, making them a less targeted approach for these specific changes related to ICMP. The modifications are actually more focused on handling ICMP packets within those hooks, specifically in `ip_vs_in_icmp` and `ip_vs_out_icmp`.

Since these `ip_vs_in_icmp` and `ip_vs_out_icmp` functions are static and not directly exported, I can't directly list them *unless* they're present in the symbol table (kallsyms). But syzkaller *can* fuzz static functions, assuming they are in kallsyms. Static functions are usually fine to list. Thus, I'll prioritize fuzzing `ip_vs_in_icmp`, `ip_vs_out_icmp`, `ip_vs_in_icmp_v6`, and `ip_vs_out_icmp_v6` because they are specific to the ICMP handling. That's better than directly fuzzing the hooks themselves.

I confirmed these are indeed just `static int ip_vs_in_icmp(...)` and `static int ip_vs_out_icmp(...)`, so they are *not* inline and *will* be in kallsyms.

So, the fuzzing list will be:

`ip_vs_in_icmp`
`ip_vs_out_icmp`
`ip_vs_in_icmp_v6`
`ip_vs_out_icmp_v6`
`ip_vs_forward_icmp`
`ip_vs_icmp_xmit`
`ip_vs_icmp_xmit_v6`
`sctp_snat_handler`
`sctp_dnat_handler`
`tcp_snat_handler`
`tcp_dnat_handler`
`udp_snat_handler`
`udp_dnat_handler`

I'll also need to consider the required kernel configs: `IP_VS`, `IP_VS_IPV6`, and `IP_VS_PROTO_SCTP`. Now, let me just double-check, is there an `IP_VS_PROTO_TCP` config?



22/2 2026/07/21 04:39 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config IP_VS_PROTO_TCP",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "error": "no matches"
}

23/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 37340
							output: 37
							thoughts: 16
						

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

**Checking for the Flag: A Brief Diagnostic**

Alright, let's just make a quick sanity check here. I need to confirm that `IP_VS_PROTO_TCP` is indeed defined. It's a fundamental constant, and without it, a particular aspect of the kernel's virtual server functionality won't work as expected. Before I dive into anything else, whether it be debugging a configuration issue, analyzing performance metrics, or developing some new related feature, I need to make sure this key piece of the puzzle is in place. So, a quick look to verify its existence is a good first step to avoid spinning my wheels later. It's the equivalent of checking that your tools are actually present before starting work on a project.



24/2 2026/07/21 04:39 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config IP_VS_PROTO_",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "error": "no matches"
}

25/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 37579
							output: 36
							thoughts: 33
						

Thoughts:
Okay, let's see... I'm pretty sure I saw some related constants earlier. I'll need to double-check those. Specifically, I seem to recall encountering `IP_VS_PROTO_AH` and `IP_VS_PROTO_SCTP` in the previous code I was analyzing. I'd better confirm their presence and context before moving forward. I want to make sure I understand how they fit into the broader architecture.



26/2 2026/07/21 04:39 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "config IP_VS_PROTO",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "error": "no matches"
}

27/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 37756
							output: 35
							thoughts: 33
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:

**Initial Regex Check & Contextual Investigation**

Right, my first instinct was to check the configuration syntax, thinking it was probably a simple regex match, likely starting with `^config `. That feels right given the context. Let me make sure that's how it's handled in the kernel code. Now, I should double-check the `net/netfilter/ipvs/Kconfig` file because, if I remember correctly, the `IP_VS_PROTO` symbol is defined there. That's a solid place to start digging for the specific configuration option I'm after, and it's a very common pattern to use Kconfig files to configure that part of the code.



28/2 2026/07/21 04:39 tool grepper
0m Args:
{
  "Expression": "IP_VS_PROTO",
  "PathPrefix": "net/netfilter/ipvs/Kconfig"
}

Results:
{
  "Output": "net/netfilter/ipvs/Kconfig=77=comment \"IPVS transport protocol load balancing support\"\nnet/netfilter/ipvs/Kconfig-78-\nnet/netfilter/ipvs/Kconfig:79:config\tIP_VS_PROTO_TCP\nnet/netfilter/ipvs/Kconfig-80-\tbool \"TCP load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig-84-\nnet/netfilter/ipvs/Kconfig:85:config\tIP_VS_PROTO_UDP\nnet/netfilter/ipvs/Kconfig-86-\tbool \"UDP load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig-90-\nnet/netfilter/ipvs/Kconfig:91:config\tIP_VS_PROTO_AH_ESP\nnet/netfilter/ipvs/Kconfig:92:\tdef_bool IP_VS_PROTO_ESP || IP_VS_PROTO_AH\nnet/netfilter/ipvs/Kconfig-93-\nnet/netfilter/ipvs/Kconfig:94:config\tIP_VS_PROTO_ESP\nnet/netfilter/ipvs/Kconfig-95-\tbool \"ESP load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig-99-\nnet/netfilter/ipvs/Kconfig:100:config\tIP_VS_PROTO_AH\nnet/netfilter/ipvs/Kconfig-101-\tbool \"AH load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig-105-\nnet/netfilter/ipvs/Kconfig:106:config  IP_VS_PROTO_SCTP\nnet/netfilter/ipvs/Kconfig-107-\tbool \"SCTP load balancing support\"\n--\nnet/netfilter/ipvs/Kconfig=321=config\tIP_VS_FTP\nnet/netfilter/ipvs/Kconfig-322-\ttristate \"FTP protocol helper\"\nnet/netfilter/ipvs/Kconfig:323:\tdepends on IP_VS_PROTO_TCP \u0026\u0026 NF_CONNTRACK \u0026\u0026 NF_NAT \u0026\u0026 \\\nnet/netfilter/ipvs/Kconfig-324-\t\tNF_CONNTRACK_FTP\n--\nnet/netfilter/ipvs/Kconfig=345=config\tIP_VS_PE_SIP\nnet/netfilter/ipvs/Kconfig-346-\ttristate \"SIP persistence engine\"\nnet/netfilter/ipvs/Kconfig:347:\tdepends on IP_VS_PROTO_UDP\nnet/netfilter/ipvs/Kconfig-348-\tdepends on NF_CONNTRACK_SIP\n"
}

29/2 2026/07/21 04:39 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 38644
							output: 290
							thoughts: 571
						

Thoughts:
**My Analysis of this IPVS Patch**

Okay, so I've looked through this and it's pretty clear: `IP_VS_PROTO_TCP`, `IP_VS_PROTO_UDP`, and `IP_VS_PROTO_SCTP` are definitely configuration options. We need to enable `IP_VS`, `IP_VS_IPV6`, `IP_VS_PROTO_TCP`, `IP_VS_PROTO_UDP`, and `IP_VS_PROTO_SCTP` to get the full functionality. I've double-checked that there aren't any other related configs we need to consider.

Looking at the file modifications, it's modifying several key IPVS files: `ip_vs_app.c`, `ip_vs_core.c`, `ip_vs_proto_sctp.c`, `ip_vs_proto_tcp.c`, `ip_vs_proto_udp.c`, and `ip_vs_xmit.c`. These are all compiled under `CONFIG_IP_VS`, and the protocol-specific files depend on their respective protocol configs.

This patch is definitely worth fuzzing. It's touching core IPVS logic, particularly handling checksums and NAT for ICMP, TCP, UDP, and SCTP. It looks like there's some new checksum validation being introduced, and it's playing with packet mangling offsets. This is *reachable* core network functionality – perfect for fuzzing.

My primary focus should be on the following symbols: `ip_vs_in_icmp`, `ip_vs_out_icmp`, `ip_vs_in_icmp_v6`, `ip_vs_out_icmp_v6`, `ip_vs_forward_icmp`, `ip_vs_icmp_xmit`, `ip_vs_icmp_xmit_v6`, `sctp_snat_handler`, `sctp_dnat_handler`, `tcp_snat_handler`, `tcp_dnat_handler`, `udp_snat_handler`, `udp_dnat_handler`, `ip_vs_nat_icmp`, and `ip_vs_nat_icmp_v6`.

So, in summary, I need to enable the following configs to properly exercise the changes: `IP_VS`, `IP_VS_IPV6`, `IP_VS_PROTO_TCP`, `IP_VS_PROTO_UDP`, and `IP_VS_PROTO_SCTP`. Now, let's call set-results.



30/2 2026/07/21 04:39 tool set-results
0m Args:
{
  "EnableConfigs": [
    "IP_VS",
    "IP_VS_IPV6",
    "IP_VS_PROTO_TCP",
    "IP_VS_PROTO_UDP",
    "IP_VS_PROTO_SCTP"
  ],
  "FocusSymbols": [
    "ip_vs_in_icmp",
    "ip_vs_out_icmp",
    "ip_vs_in_icmp_v6",
    "ip_vs_out_icmp_v6",
    "ip_vs_forward_icmp",
    "ip_vs_icmp_xmit",
    "ip_vs_icmp_xmit_v6",
    "sctp_snat_handler",
    "sctp_dnat_handler",
    "tcp_snat_handler",
    "tcp_dnat_handler",
    "udp_snat_handler",
    "udp_dnat_handler",
    "ip_vs_nat_icmp",
    "ip_vs_nat_icmp_v6"
  ],
  "Reasoning": "The patch modifies core IPVS logic for handling checksums and NAT for ICMP, TCP, UDP, and SCTP packets. It introduces new checksum validation logic and alters packet mangling offsets. This is reachable core network functionality that should be fuzzed.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "IP_VS",
    "IP_VS_IPV6",
    "IP_VS_PROTO_TCP",
    "IP_VS_PROTO_UDP",
    "IP_VS_PROTO_SCTP"
  ],
  "FocusSymbols": [
    "ip_vs_in_icmp",
    "ip_vs_out_icmp",
    "ip_vs_in_icmp_v6",
    "ip_vs_out_icmp_v6",
    "ip_vs_forward_icmp",
    "ip_vs_icmp_xmit",
    "ip_vs_icmp_xmit_v6",
    "sctp_snat_handler",
    "sctp_dnat_handler",
    "tcp_snat_handler",
    "tcp_dnat_handler",
    "udp_snat_handler",
    "udp_dnat_handler",
    "ip_vs_nat_icmp",
    "ip_vs_nat_icmp_v6"
  ],
  "Reasoning": "The patch modifies core IPVS logic for handling checksums and NAT for ICMP, TCP, UDP, and SCTP packets. It introduces new checksum validation logic and alters packet mangling offsets. This is reachable core network functionality that should be fuzzed.",
  "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)