| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/02 02:58 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"IP_VS",
"IP_VS_PROTO_TCP",
"IP_VS_PROTO_UDP"
],
"FocusSymbols": [
"ip_vs_conn_change_fwd_mask",
"ip_vs_bind_dest",
"ip_vs_conn_fill_cport",
"ip_vs_conn_hash",
"ip_vs_conn_unlink"
],
"Reasoning": "This patch modifies the core IPVS connection hashing and locking logic, specifically introducing changes to how double hashing and forwarding methods are handled. This is reachable core networking logic that should be fuzzed to ensure no race conditions or deadlocks are introduced.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/02 02:58 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit f7751d97459924abd1ca435c2daa5b06aed000fa\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Jul 2 02:58:13 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c\nindex cb36641f8d1cc1..2a903af927f76b 100644\n--- a/net/netfilter/ipvs/ip_vs_conn.c\n+++ b/net/netfilter/ipvs/ip_vs_conn.c\n@@ -70,25 +70,45 @@ static struct kmem_cache *ip_vs_conn_cachep __read_mostly;\n * bucket or hash table\n * - hash table resize works like rehash but always rehashes into new table\n * - bit lock on bucket serializes all operations that modify the chain\n+ * - on resize, bucket from the old table is locked before bucket from the\n+ * new table\n * - cp-\u003elock protects conn fields like cp-\u003eflags, cp-\u003edest\n */\n \n-/* Lock conn_tab bucket for conn hash/unhash, not for rehash */\n+/**\n+ * conn_tab_lock - Lock conn_tab buckets for conn hash/unhash, not for rehash\n+ * @t:\t\thash table for hn0, new_tbl when new_hash=true\n+ * @t2:\thash table for hn1, new_tbl when new_hash2=true\n+ * @cp:\tconnection\n+ * @hash_key:\thash key for hn0\n+ * @hash_key2:\thash key for hn1\n+ * @use2:\tusing hn1 (double hashing) based on the forwarding method\n+ * @new_hash:\tmode for hn0, hash node (true) or seek node (false)\n+ * @new_hash2:\tmode for hn1, hash node (true) or seek node (false)\n+ * @head_ret:\treturned head for hn0\n+ * @head2_ret:\treturned head for hn1\n+ *\n+ * We support 3 modes:\n+ * - seek mode for both nodes, used for unhashing\n+ * - hash mode for both nodes, used for hashing\n+ * - seek hn0 and hash hn1, used when forwarding method is changed\n+ */\n static __always_inline void\n-conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_conn *cp, u32 hash_key,\n-\t u32 hash_key2, bool use2, bool new_hash,\n-\t struct hlist_bl_head **head_ret, struct hlist_bl_head **head2_ret)\n+conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_rht *t2, struct ip_vs_conn *cp,\n+\t u32 hash_key, u32 hash_key2, bool use2, bool new_hash,\n+\t bool new_hash2, struct hlist_bl_head **head_ret,\n+\t struct hlist_bl_head **head2_ret)\n {\n \tstruct hlist_bl_head *head, *head2;\n \tu32 hash_key_new, hash_key_new2;\n-\tstruct ip_vs_rht *t2 = t;\n-\tu32 idx, idx2;\n+\tint idx = 0, idx2 = 0;\n+\n+\t/* Advance idx2 when new_hash is not set but hash_key2\n+\t * is for new table\n+\t */\n+\tif (new_hash2 \u0026\u0026 use2 \u0026\u0026 t != t2)\n+\t\tidx2++;\n \n-\tidx = hash_key \u0026 t-\u003emask;\n-\tif (use2)\n-\t\tidx2 = hash_key2 \u0026 t-\u003emask;\n-\telse\n-\t\tidx2 = idx;\n \tif (!new_hash) {\n \t\t/* We need to lock the bucket in the right table */\n \n@@ -100,46 +120,45 @@ conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_conn *cp, u32 hash_key,\n \t\t\t * both nodes in different tables, use idx/idx2\n \t\t\t * for proper lock ordering for heads.\n \t\t\t */\n-\t\t\tidx = hash_key \u0026 t-\u003emask;\n-\t\t\tidx |= IP_VS_RHT_TABLE_ID_MASK;\n-\t\t}\n-\t\tif (use2) {\n-\t\t\tif (!ip_vs_rht_same_table(t2, hash_key2)) {\n-\t\t\t\t/* It is already moved to new table */\n-\t\t\t\tt2 = rcu_dereference(t2-\u003enew_tbl);\n-\t\t\t\tidx2 = hash_key2 \u0026 t2-\u003emask;\n-\t\t\t\tidx2 |= IP_VS_RHT_TABLE_ID_MASK;\n-\t\t\t}\n-\t\t} else {\n-\t\t\tidx2 = idx;\n+\t\t\tidx++;\n \t\t}\n \t}\n+\tif (use2 \u0026\u0026 !new_hash2 \u0026\u0026 !ip_vs_rht_same_table(t2, hash_key2)) {\n+\t\t/* It is already moved to new table */\n+\t\tt2 = rcu_dereference(t2-\u003enew_tbl);\n+\t\tidx2++;\n+\t}\n \n+\tif (!use2)\n+\t\tidx2 = idx;\n \thead = t-\u003ebuckets + (hash_key \u0026 t-\u003emask);\n \thead2 = use2 ? t2-\u003ebuckets + (hash_key2 \u0026 t2-\u003emask) : head;\n \n-\tlocal_bh_disable();\n-\t/* Do not touch seqcount, this is a safe operation */\n-\n-\tif (idx \u003c= idx2) {\n+\tif (idx \u003e idx2 || (head \u003e head2 \u0026\u0026 idx == idx2)) {\n+\t\thlist_bl_lock(head2);\n \t\thlist_bl_lock(head);\n-\t\tif (head != head2)\n-\t\t\thlist_bl_lock(head2);\n \t} else {\n-\t\thlist_bl_lock(head2);\n \t\thlist_bl_lock(head);\n+\t\tif (head != head2)\n+\t\t\thlist_bl_lock(head2);\n \t}\n \tif (!new_hash) {\n+\t\tbool changed;\n+\n \t\t/* Ensure hash_key is read under lock */\n \t\thash_key_new = READ_ONCE(cp-\u003ehn0.hash_key);\n-\t\thash_key_new2 = READ_ONCE(cp-\u003ehn1.hash_key);\n+\t\tchanged = hash_key != hash_key_new;\n+\t\tif (use2 \u0026\u0026 !new_hash2) {\n+\t\t\thash_key_new2 = READ_ONCE(cp-\u003ehn1.hash_key);\n+\t\t\tchanged |= hash_key2 != hash_key_new2;\n+\t\t} else {\n+\t\t\thash_key_new2 = hash_key2;\n+\t\t}\n \t\t/* Hash changed ? */\n-\t\tif (hash_key != hash_key_new ||\n-\t\t (hash_key2 != hash_key_new2 \u0026\u0026 use2)) {\n+\t\tif (changed) {\n \t\t\tif (head != head2)\n \t\t\t\thlist_bl_unlock(head2);\n \t\t\thlist_bl_unlock(head);\n-\t\t\tlocal_bh_enable();\n \t\t\thash_key = hash_key_new;\n \t\t\thash_key2 = hash_key_new2;\n \t\t\tgoto retry;\n@@ -155,7 +174,6 @@ static inline void conn_tab_unlock(struct hlist_bl_head *head,\n \tif (head != head2)\n \t\thlist_bl_unlock(head2);\n \thlist_bl_unlock(head);\n-\tlocal_bh_enable();\n }\n \n static void ip_vs_conn_expire(struct timer_list *t);\n@@ -268,8 +286,9 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)\n \t\tuse2 = false;\n \t}\n \n-\tconn_tab_lock(t, cp, hash_key, hash_key2, use2, true /* new_hash */,\n-\t\t \u0026head, \u0026head2);\n+\tlocal_bh_disable();\n+\tconn_tab_lock(t, t, cp, hash_key, hash_key2, use2, true /* new_hash */,\n+\t\t true /* new_hash2 */, \u0026head, \u0026head2);\n \n \tcp-\u003eflags |= IP_VS_CONN_F_HASHED;\n \tWRITE_ONCE(cp-\u003ehn0.hash_key, hash_key);\n@@ -280,6 +299,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)\n \t\thlist_bl_add_head_rcu(\u0026cp-\u003ehn1.node, head2);\n \n \tconn_tab_unlock(head, head2);\n+\tlocal_bh_enable();\n \tret = 1;\n \n \t/* Schedule resizing if load increases */\n@@ -306,18 +326,20 @@ static inline bool ip_vs_conn_unlink(struct ip_vs_conn *cp)\n \t\treturn refcount_dec_if_one(\u0026cp-\u003erefcnt);\n \n \trcu_read_lock();\n+\tlocal_bh_disable();\n \n \tt = rcu_dereference(ipvs-\u003econn_tab);\n \thash_key = READ_ONCE(cp-\u003ehn0.hash_key);\n \thash_key2 = READ_ONCE(cp-\u003ehn1.hash_key);\n \tuse2 = ip_vs_conn_use_hash2(cp);\n \n-\tconn_tab_lock(t, cp, hash_key, hash_key2, use2, false /* new_hash */,\n-\t\t \u0026head, \u0026head2);\n+\tconn_tab_lock(t, t, cp, hash_key, hash_key2, use2, false /* new_hash */,\n+\t\t false /* new_hash2 */, \u0026head, \u0026head2);\n \n \tif (cp-\u003eflags \u0026 IP_VS_CONN_F_HASHED) {\n \t\t/* Decrease refcnt and unlink conn only if we are last user */\n-\t\tif (refcount_dec_if_one(\u0026cp-\u003erefcnt)) {\n+\t\tif (use2 == ip_vs_conn_use_hash2(cp) \u0026\u0026\n+\t\t refcount_dec_if_one(\u0026cp-\u003erefcnt)) {\n \t\t\thlist_bl_del_rcu(\u0026cp-\u003ehn0.node);\n \t\t\tif (use2)\n \t\t\t\thlist_bl_del_rcu(\u0026cp-\u003ehn1.node);\n@@ -328,6 +350,7 @@ static inline bool ip_vs_conn_unlink(struct ip_vs_conn *cp)\n \n \tconn_tab_unlock(head, head2);\n \n+\tlocal_bh_enable();\n \trcu_read_unlock();\n \n \treturn ret;\n@@ -632,6 +655,7 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)\n \tint ntbl;\n \tint dir;\n \n+restart:\n \t/* No packets from inside, so we can do it in 2 steps. */\n \tdir = use2 ? 1 : 0;\n \n@@ -686,6 +710,23 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)\n \t/* Protect the cp-\u003eflags modification */\n \tspin_lock_bh(\u0026cp-\u003elock);\n \n+\t/* Recheck the forwarding method under lock */\n+\tif (use2 != ip_vs_conn_use_hash2(cp)) {\n+\t\tuse2 = !use2;\n+\t\tif (use2) {\n+\t\t\tspin_unlock_bh(\u0026cp-\u003elock);\n+\t\t\t/* Restart with new use2 value */\n+\t\t\tgoto restart;\n+\t\t}\n+\t\tif (dir) {\n+\t\t\t/* Not started yet, so just skip dir 1 */\n+\t\t\tspin_unlock_bh(\u0026cp-\u003elock);\n+\t\t\tdir--;\n+\t\t\tgoto next_dir;\n+\t\t}\n+\t\t/* Just finish dir 0 */\n+\t}\n+\n \t/* Lock seqcount only for the old bucket, even if we are on new table\n \t * because it affects the del operation, not the adding.\n \t */\n@@ -752,6 +793,61 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)\n \t\tgoto next_dir;\n }\n \n+/* Change forwarding method for hashed conn */\n+static void ip_vs_conn_change_fwd_mask(struct ip_vs_conn *cp, u32 new_flags)\n+{\n+\tstruct netns_ipvs *ipvs = cp-\u003eipvs;\n+\tstruct hlist_bl_head *head, *head2;\n+\tu32 hash2, hash_key, hash_key2;\n+\tstruct ip_vs_rht *t, *t2;\n+\n+\t/* See ip_vs_conn_use_hash2() for reference */\n+\tif ((cp-\u003eflags \u0026 IP_VS_CONN_F_TEMPLATE) ||\n+\t /* No change in double hashing ? */\n+\t (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) ==\n+\t ((new_flags \u0026 IP_VS_CONN_F_FWD_MASK) == IP_VS_CONN_F_MASQ)) {\n+\t\tcp-\u003eflags = new_flags;\n+\t\treturn;\n+\t}\n+\tt = rcu_dereference(ipvs-\u003econn_tab);\n+\tif (ip_vs_conn_use_hash2(cp)) {\n+\t\t/* Stop double hashing */\n+\t\thash_key = READ_ONCE(cp-\u003ehn0.hash_key);\n+\t\thash_key2 = READ_ONCE(cp-\u003ehn1.hash_key);\n+\n+\t\tconn_tab_lock(t, t, cp, hash_key, hash_key2, true /* use2 */,\n+\t\t\t false /* new_hash */, false /* new_hash2 */,\n+\t\t\t \u0026head, \u0026head2);\n+\n+\t\t/* Keep both hash keys in same table */\n+\t\thash_key = READ_ONCE(cp-\u003ehn0.hash_key);\n+\t\tWRITE_ONCE(cp-\u003ehn1.hash_key, hash_key);\n+\t\thlist_bl_del_rcu(\u0026cp-\u003ehn1.node);\n+\t\tcp-\u003eflags = new_flags;\n+\n+\t\tconn_tab_unlock(head, head2);\n+\t} else {\n+\t\t/* Start double hashing */\n+\n+\t\thash_key = READ_ONCE(cp-\u003ehn0.hash_key);\n+\n+\t\tt2 = rcu_dereference(t-\u003enew_tbl);\n+\t\thash2 = ip_vs_conn_hashkey_conn(t2, cp, true);\n+\t\thash_key2 = ip_vs_rht_build_hash_key(t2, hash2);\n+\n+\t\t/* Change the forwarding method under locked hn0 */\n+\t\tconn_tab_lock(t, t2, cp, hash_key, hash_key2, true /* use2 */,\n+\t\t\t false /* new_hash */, true /* new_hash2 */,\n+\t\t\t \u0026head, \u0026head2);\n+\n+\t\tWRITE_ONCE(cp-\u003ehn1.hash_key, hash_key2);\n+\t\tcp-\u003eflags = new_flags;\n+\t\thlist_bl_add_head_rcu(\u0026cp-\u003ehn1.node, head2);\n+\n+\t\tconn_tab_unlock(head, head2);\n+\t}\n+}\n+\n /* Get default load factor to map conn_count/u_thresh to t-\u003esize */\n static int ip_vs_conn_default_load_factor(struct netns_ipvs *ipvs)\n {\n@@ -1014,6 +1110,9 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)\n \tflags = cp-\u003eflags;\n \t/* Bind with the destination and its corresponding transmitter */\n \tif (flags \u0026 IP_VS_CONN_F_SYNC) {\n+\t\t/* Synced conns are hashed, so they can not get this flag */\n+\t\tconn_flags \u0026= ~IP_VS_CONN_F_ONE_PACKET;\n+\n \t\t/* if the connection is not template and is created\n \t\t * by sync, preserve the activity flag.\n \t\t */\n@@ -1021,9 +1120,18 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)\n \t\t\tconn_flags \u0026= ~IP_VS_CONN_F_INACTIVE;\n \t\t/* connections inherit forwarding method from dest */\n \t\tflags \u0026= ~(IP_VS_CONN_F_FWD_MASK | IP_VS_CONN_F_NOOUTPUT);\n+\t\tflags |= conn_flags;\n+\t\t/* Changing forwarding method for hashed conn can\n+\t\t * happen only under locks\n+\t\t */\n+\t\tif (cp-\u003eflags \u0026 IP_VS_CONN_F_HASHED)\n+\t\t\tip_vs_conn_change_fwd_mask(cp, flags);\n+\t\telse\n+\t\t\tcp-\u003eflags = flags;\n+\t} else {\n+\t\tflags |= conn_flags;\n+\t\tcp-\u003eflags = flags;\n \t}\n-\tflags |= conn_flags;\n-\tcp-\u003eflags = flags;\n \tcp-\u003edest = dest;\n \n \tIP_VS_DBG_BUF(7, \"Bind-dest %s c:%s:%d v:%s:%d \"\n"
} |
| 2/1 | 2026/07/02 02:58 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"IP_VS",
"IP_VS_PROTO_TCP",
"IP_VS_PROTO_UDP"
],
"FocusSymbols": [
"ip_vs_conn_change_fwd_mask",
"ip_vs_bind_dest",
"ip_vs_conn_fill_cport",
"ip_vs_conn_hash",
"ip_vs_conn_unlink"
],
"Reasoning": "This patch modifies the core IPVS connection hashing and locking logic, specifically introducing changes to how double hashing and forwarding methods are handled. This is reachable core networking logic that should be fuzzed to ensure no race conditions or deadlocks are introduced.",
"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 f7751d97459924abd1ca435c2daa5b06aed000fa
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Jul 2 02:58:13 2026 +0000
syz-cluster: applied patch under review
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index cb36641f8d1cc1..2a903af927f76b 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -70,25 +70,45 @@ static struct kmem_cache *ip_vs_conn_cachep __read_mostly;
* bucket or hash table
* - hash table resize works like rehash but always rehashes into new table
* - bit lock on bucket serializes all operations that modify the chain
+ * - on resize, bucket from the old table is locked before bucket from the
+ * new table
* - cp->lock protects conn fields like cp->flags, cp->dest
*/
-/* Lock conn_tab bucket for conn hash/unhash, not for rehash */
+/**
+ * conn_tab_lock - Lock conn_tab buckets for conn hash/unhash, not for rehash
+ * @t: hash table for hn0, new_tbl when new_hash=true
+ * @t2: hash table for hn1, new_tbl when new_hash2=true
+ * @cp: connection
+ * @hash_key: hash key for hn0
+ * @hash_key2: hash key for hn1
+ * @use2: using hn1 (double hashing) based on the forwarding method
+ * @new_hash: mode for hn0, hash node (true) or seek node (false)
+ * @new_hash2: mode for hn1, hash node (true) or seek node (false)
+ * @head_ret: returned head for hn0
+ * @head2_ret: returned head for hn1
+ *
+ * We support 3 modes:
+ * - seek mode for both nodes, used for unhashing
+ * - hash mode for both nodes, used for hashing
+ * - seek hn0 and hash hn1, used when forwarding method is changed
+ */
static __always_inline void
-conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_conn *cp, u32 hash_key,
- u32 hash_key2, bool use2, bool new_hash,
- struct hlist_bl_head **head_ret, struct hlist_bl_head **head2_ret)
+conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_rht *t2, struct ip_vs_conn *cp,
+ u32 hash_key, u32 hash_key2, bool use2, bool new_hash,
+ bool new_hash2, struct hlist_bl_head **head_ret,
+ struct hlist_bl_head **head2_ret)
{
struct hlist_bl_head *head, *head2;
u32 hash_key_new, hash_key_new2;
- struct ip_vs_rht *t2 = t;
- u32 idx, idx2;
+ int idx = 0, idx2 = 0;
+
+ /* Advance idx2 when new_hash is not set but hash_key2
+ * is for new table
+ */
+ if (new_hash2 && use2 && t != t2)
+ idx2++;
- idx = hash_key & t->mask;
- if (use2)
- idx2 = hash_key2 & t->mask;
- else
- idx2 = idx;
if (!new_hash) {
/* We need to lock the bucket in the right table */
@@ -100,46 +120,45 @@ conn_tab_lock(struct ip_vs_rht *t, struct ip_vs_conn *cp, u32 hash_key,
* both nodes in different tables, use idx/idx2
* for proper lock ordering for heads.
*/
- idx = hash_key & t->mask;
- idx |= IP_VS_RHT_TABLE_ID_MASK;
- }
- if (use2) {
- if (!ip_vs_rht_same_table(t2, hash_key2)) {
- /* It is already moved to new table */
- t2 = rcu_dereference(t2->new_tbl);
- idx2 = hash_key2 & t2->mask;
- idx2 |= IP_VS_RHT_TABLE_ID_MASK;
- }
- } else {
- idx2 = idx;
+ idx++;
}
}
+ if (use2 && !new_hash2 && !ip_vs_rht_same_table(t2, hash_key2)) {
+ /* It is already moved to new table */
+ t2 = rcu_dereference(t2->new_tbl);
+ idx2++;
+ }
+ if (!use2)
+ idx2 = idx;
head = t->buckets + (hash_key & t->mask);
head2 = use2 ? t2->buckets + (hash_key2 & t2->mask) : head;
- local_bh_disable();
- /* Do not touch seqcount, this is a safe operation */
-
- if (idx <= idx2) {
+ if (idx > idx2 || (head > head2 && idx == idx2)) {
+ hlist_bl_lock(head2);
hlist_bl_lock(head);
- if (head != head2)
- hlist_bl_lock(head2);
} else {
- hlist_bl_lock(head2);
hlist_bl_lock(head);
+ if (head != head2)
+ hlist_bl_lock(head2);
}
if (!new_hash) {
+ bool changed;
+
/* Ensure hash_key is read under lock */
hash_key_new = READ_ONCE(cp->hn0.hash_key);
- hash_key_new2 = READ_ONCE(cp->hn1.hash_key);
+ changed = hash_key != hash_key_new;
+ if (use2 && !new_hash2) {
+ hash_key_new2 = READ_ONCE(cp->hn1.hash_key);
+ changed |= hash_key2 != hash_key_new2;
+ } else {
+ hash_key_new2 = hash_key2;
+ }
/* Hash changed ? */
- if (hash_key != hash_key_new ||
- (hash_key2 != hash_key_new2 && use2)) {
+ if (changed) {
if (head != head2)
hlist_bl_unlock(head2);
hlist_bl_unlock(head);
- local_bh_enable();
hash_key = hash_key_new;
hash_key2 = hash_key_new2;
goto retry;
@@ -155,7 +174,6 @@ static inline void conn_tab_unlock(struct hlist_bl_head *head,
if (head != head2)
hlist_bl_unlock(head2);
hlist_bl_unlock(head);
- local_bh_enable();
}
static void ip_vs_conn_expire(struct timer_list *t);
@@ -268,8 +286,9 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
use2 = false;
}
- conn_tab_lock(t, cp, hash_key, hash_key2, use2, true /* new_hash */,
- &head, &head2);
+ local_bh_disable();
+ conn_tab_lock(t, t, cp, hash_key, hash_key2, use2, true /* new_hash */,
+ true /* new_hash2 */, &head, &head2);
cp->flags |= IP_VS_CONN_F_HASHED;
WRITE_ONCE(cp->hn0.hash_key, hash_key);
@@ -280,6 +299,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
hlist_bl_add_head_rcu(&cp->hn1.node, head2);
conn_tab_unlock(head, head2);
+ local_bh_enable();
ret = 1;
/* Schedule resizing if load increases */
@@ -306,18 +326,20 @@ static inline bool ip_vs_conn_unlink(struct ip_vs_conn *cp)
return refcount_dec_if_one(&cp->refcnt);
rcu_read_lock();
+ local_bh_disable();
t = rcu_dereference(ipvs->conn_tab);
hash_key = READ_ONCE(cp->hn0.hash_key);
hash_key2 = READ_ONCE(cp->hn1.hash_key);
use2 = ip_vs_conn_use_hash2(cp);
- conn_tab_lock(t, cp, hash_key, hash_key2, use2, false /* new_hash */,
- &head, &head2);
+ conn_tab_lock(t, t, cp, hash_key, hash_key2, use2, false /* new_hash */,
+ false /* new_hash2 */, &head, &head2);
if (cp->flags & IP_VS_CONN_F_HASHED) {
/* Decrease refcnt and unlink conn only if we are last user */
- if (refcount_dec_if_one(&cp->refcnt)) {
+ if (use2 == ip_vs_conn_use_hash2(cp) &&
+ refcount_dec_if_one(&cp->refcnt)) {
hlist_bl_del_rcu(&cp->hn0.node);
if (use2)
hlist_bl_del_rcu(&cp->hn1.node);
@@ -328,6 +350,7 @@ static inline bool ip_vs_conn_unlink(struct ip_vs_conn *cp)
conn_tab_unlock(head, head2);
+ local_bh_enable();
rcu_read_unlock();
return ret;
@@ -632,6 +655,7 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)
int ntbl;
int dir;
+restart:
/* No packets from inside, so we can do it in 2 steps. */
dir = use2 ? 1 : 0;
@@ -686,6 +710,23 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)
/* Protect the cp->flags modification */
spin_lock_bh(&cp->lock);
+ /* Recheck the forwarding method under lock */
+ if (use2 != ip_vs_conn_use_hash2(cp)) {
+ use2 = !use2;
+ if (use2) {
+ spin_unlock_bh(&cp->lock);
+ /* Restart with new use2 value */
+ goto restart;
+ }
+ if (dir) {
+ /* Not started yet, so just skip dir 1 */
+ spin_unlock_bh(&cp->lock);
+ dir--;
+ goto next_dir;
+ }
+ /* Just finish dir 0 */
+ }
+
/* Lock seqcount only for the old bucket, even if we are on new table
* because it affects the del operation, not the adding.
*/
@@ -752,6 +793,61 @@ void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport)
goto next_dir;
}
+/* Change forwarding method for hashed conn */
+static void ip_vs_conn_change_fwd_mask(struct ip_vs_conn *cp, u32 new_flags)
+{
+ struct netns_ipvs *ipvs = cp->ipvs;
+ struct hlist_bl_head *head, *head2;
+ u32 hash2, hash_key, hash_key2;
+ struct ip_vs_rht *t, *t2;
+
+ /* See ip_vs_conn_use_hash2() for reference */
+ if ((cp->flags & IP_VS_CONN_F_TEMPLATE) ||
+ /* No change in double hashing ? */
+ (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) ==
+ ((new_flags & IP_VS_CONN_F_FWD_MASK) == IP_VS_CONN_F_MASQ)) {
+ cp->flags = new_flags;
+ return;
+ }
+ t = rcu_dereference(ipvs->conn_tab);
+ if (ip_vs_conn_use_hash2(cp)) {
+ /* Stop double hashing */
+ hash_key = READ_ONCE(cp->hn0.hash_key);
+ hash_key2 = READ_ONCE(cp->hn1.hash_key);
+
+ conn_tab_lock(t, t, cp, hash_key, hash_key2, true /* use2 */,
+ false /* new_hash */, false /* new_hash2 */,
+ &head, &head2);
+
+ /* Keep both hash keys in same table */
+ hash_key = READ_ONCE(cp->hn0.hash_key);
+ WRITE_ONCE(cp->hn1.hash_key, hash_key);
+ hlist_bl_del_rcu(&cp->hn1.node);
+ cp->flags = new_flags;
+
+ conn_tab_unlock(head, head2);
+ } else {
+ /* Start double hashing */
+
+ hash_key = READ_ONCE(cp->hn0.hash_key);
+
+ t2 = rcu_dereference(t->new_tbl);
+ hash2 = ip_vs_conn_hashkey_conn(t2, cp, true);
+ hash_key2 = ip_vs_rht_build_hash_key(t2, hash2);
+
+ /* Change the forwarding method under locked hn0 */
+ conn_tab_lock(t, t2, cp, hash_key, hash_key2, true /* use2 */,
+ false /* new_hash */, true /* new_hash2 */,
+ &head, &head2);
+
+ WRITE_ONCE(cp->hn1.hash_key, hash_key2);
+ cp->flags = new_flags;
+ hlist_bl_add_head_rcu(&cp->hn1.node, head2);
+
+ conn_tab_unlock(head, head2);
+ }
+}
+
/* Get default load factor to map conn_count/u_thresh to t->size */
static int ip_vs_conn_default_load_factor(struct netns_ipvs *ipvs)
{
@@ -1014,6 +1110,9 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
flags = cp->flags;
/* Bind with the destination and its corresponding transmitter */
if (flags & IP_VS_CONN_F_SYNC) {
+ /* Synced conns are hashed, so they can not get this flag */
+ conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
+
/* if the connection is not template and is created
* by sync, preserve the activity flag.
*/
@@ -1021,9 +1120,18 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
conn_flags &= ~IP_VS_CONN_F_INACTIVE;
/* connections inherit forwarding method from dest */
flags &= ~(IP_VS_CONN_F_FWD_MASK | IP_VS_CONN_F_NOOUTPUT);
+ flags |= conn_flags;
+ /* Changing forwarding method for hashed conn can
+ * happen only under locks
+ */
+ if (cp->flags & IP_VS_CONN_F_HASHED)
+ ip_vs_conn_change_fwd_mask(cp, flags);
+ else
+ cp->flags = flags;
+ } else {
+ flags |= conn_flags;
+ cp->flags = flags;
}
- flags |= conn_flags;
- cp->flags = flags;
cp->dest = dest;
IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
|
| 3/2 | 2026/07/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5982 output: 34 thoughts: 344 Thoughts: **Analyzing a Kernel Patch for IPVS Connection Handling** Okay, so I'm looking at this patch that tweaks `net/netfilter/ipvs/ip_vs_conn.c`. It's all about how IPVS connections are hashed and locked, specifically concerning double hashing and how forwarding is handled. The changes introduce `ip_vs_conn_change_fwd_mask` and they've also fiddled with `conn_tab_lock`. Right away, I see this is core IPVS logic – the guts of its connection management. The first question that pops up in my head is always: "Is this reachable?" Considering IPVS is a kernel load balancer, used through netlink or socket options, and processes actual network packets, the answer is a resounding "yes". This thing *absolutely* makes functional changes to the kernel that screams for fuzzing. We need to hit this hard. Now, let's drill down and pinpoint the exact functions that this patch has modified. We need to focus our fuzzing efforts. Alright, the modified functions are: `conn_tab_lock` (which, from the looks of it, is an inline function), `ip_vs_conn_hash`, `ip_vs_conn_unlink`, `ip_vs_conn_fill_cport`, `ip_vs_conn_change_fwd_mask`, and `ip_vs_bind_dest`. I've got a good list to start with. So my specific focus symbols for fuzzing will be: `ip_vs_conn_hash`, `ip_vs_conn_unlink`, `ip_vs_conn_fill_cport`, `ip_vs_conn_change_fwd_mask`, and `ip_vs_bind_dest`. Before I forget, I need to make sure we've got the necessary configs enabled. Obviously, IPVS needs to be up and running for any of this to matter. I'll need to check the Kconfig file for IPVS, which should be in `net/netfilter/ipvs/Kconfig`. Generally, I think it's `CONFIG_IP_VS` that we need. Just to be sure, let me run a quick grep to verify and confirm. |
| 4/2 | 2026/07/02 02:58 | tool | grepper |
0mArgs:{
"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/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7107 output: 34 thoughts: 86 Thoughts: Okay, here's my summary, considering my expertise: **Examining IPVS Configuration for Synchronization and NAT** Right, so we're primarily dealing with `IP_VS` here. That's the core. But I need to be thorough; I have to consider the broader picture and the potential interdependencies. Let me just quickly scan the landscape. Ah, the patch notes mention `IP_VS_CONN_F_MASQ`, `IP_VS_CONN_F_SYNC`, and `IP_VS_CONN_F_TEMPLATE`. Interesting. They're flags, not direct configs, which simplifies things a bit. They'll influence behavior, certainly, but they're not the primary knobs to twiddle. Given this context, I have to determine if there are any specific kernel configurations directly related to IPVS synchronization or NAT functionality. I need to be sure I'm considering all relevant settings. It's time to refine the search. |
| 6/2 | 2026/07/02 02:58 | tool | grepper |
0mArgs:{
"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/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7698 output: 35 thoughts: 28 Thoughts: Here's my thought process, summarized as you requested: **IPVS Configuration Exploration** Okay, so I need to get a handle on the available configuration options related to IPVS. My immediate instinct is to dive into the kernel source, specifically the `Kconfig` files where the configuration options are defined. I'm going to jump into the `net/netfilter/ipvs/Kconfig` file. That seems like the logical place to start, given that IPVS is a part of netfilter. To quickly filter down to what I need, I'll use `grep`. I'll run `grep IP_VS` on that file. That should pull out all the lines that define or relate to IPVS configurations. This will hopefully give me a concise list to work from, rather than needing to manually scan the entire `Kconfig` file. From there, I can start to understand the dependencies and relationships between the various IPVS features and options. |
| 8/2 | 2026/07/02 02:58 | tool | grepper |
0mArgs:{
"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"
} |
| 9/2 | 2026/07/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8172 output: 37 thoughts: 62 Thoughts: **Examining the IPVS Configuration** Okay, hold on. Looking back, it's clear that focusing on `menuconfig IP_VS` is actually misleading. The real core of the matter is the `IP_VS` option itself. That's the one we need to be concerned with. Now, the question is, does enabling just `IP_VS` give us the full functionality we need? Or, do we need to specifically enable the protocol-specific modules too, like `IP_VS_PROTO_TCP`, `IP_VS_PROTO_UDP`, and so forth? Time to check that out. |
| 10/2 | 2026/07/02 02:58 | tool | grepper |
0mError:no matches Args: {
"Expression": "^config IP_VS_PROTO",
"PathPrefix": "net/netfilter/ipvs/Kconfig"
}Results: {
"error": "no matches"
} |
| 11/2 | 2026/07/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8416 output: 37 thoughts: 18 Thoughts: Here's my take on the `net/netfilter/ipvs/Kconfig` file, thinking like a kernel networking expert: **Diving into the IPVS Configuration** Okay, time to quickly scan the `net/netfilter/ipvs/Kconfig` file. I need to get a high-level view of the configuration options for IPVS. I'm looking for the dependencies, the default settings, and any potentially interesting build-time configurations that might be relevant for deployment or troubleshooting. I'll pay close attention to which options are directly exposed to the user versus those handled internally. I'm expecting the usual Kconfig conventions, but I want to see if anything jumps out as particularly innovative or problematic in the current implementation. Basically, I'm trying to mentally map the IPVS configuration landscape in a few seconds. |
| 12/2 | 2026/07/02 02:58 | tool | read-file |
0mArgs:{
"File": "net/netfilter/ipvs/Kconfig",
"FirstLine": 1,
"LineCount": 100
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\t#\n 3:\t# IP Virtual Server configuration\n 4:\t#\n 5:\tmenuconfig IP_VS\n 6:\t\ttristate \"IP virtual server support\"\n 7:\t\tdepends on INET \u0026\u0026 NETFILTER\n 8:\t\tdepends on (NF_CONNTRACK || NF_CONNTRACK=n)\n 9:\t\thelp\n 10:\t\t IP Virtual Server support will let you build a high-performance\n 11:\t\t virtual server based on cluster of two or more real servers. This\n 12:\t\t option must be enabled for at least one of the clustered computers\n 13:\t\t that will take care of intercepting incoming connections to a\n 14:\t\t single IP address and scheduling them to real servers.\n 15:\t\n 16:\t\t Three request dispatching techniques are implemented, they are\n 17:\t\t virtual server via NAT, virtual server via tunneling and virtual\n 18:\t\t server via direct routing. The several scheduling algorithms can\n 19:\t\t be used to choose which server the connection is directed to,\n 20:\t\t thus load balancing can be achieved among the servers. For more\n 21:\t\t information and its administration program, please visit the\n 22:\t\t following URL: \u003chttp://www.linuxvirtualserver.org/\u003e.\n 23:\t\n 24:\t\t If you want to compile it in kernel, say Y. To compile it as a\n 25:\t\t module, choose M here. If unsure, say N.\n 26:\t\n 27:\tif IP_VS\n 28:\t\n 29:\tconfig\tIP_VS_IPV6\n 30:\t\tbool \"IPv6 support for IPVS\"\n 31:\t\tdepends on IPV6 = y || IP_VS = IPV6\n 32:\t\tselect NF_DEFRAG_IPV6\n 33:\t\thelp\n 34:\t\t Add IPv6 support to IPVS.\n 35:\t\n 36:\t\t Say Y if unsure.\n 37:\t\n 38:\tconfig\tIP_VS_DEBUG\n 39:\t\tbool \"IP virtual server debugging\"\n 40:\t\thelp\n 41:\t\t Say Y here if you want to get additional messages useful in\n 42:\t\t debugging the IP virtual server code. You can change the debug\n 43:\t\t level in /proc/sys/net/ipv4/vs/debug_level\n 44:\t\n 45:\tconfig\tIP_VS_TAB_BITS\n 46:\t\tint \"IPVS connection table size (the Nth power of 2)\"\n 47:\t\trange 8 20 if !64BIT\n 48:\t\trange 8 27 if 64BIT\n 49:\t\tdefault 12\n 50:\t\thelp\n 51:\t\t The IPVS connection hash table uses the chaining scheme to handle\n 52:\t\t hash collisions. Using a big IPVS connection hash table will greatly\n 53:\t\t reduce conflicts when there are hundreds of thousands of connections\n 54:\t\t in the hash table.\n 55:\t\n 56:\t\t Note the table size must be power of 2. The table size will be the\n 57:\t\t value of 2 to the your input number power. The number to choose is\n 58:\t\t from 8 to 27 for 64BIT(20 otherwise), the default number is 12,\n 59:\t\t which means the table size is 4096. Don't input the number too\n 60:\t\t small, otherwise you will lose performance on it. You can adapt the\n 61:\t\t table size yourself, according to your virtual server application.\n 62:\t\t It is good to set the table size not far less than the number of\n 63:\t\t connections per second multiplying average lasting time of\n 64:\t\t connection in the table. For example, your virtual server gets 200\n 65:\t\t connections per second, the connection lasts for 200 seconds in\n 66:\t\t average in the connection table, the table size should be not far\n 67:\t\t less than 200x200, it is good to set the table size 32768 (2**15).\n 68:\t\n 69:\t\t Another note that each connection occupies 128 bytes effectively and\n 70:\t\t each hash entry uses 8 bytes, so you can estimate how much memory is\n 71:\t\t needed for your box.\n 72:\t\n 73:\t\t You can overwrite this number setting conn_tab_bits module parameter\n 74:\t\t or by appending ip_vs.conn_tab_bits=? to the kernel command line if\n 75:\t\t IP VS was compiled built-in.\n 76:\t\n 77:\tcomment \"IPVS transport protocol load balancing support\"\n 78:\t\n 79:\tconfig\tIP_VS_PROTO_TCP\n 80:\t\tbool \"TCP load balancing support\"\n 81:\t\thelp\n 82:\t\t This option enables support for load balancing TCP transport\n 83:\t\t protocol. Say Y if unsure.\n 84:\t\n 85:\tconfig\tIP_VS_PROTO_UDP\n 86:\t\tbool \"UDP load balancing support\"\n 87:\t\thelp\n 88:\t\t This option enables support for load balancing UDP transport\n 89:\t\t protocol. Say Y if unsure.\n 90:\t\n 91:\tconfig\tIP_VS_PROTO_AH_ESP\n 92:\t\tdef_bool IP_VS_PROTO_ESP || IP_VS_PROTO_AH\n 93:\t\n 94:\tconfig\tIP_VS_PROTO_ESP\n 95:\t\tbool \"ESP load balancing support\"\n 96:\t\thelp\n 97:\t\t This option enables support for load balancing ESP (Encapsulation\n 98:\t\t Security Payload) transport protocol. Say Y if unsure.\n 99:\t\n 100:\tconfig\tIP_VS_PROTO_AH\n"
} |
| 13/2 | 2026/07/02 02:58 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10158 output: 162 thoughts: 548 Thoughts: **Focusing on IPVS Connection Management** Alright, let's nail down what this patch is really doing. The core module is undoubtedly `IP_VS`, and while we could be exhaustive and include `IP_VS_PROTO_TCP` and `IP_VS_PROTO_UDP` for completeness, `IP_VS` is the critical piece. I need to make sure I'm not missing anything crucial here. I've reviewed the patch and it touches `ip_vs_conn.c`. Let's clarify which functions have been modified. I recall them but I will make sure I have them exactly right. It's: `conn_tab_lock`, `ip_vs_conn_hash`, `ip_vs_conn_unlink`, `ip_vs_conn_fill_cport`, `ip_vs_conn_change_fwd_mask`, and `ip_vs_bind_dest`. I've got the list. Time to refine this list. `conn_tab_lock` is marked `static __always_inline`, so I can almost ignore it, as it is inlined. So the main functions to focus on are `ip_vs_conn_hash`, `ip_vs_conn_unlink`, `ip_vs_conn_fill_cport`, `ip_vs_conn_change_fwd_mask`, and `ip_vs_bind_dest`. I should give additional consideration to `ip_vs_conn_hash` and `ip_vs_conn_unlink`, given they likely sit on the hot path. These are called for every connection, which is important to consider. `ip_vs_conn_change_fwd_mask` is called when a forwarding method changes; `ip_vs_bind_dest` is called when binding a destination, and `ip_vs_conn_fill_cport` is for the client port, so they are not quite as hot, but more specific. Given the nature of the functions, I'm going to include `ip_vs_conn_change_fwd_mask` and `ip_vs_bind_dest` as they are more specialized and likely impact specific connection behaviors. `ip_vs_conn_fill_cport` is also good. I will also quickly check whether any are `static`. `ip_vs_conn_change_fwd_mask` is static; the rest are not. That's good to know. Now I'm ready to present my findings. |
| 14/2 | 2026/07/02 02:58 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"IP_VS",
"IP_VS_PROTO_TCP",
"IP_VS_PROTO_UDP"
],
"FocusSymbols": [
"ip_vs_conn_change_fwd_mask",
"ip_vs_bind_dest",
"ip_vs_conn_fill_cport",
"ip_vs_conn_hash",
"ip_vs_conn_unlink"
],
"Reasoning": "This patch modifies the core IPVS connection hashing and locking logic, specifically introducing changes to how double hashing and forwarding methods are handled. This is reachable core networking logic that should be fuzzed to ensure no race conditions or deadlocks are introduced.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"IP_VS",
"IP_VS_PROTO_TCP",
"IP_VS_PROTO_UDP"
],
"FocusSymbols": [
"ip_vs_conn_change_fwd_mask",
"ip_vs_bind_dest",
"ip_vs_conn_fill_cport",
"ip_vs_conn_hash",
"ip_vs_conn_unlink"
],
"Reasoning": "This patch modifies the core IPVS connection hashing and locking logic, specifically introducing changes to how double hashing and forwarding methods are handled. This is reachable core networking logic that should be fuzzed to ensure no race conditions or deadlocks are introduced.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|