| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/02 15:20 | flow | patch-triage |
4mArgs:null Results: {
"EnableConfigs": [
"NF_CONNTRACK",
"NF_NAT",
"BRIDGE_NF_EBTABLES",
"NETFILTER_NETLINK_HOOK",
"NF_CT_NETLINK_HELPER",
"NF_CT_NETLINK_TIMEOUT",
"NFT_CT",
"NETFILTER_XT_MATCH_DSCP",
"NETFILTER_XT_MATCH_TCPMSS",
"NETFILTER_XT_MATCH_RECENT",
"NETFILTER_XT_TARGET_TCPOPTSTRIP",
"NF_CONNTRACK_AMANDA",
"NF_CONNTRACK_FTP",
"NF_CONNTRACK_H323",
"NF_CONNTRACK_IRC",
"NF_CONNTRACK_NETBIOS_NS",
"NF_CONNTRACK_SNMP",
"NF_CONNTRACK_PPTP",
"NF_CONNTRACK_SANE",
"NF_CONNTRACK_SIP",
"NF_CONNTRACK_TFTP",
"NF_NAT_SNMP_BASIC"
],
"FocusSymbols": [
"__nf_conntrack_helper_register",
"nf_ct_helper_init",
"__nf_conntrack_helper_find",
"nfnl_hook_dump_nat",
"nfnl_cthelper_new",
"cttimeout_new_timeout",
"tos_mt_check",
"tcpmss_mt_check",
"nft_ct_nat_follow_master",
"do_replace",
"compat_copy_ebt_replace_from_user"
],
"Reasoning": "The patch series makes functional changes to netfilter connection tracking helpers, NAT hooks, and ebtables. It changes how conntrack helpers are registered and looked up (removing port-specific defaults), adds a new NF_HOOK_OP_NAT type and fixes NAT hook dumping, adds a NAT follow master expectfn for nft_ct, and fixes an integer overflow in ebtables do_replace. It also adds validation checks for xt_dscp and xt_tcpmss matches. These are reachable core kernel and netfilter logic changes that should be fuzzed.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/02 15:20 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 3ce126b24f3cbc0f8498cf7bff8905a8d6f3d014\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Jul 2 15:20:02 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/include/linux/netfilter.h b/include/linux/netfilter.h\nindex efbbfa770d6617..e99afc1414cd39 100644\n--- a/include/linux/netfilter.h\n+++ b/include/linux/netfilter.h\n@@ -93,6 +93,7 @@ enum nf_hook_ops_type {\n \tNF_HOOK_OP_NF_TABLES,\n \tNF_HOOK_OP_BPF,\n \tNF_HOOK_OP_NFT_FT,\n+\tNF_HOOK_OP_NAT,\n };\n \n struct nf_hook_ops {\n@@ -140,6 +141,12 @@ struct nf_hook_entries {\n \t */\n };\n \n+struct nf_nat_lookup_hook_priv {\n+\tstruct nf_hook_entries __rcu *entries;\n+\n+\tstruct rcu_head rcu_head;\n+};\n+\n #ifdef CONFIG_NETFILTER\n static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e)\n {\ndiff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h\nindex 81286c49932521..b15f37604cde4e 100644\n--- a/include/linux/netfilter/nf_conntrack_h323.h\n+++ b/include/linux/netfilter/nf_conntrack_h323.h\n@@ -9,8 +9,6 @@\n #include \u003cnet/netfilter/nf_conntrack_expect.h\u003e\n #include \u003cuapi/linux/netfilter/nf_conntrack_tuple_common.h\u003e\n \n-#define RAS_PORT 1719\n-#define Q931_PORT 1720\n #define H323_RTP_CHANNEL_MAX 4\t/* Audio, video, FAX and other */\n \n /* This structure exists only once per master */\ndiff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h\nindex c3bdb43709384d..c0b305ce7c3c6b 100644\n--- a/include/linux/netfilter/nf_conntrack_pptp.h\n+++ b/include/linux/netfilter/nf_conntrack_pptp.h\n@@ -50,8 +50,6 @@ struct nf_nat_pptp {\n \t__be16 pac_call_id;\t\t\t/* NAT'ed PAC call id */\n };\n \n-#define PPTP_CONTROL_PORT\t1723\n-\n #define PPTP_PACKET_CONTROL\t1\n #define PPTP_PACKET_MGMT\t2\n \ndiff --git a/include/linux/netfilter/nf_conntrack_sane.h b/include/linux/netfilter/nf_conntrack_sane.h\nindex 46c7acd1b4a70f..8501035d733559 100644\n--- a/include/linux/netfilter/nf_conntrack_sane.h\n+++ b/include/linux/netfilter/nf_conntrack_sane.h\n@@ -3,8 +3,6 @@\n #define _NF_CONNTRACK_SANE_H\n /* SANE tracking. */\n \n-#define SANE_PORT\t6566\n-\n enum sane_state {\n \tSANE_STATE_NORMAL,\n \tSANE_STATE_START_REQUESTED,\ndiff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h\nindex 90b334bbce3ce6..e3d1739c557d15 100644\n--- a/include/linux/netfilter/nf_conntrack_tftp.h\n+++ b/include/linux/netfilter/nf_conntrack_tftp.h\n@@ -2,8 +2,6 @@\n #ifndef _NF_CONNTRACK_TFTP_H\n #define _NF_CONNTRACK_TFTP_H\n \n-#define TFTP_PORT 69\n-\n #include \u003clinux/netfilter.h\u003e\n #include \u003clinux/skbuff.h\u003e\n #include \u003clinux/types.h\u003e\ndiff --git a/include/net/ip_vs.h b/include/net/ip_vs.h\nindex 49297fec448a82..ed2e9bc1bb4e95 100644\n--- a/include/net/ip_vs.h\n+++ b/include/net/ip_vs.h\n@@ -2123,7 +2123,7 @@ void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,\n \t\t\t int outin);\n int ip_vs_confirm_conntrack(struct sk_buff *skb);\n void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,\n-\t\t\t struct ip_vs_conn *cp, u_int8_t proto,\n+\t\t\t struct ip_vs_conn *cp, u8 proto,\n \t\t\t const __be16 port, int from_rs);\n void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);\n \ndiff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h\nindex c761cd8158b253..bc5427d239f4c0 100644\n--- a/include/net/netfilter/nf_conntrack_helper.h\n+++ b/include/net/netfilter/nf_conntrack_helper.h\n@@ -43,11 +43,10 @@ struct nf_conntrack_helper {\n \n \trefcount_t ct_refcnt;\n \n-\t/* Tuple of things we will help (compared against server response) */\n-\tstruct nf_conntrack_tuple tuple;\n+\tu8 nfproto;\t/* NFPROTO_*, can be NFPROTO_UNSPEC */\n+\tu8 l4proto;\t/* IPPROTO_UDP/TCP */\n \n-\t/* Function to call when data passes; return verdict, or -1 to\n- invalidate. */\n+\t/* Function to call when data passes; return verdict */\n \tint __rcu (*help)(struct sk_buff *skb, unsigned int protoff,\n \t\t\t struct nf_conn *ct,\n \t\t\t enum ip_conntrack_info conntrackinfo);\n@@ -94,8 +93,7 @@ struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,\n void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);\n \n void nf_ct_helper_init(struct nf_conntrack_helper *helper,\n-\t\t u16 l3num, u16 protonum, const char *name,\n-\t\t u16 default_port, u16 spec_port, u32 id,\n+\t\t u8 l3num, u16 protonum, const char *name,\n \t\t const struct nf_conntrack_expect_policy *exp_pol,\n \t\t u32 expect_class_max,\n \t\t int (*help)(struct sk_buff *skb, unsigned int protoff,\ndiff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c\nindex f20c039e44c8d7..042d31278713df 100644\n--- a/net/bridge/netfilter/ebtables.c\n+++ b/net/bridge/netfilter/ebtables.c\n@@ -39,6 +39,8 @@\n #define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))\n #define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \\\n \t\t\t\t COUNTER_OFFSET(n) * cpu))\n+#define MAX_EBT_ENTRIES (((INT_MAX - sizeof(struct ebt_table_info)) / \\\n+\t\t\t NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))\n \n struct ebt_pernet {\n \tstruct list_head tables;\n@@ -1124,10 +1126,9 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)\n \t\treturn -EINVAL;\n \n \t/* overflow check */\n-\tif (tmp.nentries \u003e= ((INT_MAX - sizeof(struct ebt_table_info)) /\n-\t\t\tNR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))\n+\tif (tmp.nentries \u003e= MAX_EBT_ENTRIES)\n \t\treturn -ENOMEM;\n-\tif (tmp.num_counters \u003e= INT_MAX / sizeof(struct ebt_counter))\n+\tif (tmp.num_counters \u003e= MAX_EBT_ENTRIES)\n \t\treturn -ENOMEM;\n \n \ttmp.name[sizeof(tmp.name) - 1] = 0;\n@@ -2265,10 +2266,9 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,\n \tif (tmp.entries_size == 0)\n \t\treturn -EINVAL;\n \n-\tif (tmp.nentries \u003e= ((INT_MAX - sizeof(struct ebt_table_info)) /\n-\t\t\tNR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))\n+\tif (tmp.nentries \u003e= MAX_EBT_ENTRIES)\n \t\treturn -ENOMEM;\n-\tif (tmp.num_counters \u003e= INT_MAX / sizeof(struct ebt_counter))\n+\tif (tmp.num_counters \u003e= MAX_EBT_ENTRIES)\n \t\treturn -ENOMEM;\n \n \tmemcpy(repl, \u0026tmp, offsetof(struct ebt_replace, hook_entry));\ndiff --git a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c\nindex 0ede138dfd29e7..e540b86bd15b6b 100644\n--- a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c\n+++ b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c\n@@ -213,7 +213,7 @@ static int __init nf_nat_snmp_basic_init(void)\n \tRCU_INIT_POINTER(nf_nat_snmp_hook, help);\n \n \tnf_ct_helper_init(\u0026snmp_trap_helper, AF_INET, IPPROTO_UDP,\n-\t\t\t \"snmp_trap\", SNMP_TRAP_PORT, SNMP_TRAP_PORT, SNMP_TRAP_PORT,\n+\t\t\t \"snmp_trap\",\n \t\t\t \u0026snmp_exp_policy, 0, help, NULL, THIS_MODULE);\n \n \terr = nf_conntrack_helper_register(\u0026snmp_trap_helper, \u0026snmp_trap_helper_ptr);\ndiff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c\nindex 81974f69e5bb4e..347185fd0c8c6f 100644\n--- a/net/netfilter/ipvs/ip_vs_nfct.c\n+++ b/net/netfilter/ipvs/ip_vs_nfct.c\n@@ -208,7 +208,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,\n * Use port 0 to expect connection from any port.\n */\n void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,\n-\t\t\t struct ip_vs_conn *cp, u_int8_t proto,\n+\t\t\t struct ip_vs_conn *cp, u8 proto,\n \t\t\t const __be16 port, int from_rs)\n {\n \tstruct nf_conntrack_expect *exp;\ndiff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c\nindex ddafbdfc96dc35..06d6ec12c86dfa 100644\n--- a/net/netfilter/nf_conntrack_amanda.c\n+++ b/net/netfilter/nf_conntrack_amanda.c\n@@ -89,7 +89,7 @@ static int amanda_help(struct sk_buff *skb,\n \tstruct nf_conntrack_tuple *tuple;\n \tunsigned int dataoff, start, stop, off, i;\n \tchar pbuf[sizeof(\"65535\")], *tmp;\n-\tu_int16_t len;\n+\tu16 len;\n \t__be16 port;\n \tint ret = NF_ACCEPT;\n \tnf_nat_amanda_hook_fn *nf_nat_amanda;\n@@ -199,10 +199,10 @@ static int __init nf_conntrack_amanda_init(void)\n \t}\n \n \tnf_ct_helper_init(\u0026amanda_helper[0], AF_INET, IPPROTO_UDP,\n-\t\t\t HELPER_NAME, 10080, 10080, 10080,\n+\t\t\t HELPER_NAME,\n \t\t\t \u0026amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);\n \tnf_ct_helper_init(\u0026amanda_helper[1], AF_INET6, IPPROTO_UDP,\n-\t\t\t HELPER_NAME, 10080, 10080, 10080,\n+\t\t\t HELPER_NAME,\n \t\t\t \u0026amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);\n \n \tret = nf_conntrack_helpers_register(amanda_helper,\ndiff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c\nindex bf78828c7549d4..6ff954f1bfb87c 100644\n--- a/net/netfilter/nf_conntrack_broadcast.c\n+++ b/net/netfilter/nf_conntrack_broadcast.c\n@@ -66,8 +66,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,\n \texp-\u003etuple = ct-\u003etuplehash[IP_CT_DIR_REPLY].tuple;\n \n \thelper = rcu_dereference(help-\u003ehelper);\n-\tif (helper)\n-\t\texp-\u003etuple.src.u.udp.port = helper-\u003etuple.src.u.udp.port;\n \n \texp-\u003emask.src.u3.ip = mask;\n \texp-\u003emask.src.u.udp.port = htons(0xFFFF);\ndiff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c\nindex 0847f845613d6a..f3944598c1726f 100644\n--- a/net/netfilter/nf_conntrack_ftp.c\n+++ b/net/netfilter/nf_conntrack_ftp.c\n@@ -35,11 +35,6 @@ MODULE_ALIAS(\"ip_conntrack_ftp\");\n MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);\n static DEFINE_SPINLOCK(nf_ftp_lock);\n \n-#define MAX_PORTS 8\n-static u_int16_t ports[MAX_PORTS];\n-static unsigned int ports_c;\n-module_param_array(ports, ushort, \u0026ports_c, 0400);\n-\n static bool loose;\n module_param(loose, bool, 0600);\n \n@@ -560,8 +555,8 @@ static int nf_ct_ftp_from_nlattr(struct nlattr *attr, struct nf_conn *ct)\n \treturn 0;\n }\n \n-static struct nf_conntrack_helper ftp[MAX_PORTS * 2] __read_mostly;\n-static struct nf_conntrack_helper *ftp_ptr[MAX_PORTS * 2] __read_mostly;\n+static struct nf_conntrack_helper ftp __read_mostly;\n+static struct nf_conntrack_helper *ftp_ptr __read_mostly;\n \n static const struct nf_conntrack_expect_policy ftp_exp_policy = {\n \t.max_expected\t= 1,\n@@ -570,32 +565,23 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {\n \n static void __exit nf_conntrack_ftp_fini(void)\n {\n-\tnf_conntrack_helpers_unregister(ftp_ptr, ports_c * 2);\n+\tnf_conntrack_helper_unregister(ftp_ptr);\n }\n \n static int __init nf_conntrack_ftp_init(void)\n {\n-\tint i, ret = 0;\n+\tint ret = 0;\n \n \tNF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master));\n \n-\tif (ports_c == 0)\n-\t\tports[ports_c++] = FTP_PORT;\n-\n \t/* FIXME should be configurable whether IPv4 and IPv6 FTP connections\n \t\t are tracked or not - YK */\n-\tfor (i = 0; i \u003c ports_c; i++) {\n-\t\tnf_ct_helper_init(\u0026ftp[2 * i], AF_INET, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, FTP_PORT, ports[i], ports[i],\n-\t\t\t\t \u0026ftp_exp_policy, 0, help,\n-\t\t\t\t nf_ct_ftp_from_nlattr, THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026ftp[2 * i + 1], AF_INET6, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, FTP_PORT, ports[i], ports[i],\n-\t\t\t\t \u0026ftp_exp_policy, 0, help,\n-\t\t\t\t nf_ct_ftp_from_nlattr, THIS_MODULE);\n-\t}\n+\tnf_ct_helper_init(\u0026ftp, NFPROTO_UNSPEC, IPPROTO_TCP,\n+\t\t\t HELPER_NAME,\n+\t\t\t \u0026ftp_exp_policy, 0, help,\n+\t\t\t nf_ct_ftp_from_nlattr, THIS_MODULE);\n \n-\tret = nf_conntrack_helpers_register(ftp, ports_c * 2, ftp_ptr);\n+\tret = nf_conntrack_helper_register(\u0026ftp, \u0026ftp_ptr);\n \tif (ret \u003c 0) {\n \t\tpr_err(\"failed to register helpers\\n\");\n \t\treturn ret;\ndiff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c\nindex 24931e379985bb..4cb1665bba0214 100644\n--- a/net/netfilter/nf_conntrack_h323_main.c\n+++ b/net/netfilter/nf_conntrack_h323_main.c\n@@ -671,7 +671,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,\n static int callforward_do_filter(struct net *net,\n \t\t\t\t const union nf_inet_addr *src,\n \t\t\t\t const union nf_inet_addr *dst,\n-\t\t\t\t u_int8_t family)\n+\t\t\t\t u8 family)\n {\n \tint ret = 0;\n \n@@ -1713,19 +1713,19 @@ static int __init h323_helper_init(void)\n \tint ret;\n \n \tnf_ct_helper_init(\u0026nf_conntrack_helper_ras[0], AF_INET, IPPROTO_UDP,\n-\t\t\t \"RAS\", RAS_PORT, RAS_PORT, RAS_PORT,\n+\t\t\t \"RAS\",\n \t\t\t \u0026ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);\n \tnf_ct_helper_init(\u0026nf_conntrack_helper_ras[1], AF_INET6, IPPROTO_UDP,\n-\t\t\t \"RAS\", RAS_PORT, RAS_PORT, RAS_PORT,\n+\t\t\t \"RAS\",\n \t\t\t \u0026ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);\n \tnf_ct_helper_init(\u0026nf_conntrack_helper_h245, AF_UNSPEC, IPPROTO_UDP,\n-\t\t\t \"H.245\", 0, 0, 0,\n+\t\t\t \"H.245\",\n \t\t\t \u0026h245_exp_policy, 0, h245_help, NULL, THIS_MODULE);\n \tnf_ct_helper_init(\u0026nf_conntrack_helper_q931[0], AF_INET, IPPROTO_TCP,\n-\t\t\t \"Q.931\", Q931_PORT, Q931_PORT, Q931_PORT,\n+\t\t\t \"Q.931\",\n \t\t\t \u0026q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);\n \tnf_ct_helper_init(\u0026nf_conntrack_helper_q931[1], AF_INET6, IPPROTO_TCP,\n-\t\t\t \"Q.931\", Q931_PORT, Q931_PORT, Q931_PORT,\n+\t\t\t \"Q.931\",\n \t\t\t \u0026q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);\n \n \tret = nf_conntrack_helper_register(\u0026nf_conntrack_helper_h245,\ndiff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c\nindex 500509b17663ed..506c5803476155 100644\n--- a/net/netfilter/nf_conntrack_helper.c\n+++ b/net/netfilter/nf_conntrack_helper.c\n@@ -40,12 +40,16 @@ static unsigned int nf_ct_helper_count __read_mostly;\n static DEFINE_MUTEX(nf_ct_nat_helpers_mutex);\n static struct list_head nf_ct_nat_helpers __read_mostly;\n \n-/* Stupid hash, but collision free for the default registrations of the\n- * helpers currently in the kernel. */\n-static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)\n+static unsigned int helper_hash(const char *name, u8 protonum)\n {\n-\treturn (((tuple-\u003esrc.l3num \u003c\u003c 8) | tuple-\u003edst.protonum) ^\n-\t\t(__force __u16)tuple-\u003esrc.u.all) % nf_ct_helper_hsize;\n+\tstatic u32 seed;\n+\tu32 initval;\n+\n+\tget_random_once(\u0026seed, sizeof(seed));\n+\n+\tinitval = seed ^ protonum;\n+\n+\treturn jhash(name, strlen(name), initval) % nf_ct_helper_hsize;\n }\n \n struct nf_conntrack_helper *\n@@ -54,18 +58,18 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)\n \tstruct nf_conntrack_helper *h;\n \tunsigned int i;\n \n-\tfor (i = 0; i \u003c nf_ct_helper_hsize; i++) {\n-\t\thlist_for_each_entry_rcu(h, \u0026nf_ct_helper_hash[i], hnode) {\n-\t\t\tif (strcmp(h-\u003ename, name))\n-\t\t\t\tcontinue;\n+\tif (!nf_ct_helper_hash)\n+\t\treturn NULL;\n \n-\t\t\tif (h-\u003etuple.src.l3num != NFPROTO_UNSPEC \u0026\u0026\n-\t\t\t h-\u003etuple.src.l3num != l3num)\n-\t\t\t\tcontinue;\n+\ti = helper_hash(name, protonum);\n \n-\t\t\tif (h-\u003etuple.dst.protonum == protonum)\n-\t\t\t\treturn h;\n-\t\t}\n+\thlist_for_each_entry_rcu(h, \u0026nf_ct_helper_hash[i], hnode) {\n+\t\tif (strcmp(h-\u003ename, name))\n+\t\t\tcontinue;\n+\t\tif (h-\u003enfproto != NFPROTO_UNSPEC \u0026\u0026 h-\u003enfproto != l3num)\n+\t\t\tcontinue;\n+\t\tif (h-\u003el4proto == protonum)\n+\t\t\treturn h;\n \t}\n \treturn NULL;\n }\n@@ -363,9 +367,8 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log);\n \n int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)\n {\n-\tstruct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };\n-\tunsigned int h = helper_hash(\u0026me-\u003etuple);\n \tstruct nf_conntrack_helper *cur;\n+\tunsigned int h;\n \tint ret = 0, i;\n \n \tBUG_ON(me-\u003eexpect_class_max \u003e= NF_CT_MAX_EXPECT_CLASSES);\n@@ -382,29 +385,18 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)\n \t\t\treturn -EINVAL;\n \t}\n \n+\th = helper_hash(me-\u003ename, me-\u003el4proto);\n \tmutex_lock(\u0026nf_ct_helper_mutex);\n-\tfor (i = 0; i \u003c nf_ct_helper_hsize; i++) {\n-\t\thlist_for_each_entry(cur, \u0026nf_ct_helper_hash[i], hnode) {\n-\t\t\tif (!strcmp(cur-\u003ename, me-\u003ename) \u0026\u0026\n-\t\t\t (cur-\u003etuple.src.l3num == NFPROTO_UNSPEC ||\n-\t\t\t cur-\u003etuple.src.l3num == me-\u003etuple.src.l3num) \u0026\u0026\n-\t\t\t cur-\u003etuple.dst.protonum == me-\u003etuple.dst.protonum) {\n-\t\t\t\tret = -EBUSY;\n-\t\t\t\tgoto out;\n-\t\t\t}\n+\thlist_for_each_entry(cur, \u0026nf_ct_helper_hash[h], hnode) {\n+\t\tif (!strcmp(cur-\u003ename, me-\u003ename) \u0026\u0026\n+\t\t (cur-\u003enfproto == NFPROTO_UNSPEC ||\n+\t\t cur-\u003enfproto == me-\u003enfproto) \u0026\u0026\n+\t\t cur-\u003el4proto == me-\u003el4proto) {\n+\t\t\tret = -EBUSY;\n+\t\t\tgoto out;\n \t\t}\n \t}\n \n-\t/* avoid unpredictable behaviour for auto_assign_helper */\n-\tif (!(me-\u003eflags \u0026 NF_CT_HELPER_F_USERSPACE)) {\n-\t\thlist_for_each_entry(cur, \u0026nf_ct_helper_hash[h], hnode) {\n-\t\t\tif (nf_ct_tuple_src_mask_cmp(\u0026cur-\u003etuple, \u0026me-\u003etuple,\n-\t\t\t\t\t\t \u0026mask)) {\n-\t\t\t\tret = -EBUSY;\n-\t\t\t\tgoto out;\n-\t\t\t}\n-\t\t}\n-\t}\n \trefcount_set(\u0026me-\u003ect_refcnt, 1);\n \thlist_add_head_rcu(\u0026me-\u003ehnode, \u0026nf_ct_helper_hash[h]);\n \tnf_ct_helper_count++;\n@@ -479,8 +471,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)\n EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);\n \n void nf_ct_helper_init(struct nf_conntrack_helper *helper,\n-\t\t u16 l3num, u16 protonum, const char *name,\n-\t\t u16 default_port, u16 spec_port, u32 id,\n+\t\t u8 l3num, u16 protonum, const char *name,\n \t\t const struct nf_conntrack_expect_policy *exp_pol,\n \t\t u32 expect_class_max,\n \t\t int (*help)(struct sk_buff *skb, unsigned int protoff,\n@@ -492,9 +483,8 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,\n {\n \tmemset(helper, 0, sizeof(*helper));\n \n-\thelper-\u003etuple.src.l3num = l3num;\n-\thelper-\u003etuple.dst.protonum = protonum;\n-\thelper-\u003etuple.src.u.all = htons(spec_port);\n+\thelper-\u003enfproto = l3num;\n+\thelper-\u003el4proto = protonum;\n \n \trcu_assign_pointer(helper-\u003ehelp, help);\n \thelper-\u003efrom_nlattr = from_nlattr;\n@@ -502,10 +492,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,\n \tsnprintf(helper-\u003enat_mod_name, sizeof(helper-\u003enat_mod_name),\n \t\t NF_NAT_HELPER_PREFIX \"%s\", name);\n \n-\tif (spec_port == default_port)\n-\t\tsnprintf(helper-\u003ename, sizeof(helper-\u003ename), \"%s\", name);\n-\telse\n-\t\tsnprintf(helper-\u003ename, sizeof(helper-\u003ename), \"%s-%u\", name, id);\n+\tsnprintf(helper-\u003ename, sizeof(helper-\u003ename), \"%s\", name);\n \n \tif (WARN_ON_ONCE(expect_class_max \u003e= NF_CT_MAX_EXPECT_CLASSES))\n \t\treturn;\ndiff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c\nindex 193ab34db795f9..4e6bafe4143752 100644\n--- a/net/netfilter/nf_conntrack_irc.c\n+++ b/net/netfilter/nf_conntrack_irc.c\n@@ -21,9 +21,6 @@\n #include \u003cnet/netfilter/nf_conntrack_helper.h\u003e\n #include \u003clinux/netfilter/nf_conntrack_irc.h\u003e\n \n-#define MAX_PORTS 8\n-static unsigned short ports[MAX_PORTS];\n-static unsigned int ports_c;\n static unsigned int max_dcc_channels = 8;\n static unsigned int dcc_timeout __read_mostly = 300;\n /* This is slow, but it's simple. --RR */\n@@ -42,8 +39,6 @@ MODULE_LICENSE(\"GPL\");\n MODULE_ALIAS(\"ip_conntrack_irc\");\n MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);\n \n-module_param_array(ports, ushort, \u0026ports_c, 0400);\n-MODULE_PARM_DESC(ports, \"port numbers of IRC servers\");\n module_param(max_dcc_channels, uint, 0400);\n MODULE_PARM_DESC(max_dcc_channels, \"max number of expected DCC channels per \"\n \t\t\t\t \"IRC session\");\n@@ -254,13 +249,13 @@ static int help(struct sk_buff *skb, unsigned int protoff,\n \treturn ret;\n }\n \n-static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;\n-static struct nf_conntrack_helper *irc_ptr[MAX_PORTS] __read_mostly;\n+static struct nf_conntrack_helper irc __read_mostly;\n+static struct nf_conntrack_helper *irc_ptr __read_mostly;\n static struct nf_conntrack_expect_policy irc_exp_policy;\n \n static int __init nf_conntrack_irc_init(void)\n {\n-\tint i, ret;\n+\tint ret;\n \n \tnf_conntrack_helper_deprecated(HELPER_NAME);\n \n@@ -282,17 +277,11 @@ static int __init nf_conntrack_irc_init(void)\n \tif (!irc_buffer)\n \t\treturn -ENOMEM;\n \n-\t/* If no port given, default to standard irc port */\n-\tif (ports_c == 0)\n-\t\tports[ports_c++] = IRC_PORT;\n+\tnf_ct_helper_init(\u0026irc, AF_INET, IPPROTO_TCP, HELPER_NAME,\n+\t\t\t \u0026irc_exp_policy,\n+\t\t\t 0, help, NULL, THIS_MODULE);\n \n-\tfor (i = 0; i \u003c ports_c; i++) {\n-\t\tnf_ct_helper_init(\u0026irc[i], AF_INET, IPPROTO_TCP, HELPER_NAME,\n-\t\t\t\t IRC_PORT, ports[i], i, \u0026irc_exp_policy,\n-\t\t\t\t 0, help, NULL, THIS_MODULE);\n-\t}\n-\n-\tret = nf_conntrack_helpers_register(\u0026irc[0], ports_c, irc_ptr);\n+\tret = nf_conntrack_helper_register(\u0026irc, \u0026irc_ptr);\n \tif (ret) {\n \t\tpr_err(\"failed to register helpers\\n\");\n \t\tkfree(irc_buffer);\n@@ -304,7 +293,7 @@ static int __init nf_conntrack_irc_init(void)\n \n static void __exit nf_conntrack_irc_fini(void)\n {\n-\tnf_conntrack_helpers_unregister(irc_ptr, ports_c);\n+\tnf_conntrack_helper_unregister(irc_ptr);\n \tkfree(irc_buffer);\n }\n \ndiff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c\nindex 89d1cf7d6512e7..caa2b101fa9e5e 100644\n--- a/net/netfilter/nf_conntrack_netbios_ns.c\n+++ b/net/netfilter/nf_conntrack_netbios_ns.c\n@@ -21,7 +21,6 @@\n #include \u003cnet/netfilter/nf_conntrack_expect.h\u003e\n \n #define HELPER_NAME\t\"netbios-ns\"\n-#define NMBD_PORT\t137\n \n MODULE_AUTHOR(\"Patrick McHardy \u003ckaber@trash.net\u003e\");\n MODULE_DESCRIPTION(\"NetBIOS name service broadcast connection tracking helper\");\n@@ -54,7 +53,6 @@ static int __init nf_conntrack_netbios_ns_init(void)\n \texp_policy.timeout = timeout;\n \n \tnf_ct_helper_init(\u0026helper, AF_INET, IPPROTO_UDP, HELPER_NAME,\n-\t\t\t NMBD_PORT, NMBD_PORT, NMBD_PORT,\n \t\t\t \u0026exp_policy, 0, netbios_ns_help, NULL, THIS_MODULE);\n \n \treturn nf_conntrack_helper_register(\u0026helper, \u0026helper_ptr);\ndiff --git a/net/netfilter/nf_conntrack_ovs.c b/net/netfilter/nf_conntrack_ovs.c\nindex 49d1511e992185..b4085af3ad1ce0 100644\n--- a/net/netfilter/nf_conntrack_ovs.c\n+++ b/net/netfilter/nf_conntrack_ovs.c\n@@ -31,8 +31,8 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,\n \tif (!helper)\n \t\treturn NF_ACCEPT;\n \n-\tif (helper-\u003etuple.src.l3num != NFPROTO_UNSPEC \u0026\u0026\n-\t helper-\u003etuple.src.l3num != proto)\n+\tif (helper-\u003enfproto != NFPROTO_UNSPEC \u0026\u0026\n+\t helper-\u003enfproto != proto)\n \t\treturn NF_ACCEPT;\n \n \tswitch (proto) {\n@@ -60,7 +60,7 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,\n \t\treturn NF_DROP;\n \t}\n \n-\tif (helper-\u003etuple.dst.protonum != proto)\n+\tif (helper-\u003el4proto != proto)\n \t\treturn NF_ACCEPT;\n \n \thelper_cb = rcu_dereference(helper-\u003ehelp);\ndiff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c\nindex 80fc14c87ddc4b..cbf32a3cb1f612 100644\n--- a/net/netfilter/nf_conntrack_pptp.c\n+++ b/net/netfilter/nf_conntrack_pptp.c\n@@ -540,7 +540,7 @@ static int __init nf_conntrack_pptp_init(void)\n \tNF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_pptp_master));\n \n \tnf_ct_helper_init(\u0026pptp, AF_INET, IPPROTO_TCP,\n-\t\t\t \"pptp\", PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, PPTP_CONTROL_PORT,\n+\t\t\t \"pptp\",\n \t\t\t \u0026pptp_exp_policy, 0, conntrack_pptp_help, NULL, THIS_MODULE);\n \n \tpptp.destroy = gre_pptp_destroy_siblings;\ndiff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c\nindex 39085acf7a7185..a0658f69d78fbb 100644\n--- a/net/netfilter/nf_conntrack_sane.c\n+++ b/net/netfilter/nf_conntrack_sane.c\n@@ -34,11 +34,6 @@ MODULE_AUTHOR(\"Michal Schmidt \u003cmschmidt@redhat.com\u003e\");\n MODULE_DESCRIPTION(\"SANE connection tracking helper\");\n MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);\n \n-#define MAX_PORTS 8\n-static u_int16_t ports[MAX_PORTS];\n-static unsigned int ports_c;\n-module_param_array(ports, ushort, \u0026ports_c, 0400);\n-\n struct sane_request {\n \t__be32 RPC_code;\n #define SANE_NET_START 7 /* RPC code */\n@@ -169,8 +164,8 @@ static int help(struct sk_buff *skb,\n \treturn ret;\n }\n \n-static struct nf_conntrack_helper sane[MAX_PORTS * 2] __read_mostly;\n-static struct nf_conntrack_helper *sane_ptr[MAX_PORTS * 2] __read_mostly;\n+static struct nf_conntrack_helper sane __read_mostly;\n+static struct nf_conntrack_helper *sane_ptr __read_mostly;\n \n static const struct nf_conntrack_expect_policy sane_exp_policy = {\n \t.max_expected\t= 1,\n@@ -179,32 +174,21 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {\n \n static void __exit nf_conntrack_sane_fini(void)\n {\n-\tnf_conntrack_helpers_unregister(sane_ptr, ports_c * 2);\n+\tnf_conntrack_helper_unregister(sane_ptr);\n }\n \n static int __init nf_conntrack_sane_init(void)\n {\n-\tint i, ret = 0;\n+\tint ret = 0;\n \n \tNF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master));\n \n-\tif (ports_c == 0)\n-\t\tports[ports_c++] = SANE_PORT;\n-\n-\t/* FIXME should be configurable whether IPv4 and IPv6 connections\n-\t\t are tracked or not - YK */\n-\tfor (i = 0; i \u003c ports_c; i++) {\n-\t\tnf_ct_helper_init(\u0026sane[2 * i], AF_INET, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, SANE_PORT, ports[i], ports[i],\n-\t\t\t\t \u0026sane_exp_policy, 0, help, NULL,\n-\t\t\t\t THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026sane[2 * i + 1], AF_INET6, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, SANE_PORT, ports[i], ports[i],\n-\t\t\t\t \u0026sane_exp_policy, 0, help, NULL,\n-\t\t\t\t THIS_MODULE);\n-\t}\n+\tnf_ct_helper_init(\u0026sane, NFPROTO_UNSPEC, IPPROTO_TCP,\n+\t\t\t HELPER_NAME,\n+\t\t\t \u0026sane_exp_policy, 0, help, NULL,\n+\t\t\t THIS_MODULE);\n \n-\tret = nf_conntrack_helpers_register(sane, ports_c * 2, sane_ptr);\n+\tret = nf_conntrack_helper_register(\u0026sane, \u0026sane_ptr);\n \tif (ret \u003c 0) {\n \t\tpr_err(\"failed to register helpers\\n\");\n \t\treturn ret;\ndiff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c\nindex 5ec3a4a4bbd707..d0b85b8ad1e6d8 100644\n--- a/net/netfilter/nf_conntrack_sip.c\n+++ b/net/netfilter/nf_conntrack_sip.c\n@@ -35,12 +35,6 @@ MODULE_DESCRIPTION(\"SIP connection tracking helper\");\n MODULE_ALIAS(\"ip_conntrack_sip\");\n MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);\n \n-#define MAX_PORTS\t8\n-static unsigned short ports[MAX_PORTS];\n-static unsigned int ports_c;\n-module_param_array(ports, ushort, \u0026ports_c, 0400);\n-MODULE_PARM_DESC(ports, \"port numbers of SIP servers\");\n-\n static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;\n module_param(sip_timeout, uint, 0600);\n MODULE_PARM_DESC(sip_timeout, \"timeout for the master SIP session\");\n@@ -1764,8 +1758,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,\n \treturn process_sip_msg(skb, ct, protoff, dataoff, \u0026dptr, \u0026datalen);\n }\n \n-static struct nf_conntrack_helper sip[MAX_PORTS * 4] __read_mostly;\n-static struct nf_conntrack_helper *sip_ptr[MAX_PORTS * 4] __read_mostly;\n+static struct nf_conntrack_helper sip[2] __read_mostly;\n+static struct nf_conntrack_helper *sip_ptr[2] __read_mostly;\n \n static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {\n \t[SIP_EXPECT_SIGNALLING] = {\n@@ -1792,38 +1786,25 @@ static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1\n \n static void __exit nf_conntrack_sip_fini(void)\n {\n-\tnf_conntrack_helpers_unregister(sip_ptr, ports_c * 4);\n+\tnf_conntrack_helpers_unregister(sip_ptr, 2);\n }\n \n static int __init nf_conntrack_sip_init(void)\n {\n-\tint i, ret;\n+\tint ret;\n \n \tNF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sip_master));\n \n-\tif (ports_c == 0)\n-\t\tports[ports_c++] = SIP_PORT;\n-\n-\tfor (i = 0; i \u003c ports_c; i++) {\n-\t\tnf_ct_helper_init(\u0026sip[4 * i], AF_INET, IPPROTO_UDP,\n-\t\t\t\t HELPER_NAME, SIP_PORT, ports[i], i,\n-\t\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,\n-\t\t\t\t NULL, THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026sip[4 * i + 1], AF_INET, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, SIP_PORT, ports[i], i,\n-\t\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,\n-\t\t\t\t NULL, THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026sip[4 * i + 2], AF_INET6, IPPROTO_UDP,\n-\t\t\t\t HELPER_NAME, SIP_PORT, ports[i], i,\n-\t\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,\n-\t\t\t\t NULL, THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026sip[4 * i + 3], AF_INET6, IPPROTO_TCP,\n-\t\t\t\t HELPER_NAME, SIP_PORT, ports[i], i,\n-\t\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,\n-\t\t\t\t NULL, THIS_MODULE);\n-\t}\n+\tnf_ct_helper_init(\u0026sip[0], NFPROTO_UNSPEC, IPPROTO_UDP,\n+\t\t\t HELPER_NAME,\n+\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,\n+\t\t\t NULL, THIS_MODULE);\n+\tnf_ct_helper_init(\u0026sip[1], NFPROTO_UNSPEC, IPPROTO_TCP,\n+\t\t\t HELPER_NAME,\n+\t\t\t sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,\n+\t\t\t NULL, THIS_MODULE);\n \n-\tret = nf_conntrack_helpers_register(sip, ports_c * 4, sip_ptr);\n+\tret = nf_conntrack_helpers_register(sip, 2, sip_ptr);\n \tif (ret \u003c 0) {\n \t\tpr_err(\"failed to register helpers\\n\");\n \t\treturn ret;\ndiff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c\nindex b6fce5703fce77..109986d5d55e69 100644\n--- a/net/netfilter/nf_conntrack_snmp.c\n+++ b/net/netfilter/nf_conntrack_snmp.c\n@@ -14,8 +14,6 @@\n #include \u003cnet/netfilter/nf_conntrack_expect.h\u003e\n #include \u003clinux/netfilter/nf_conntrack_snmp.h\u003e\n \n-#define SNMP_PORT\t161\n-\n MODULE_AUTHOR(\"Jiri Olsa \u003cjolsa@redhat.com\u003e\");\n MODULE_DESCRIPTION(\"SNMP service broadcast connection tracking helper\");\n MODULE_LICENSE(\"GPL\");\n@@ -55,7 +53,7 @@ static int __init nf_conntrack_snmp_init(void)\n \texp_policy.timeout = timeout;\n \n \tnf_ct_helper_init(\u0026helper, AF_INET, IPPROTO_UDP,\n-\t\t\t \"snmp\", SNMP_PORT, SNMP_PORT, SNMP_PORT,\n+\t\t\t \"snmp\",\n \t\t\t \u0026exp_policy, 0, snmp_conntrack_help, NULL,\n \t\t\t THIS_MODULE);\n \ndiff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c\nindex 4393c435aa3549..a69559edf9b363 100644\n--- a/net/netfilter/nf_conntrack_tftp.c\n+++ b/net/netfilter/nf_conntrack_tftp.c\n@@ -26,12 +26,6 @@ MODULE_LICENSE(\"GPL\");\n MODULE_ALIAS(\"ip_conntrack_tftp\");\n MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);\n \n-#define MAX_PORTS 8\n-static unsigned short ports[MAX_PORTS];\n-static unsigned int ports_c;\n-module_param_array(ports, ushort, \u0026ports_c, 0400);\n-MODULE_PARM_DESC(ports, \"Port numbers of TFTP servers\");\n-\n nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook __read_mostly;\n EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);\n \n@@ -95,8 +89,8 @@ static int tftp_help(struct sk_buff *skb,\n \treturn ret;\n }\n \n-static struct nf_conntrack_helper tftp[MAX_PORTS * 2] __read_mostly;\n-static struct nf_conntrack_helper *tftp_ptr[MAX_PORTS * 2] __read_mostly;\n+static struct nf_conntrack_helper tftp __read_mostly;\n+static struct nf_conntrack_helper *tftp_ptr __read_mostly;\n \n static const struct nf_conntrack_expect_policy tftp_exp_policy = {\n \t.max_expected\t= 1,\n@@ -105,30 +99,21 @@ static const struct nf_conntrack_expect_policy tftp_exp_policy = {\n \n static void __exit nf_conntrack_tftp_fini(void)\n {\n-\tnf_conntrack_helpers_unregister(tftp_ptr, ports_c * 2);\n+\tnf_conntrack_helper_unregister(tftp_ptr);\n }\n \n static int __init nf_conntrack_tftp_init(void)\n {\n-\tint i, ret;\n+\tint ret;\n \n \tNF_CT_HELPER_BUILD_BUG_ON(0);\n \n-\tif (ports_c == 0)\n-\t\tports[ports_c++] = TFTP_PORT;\n-\n-\tfor (i = 0; i \u003c ports_c; i++) {\n-\t\tnf_ct_helper_init(\u0026tftp[2 * i], AF_INET, IPPROTO_UDP,\n-\t\t\t\t HELPER_NAME, TFTP_PORT, ports[i], i,\n-\t\t\t\t \u0026tftp_exp_policy, 0, tftp_help, NULL,\n-\t\t\t\t THIS_MODULE);\n-\t\tnf_ct_helper_init(\u0026tftp[2 * i + 1], AF_INET6, IPPROTO_UDP,\n-\t\t\t\t HELPER_NAME, TFTP_PORT, ports[i], i,\n-\t\t\t\t \u0026tftp_exp_policy, 0, tftp_help, NULL,\n-\t\t\t\t THIS_MODULE);\n-\t}\n+\tnf_ct_helper_init(\u0026tftp, NFPROTO_UNSPEC, IPPROTO_UDP,\n+\t\t\t HELPER_NAME,\n+\t\t\t \u0026tftp_exp_policy, 0, tftp_help, NULL,\n+\t\t\t THIS_MODULE);\n \n-\tret = nf_conntrack_helpers_register(tftp, ports_c * 2, tftp_ptr);\n+\tret = nf_conntrack_helper_register(\u0026tftp, \u0026tftp_ptr);\n \tif (ret \u003c 0) {\n \t\tpr_err(\"failed to register helpers\\n\");\n \t\treturn ret;\ndiff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c\nindex 63ff6b4d5d214a..8ac326e1eb5ba9 100644\n--- a/net/netfilter/nf_nat_core.c\n+++ b/net/netfilter/nf_nat_core.c\n@@ -39,12 +39,6 @@ static struct hlist_head *nf_nat_bysource __read_mostly;\n static unsigned int nf_nat_htable_size __read_mostly;\n static siphash_aligned_key_t nf_nat_hash_rnd;\n \n-struct nf_nat_lookup_hook_priv {\n-\tstruct nf_hook_entries __rcu *entries;\n-\n-\tstruct rcu_head rcu_head;\n-};\n-\n struct nf_nat_hooks_net {\n \tstruct nf_hook_ops *nat_hook_ops;\n \tunsigned int users;\ndiff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c\nindex 07f51fe75fbe43..64b9bac228eae8 100644\n--- a/net/netfilter/nf_nat_proto.c\n+++ b/net/netfilter/nf_nat_proto.c\n@@ -770,6 +770,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV4,\n \t\t.hooknum\t= NF_INET_PRE_ROUTING,\n \t\t.priority\t= NF_IP_PRI_NAT_DST,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* After packet filtering, change source */\n \t{\n@@ -777,6 +778,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV4,\n \t\t.hooknum\t= NF_INET_POST_ROUTING,\n \t\t.priority\t= NF_IP_PRI_NAT_SRC,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* Before packet filtering, change destination */\n \t{\n@@ -784,6 +786,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV4,\n \t\t.hooknum\t= NF_INET_LOCAL_OUT,\n \t\t.priority\t= NF_IP_PRI_NAT_DST,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* After packet filtering, change source */\n \t{\n@@ -791,6 +794,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV4,\n \t\t.hooknum\t= NF_INET_LOCAL_IN,\n \t\t.priority\t= NF_IP_PRI_NAT_SRC,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n };\n \n@@ -1031,6 +1035,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV6,\n \t\t.hooknum\t= NF_INET_PRE_ROUTING,\n \t\t.priority\t= NF_IP6_PRI_NAT_DST,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* After packet filtering, change source */\n \t{\n@@ -1038,6 +1043,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV6,\n \t\t.hooknum\t= NF_INET_POST_ROUTING,\n \t\t.priority\t= NF_IP6_PRI_NAT_SRC,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* Before packet filtering, change destination */\n \t{\n@@ -1045,6 +1051,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV6,\n \t\t.hooknum\t= NF_INET_LOCAL_OUT,\n \t\t.priority\t= NF_IP6_PRI_NAT_DST,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n \t/* After packet filtering, change source */\n \t{\n@@ -1052,6 +1059,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {\n \t\t.pf\t\t= NFPROTO_IPV6,\n \t\t.hooknum\t= NF_INET_LOCAL_IN,\n \t\t.priority\t= NF_IP6_PRI_NAT_SRC,\n+\t\t.hook_ops_type\t= NF_HOOK_OP_NAT,\n \t},\n };\n \ndiff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c\nindex f1460b683d7af7..56655cb7fe2ad0 100644\n--- a/net/netfilter/nfnetlink_cthelper.c\n+++ b/net/netfilter/nfnetlink_cthelper.c\n@@ -67,7 +67,7 @@ nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,\n }\n \n static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = {\n-\t[NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, },\n+\t[NFCTH_TUPLE_L3PROTONUM] = NLA_POLICY_MAX(NLA_BE16, NFPROTO_IPV6),\n \t[NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, },\n };\n \n@@ -254,7 +254,8 @@ nfnl_cthelper_create(const struct nlattr * const tb[],\n \thelper-\u003edata_len = size;\n \n \thelper-\u003eflags |= NF_CT_HELPER_F_USERSPACE;\n-\tmemcpy(\u0026helper-\u003etuple, tuple, sizeof(struct nf_conntrack_tuple));\n+\thelper-\u003enfproto = tuple-\u003esrc.l3num;\n+\thelper-\u003el4proto = tuple-\u003edst.protonum;\n \n \thelper-\u003eme = THIS_MODULE;\n \thelper-\u003ehelp = nfnl_userspace_cthelper;\n@@ -449,8 +450,8 @@ static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,\n \t\tif (strncmp(cur-\u003ename, helper_name, NF_CT_HELPER_NAME_LEN))\n \t\t\tcontinue;\n \n-\t\tif ((tuple.src.l3num != cur-\u003etuple.src.l3num ||\n-\t\t tuple.dst.protonum != cur-\u003etuple.dst.protonum))\n+\t\tif ((tuple.src.l3num != cur-\u003enfproto ||\n+\t\t tuple.dst.protonum != cur-\u003el4proto))\n \t\t\tcontinue;\n \n \t\tif (info-\u003enlh-\u003enlmsg_flags \u0026 NLM_F_EXCL)\n@@ -479,10 +480,10 @@ nfnl_cthelper_dump_tuple(struct sk_buff *skb,\n \t\tgoto nla_put_failure;\n \n \tif (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM,\n-\t\t\t htons(helper-\u003etuple.src.l3num)))\n+\t\t\t htons(helper-\u003enfproto)))\n \t\tgoto nla_put_failure;\n \n-\tif (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper-\u003etuple.dst.protonum))\n+\tif (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper-\u003el4proto))\n \t\tgoto nla_put_failure;\n \n \tnla_nest_end(skb, nest_parms);\n@@ -661,8 +662,8 @@ static int nfnl_cthelper_get(struct sk_buff *skb, const struct nfnl_info *info,\n \t\t\tcontinue;\n \n \t\tif (tuple_set \u0026\u0026\n-\t\t (tuple.src.l3num != cur-\u003etuple.src.l3num ||\n-\t\t tuple.dst.protonum != cur-\u003etuple.dst.protonum))\n+\t\t (tuple.src.l3num != cur-\u003enfproto ||\n+\t\t tuple.dst.protonum != cur-\u003el4proto))\n \t\t\tcontinue;\n \n \t\tskb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);\n@@ -721,8 +722,8 @@ static int nfnl_cthelper_del(struct sk_buff *skb, const struct nfnl_info *info,\n \t\t\tcontinue;\n \n \t\tif (tuple_set \u0026\u0026\n-\t\t (tuple.src.l3num != cur-\u003etuple.src.l3num ||\n-\t\t tuple.dst.protonum != cur-\u003etuple.dst.protonum))\n+\t\t (tuple.src.l3num != cur-\u003enfproto ||\n+\t\t tuple.dst.protonum != cur-\u003el4proto))\n \t\t\tcontinue;\n \n \t\tfound = true;\ndiff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c\nindex 170d3db860c564..66c2016f6049d7 100644\n--- a/net/netfilter/nfnetlink_cttimeout.c\n+++ b/net/netfilter/nfnetlink_cttimeout.c\n@@ -168,7 +168,7 @@ static int cttimeout_new_timeout(struct sk_buff *skb,\n \tif (ret \u003c 0)\n \t\tgoto err_free_timeout_policy;\n \n-\tstrcpy(timeout-\u003ename, nla_data(cda[CTA_TIMEOUT_NAME]));\n+\tnla_strscpy(timeout-\u003ename, cda[CTA_TIMEOUT_NAME], sizeof(timeout-\u003ename));\n \ttimeout-\u003etimeout-\u003el3num = l3num;\n \ttimeout-\u003etimeout-\u003el4proto = l4proto;\n \trefcount_set(\u0026timeout-\u003etimeout-\u003erefcnt, 1);\ndiff --git a/net/netfilter/nfnetlink_hook.c b/net/netfilter/nfnetlink_hook.c\nindex 5623c18fcd12f0..95005e9a606688 100644\n--- a/net/netfilter/nfnetlink_hook.c\n+++ b/net/netfilter/nfnetlink_hook.c\n@@ -190,7 +190,7 @@ static int nfnl_hook_put_nft_ft_info(struct sk_buff *nlskb,\n \n static int nfnl_hook_dump_one(struct sk_buff *nlskb,\n \t\t\t const struct nfnl_dump_hook_data *ctx,\n-\t\t\t const struct nf_hook_ops *ops,\n+\t\t\t const struct nf_hook_ops *ops, int priority,\n \t\t\t int family, unsigned int seq)\n {\n \tu16 event = nfnl_msg_type(NFNL_SUBSYS_HOOK, NFNL_MSG_HOOK_GET);\n@@ -244,7 +244,7 @@ static int nfnl_hook_dump_one(struct sk_buff *nlskb,\n \tif (ret)\n \t\tgoto nla_put_failure;\n \n-\tret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(ops-\u003epriority));\n+\tret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(priority));\n \tif (ret)\n \t\tgoto nla_put_failure;\n \n@@ -337,6 +337,30 @@ nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *de\n \treturn hook_head;\n }\n \n+static int nfnl_hook_dump_nat(struct sk_buff *nlskb,\n+\t\t\t const struct nfnl_dump_hook_data *ctx,\n+\t\t\t const struct nf_hook_ops *ops,\n+\t\t\t int family, unsigned int seq)\n+{\n+\tstruct nf_nat_lookup_hook_priv *priv = ops-\u003epriv;\n+\tstruct nf_hook_entries *e = rcu_dereference(priv-\u003eentries);\n+\tstruct nf_hook_ops **nat_ops;\n+\tint i, err;\n+\n+\tif (!e)\n+\t\treturn 0;\n+\n+\tnat_ops = nf_hook_entries_get_hook_ops(e);\n+\n+\tfor (i = 0; i \u003c e-\u003enum_hook_entries; i++) {\n+\t\terr = nfnl_hook_dump_one(nlskb, ctx, nat_ops[i],\n+\t\t\t\t\t ops-\u003epriority, family, seq);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\treturn 0;\n+}\n+\n static int nfnl_hook_dump(struct sk_buff *nlskb,\n \t\t\t struct netlink_callback *cb)\n {\n@@ -365,8 +389,13 @@ static int nfnl_hook_dump(struct sk_buff *nlskb,\n \tops = nf_hook_entries_get_hook_ops(e);\n \n \tfor (; i \u003c e-\u003enum_hook_entries; i++) {\n-\t\terr = nfnl_hook_dump_one(nlskb, ctx, ops[i], family,\n-\t\t\t\t\t cb-\u003enlh-\u003enlmsg_seq);\n+\t\tif (ops[i]-\u003ehook_ops_type == NF_HOOK_OP_NAT)\n+\t\t\terr = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,\n+\t\t\t\t\t\t cb-\u003enlh-\u003enlmsg_seq);\n+\t\telse\n+\t\t\terr = nfnl_hook_dump_one(nlskb, ctx, ops[i],\n+\t\t\t\t\t\t ops[i]-\u003epriority, family,\n+\t\t\t\t\t\t cb-\u003enlh-\u003enlmsg_seq);\n \t\tif (err)\n \t\t\tbreak;\n \t}\ndiff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c\nindex 03a88c77e0f028..358b9287e12e87 100644\n--- a/net/netfilter/nft_ct.c\n+++ b/net/netfilter/nft_ct.c\n@@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,\n \treturn 0;\n }\n \n+#if IS_ENABLED(CONFIG_NF_NAT)\n+static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)\n+{\n+\tconst struct nf_ct_helper_expectfn *expfn;\n+\n+\texpfn = nf_ct_helper_expectfn_find_by_name(\"nat-follow-master\");\n+\tif (expfn)\n+\t\texpfn-\u003eexpectfn(ct, this);\n+}\n+#endif\n+\n static void nft_ct_expect_obj_eval(struct nft_object *obj,\n \t\t\t\t struct nft_regs *regs,\n \t\t\t\t const struct nft_pktinfo *pkt)\n@@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,\n \t\t priv-\u003el4proto, NULL, \u0026priv-\u003edport);\n \texp-\u003etimeout += priv-\u003etimeout;\n \n+#if IS_ENABLED(CONFIG_NF_NAT)\n+\tif (ct-\u003estatus \u0026 IPS_NAT_MASK) {\n+\t\texp-\u003esaved_proto.tcp.port = priv-\u003edport;\n+\t\texp-\u003edir = !dir;\n+\t\texp-\u003eexpectfn = nft_ct_nat_follow_master;\n+\t}\n+#endif\n \tif (nf_ct_expect_related(exp, 0) != 0)\n \t\tregs-\u003everdict.code = NF_DROP;\n \n@@ -1375,6 +1393,13 @@ static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {\n \t.owner\t\t= THIS_MODULE,\n };\n \n+#if IS_ENABLED(CONFIG_NF_NAT)\n+static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {\n+\t.name = \"nft_ct-follow-master\",\n+\t.expectfn = nft_ct_nat_follow_master,\n+};\n+#endif\n+\n static int __init nft_ct_module_init(void)\n {\n \tint err;\n@@ -1400,6 +1425,9 @@ static int __init nft_ct_module_init(void)\n \terr = nft_register_obj(\u0026nft_ct_timeout_obj_type);\n \tif (err \u003c 0)\n \t\tgoto err4;\n+#endif\n+#if IS_ENABLED(CONFIG_NF_NAT)\n+\tnf_ct_helper_expectfn_register(\u0026nft_ct_nat);\n #endif\n \treturn 0;\n \n@@ -1425,6 +1453,13 @@ static void __exit nft_ct_module_exit(void)\n \tnft_unregister_obj(\u0026nft_ct_helper_obj_type);\n \tnft_unregister_expr(\u0026nft_notrack_type);\n \tnft_unregister_expr(\u0026nft_ct_type);\n+\n+#if IS_ENABLED(CONFIG_NF_NAT)\n+\tnf_ct_helper_expectfn_unregister(\u0026nft_ct_nat);\n+\tsynchronize_rcu();\n+\tnf_ct_helper_expectfn_destroy(\u0026nft_ct_nat);\n+\tsynchronize_rcu();\n+#endif\n }\n \n module_init(nft_ct_module_init);\ndiff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c\nindex 018bbb6df4ce43..efc25e788a1c52 100644\n--- a/net/netfilter/nft_set_rbtree.c\n+++ b/net/netfilter/nft_set_rbtree.c\n@@ -544,8 +544,7 @@ static int nft_array_intervals_alloc(struct nft_array *array, u32 max_intervals)\n \tif (!intervals)\n \t\treturn -ENOMEM;\n \n-\tif (array-\u003eintervals)\n-\t\tkvfree(array-\u003eintervals);\n+\tkvfree(array-\u003eintervals);\n \n \tarray-\u003eintervals = intervals;\n \tarray-\u003emax_intervals = max_intervals;\ndiff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c\nindex 4e6708c23922b9..e64116bf263786 100644\n--- a/net/netfilter/x_tables.c\n+++ b/net/netfilter/x_tables.c\n@@ -1920,9 +1920,9 @@ static const struct seq_operations xt_target_seq_ops = {\n \t.show\t= xt_target_seq_show,\n };\n \n-#define FORMAT_TABLES\t\"_tables_names\"\n-#define\tFORMAT_MATCHES\t\"_tables_matches\"\n-#define FORMAT_TARGETS \t\"_tables_targets\"\n+#define FORMAT_TABLES\t\"%s_tables_names\"\n+#define\tFORMAT_MATCHES\t\"%s_tables_matches\"\n+#define FORMAT_TARGETS\t\"%s_tables_targets\"\n \n #endif /* CONFIG_PROC_FS */\n \n@@ -2033,8 +2033,7 @@ int xt_proto_init(struct net *net, u_int8_t af)\n \troot_uid = make_kuid(net-\u003euser_ns, 0);\n \troot_gid = make_kgid(net-\u003euser_ns, 0);\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_TABLES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);\n \tproc = proc_create_net_data(buf, 0440, net-\u003eproc_net, \u0026xt_table_seq_ops,\n \t\t\tsizeof(struct seq_net_private),\n \t\t\t(void *)(unsigned long)af);\n@@ -2043,8 +2042,7 @@ int xt_proto_init(struct net *net, u_int8_t af)\n \tif (uid_valid(root_uid) \u0026\u0026 gid_valid(root_gid))\n \t\tproc_set_user(proc, root_uid, root_gid);\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_MATCHES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);\n \tproc = proc_create_seq_private(buf, 0440, net-\u003eproc_net,\n \t\t\t\u0026xt_match_seq_ops, sizeof(struct nf_mttg_trav),\n \t\t\t(void *)(unsigned long)af);\n@@ -2053,8 +2051,7 @@ int xt_proto_init(struct net *net, u_int8_t af)\n \tif (uid_valid(root_uid) \u0026\u0026 gid_valid(root_gid))\n \t\tproc_set_user(proc, root_uid, root_gid);\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_TARGETS, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);\n \tproc = proc_create_seq_private(buf, 0440, net-\u003eproc_net,\n \t\t\t \u0026xt_target_seq_ops, sizeof(struct nf_mttg_trav),\n \t\t\t (void *)(unsigned long)af);\n@@ -2068,13 +2065,11 @@ int xt_proto_init(struct net *net, u_int8_t af)\n \n #ifdef CONFIG_PROC_FS\n out_remove_matches:\n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_MATCHES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);\n \tremove_proc_entry(buf, net-\u003eproc_net);\n \n out_remove_tables:\n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_TABLES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);\n \tremove_proc_entry(buf, net-\u003eproc_net);\n out:\n \treturn -1;\n@@ -2087,16 +2082,13 @@ void xt_proto_fini(struct net *net, u_int8_t af)\n #ifdef CONFIG_PROC_FS\n \tchar buf[XT_FUNCTION_MAXNAMELEN];\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_TABLES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);\n \tremove_proc_entry(buf, net-\u003eproc_net);\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_TARGETS, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);\n \tremove_proc_entry(buf, net-\u003eproc_net);\n \n-\tstrscpy(buf, xt_prefix[af], sizeof(buf));\n-\tstrlcat(buf, FORMAT_MATCHES, sizeof(buf));\n+\tsnprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);\n \tremove_proc_entry(buf, net-\u003eproc_net);\n #endif /*CONFIG_PROC_FS*/\n }\ndiff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c\nindex 93f064306901c0..265d21697847bd 100644\n--- a/net/netfilter/xt_TCPOPTSTRIP.c\n+++ b/net/netfilter/xt_TCPOPTSTRIP.c\n@@ -16,7 +16,7 @@\n #include \u003clinux/netfilter/x_tables.h\u003e\n #include \u003clinux/netfilter/xt_TCPOPTSTRIP.h\u003e\n \n-static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)\n+static inline unsigned int optlen(const u8 *opt, unsigned int offset)\n {\n \t/* Beware zero-length options: make finite progress */\n \tif (opt[offset] \u003c= TCPOPT_NOP || opt[offset+1] == 0)\n@@ -33,8 +33,8 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,\n \tconst struct xt_tcpoptstrip_target_info *info = par-\u003etarginfo;\n \tstruct tcphdr *tcph, _th;\n \tunsigned int optl, i, j;\n-\tu_int16_t n, o;\n-\tu_int8_t *opt;\n+\tu16 n, o;\n+\tu8 *opt;\n \tint tcp_hdrlen;\n \n \t/* This is a fragment, no TCP header is available */\n@@ -97,7 +97,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)\n {\n \tstruct ipv6hdr *ipv6h = ipv6_hdr(skb);\n \tint tcphoff;\n-\tu_int8_t nexthdr;\n+\tu8 nexthdr;\n \t__be16 frag_off;\n \n \tnexthdr = ipv6h-\u003enexthdr;\ndiff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c\nindex fb0169a8f9bbd3..878f27016e9988 100644\n--- a/net/netfilter/xt_dscp.c\n+++ b/net/netfilter/xt_dscp.c\n@@ -49,6 +49,16 @@ static int dscp_mt_check(const struct xt_mtchk_param *par)\n \treturn 0;\n }\n \n+static int tos_mt_check(const struct xt_mtchk_param *par)\n+{\n+\tconst struct xt_tos_match_info *info = par-\u003ematchinfo;\n+\n+\tif (info-\u003einvert \u003e 1)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par)\n {\n \tconst struct xt_tos_match_info *info = par-\u003ematchinfo;\n@@ -82,6 +92,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {\n \t\t.name\t\t= \"tos\",\n \t\t.revision\t= 1,\n \t\t.family\t\t= NFPROTO_IPV4,\n+\t\t.checkentry\t= tos_mt_check,\n \t\t.match\t\t= tos_mt,\n \t\t.matchsize\t= sizeof(struct xt_tos_match_info),\n \t\t.me\t\t= THIS_MODULE,\n@@ -90,6 +101,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {\n \t\t.name\t\t= \"tos\",\n \t\t.revision\t= 1,\n \t\t.family\t\t= NFPROTO_IPV6,\n+\t\t.checkentry\t= tos_mt_check,\n \t\t.match\t\t= tos_mt,\n \t\t.matchsize\t= sizeof(struct xt_tos_match_info),\n \t\t.me\t\t= THIS_MODULE,\ndiff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c\nindex f72752fa4374da..d34831ce3adfbb 100644\n--- a/net/netfilter/xt_recent.c\n+++ b/net/netfilter/xt_recent.c\n@@ -400,7 +400,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,\n \tt-\u003enstamps_max_mask = nstamp_mask;\n \n \tmemcpy(\u0026t-\u003emask, \u0026info-\u003emask, sizeof(t-\u003emask));\n-\tstrcpy(t-\u003ename, info-\u003ename);\n+\tstrscpy(t-\u003ename, info-\u003ename);\n \tINIT_LIST_HEAD(\u0026t-\u003elru_list);\n \tfor (i = 0; i \u003c ip_list_hash_size; i++)\n \t\tINIT_LIST_HEAD(\u0026t-\u003eiphash[i]);\ndiff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c\nindex b9da8269161d8f..b08b077d7f0ada 100644\n--- a/net/netfilter/xt_tcpmss.c\n+++ b/net/netfilter/xt_tcpmss.c\n@@ -78,10 +78,23 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)\n \treturn false;\n }\n \n+static int tcpmss_mt_check(const struct xt_mtchk_param *par)\n+{\n+\tconst struct xt_tcpmss_match_info *info = par-\u003ematchinfo;\n+\n+\tif (info-\u003emss_min \u003e info-\u003emss_max)\n+\t\treturn -EINVAL;\n+\tif (info-\u003einvert \u003e 1)\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n static struct xt_match tcpmss_mt_reg[] __read_mostly = {\n \t{\n \t\t.name\t\t= \"tcpmss\",\n \t\t.family\t\t= NFPROTO_IPV4,\n+\t\t.checkentry\t= tcpmss_mt_check,\n \t\t.match\t\t= tcpmss_mt,\n \t\t.matchsize\t= sizeof(struct xt_tcpmss_match_info),\n \t\t.proto\t\t= IPPROTO_TCP,\ndiff --git a/net/sched/act_ct.c b/net/sched/act_ct.c\nindex be535a261fa04a..4ca7964e83c857 100644\n--- a/net/sched/act_ct.c\n+++ b/net/sched/act_ct.c\n@@ -1527,8 +1527,8 @@ static int tcf_ct_dump_helper(struct sk_buff *skb,\n \t\treturn 0;\n \n \tif (nla_put_string(skb, TCA_CT_HELPER_NAME, helper-\u003ename) ||\n-\t nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper-\u003etuple.src.l3num) ||\n-\t nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper-\u003etuple.dst.protonum))\n+\t nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper-\u003enfproto) ||\n+\t nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper-\u003el4proto))\n \t\treturn -1;\n \n \treturn 0;\n"
} |
| 2/1 | 2026/07/02 15:20 | agent | patch-evaluator |
4mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"NF_CONNTRACK",
"NF_NAT",
"BRIDGE_NF_EBTABLES",
"NETFILTER_NETLINK_HOOK",
"NF_CT_NETLINK_HELPER",
"NF_CT_NETLINK_TIMEOUT",
"NFT_CT",
"NETFILTER_XT_MATCH_DSCP",
"NETFILTER_XT_MATCH_TCPMSS",
"NETFILTER_XT_MATCH_RECENT",
"NETFILTER_XT_TARGET_TCPOPTSTRIP",
"NF_CONNTRACK_AMANDA",
"NF_CONNTRACK_FTP",
"NF_CONNTRACK_H323",
"NF_CONNTRACK_IRC",
"NF_CONNTRACK_NETBIOS_NS",
"NF_CONNTRACK_SNMP",
"NF_CONNTRACK_PPTP",
"NF_CONNTRACK_SANE",
"NF_CONNTRACK_SIP",
"NF_CONNTRACK_TFTP",
"NF_NAT_SNMP_BASIC"
],
"FocusSymbols": [
"__nf_conntrack_helper_register",
"nf_ct_helper_init",
"__nf_conntrack_helper_find",
"nfnl_hook_dump_nat",
"nfnl_cthelper_new",
"cttimeout_new_timeout",
"tos_mt_check",
"tcpmss_mt_check",
"nft_ct_nat_follow_master",
"do_replace",
"compat_copy_ebt_replace_from_user"
],
"Reasoning": "The patch series makes functional changes to netfilter connection tracking helpers, NAT hooks, and ebtables. It changes how conntrack helpers are registered and looked up (removing port-specific defaults), adds a new NF_HOOK_OP_NAT type and fixes NAT hook dumping, adds a NAT follow master expectfn for nft_ct, and fixes an integer overflow in ebtables do_replace. It also adds validation checks for xt_dscp and xt_tcpmss matches. These are reachable core kernel and netfilter logic changes 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 3ce126b24f3cbc0f8498cf7bff8905a8d6f3d014
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Jul 2 15:20:02 2026 +0000
syz-cluster: applied patch under review
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index efbbfa770d6617..e99afc1414cd39 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -93,6 +93,7 @@ enum nf_hook_ops_type {
NF_HOOK_OP_NF_TABLES,
NF_HOOK_OP_BPF,
NF_HOOK_OP_NFT_FT,
+ NF_HOOK_OP_NAT,
};
struct nf_hook_ops {
@@ -140,6 +141,12 @@ struct nf_hook_entries {
*/
};
+struct nf_nat_lookup_hook_priv {
+ struct nf_hook_entries __rcu *entries;
+
+ struct rcu_head rcu_head;
+};
+
#ifdef CONFIG_NETFILTER
static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e)
{
diff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h
index 81286c49932521..b15f37604cde4e 100644
--- a/include/linux/netfilter/nf_conntrack_h323.h
+++ b/include/linux/netfilter/nf_conntrack_h323.h
@@ -9,8 +9,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <uapi/linux/netfilter/nf_conntrack_tuple_common.h>
-#define RAS_PORT 1719
-#define Q931_PORT 1720
#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */
/* This structure exists only once per master */
diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h
index c3bdb43709384d..c0b305ce7c3c6b 100644
--- a/include/linux/netfilter/nf_conntrack_pptp.h
+++ b/include/linux/netfilter/nf_conntrack_pptp.h
@@ -50,8 +50,6 @@ struct nf_nat_pptp {
__be16 pac_call_id; /* NAT'ed PAC call id */
};
-#define PPTP_CONTROL_PORT 1723
-
#define PPTP_PACKET_CONTROL 1
#define PPTP_PACKET_MGMT 2
diff --git a/include/linux/netfilter/nf_conntrack_sane.h b/include/linux/netfilter/nf_conntrack_sane.h
index 46c7acd1b4a70f..8501035d733559 100644
--- a/include/linux/netfilter/nf_conntrack_sane.h
+++ b/include/linux/netfilter/nf_conntrack_sane.h
@@ -3,8 +3,6 @@
#define _NF_CONNTRACK_SANE_H
/* SANE tracking. */
-#define SANE_PORT 6566
-
enum sane_state {
SANE_STATE_NORMAL,
SANE_STATE_START_REQUESTED,
diff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h
index 90b334bbce3ce6..e3d1739c557d15 100644
--- a/include/linux/netfilter/nf_conntrack_tftp.h
+++ b/include/linux/netfilter/nf_conntrack_tftp.h
@@ -2,8 +2,6 @@
#ifndef _NF_CONNTRACK_TFTP_H
#define _NF_CONNTRACK_TFTP_H
-#define TFTP_PORT 69
-
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/types.h>
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 49297fec448a82..ed2e9bc1bb4e95 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -2123,7 +2123,7 @@ void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);
int ip_vs_confirm_conntrack(struct sk_buff *skb);
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
+ struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs);
void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index c761cd8158b253..bc5427d239f4c0 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -43,11 +43,10 @@ struct nf_conntrack_helper {
refcount_t ct_refcnt;
- /* Tuple of things we will help (compared against server response) */
- struct nf_conntrack_tuple tuple;
+ u8 nfproto; /* NFPROTO_*, can be NFPROTO_UNSPEC */
+ u8 l4proto; /* IPPROTO_UDP/TCP */
- /* Function to call when data passes; return verdict, or -1 to
- invalidate. */
+ /* Function to call when data passes; return verdict */
int __rcu (*help)(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info conntrackinfo);
@@ -94,8 +93,7 @@ struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
- u16 l3num, u16 protonum, const char *name,
- u16 default_port, u16 spec_port, u32 id,
+ u8 l3num, u16 protonum, const char *name,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index f20c039e44c8d7..042d31278713df 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -39,6 +39,8 @@
#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
COUNTER_OFFSET(n) * cpu))
+#define MAX_EBT_ENTRIES (((INT_MAX - sizeof(struct ebt_table_info)) / \
+ NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
struct ebt_pernet {
struct list_head tables;
@@ -1124,10 +1126,9 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
return -EINVAL;
/* overflow check */
- if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
- NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+ if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
- if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+ if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
tmp.name[sizeof(tmp.name) - 1] = 0;
@@ -2265,10 +2266,9 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
if (tmp.entries_size == 0)
return -EINVAL;
- if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
- NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+ if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
- if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+ if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
index 0ede138dfd29e7..e540b86bd15b6b 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
@@ -213,7 +213,7 @@ static int __init nf_nat_snmp_basic_init(void)
RCU_INIT_POINTER(nf_nat_snmp_hook, help);
nf_ct_helper_init(&snmp_trap_helper, AF_INET, IPPROTO_UDP,
- "snmp_trap", SNMP_TRAP_PORT, SNMP_TRAP_PORT, SNMP_TRAP_PORT,
+ "snmp_trap",
&snmp_exp_policy, 0, help, NULL, THIS_MODULE);
err = nf_conntrack_helper_register(&snmp_trap_helper, &snmp_trap_helper_ptr);
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c
index 81974f69e5bb4e..347185fd0c8c6f 100644
--- a/net/netfilter/ipvs/ip_vs_nfct.c
+++ b/net/netfilter/ipvs/ip_vs_nfct.c
@@ -208,7 +208,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
* Use port 0 to expect connection from any port.
*/
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
+ struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs)
{
struct nf_conntrack_expect *exp;
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index ddafbdfc96dc35..06d6ec12c86dfa 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -89,7 +89,7 @@ static int amanda_help(struct sk_buff *skb,
struct nf_conntrack_tuple *tuple;
unsigned int dataoff, start, stop, off, i;
char pbuf[sizeof("65535")], *tmp;
- u_int16_t len;
+ u16 len;
__be16 port;
int ret = NF_ACCEPT;
nf_nat_amanda_hook_fn *nf_nat_amanda;
@@ -199,10 +199,10 @@ static int __init nf_conntrack_amanda_init(void)
}
nf_ct_helper_init(&amanda_helper[0], AF_INET, IPPROTO_UDP,
- HELPER_NAME, 10080, 10080, 10080,
+ HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
nf_ct_helper_init(&amanda_helper[1], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, 10080, 10080, 10080,
+ HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
ret = nf_conntrack_helpers_register(amanda_helper,
diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c
index bf78828c7549d4..6ff954f1bfb87c 100644
--- a/net/netfilter/nf_conntrack_broadcast.c
+++ b/net/netfilter/nf_conntrack_broadcast.c
@@ -66,8 +66,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
helper = rcu_dereference(help->helper);
- if (helper)
- exp->tuple.src.u.udp.port = helper->tuple.src.u.udp.port;
exp->mask.src.u3.ip = mask;
exp->mask.src.u.udp.port = htons(0xFFFF);
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 0847f845613d6a..f3944598c1726f 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -35,11 +35,6 @@ MODULE_ALIAS("ip_conntrack_ftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
static DEFINE_SPINLOCK(nf_ftp_lock);
-#define MAX_PORTS 8
-static u_int16_t ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-
static bool loose;
module_param(loose, bool, 0600);
@@ -560,8 +555,8 @@ static int nf_ct_ftp_from_nlattr(struct nlattr *attr, struct nf_conn *ct)
return 0;
}
-static struct nf_conntrack_helper ftp[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *ftp_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper ftp __read_mostly;
+static struct nf_conntrack_helper *ftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy ftp_exp_policy = {
.max_expected = 1,
@@ -570,32 +565,23 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {
static void __exit nf_conntrack_ftp_fini(void)
{
- nf_conntrack_helpers_unregister(ftp_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(ftp_ptr);
}
static int __init nf_conntrack_ftp_init(void)
{
- int i, ret = 0;
+ int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master));
- if (ports_c == 0)
- ports[ports_c++] = FTP_PORT;
-
/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
are tracked or not - YK */
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP,
- HELPER_NAME, FTP_PORT, ports[i], ports[i],
- &ftp_exp_policy, 0, help,
- nf_ct_ftp_from_nlattr, THIS_MODULE);
- nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, FTP_PORT, ports[i], ports[i],
- &ftp_exp_policy, 0, help,
- nf_ct_ftp_from_nlattr, THIS_MODULE);
- }
+ nf_ct_helper_init(&ftp, NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ &ftp_exp_policy, 0, help,
+ nf_ct_ftp_from_nlattr, THIS_MODULE);
- ret = nf_conntrack_helpers_register(ftp, ports_c * 2, ftp_ptr);
+ ret = nf_conntrack_helper_register(&ftp, &ftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 24931e379985bb..4cb1665bba0214 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -671,7 +671,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
static int callforward_do_filter(struct net *net,
const union nf_inet_addr *src,
const union nf_inet_addr *dst,
- u_int8_t family)
+ u8 family)
{
int ret = 0;
@@ -1713,19 +1713,19 @@ static int __init h323_helper_init(void)
int ret;
nf_ct_helper_init(&nf_conntrack_helper_ras[0], AF_INET, IPPROTO_UDP,
- "RAS", RAS_PORT, RAS_PORT, RAS_PORT,
+ "RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_ras[1], AF_INET6, IPPROTO_UDP,
- "RAS", RAS_PORT, RAS_PORT, RAS_PORT,
+ "RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_h245, AF_UNSPEC, IPPROTO_UDP,
- "H.245", 0, 0, 0,
+ "H.245",
&h245_exp_policy, 0, h245_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[0], AF_INET, IPPROTO_TCP,
- "Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
+ "Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[1], AF_INET6, IPPROTO_TCP,
- "Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
+ "Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245,
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 500509b17663ed..506c5803476155 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -40,12 +40,16 @@ static unsigned int nf_ct_helper_count __read_mostly;
static DEFINE_MUTEX(nf_ct_nat_helpers_mutex);
static struct list_head nf_ct_nat_helpers __read_mostly;
-/* Stupid hash, but collision free for the default registrations of the
- * helpers currently in the kernel. */
-static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
+static unsigned int helper_hash(const char *name, u8 protonum)
{
- return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
- (__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
+ static u32 seed;
+ u32 initval;
+
+ get_random_once(&seed, sizeof(seed));
+
+ initval = seed ^ protonum;
+
+ return jhash(name, strlen(name), initval) % nf_ct_helper_hsize;
}
struct nf_conntrack_helper *
@@ -54,18 +58,18 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)
struct nf_conntrack_helper *h;
unsigned int i;
- for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
- if (strcmp(h->name, name))
- continue;
+ if (!nf_ct_helper_hash)
+ return NULL;
- if (h->tuple.src.l3num != NFPROTO_UNSPEC &&
- h->tuple.src.l3num != l3num)
- continue;
+ i = helper_hash(name, protonum);
- if (h->tuple.dst.protonum == protonum)
- return h;
- }
+ hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
+ if (strcmp(h->name, name))
+ continue;
+ if (h->nfproto != NFPROTO_UNSPEC && h->nfproto != l3num)
+ continue;
+ if (h->l4proto == protonum)
+ return h;
}
return NULL;
}
@@ -363,9 +367,8 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log);
int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
{
- struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
- unsigned int h = helper_hash(&me->tuple);
struct nf_conntrack_helper *cur;
+ unsigned int h;
int ret = 0, i;
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
@@ -382,29 +385,18 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
return -EINVAL;
}
+ h = helper_hash(me->name, me->l4proto);
mutex_lock(&nf_ct_helper_mutex);
- for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry(cur, &nf_ct_helper_hash[i], hnode) {
- if (!strcmp(cur->name, me->name) &&
- (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
- cur->tuple.src.l3num == me->tuple.src.l3num) &&
- cur->tuple.dst.protonum == me->tuple.dst.protonum) {
- ret = -EBUSY;
- goto out;
- }
+ hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
+ if (!strcmp(cur->name, me->name) &&
+ (cur->nfproto == NFPROTO_UNSPEC ||
+ cur->nfproto == me->nfproto) &&
+ cur->l4proto == me->l4proto) {
+ ret = -EBUSY;
+ goto out;
}
}
- /* avoid unpredictable behaviour for auto_assign_helper */
- if (!(me->flags & NF_CT_HELPER_F_USERSPACE)) {
- hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
- if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple,
- &mask)) {
- ret = -EBUSY;
- goto out;
- }
- }
- }
refcount_set(&me->ct_refcnt, 1);
hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
nf_ct_helper_count++;
@@ -479,8 +471,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
- u16 l3num, u16 protonum, const char *name,
- u16 default_port, u16 spec_port, u32 id,
+ u8 l3num, u16 protonum, const char *name,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,
@@ -492,9 +483,8 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
{
memset(helper, 0, sizeof(*helper));
- helper->tuple.src.l3num = l3num;
- helper->tuple.dst.protonum = protonum;
- helper->tuple.src.u.all = htons(spec_port);
+ helper->nfproto = l3num;
+ helper->l4proto = protonum;
rcu_assign_pointer(helper->help, help);
helper->from_nlattr = from_nlattr;
@@ -502,10 +492,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
snprintf(helper->nat_mod_name, sizeof(helper->nat_mod_name),
NF_NAT_HELPER_PREFIX "%s", name);
- if (spec_port == default_port)
- snprintf(helper->name, sizeof(helper->name), "%s", name);
- else
- snprintf(helper->name, sizeof(helper->name), "%s-%u", name, id);
+ snprintf(helper->name, sizeof(helper->name), "%s", name);
if (WARN_ON_ONCE(expect_class_max >= NF_CT_MAX_EXPECT_CLASSES))
return;
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 193ab34db795f9..4e6bafe4143752 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -21,9 +21,6 @@
#include <net/netfilter/nf_conntrack_helper.h>
#include <linux/netfilter/nf_conntrack_irc.h>
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout __read_mostly = 300;
/* This is slow, but it's simple. --RR */
@@ -42,8 +39,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_irc");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of IRC servers");
module_param(max_dcc_channels, uint, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per "
"IRC session");
@@ -254,13 +249,13 @@ static int help(struct sk_buff *skb, unsigned int protoff,
return ret;
}
-static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;
-static struct nf_conntrack_helper *irc_ptr[MAX_PORTS] __read_mostly;
+static struct nf_conntrack_helper irc __read_mostly;
+static struct nf_conntrack_helper *irc_ptr __read_mostly;
static struct nf_conntrack_expect_policy irc_exp_policy;
static int __init nf_conntrack_irc_init(void)
{
- int i, ret;
+ int ret;
nf_conntrack_helper_deprecated(HELPER_NAME);
@@ -282,17 +277,11 @@ static int __init nf_conntrack_irc_init(void)
if (!irc_buffer)
return -ENOMEM;
- /* If no port given, default to standard irc port */
- if (ports_c == 0)
- ports[ports_c++] = IRC_PORT;
+ nf_ct_helper_init(&irc, AF_INET, IPPROTO_TCP, HELPER_NAME,
+ &irc_exp_policy,
+ 0, help, NULL, THIS_MODULE);
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, HELPER_NAME,
- IRC_PORT, ports[i], i, &irc_exp_policy,
- 0, help, NULL, THIS_MODULE);
- }
-
- ret = nf_conntrack_helpers_register(&irc[0], ports_c, irc_ptr);
+ ret = nf_conntrack_helper_register(&irc, &irc_ptr);
if (ret) {
pr_err("failed to register helpers\n");
kfree(irc_buffer);
@@ -304,7 +293,7 @@ static int __init nf_conntrack_irc_init(void)
static void __exit nf_conntrack_irc_fini(void)
{
- nf_conntrack_helpers_unregister(irc_ptr, ports_c);
+ nf_conntrack_helper_unregister(irc_ptr);
kfree(irc_buffer);
}
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 89d1cf7d6512e7..caa2b101fa9e5e 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -21,7 +21,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#define HELPER_NAME "netbios-ns"
-#define NMBD_PORT 137
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
@@ -54,7 +53,6 @@ static int __init nf_conntrack_netbios_ns_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP, HELPER_NAME,
- NMBD_PORT, NMBD_PORT, NMBD_PORT,
&exp_policy, 0, netbios_ns_help, NULL, THIS_MODULE);
return nf_conntrack_helper_register(&helper, &helper_ptr);
diff --git a/net/netfilter/nf_conntrack_ovs.c b/net/netfilter/nf_conntrack_ovs.c
index 49d1511e992185..b4085af3ad1ce0 100644
--- a/net/netfilter/nf_conntrack_ovs.c
+++ b/net/netfilter/nf_conntrack_ovs.c
@@ -31,8 +31,8 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
if (!helper)
return NF_ACCEPT;
- if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
- helper->tuple.src.l3num != proto)
+ if (helper->nfproto != NFPROTO_UNSPEC &&
+ helper->nfproto != proto)
return NF_ACCEPT;
switch (proto) {
@@ -60,7 +60,7 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
return NF_DROP;
}
- if (helper->tuple.dst.protonum != proto)
+ if (helper->l4proto != proto)
return NF_ACCEPT;
helper_cb = rcu_dereference(helper->help);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 80fc14c87ddc4b..cbf32a3cb1f612 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -540,7 +540,7 @@ static int __init nf_conntrack_pptp_init(void)
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_pptp_master));
nf_ct_helper_init(&pptp, AF_INET, IPPROTO_TCP,
- "pptp", PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, PPTP_CONTROL_PORT,
+ "pptp",
&pptp_exp_policy, 0, conntrack_pptp_help, NULL, THIS_MODULE);
pptp.destroy = gre_pptp_destroy_siblings;
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 39085acf7a7185..a0658f69d78fbb 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -34,11 +34,6 @@ MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
MODULE_DESCRIPTION("SANE connection tracking helper");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static u_int16_t ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-
struct sane_request {
__be32 RPC_code;
#define SANE_NET_START 7 /* RPC code */
@@ -169,8 +164,8 @@ static int help(struct sk_buff *skb,
return ret;
}
-static struct nf_conntrack_helper sane[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *sane_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper sane __read_mostly;
+static struct nf_conntrack_helper *sane_ptr __read_mostly;
static const struct nf_conntrack_expect_policy sane_exp_policy = {
.max_expected = 1,
@@ -179,32 +174,21 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {
static void __exit nf_conntrack_sane_fini(void)
{
- nf_conntrack_helpers_unregister(sane_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(sane_ptr);
}
static int __init nf_conntrack_sane_init(void)
{
- int i, ret = 0;
+ int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master));
- if (ports_c == 0)
- ports[ports_c++] = SANE_PORT;
-
- /* FIXME should be configurable whether IPv4 and IPv6 connections
- are tracked or not - YK */
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP,
- HELPER_NAME, SANE_PORT, ports[i], ports[i],
- &sane_exp_policy, 0, help, NULL,
- THIS_MODULE);
- nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, SANE_PORT, ports[i], ports[i],
- &sane_exp_policy, 0, help, NULL,
- THIS_MODULE);
- }
+ nf_ct_helper_init(&sane, NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ &sane_exp_policy, 0, help, NULL,
+ THIS_MODULE);
- ret = nf_conntrack_helpers_register(sane, ports_c * 2, sane_ptr);
+ ret = nf_conntrack_helper_register(&sane, &sane_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 5ec3a4a4bbd707..d0b85b8ad1e6d8 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -35,12 +35,6 @@ MODULE_DESCRIPTION("SIP connection tracking helper");
MODULE_ALIAS("ip_conntrack_sip");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of SIP servers");
-
static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
module_param(sip_timeout, uint, 0600);
MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
@@ -1764,8 +1758,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
return process_sip_msg(skb, ct, protoff, dataoff, &dptr, &datalen);
}
-static struct nf_conntrack_helper sip[MAX_PORTS * 4] __read_mostly;
-static struct nf_conntrack_helper *sip_ptr[MAX_PORTS * 4] __read_mostly;
+static struct nf_conntrack_helper sip[2] __read_mostly;
+static struct nf_conntrack_helper *sip_ptr[2] __read_mostly;
static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
[SIP_EXPECT_SIGNALLING] = {
@@ -1792,38 +1786,25 @@ static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1
static void __exit nf_conntrack_sip_fini(void)
{
- nf_conntrack_helpers_unregister(sip_ptr, ports_c * 4);
+ nf_conntrack_helpers_unregister(sip_ptr, 2);
}
static int __init nf_conntrack_sip_init(void)
{
- int i, ret;
+ int ret;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sip_master));
- if (ports_c == 0)
- ports[ports_c++] = SIP_PORT;
-
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
- NULL, THIS_MODULE);
- }
+ nf_ct_helper_init(&sip[0], NFPROTO_UNSPEC, IPPROTO_UDP,
+ HELPER_NAME,
+ sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
+ NULL, THIS_MODULE);
+ nf_ct_helper_init(&sip[1], NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
+ NULL, THIS_MODULE);
- ret = nf_conntrack_helpers_register(sip, ports_c * 4, sip_ptr);
+ ret = nf_conntrack_helpers_register(sip, 2, sip_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c
index b6fce5703fce77..109986d5d55e69 100644
--- a/net/netfilter/nf_conntrack_snmp.c
+++ b/net/netfilter/nf_conntrack_snmp.c
@@ -14,8 +14,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <linux/netfilter/nf_conntrack_snmp.h>
-#define SNMP_PORT 161
-
MODULE_AUTHOR("Jiri Olsa <jolsa@redhat.com>");
MODULE_DESCRIPTION("SNMP service broadcast connection tracking helper");
MODULE_LICENSE("GPL");
@@ -55,7 +53,7 @@ static int __init nf_conntrack_snmp_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP,
- "snmp", SNMP_PORT, SNMP_PORT, SNMP_PORT,
+ "snmp",
&exp_policy, 0, snmp_conntrack_help, NULL,
THIS_MODULE);
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 4393c435aa3549..a69559edf9b363 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -26,12 +26,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_tftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
-
nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
@@ -95,8 +89,8 @@ static int tftp_help(struct sk_buff *skb,
return ret;
}
-static struct nf_conntrack_helper tftp[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *tftp_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper tftp __read_mostly;
+static struct nf_conntrack_helper *tftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy tftp_exp_policy = {
.max_expected = 1,
@@ -105,30 +99,21 @@ static const struct nf_conntrack_expect_policy tftp_exp_policy = {
static void __exit nf_conntrack_tftp_fini(void)
{
- nf_conntrack_helpers_unregister(tftp_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(tftp_ptr);
}
static int __init nf_conntrack_tftp_init(void)
{
- int i, ret;
+ int ret;
NF_CT_HELPER_BUILD_BUG_ON(0);
- if (ports_c == 0)
- ports[ports_c++] = TFTP_PORT;
-
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP,
- HELPER_NAME, TFTP_PORT, ports[i], i,
- &tftp_exp_policy, 0, tftp_help, NULL,
- THIS_MODULE);
- nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, TFTP_PORT, ports[i], i,
- &tftp_exp_policy, 0, tftp_help, NULL,
- THIS_MODULE);
- }
+ nf_ct_helper_init(&tftp, NFPROTO_UNSPEC, IPPROTO_UDP,
+ HELPER_NAME,
+ &tftp_exp_policy, 0, tftp_help, NULL,
+ THIS_MODULE);
- ret = nf_conntrack_helpers_register(tftp, ports_c * 2, tftp_ptr);
+ ret = nf_conntrack_helper_register(&tftp, &tftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 63ff6b4d5d214a..8ac326e1eb5ba9 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -39,12 +39,6 @@ static struct hlist_head *nf_nat_bysource __read_mostly;
static unsigned int nf_nat_htable_size __read_mostly;
static siphash_aligned_key_t nf_nat_hash_rnd;
-struct nf_nat_lookup_hook_priv {
- struct nf_hook_entries __rcu *entries;
-
- struct rcu_head rcu_head;
-};
-
struct nf_nat_hooks_net {
struct nf_hook_ops *nat_hook_ops;
unsigned int users;
diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c
index 07f51fe75fbe43..64b9bac228eae8 100644
--- a/net/netfilter/nf_nat_proto.c
+++ b/net/netfilter/nf_nat_proto.c
@@ -770,6 +770,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -777,6 +778,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -784,6 +786,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -791,6 +794,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
};
@@ -1031,6 +1035,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1038,6 +1043,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -1045,6 +1051,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1052,6 +1059,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
};
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index f1460b683d7af7..56655cb7fe2ad0 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -67,7 +67,7 @@ nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
}
static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = {
- [NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, },
+ [NFCTH_TUPLE_L3PROTONUM] = NLA_POLICY_MAX(NLA_BE16, NFPROTO_IPV6),
[NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, },
};
@@ -254,7 +254,8 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
helper->data_len = size;
helper->flags |= NF_CT_HELPER_F_USERSPACE;
- memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple));
+ helper->nfproto = tuple->src.l3num;
+ helper->l4proto = tuple->dst.protonum;
helper->me = THIS_MODULE;
helper->help = nfnl_userspace_cthelper;
@@ -449,8 +450,8 @@ static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,
if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
continue;
- if ((tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ if ((tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
if (info->nlh->nlmsg_flags & NLM_F_EXCL)
@@ -479,10 +480,10 @@ nfnl_cthelper_dump_tuple(struct sk_buff *skb,
goto nla_put_failure;
if (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM,
- htons(helper->tuple.src.l3num)))
+ htons(helper->nfproto)))
goto nla_put_failure;
- if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->tuple.dst.protonum))
+ if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->l4proto))
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
@@ -661,8 +662,8 @@ static int nfnl_cthelper_get(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
- (tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ (tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -721,8 +722,8 @@ static int nfnl_cthelper_del(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
- (tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ (tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
found = true;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 170d3db860c564..66c2016f6049d7 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -168,7 +168,7 @@ static int cttimeout_new_timeout(struct sk_buff *skb,
if (ret < 0)
goto err_free_timeout_policy;
- strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
+ nla_strscpy(timeout->name, cda[CTA_TIMEOUT_NAME], sizeof(timeout->name));
timeout->timeout->l3num = l3num;
timeout->timeout->l4proto = l4proto;
refcount_set(&timeout->timeout->refcnt, 1);
diff --git a/net/netfilter/nfnetlink_hook.c b/net/netfilter/nfnetlink_hook.c
index 5623c18fcd12f0..95005e9a606688 100644
--- a/net/netfilter/nfnetlink_hook.c
+++ b/net/netfilter/nfnetlink_hook.c
@@ -190,7 +190,7 @@ static int nfnl_hook_put_nft_ft_info(struct sk_buff *nlskb,
static int nfnl_hook_dump_one(struct sk_buff *nlskb,
const struct nfnl_dump_hook_data *ctx,
- const struct nf_hook_ops *ops,
+ const struct nf_hook_ops *ops, int priority,
int family, unsigned int seq)
{
u16 event = nfnl_msg_type(NFNL_SUBSYS_HOOK, NFNL_MSG_HOOK_GET);
@@ -244,7 +244,7 @@ static int nfnl_hook_dump_one(struct sk_buff *nlskb,
if (ret)
goto nla_put_failure;
- ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(ops->priority));
+ ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(priority));
if (ret)
goto nla_put_failure;
@@ -337,6 +337,30 @@ nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *de
return hook_head;
}
+static int nfnl_hook_dump_nat(struct sk_buff *nlskb,
+ const struct nfnl_dump_hook_data *ctx,
+ const struct nf_hook_ops *ops,
+ int family, unsigned int seq)
+{
+ struct nf_nat_lookup_hook_priv *priv = ops->priv;
+ struct nf_hook_entries *e = rcu_dereference(priv->entries);
+ struct nf_hook_ops **nat_ops;
+ int i, err;
+
+ if (!e)
+ return 0;
+
+ nat_ops = nf_hook_entries_get_hook_ops(e);
+
+ for (i = 0; i < e->num_hook_entries; i++) {
+ err = nfnl_hook_dump_one(nlskb, ctx, nat_ops[i],
+ ops->priority, family, seq);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
static int nfnl_hook_dump(struct sk_buff *nlskb,
struct netlink_callback *cb)
{
@@ -365,8 +389,13 @@ static int nfnl_hook_dump(struct sk_buff *nlskb,
ops = nf_hook_entries_get_hook_ops(e);
for (; i < e->num_hook_entries; i++) {
- err = nfnl_hook_dump_one(nlskb, ctx, ops[i], family,
- cb->nlh->nlmsg_seq);
+ if (ops[i]->hook_ops_type == NF_HOOK_OP_NAT)
+ err = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,
+ cb->nlh->nlmsg_seq);
+ else
+ err = nfnl_hook_dump_one(nlskb, ctx, ops[i],
+ ops[i]->priority, family,
+ cb->nlh->nlmsg_seq);
if (err)
break;
}
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 03a88c77e0f028..358b9287e12e87 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,
return 0;
}
+#if IS_ENABLED(CONFIG_NF_NAT)
+static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)
+{
+ const struct nf_ct_helper_expectfn *expfn;
+
+ expfn = nf_ct_helper_expectfn_find_by_name("nat-follow-master");
+ if (expfn)
+ expfn->expectfn(ct, this);
+}
+#endif
+
static void nft_ct_expect_obj_eval(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
@@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
priv->l4proto, NULL, &priv->dport);
exp->timeout += priv->timeout;
+#if IS_ENABLED(CONFIG_NF_NAT)
+ if (ct->status & IPS_NAT_MASK) {
+ exp->saved_proto.tcp.port = priv->dport;
+ exp->dir = !dir;
+ exp->expectfn = nft_ct_nat_follow_master;
+ }
+#endif
if (nf_ct_expect_related(exp, 0) != 0)
regs->verdict.code = NF_DROP;
@@ -1375,6 +1393,13 @@ static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
.owner = THIS_MODULE,
};
+#if IS_ENABLED(CONFIG_NF_NAT)
+static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {
+ .name = "nft_ct-follow-master",
+ .expectfn = nft_ct_nat_follow_master,
+};
+#endif
+
static int __init nft_ct_module_init(void)
{
int err;
@@ -1400,6 +1425,9 @@ static int __init nft_ct_module_init(void)
err = nft_register_obj(&nft_ct_timeout_obj_type);
if (err < 0)
goto err4;
+#endif
+#if IS_ENABLED(CONFIG_NF_NAT)
+ nf_ct_helper_expectfn_register(&nft_ct_nat);
#endif
return 0;
@@ -1425,6 +1453,13 @@ static void __exit nft_ct_module_exit(void)
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
+
+#if IS_ENABLED(CONFIG_NF_NAT)
+ nf_ct_helper_expectfn_unregister(&nft_ct_nat);
+ synchronize_rcu();
+ nf_ct_helper_expectfn_destroy(&nft_ct_nat);
+ synchronize_rcu();
+#endif
}
module_init(nft_ct_module_init);
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 018bbb6df4ce43..efc25e788a1c52 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -544,8 +544,7 @@ static int nft_array_intervals_alloc(struct nft_array *array, u32 max_intervals)
if (!intervals)
return -ENOMEM;
- if (array->intervals)
- kvfree(array->intervals);
+ kvfree(array->intervals);
array->intervals = intervals;
array->max_intervals = max_intervals;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 4e6708c23922b9..e64116bf263786 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1920,9 +1920,9 @@ static const struct seq_operations xt_target_seq_ops = {
.show = xt_target_seq_show,
};
-#define FORMAT_TABLES "_tables_names"
-#define FORMAT_MATCHES "_tables_matches"
-#define FORMAT_TARGETS "_tables_targets"
+#define FORMAT_TABLES "%s_tables_names"
+#define FORMAT_MATCHES "%s_tables_matches"
+#define FORMAT_TARGETS "%s_tables_targets"
#endif /* CONFIG_PROC_FS */
@@ -2033,8 +2033,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
root_uid = make_kuid(net->user_ns, 0);
root_gid = make_kgid(net->user_ns, 0);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
proc = proc_create_net_data(buf, 0440, net->proc_net, &xt_table_seq_ops,
sizeof(struct seq_net_private),
(void *)(unsigned long)af);
@@ -2043,8 +2042,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_match_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2053,8 +2051,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_target_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2068,13 +2065,11 @@ int xt_proto_init(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
out_remove_matches:
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out_remove_tables:
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out:
return -1;
@@ -2087,16 +2082,13 @@ void xt_proto_fini(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
#endif /*CONFIG_PROC_FS*/
}
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 93f064306901c0..265d21697847bd 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -16,7 +16,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_TCPOPTSTRIP.h>
-static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
+static inline unsigned int optlen(const u8 *opt, unsigned int offset)
{
/* Beware zero-length options: make finite progress */
if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
@@ -33,8 +33,8 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
const struct xt_tcpoptstrip_target_info *info = par->targinfo;
struct tcphdr *tcph, _th;
unsigned int optl, i, j;
- u_int16_t n, o;
- u_int8_t *opt;
+ u16 n, o;
+ u8 *opt;
int tcp_hdrlen;
/* This is a fragment, no TCP header is available */
@@ -97,7 +97,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int tcphoff;
- u_int8_t nexthdr;
+ u8 nexthdr;
__be16 frag_off;
nexthdr = ipv6h->nexthdr;
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index fb0169a8f9bbd3..878f27016e9988 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -49,6 +49,16 @@ static int dscp_mt_check(const struct xt_mtchk_param *par)
return 0;
}
+static int tos_mt_check(const struct xt_mtchk_param *par)
+{
+ const struct xt_tos_match_info *info = par->matchinfo;
+
+ if (info->invert > 1)
+ return -EINVAL;
+
+ return 0;
+}
+
static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_tos_match_info *info = par->matchinfo;
@@ -82,6 +92,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV4,
+ .checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,
@@ -90,6 +101,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV6,
+ .checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index f72752fa4374da..d34831ce3adfbb 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -400,7 +400,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
t->nstamps_max_mask = nstamp_mask;
memcpy(&t->mask, &info->mask, sizeof(t->mask));
- strcpy(t->name, info->name);
+ strscpy(t->name, info->name);
INIT_LIST_HEAD(&t->lru_list);
for (i = 0; i < ip_list_hash_size; i++)
INIT_LIST_HEAD(&t->iphash[i]);
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index b9da8269161d8f..b08b077d7f0ada 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -78,10 +78,23 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)
return false;
}
+static int tcpmss_mt_check(const struct xt_mtchk_param *par)
+{
+ const struct xt_tcpmss_match_info *info = par->matchinfo;
+
+ if (info->mss_min > info->mss_max)
+ return -EINVAL;
+ if (info->invert > 1)
+ return -EINVAL;
+
+ return 0;
+}
+
static struct xt_match tcpmss_mt_reg[] __read_mostly = {
{
.name = "tcpmss",
.family = NFPROTO_IPV4,
+ .checkentry = tcpmss_mt_check,
.match = tcpmss_mt,
.matchsize = sizeof(struct xt_tcpmss_match_info),
.proto = IPPROTO_TCP,
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index be535a261fa04a..4ca7964e83c857 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1527,8 +1527,8 @@ static int tcf_ct_dump_helper(struct sk_buff *skb,
return 0;
if (nla_put_string(skb, TCA_CT_HELPER_NAME, helper->name) ||
- nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->tuple.src.l3num) ||
- nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->tuple.dst.protonum))
+ nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->nfproto) ||
+ nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->l4proto))
return -1;
return 0;
|
| 3/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23082 output: 33 thoughts: 1602 Thoughts: **Analysis of Netfilter Patch Series** Okay, so I'm looking at this patch series that significantly touches netfilter and related subsystems. Seems like a decent amount of churn here, enough to warrant a focused review and fuzzing. First, I see the addition of `NF_HOOK_OP_NAT` and `struct nf_nat_lookup_hook_priv` in `netfilter.h`. That's interesting, suggesting a more refined handling of NAT-specific hook operations. The removal of specific port definitions in `nf_conntrack_*.h` is also notable. It looks like the kernel is becoming less reliant on hardcoded port numbers for connection tracking. Instead, it seems like more protocol-agnostic methods are being adopted, which is a good direction. Digging into `ip_vs.h`, I see a simple change from `u_int8_t` to `u8`, which is fine. But, looking further into the helpers, I'm noting significant refactoring in `nf_conntrack_helper`. The replacement of the `tuple` struct with `nfproto` and `l4proto` in the `helper` structure is a major functional change. This means that we're moving away from relying on the tuple directly for helper identification, further enforcing a protocol-agnostic system. The signature of `nf_ct_helper_init` has been simplified, which is consistent with the refactoring. The changes to the helper hash, using `name` and `protonum` instead of `tuple`, further reinforces this shift. I'll need to keep an eye on how this affects existing helper implementations. One helper per protocol rather than multiple is a fine idea as it seems much cleaner. The fix for the overflow check in `ebtables.c` is important, especially since ebtables is often used for security-related rules. I see that the patch updates calls to `nf_ct_helper_init` and removes module parameters for ports. This is directly related to the changes in `nf_conntrack_helper` and aligns with the intent to move away from port-specific helpers. The use of `NFPROTO_UNSPEC` is as expected for general cases, and good to see. The movement of `struct nf_nat_lookup_hook_priv` and the setting of `.hook_ops_type = NF_HOOK_OP_NAT` look like they are tying up loose ends from previous changes. In the netlink code, the changes in `nfnl_cthelper_tuple_pol` and other functions to use `nfproto` and `l4proto` instead of `tuple` are another direct consequence of the helper refactoring. The same changes in `nfnetlink_hook.c` to handle the new NAT hook type and dump NAT hooks correctly are key. The addition of `nft_ct_nat_follow_master` to `nft_ct.c` is interesting, and worth investigating the implications of this new functionality for NAT within nftables. The removal of the redundant if statement in `nft_set_rbtree.c` is just housekeeping, but good to see. I see some minor changes in `x_tables.c` and `xt_TCPOPTSTRIP.c` for string operations and type definitions, which are likely aimed at consistency and robustness. The new checks for `xt_dscp.c` and `xt_tcpmss.c` look like they are in place to harden the code and prevent potential misconfigurations or vulnerabilities. Finally, `act_ct.c` has been updated to use `nfproto` and `l4proto`. Overall, this patch series is about making the netfilter more modular, configurable, and robust. It's moving towards a more streamlined way of handling connection tracking helpers. Given the scope of these changes, I'm labeling this as "WorthFuzzing" without question. It touches core kernel logic, and the refactoring is enough to warrant thorough testing. I've identified the likely configs, and they look solid to me. I'll need to double check the exact config names to make sure. I'll make sure to use these to reproduce a build. |
| 4/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NF_CONNTRACK_",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=111=config NETFILTER_CONNCOUNT\n--\nnet/netfilter/Kconfig-113-\nnet/netfilter/Kconfig:114:config NF_CONNTRACK_MARK\nnet/netfilter/Kconfig-115-\tbool 'Connection mark tracking support'\n--\nnet/netfilter/Kconfig-122-\nnet/netfilter/Kconfig:123:config NF_CONNTRACK_SECMARK\nnet/netfilter/Kconfig-124-\tbool 'Connection tracking security mark support'\n--\nnet/netfilter/Kconfig-135-\nnet/netfilter/Kconfig:136:config NF_CONNTRACK_ZONES\nnet/netfilter/Kconfig-137-\tbool 'Connection tracking zones'\n--\nnet/netfilter/Kconfig-147-\nnet/netfilter/Kconfig:148:config NF_CONNTRACK_PROCFS\nnet/netfilter/Kconfig-149-\tbool \"Supply CT list in procfs (OBSOLETE)\"\n--\nnet/netfilter/Kconfig-156-\nnet/netfilter/Kconfig:157:config NF_CONNTRACK_EVENTS\nnet/netfilter/Kconfig-158-\tbool \"Connection tracking events\"\n--\nnet/netfilter/Kconfig-166-\nnet/netfilter/Kconfig:167:config NF_CONNTRACK_TIMEOUT\nnet/netfilter/Kconfig-168-\tbool 'Connection tracking timeout'\n--\nnet/netfilter/Kconfig-176-\nnet/netfilter/Kconfig:177:config NF_CONNTRACK_TIMESTAMP\nnet/netfilter/Kconfig-178-\tbool 'Connection tracking timestamping'\n--\nnet/netfilter/Kconfig-187-\nnet/netfilter/Kconfig:188:config NF_CONNTRACK_LABELS\nnet/netfilter/Kconfig-189-\tbool \"Connection tracking labels\"\n--\nnet/netfilter/Kconfig-194-\nnet/netfilter/Kconfig:195:config NF_CONNTRACK_OVS\nnet/netfilter/Kconfig-196-\tbool\n--\nnet/netfilter/Kconfig=201=config NF_CT_PROTO_SCTP\n--\nnet/netfilter/Kconfig-211-\nnet/netfilter/Kconfig:212:config NF_CONNTRACK_AMANDA\nnet/netfilter/Kconfig-213-\ttristate \"Amanda backup protocol support\"\n--\nnet/netfilter/Kconfig-226-\nnet/netfilter/Kconfig:227:config NF_CONNTRACK_FTP\nnet/netfilter/Kconfig-228-\ttristate \"FTP protocol support\"\n--\nnet/netfilter/Kconfig-238-\nnet/netfilter/Kconfig:239:config NF_CONNTRACK_H323\nnet/netfilter/Kconfig-240-\ttristate \"H.323 protocol support\"\n--\nnet/netfilter/Kconfig-257-\nnet/netfilter/Kconfig:258:config NF_CONNTRACK_IRC\nnet/netfilter/Kconfig-259-\ttristate \"IRC DCC protocol support (obsolete)\"\n--\nnet/netfilter/Kconfig-273-\nnet/netfilter/Kconfig:274:config NF_CONNTRACK_BROADCAST\nnet/netfilter/Kconfig-275-\ttristate\nnet/netfilter/Kconfig-276-\nnet/netfilter/Kconfig:277:config NF_CONNTRACK_NETBIOS_NS\nnet/netfilter/Kconfig-278-\ttristate \"NetBIOS name service protocol support\"\n--\nnet/netfilter/Kconfig-295-\nnet/netfilter/Kconfig:296:config NF_CONNTRACK_SNMP\nnet/netfilter/Kconfig-297-\ttristate \"SNMP service protocol support\"\n--\nnet/netfilter/Kconfig-310-\nnet/netfilter/Kconfig:311:config NF_CONNTRACK_PPTP\nnet/netfilter/Kconfig-312-\ttristate \"PPtP protocol support (deprecated)\"\n--\nnet/netfilter/Kconfig-329-\nnet/netfilter/Kconfig:330:config NF_CONNTRACK_SANE\nnet/netfilter/Kconfig-331-\ttristate \"SANE protocol support\"\n--\nnet/netfilter/Kconfig-342-\nnet/netfilter/Kconfig:343:config NF_CONNTRACK_SIP\nnet/netfilter/Kconfig-344-\ttristate \"SIP protocol support\"\n--\nnet/netfilter/Kconfig-354-\nnet/netfilter/Kconfig:355:config NF_CONNTRACK_TFTP\nnet/netfilter/Kconfig-356-\ttristate \"TFTP protocol support\"\n"
} |
| 5/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26828 output: 35 thoughts: 12 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Configuration Audit and Dependency Review** Okay, so we've addressed the core issue in the primary file. Now, before we consider this fix complete, I need to perform a thorough dependency review. I'm thinking, let's systematically go through the configuration files associated with the modified ones – the "other modified files" referred to in the context. We're looking for any cascading effects or related configurations that might need adjustments as a result of the changes we've just implemented. This isn't just about syntax; it's about understanding the architectural implications. Are there environment variables, API keys, service endpoints, or even resource limits defined in those configurations that are now misaligned? I want to make sure the fix doesn't introduce any new vulnerabilities or performance bottlenecks, or unintentionally break a feature in some dependent part of the system. We have to make sure we didn't introduce a regression. A checklist to step through the configurations is the most appropriate next step. |
| 6/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NETFILTER_XT_MATCH_",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=1147=comment \"Xtables matches\"\nnet/netfilter/Kconfig-1148-\nnet/netfilter/Kconfig:1149:config NETFILTER_XT_MATCH_ADDRTYPE\nnet/netfilter/Kconfig-1150-\ttristate '\"addrtype\" address type match support'\n--\nnet/netfilter/Kconfig-1158-\nnet/netfilter/Kconfig:1159:config NETFILTER_XT_MATCH_BPF\nnet/netfilter/Kconfig-1160-\ttristate '\"bpf\" match support'\n--\nnet/netfilter/Kconfig-1167-\nnet/netfilter/Kconfig:1168:config NETFILTER_XT_MATCH_CGROUP\nnet/netfilter/Kconfig-1169-\ttristate '\"control group\" match support'\n--\nnet/netfilter/Kconfig-1177-\nnet/netfilter/Kconfig:1178:config NETFILTER_XT_MATCH_CLUSTER\nnet/netfilter/Kconfig-1179-\ttristate '\"cluster\" match support'\n--\nnet/netfilter/Kconfig-1193-\nnet/netfilter/Kconfig:1194:config NETFILTER_XT_MATCH_COMMENT\nnet/netfilter/Kconfig-1195-\ttristate '\"comment\" match support'\n--\nnet/netfilter/Kconfig-1203-\nnet/netfilter/Kconfig:1204:config NETFILTER_XT_MATCH_CONNBYTES\nnet/netfilter/Kconfig-1205-\ttristate '\"connbytes\" per-connection counter match support'\n--\nnet/netfilter/Kconfig-1214-\nnet/netfilter/Kconfig:1215:config NETFILTER_XT_MATCH_CONNLABEL\nnet/netfilter/Kconfig-1216-\ttristate '\"connlabel\" match support'\n--\nnet/netfilter/Kconfig-1227-\nnet/netfilter/Kconfig:1228:config NETFILTER_XT_MATCH_CONNLIMIT\nnet/netfilter/Kconfig-1229-\ttristate '\"connlimit\" match support'\n--\nnet/netfilter/Kconfig-1236-\nnet/netfilter/Kconfig:1237:config NETFILTER_XT_MATCH_CONNMARK\nnet/netfilter/Kconfig-1238-\ttristate '\"connmark\" connection mark match support'\n--\nnet/netfilter/Kconfig-1246-\nnet/netfilter/Kconfig:1247:config NETFILTER_XT_MATCH_CONNTRACK\nnet/netfilter/Kconfig-1248-\ttristate '\"conntrack\" connection tracking match support'\n--\nnet/netfilter/Kconfig-1259-\nnet/netfilter/Kconfig:1260:config NETFILTER_XT_MATCH_CPU\nnet/netfilter/Kconfig-1261-\ttristate '\"cpu\" match support'\n--\nnet/netfilter/Kconfig-1268-\nnet/netfilter/Kconfig:1269:config NETFILTER_XT_MATCH_DCCP\nnet/netfilter/Kconfig-1270-\ttristate '\"dccp\" protocol match support (DEPRECATED)'\n--\nnet/netfilter/Kconfig-1280-\nnet/netfilter/Kconfig:1281:config NETFILTER_XT_MATCH_DEVGROUP\nnet/netfilter/Kconfig-1282-\ttristate '\"devgroup\" match support'\n--\nnet/netfilter/Kconfig-1289-\nnet/netfilter/Kconfig:1290:config NETFILTER_XT_MATCH_DSCP\nnet/netfilter/Kconfig-1291-\ttristate '\"dscp\" and \"tos\" match support'\n--\nnet/netfilter/Kconfig-1304-\nnet/netfilter/Kconfig:1305:config NETFILTER_XT_MATCH_ECN\nnet/netfilter/Kconfig-1306-\ttristate '\"ecn\" match support'\n--\nnet/netfilter/Kconfig-1313-\nnet/netfilter/Kconfig:1314:config NETFILTER_XT_MATCH_ESP\nnet/netfilter/Kconfig-1315-\ttristate '\"esp\" match support'\n--\nnet/netfilter/Kconfig-1322-\nnet/netfilter/Kconfig:1323:config NETFILTER_XT_MATCH_HASHLIMIT\nnet/netfilter/Kconfig-1324-\ttristate '\"hashlimit\" match support'\n--\nnet/netfilter/Kconfig-1337-\nnet/netfilter/Kconfig:1338:config NETFILTER_XT_MATCH_HELPER\nnet/netfilter/Kconfig-1339-\ttristate '\"helper\" match support'\n--\nnet/netfilter/Kconfig-1347-\nnet/netfilter/Kconfig:1348:config NETFILTER_XT_MATCH_HL\nnet/netfilter/Kconfig-1349-\ttristate '\"hl\" hoplimit/TTL match support'\n--\nnet/netfilter/Kconfig-1355-\nnet/netfilter/Kconfig:1356:config NETFILTER_XT_MATCH_IPCOMP\nnet/netfilter/Kconfig-1357-\ttristate '\"ipcomp\" match support'\n--\nnet/netfilter/Kconfig-1364-\nnet/netfilter/Kconfig:1365:config NETFILTER_XT_MATCH_IPRANGE\nnet/netfilter/Kconfig-1366-\ttristate '\"iprange\" address range match support'\n--\nnet/netfilter/Kconfig-1374-\nnet/netfilter/Kconfig:1375:config NETFILTER_XT_MATCH_IPVS\nnet/netfilter/Kconfig-1376-\ttristate '\"ipvs\" match support'\n--\nnet/netfilter/Kconfig-1384-\nnet/netfilter/Kconfig:1385:config NETFILTER_XT_MATCH_L2TP\nnet/netfilter/Kconfig-1386-\ttristate '\"l2tp\" match support'\n--\nnet/netfilter/Kconfig-1394-\nnet/netfilter/Kconfig:1395:config NETFILTER_XT_MATCH_LENGTH\nnet/netfilter/Kconfig-1396-\ttristate '\"length\" match support'\n--\nnet/netfilter/Kconfig-1403-\nnet/netfilter/Kconfig:1404:config NETFILTER_XT_MATCH_LIMIT\nnet/netfilter/Kconfig-1405-\ttristate '\"limit\" match support'\n--\nnet/netfilter/Kconfig-1413-\nnet/netfilter/Kconfig:1414:config NETFILTER_XT_MATCH_MAC\nnet/netfilter/Kconfig-1415-\ttristate '\"mac\" address match support'\n--\nnet/netfilter/Kconfig-1422-\nnet/netfilter/Kconfig:1423:config NETFILTER_XT_MATCH_MARK\nnet/netfilter/Kconfig-1424-\ttristate '\"mark\" match support'\n--\nnet/netfilter/Kconfig-1431-\nnet/netfilter/Kconfig:1432:config NETFILTER_XT_MATCH_MULTIPORT\nnet/netfilter/Kconfig-1433-\ttristate '\"multiport\" Multiple port match support'\n--\nnet/netfilter/Kconfig-1441-\nnet/netfilter/Kconfig:1442:config NETFILTER_XT_MATCH_NFACCT\nnet/netfilter/Kconfig-1443-\ttristate '\"nfacct\" match support'\n--\nnet/netfilter/Kconfig-1451-\nnet/netfilter/Kconfig:1452:config NETFILTER_XT_MATCH_OSF\nnet/netfilter/Kconfig-1453-\ttristate '\"osf\" Passive OS fingerprint match'\n--\nnet/netfilter/Kconfig-1465-\nnet/netfilter/Kconfig:1466:config NETFILTER_XT_MATCH_OWNER\nnet/netfilter/Kconfig-1467-\ttristate '\"owner\" match support'\n--\nnet/netfilter/Kconfig-1473-\nnet/netfilter/Kconfig:1474:config NETFILTER_XT_MATCH_POLICY\nnet/netfilter/Kconfig-1475-\ttristate 'IPsec \"policy\" match support'\n--\nnet/netfilter/Kconfig-1484-\nnet/netfilter/Kconfig:1485:config NETFILTER_XT_MATCH_PHYSDEV\nnet/netfilter/Kconfig-1486-\ttristate '\"physdev\" match support'\n--\nnet/netfilter/Kconfig-1494-\nnet/netfilter/Kconfig:1495:config NETFILTER_XT_MATCH_PKTTYPE\nnet/netfilter/Kconfig-1496-\ttristate '\"pkttype\" packet type match support'\n--\nnet/netfilter/Kconfig-1506-\nnet/netfilter/Kconfig:1507:config NETFILTER_XT_MATCH_QUOTA\nnet/netfilter/Kconfig-1508-\ttristate '\"quota\" match support'\n--\nnet/netfilter/Kconfig-1516-\nnet/netfilter/Kconfig:1517:config NETFILTER_XT_MATCH_RATEEST\nnet/netfilter/Kconfig-1518-\ttristate '\"rateest\" match support'\n--\nnet/netfilter/Kconfig-1526-\nnet/netfilter/Kconfig:1527:config NETFILTER_XT_MATCH_REALM\nnet/netfilter/Kconfig-1528-\ttristate '\"realm\" match support'\n--\nnet/netfilter/Kconfig-1540-\nnet/netfilter/Kconfig:1541:config NETFILTER_XT_MATCH_RECENT\nnet/netfilter/Kconfig-1542-\ttristate '\"recent\" match support'\n--\nnet/netfilter/Kconfig-1550-\nnet/netfilter/Kconfig:1551:config NETFILTER_XT_MATCH_SCTP\nnet/netfilter/Kconfig-1552-\ttristate '\"sctp\" protocol match support'\n--\nnet/netfilter/Kconfig-1562-\nnet/netfilter/Kconfig:1563:config NETFILTER_XT_MATCH_SOCKET\nnet/netfilter/Kconfig-1564-\ttristate '\"socket\" match support'\n--\nnet/netfilter/Kconfig-1579-\nnet/netfilter/Kconfig:1580:config NETFILTER_XT_MATCH_STATE\nnet/netfilter/Kconfig-1581-\ttristate '\"state\" match support'\n--\nnet/netfilter/Kconfig-1590-\nnet/netfilter/Kconfig:1591:config NETFILTER_XT_MATCH_STATISTIC\nnet/netfilter/Kconfig-1592-\ttristate '\"statistic\" match support'\n--\nnet/netfilter/Kconfig-1599-\nnet/netfilter/Kconfig:1600:config NETFILTER_XT_MATCH_STRING\nnet/netfilter/Kconfig-1601-\ttristate '\"string\" match support'\n--\nnet/netfilter/Kconfig-1612-\nnet/netfilter/Kconfig:1613:config NETFILTER_XT_MATCH_TCPMSS\nnet/netfilter/Kconfig-1614-\ttristate '\"tcpmss\" match support'\n--\nnet/netfilter/Kconfig-1622-\nnet/netfilter/Kconfig:1623:config NETFILTER_XT_MATCH_TIME\nnet/netfilter/Kconfig-1624-\ttristate '\"time\" match support'\n--\nnet/netfilter/Kconfig-1636-\nnet/netfilter/Kconfig:1637:config NETFILTER_XT_MATCH_U32\nnet/netfilter/Kconfig-1638-\ttristate '\"u32\" match support'\n"
} |
| 7/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 30137 output: 75 thoughts: 26 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Kernel Module Configuration Considerations** Alright, let's just quickly confirm a couple of kernel module configurations before we move forward. I need to make sure `NETFILTER_XT_TARGET_TCPOPTSTRIP` is enabled. It's crucial for properly handling TCP option stripping within the netfilter framework, and depending on the scenario, I might need it configured in a specific way. Then, for the bridging setup I'm working with, I need to verify that `BRIDGE_EBTABLES` is properly configured. Ensuring that the ebtables module is available is critical for being able to build filtering rules. It's a quick check but I don't want to get caught down the line with missing functionality. |
| 8/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NETFILTER_XT_TARGET_TCPOPTSTRIP",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=1111=config NETFILTER_XT_TARGET_TCPMSS\n--\nnet/netfilter/Kconfig-1136-\nnet/netfilter/Kconfig:1137:config NETFILTER_XT_TARGET_TCPOPTSTRIP\nnet/netfilter/Kconfig-1138-\ttristate '\"TCPOPTSTRIP\" target support'\n"
} |
| 9/2 | 2026/07/02 15:20 | tool | grepper |
0mError:no matches Args: {
"Expression": "config BRIDGE_EBTABLES",
"PathPrefix": "net/bridge/netfilter/Kconfig"
}Results: {
"error": "no matches"
} |
| 10/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 30525 output: 28 thoughts: 42 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Investigating EBTABLES Integration within the Kernel Bridge Configuration** Right, so I need to figure out where the `BRIDGE_EBTABLES` option is defined in the kernel configuration files. My first instinct, and the most logical place to start, is within the bridge-specific Kconfig files. I'll need to check `net/bridge/netfilter/Kconfig` first, as that's where I'd expect the netfilter-related bridge settings to reside. Then, if it isn't there, I'll branch out to `net/bridge/Kconfig`, which houses general bridge options. And if for some reason that fails, I can always look for it in `net/netfilter/Kconfig` as a last resort, as the ebtables setup might be at a higher level than just the bridge itself. I need to quickly determine the correct location for a config setting related to ebtables functionality within the networking bridge context. This will impact my approach moving forward, which could include some sort of dependency tree analysis of the relevant code. |
| 11/2 | 2026/07/02 15:20 | tool | grepper |
0mError:no matches Args: {
"Expression": "config BRIDGE_EBTABLES",
"PathPrefix": "net/"
}Results: {
"error": "no matches"
} |
| 12/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 30850 output: 30 thoughts: 14 Thoughts: Okay, here's my summary, presented as a stream of thought: **EBTABLES Consideration** Hmm, thinking about the issue at hand, there's a possibility. Could it be `BRIDGE_NF_EBTABLES`? I'm leaning that way. Seems like a likely culprit given the observed behavior. Need to investigate further, but that's my initial instinct. |
| 13/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config BRIDGE_NF_EBTABLES",
"PathPrefix": "net/"
}Results: {
"Output": "net/bridge/netfilter/Kconfig=28=config NF_CONNTRACK_BRIDGE\n--\nnet/bridge/netfilter/Kconfig-42-# old sockopt interface and eval loop\nnet/bridge/netfilter/Kconfig:43:config BRIDGE_NF_EBTABLES_LEGACY\nnet/bridge/netfilter/Kconfig-44-\ttristate \"Legacy EBTABLES support\"\n--\nnet/bridge/netfilter/Kconfig-52-\nnet/bridge/netfilter/Kconfig:53:menuconfig BRIDGE_NF_EBTABLES\nnet/bridge/netfilter/Kconfig-54-\ttristate \"Ethernet Bridge tables (ebtables) support\"\n"
} |
| 14/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31150 output: 34 thoughts: 38 Thoughts: Okay, here's my attempt at summarizing those thoughts from an expert's perspective, using a first-person perspective: **Kernel Configuration Considerations for Network Bridging with Netfilter** Right, so we're talking about configuring a bridging setup that leverages Netfilter, specifically focusing on the ebtables integration. The primary requirement, as I see it, is definitely `BRIDGE_NF_EBTABLES`. That one's foundational. It's the enabling switch for using ebtables within a bridged environment, so naturally it would be the starting point. Beyond that, if we want full capabilities for more advanced network functions involving connection tracking, we should also think about `CONFIG_NETFILTER_NETLINK_CTHELPER` and `CONFIG_NETFILTER_NETLINK_HOOK`. The former provides Netlink interface to connection tracking helpers, while the latter includes hooks to enable communication between the kernel and userspace for managing Netfilter aspects. These configurations are likely required if we're also using connection tracking alongside the bridge. We would need to enable these if we wanted things like conntrack-based filtering in the bridge or wanted to do more complex interaction with Netfilter within the bridge environment. |
| 15/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NETFILTER_NETLINK_",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=33=config NETFILTER_BPF_LINK\n--\nnet/netfilter/Kconfig-35-\nnet/netfilter/Kconfig:36:config NETFILTER_NETLINK_HOOK\nnet/netfilter/Kconfig-37-\ttristate \"Netfilter base hook dump support\"\n--\nnet/netfilter/Kconfig-45-\nnet/netfilter/Kconfig:46:config NETFILTER_NETLINK_ACCT\nnet/netfilter/Kconfig-47-\ttristate \"Netfilter NFACCT over NFNETLINK interface\"\n--\nnet/netfilter/Kconfig-53-\nnet/netfilter/Kconfig:54:config NETFILTER_NETLINK_QUEUE\nnet/netfilter/Kconfig-55-\ttristate \"Netfilter NFQUEUE over NFNETLINK interface\"\n--\nnet/netfilter/Kconfig-61-\nnet/netfilter/Kconfig:62:config NETFILTER_NETLINK_LOG\nnet/netfilter/Kconfig-63-\ttristate \"Netfilter LOG over NFNETLINK interface\"\n--\nnet/netfilter/Kconfig-73-\nnet/netfilter/Kconfig:74:config NETFILTER_NETLINK_OSF\nnet/netfilter/Kconfig-75-\ttristate \"Netfilter OSF over NFNETLINK interface\"\n--\nnet/netfilter/Kconfig=385=config NF_CT_NETLINK_HELPER\n--\nnet/netfilter/Kconfig-397-\nnet/netfilter/Kconfig:398:config NETFILTER_NETLINK_GLUE_CT\nnet/netfilter/Kconfig-399-\tbool \"NFQUEUE and NFLOG integration with Connection Tracking\"\n"
} |
| 16/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31894 output: 35 thoughts: 43 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Checking Netfilter Configuration for Conntrack Helper and Timeout Options** Right, so I'm looking at this code and immediately I see `NF_CT_NETLINK_HELPER`. Hmmm, not `NETFILTER_NETLINK_CTHELPER` which I was expecting to see. Okay, no big deal, let's keep an eye out for how `NF_CT_NETLINK_HELPER` relates to the expected conntrack helper functionality. While I'm at it, I should probably double-check the related timeout configurations. I need to make sure I don't miss anything. Let me also investigate `NF_CT_NETLINK_TIMEOUT` to see if there are any subtle changes or naming differences I need to be aware of. Gotta look at the bigger picture and how all these netlink and conntrack options are integrated. |
| 17/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NF_CT_NETLINK_",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=366=config NF_CT_NETLINK\n--\nnet/netfilter/Kconfig-372-\nnet/netfilter/Kconfig:373:config NF_CT_NETLINK_TIMEOUT\nnet/netfilter/Kconfig-374-\ttristate 'Connection tracking timeout tuning via Netlink'\n--\nnet/netfilter/Kconfig-384-\nnet/netfilter/Kconfig:385:config NF_CT_NETLINK_HELPER\nnet/netfilter/Kconfig-386-\ttristate 'Connection tracking helpers in user-space via Netlink'\n"
} |
| 18/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32338 output: 31 thoughts: 34 Thoughts: Okay, here's my summarized thought process, presented as if I were thinking it: **Considering Netfilter Connection Tracking Configuration** Right, let's see. I'm thinking about connection tracking configuration, and two key parameters jump to mind: `NF_CT_NETLINK_TIMEOUT` and `NF_CT_NETLINK_HELPER`. Those are definitely relevant to managing timeouts and helper interactions. Now, to get a better overview, I need to zoom out and consider the bigger picture, so the next thing I'd check would undoubtedly be `NFT_CT`. Let's see what's going on there. |
| 19/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NFT_CT",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=485=config NFT_NUMGEN\n--\nnet/netfilter/Kconfig-490-\nnet/netfilter/Kconfig:491:config NFT_CT\nnet/netfilter/Kconfig-492-\tdepends on NF_CONNTRACK\n"
} |
| 20/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32617 output: 31 thoughts: 9 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert: **Investigating Network Address Translation (NAT) with `NF_NAT`** Right, let's dive into this. The task at hand likely involves examining the inner workings of Network Address Translation within the Linux kernel. When someone mentions NAT, my mind immediately jumps to `NF_NAT`. That keyword, `NF_NAT`, is the key. It's the Netfilter module responsible for the core NAT functionality. I need to understand what aspects are being explored. Are we looking at connection tracking, address translation rules, port mapping, or perhaps performance bottlenecks? The possibilities are vast. This could be anything from analyzing a specific configuration, debugging a NAT-related issue, or digging into the code to understand the underlying mechanics. My process will likely involve checking the kernel documentation, searching for relevant source code files, and potentially using tools like `iptables` and `conntrack` to inspect the behavior of the NAT module in action. I'll need to confirm what the objective is to focus on the specific aspects of `NF_NAT` that are relevant. |
| 21/2 | 2026/07/02 15:20 | tool | grepper |
0mArgs:{
"Expression": "config NF_NAT",
"PathPrefix": "net/netfilter/Kconfig"
}Results: {
"Output": "net/netfilter/Kconfig=398=config NETFILTER_NETLINK_GLUE_CT\n--\nnet/netfilter/Kconfig-406-\nnet/netfilter/Kconfig:407:config NF_NAT\nnet/netfilter/Kconfig-408-\ttristate \"Network Address Translation support\"\n--\nnet/netfilter/Kconfig-415-\nnet/netfilter/Kconfig:416:config NF_NAT_AMANDA\nnet/netfilter/Kconfig-417-\ttristate\n--\nnet/netfilter/Kconfig-420-\nnet/netfilter/Kconfig:421:config NF_NAT_FTP\nnet/netfilter/Kconfig-422-\ttristate\n--\nnet/netfilter/Kconfig-425-\nnet/netfilter/Kconfig:426:config NF_NAT_IRC\nnet/netfilter/Kconfig-427-\ttristate\n--\nnet/netfilter/Kconfig-430-\nnet/netfilter/Kconfig:431:config NF_NAT_SIP\nnet/netfilter/Kconfig-432-\ttristate\n--\nnet/netfilter/Kconfig-435-\nnet/netfilter/Kconfig:436:config NF_NAT_TFTP\nnet/netfilter/Kconfig-437-\ttristate\n--\nnet/netfilter/Kconfig-440-\nnet/netfilter/Kconfig:441:config NF_NAT_REDIRECT\nnet/netfilter/Kconfig-442-\tbool\nnet/netfilter/Kconfig-443-\nnet/netfilter/Kconfig:444:config NF_NAT_MASQUERADE\nnet/netfilter/Kconfig-445-\tbool\nnet/netfilter/Kconfig-446-\nnet/netfilter/Kconfig:447:config NF_NAT_OVS\nnet/netfilter/Kconfig-448-\tbool\n"
} |
| 22/2 | 2026/07/02 15:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33396 output: 39 thoughts: 27 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Investigating the SNMP NAT Module Configuration** Okay, so I'm thinking, "Where does this `NF_NAT_SNMP_BASIC` module live in the netfilter codebase?" Right, let's dive into the `net/ipv4/netfilter/Kconfig` file. That's usually the go-to place for kernel configuration options related to IPv4 netfilter modules, and SNMP NAT would fall squarely within that scope. I need to quickly confirm the presence, and if it's there I might need to look at what other modules depend on it, or are dependent by it, to understand its interactions. This might also provide clues to associated documentation or examples. I'm after a good overview of the relevant netfilter options to prepare for any discussion of this module. |
| 23/2 | 2026/07/02 15:21 | tool | grepper |
0mArgs:{
"Expression": "config NF_NAT_SNMP_BASIC",
"PathPrefix": "net/ipv4/netfilter/Kconfig"
}Results: {
"Output": "net/ipv4/netfilter/Kconfig=99=if NF_NAT\nnet/ipv4/netfilter/Kconfig:100:config NF_NAT_SNMP_BASIC\nnet/ipv4/netfilter/Kconfig-101-\ttristate \"Basic SNMP-ALG support\"\n"
} |
| 24/2 | 2026/07/02 15:21 | llm | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33726 output: 34 thoughts: 686 Thoughts: **Refining the Netfilter Focus** Okay, so I've got this initial list of Netfilter configurations: `NF_CONNTRACK`, `NF_CONNTRACK_AMANDA`, `NF_CONNTRACK_FTP`, and so on, all the way to `NETFILTER_XT_TARGET_TCPOPTSTRIP`. Right. I need to distill this down to the most relevant configurations, so I'll identify the modified ones. Looks like a bunch have been tweaked: `NF_CONNTRACK_AMANDA` through `NF_CONNTRACK_TFTP`, `NF_NAT_SNMP_BASIC`, `BRIDGE_NF_EBTABLES`, `NETFILTER_NETLINK_HOOK`, `NF_CT_NETLINK_HELPER`, `NF_CT_NETLINK_TIMEOUT`, `NFT_CT`, `NETFILTER_XT_MATCH_DSCP`, `NETFILTER_XT_MATCH_TCPMSS`, `NETFILTER_XT_MATCH_RECENT`, and `NETFILTER_XT_TARGET_TCPOPTSTRIP`. Now, that's more manageable. Next, I need to pinpoint the key functions related to these configurations. I'm focusing on the core connection tracking and NAT functionality, so let's see... I'm thinking I'll want to dig into things like: `nf_ct_helper_init`, `__nf_conntrack_helper_register`, `__nf_conntrack_helper_find`, those are the helper functions for connection tracking. Then there are some NAT-related functions: `nfnl_hook_dump_nat`, `nft_ct_nat_follow_master`, and then these matching functions: `tos_mt_check`, `tcpmss_mt_check`. I need to review these ebtables changes, so I'll check on `compat_copy_ebt_replace_from_user` and `do_replace`. I'll also want to look at `nfnl_cthelper_new`, `nfnl_cthelper_get`, `nfnl_cthelper_del`, and `cttimeout_new_timeout`. Okay, let's start with a closer look at `do_replace` in ebtables. |
| 25/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "do_replace",
"PathPrefix": "net/bridge/netfilter/ebtables.c"
}Results: {
"Output": "net/bridge/netfilter/ebtables.c=870=static int translate_table(struct net *net, const char *name,\n--\nnet/bridge/netfilter/ebtables.c-921-\tif (udc_cnt) {\nnet/bridge/netfilter/ebtables.c:922:\t\t/* this will get free'd in do_replace()/ebt_register_table()\nnet/bridge/netfilter/ebtables.c-923-\t\t * if an error occurs\n--\nnet/bridge/netfilter/ebtables.c=990=static void get_counters(const struct ebt_counter *oldcounters,\n--\nnet/bridge/netfilter/ebtables.c-1010-\nnet/bridge/netfilter/ebtables.c:1011:static int do_replace_finish(struct net *net, struct ebt_replace *repl,\nnet/bridge/netfilter/ebtables.c-1012-\t\t\t struct ebt_table_info *newinfo)\n--\nnet/bridge/netfilter/ebtables.c-1110-/* replace the table */\nnet/bridge/netfilter/ebtables.c:1111:static int do_replace(struct net *net, sockptr_t arg, unsigned int len)\nnet/bridge/netfilter/ebtables.c-1112-{\n--\nnet/bridge/netfilter/ebtables.c-1154-\nnet/bridge/netfilter/ebtables.c:1155:\tret = do_replace_finish(net, \u0026tmp, newinfo);\nnet/bridge/netfilter/ebtables.c-1156-\tif (ret == 0)\n--\nnet/bridge/netfilter/ebtables.c=2251=static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,\n--\nnet/bridge/netfilter/ebtables.c-2285-\nnet/bridge/netfilter/ebtables.c:2286:static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)\nnet/bridge/netfilter/ebtables.c-2287-{\n--\nnet/bridge/netfilter/ebtables.c-2296-\t\t/* try real handler in case userland supplied needed padding */\nnet/bridge/netfilter/ebtables.c:2297:\t\tif (ret == -EINVAL \u0026\u0026 do_replace(net, arg, len) == 0)\nnet/bridge/netfilter/ebtables.c-2298-\t\t\tret = 0;\n--\nnet/bridge/netfilter/ebtables.c-2373-\nnet/bridge/netfilter/ebtables.c:2374:\tret = do_replace_finish(net, \u0026tmp, newinfo);\nnet/bridge/netfilter/ebtables.c-2375-\tif (ret == 0)\n--\nnet/bridge/netfilter/ebtables.c=2547=static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,\n--\nnet/bridge/netfilter/ebtables.c-2561-\t\tif (in_compat_syscall())\nnet/bridge/netfilter/ebtables.c:2562:\t\t\tret = compat_do_replace(net, arg, len);\nnet/bridge/netfilter/ebtables.c-2563-\t\telse\nnet/bridge/netfilter/ebtables.c-2564-#endif\nnet/bridge/netfilter/ebtables.c:2565:\t\t\tret = do_replace(net, arg, len);\nnet/bridge/netfilter/ebtables.c-2566-\t\tbreak;\n"
} |
| 26/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 35843 output: 41 thoughts: 15 Thoughts: Okay, let's dive into this. Here's my thought process summarized, assuming I'm already pretty familiar with network security concepts: **Deep Dive into `nfnl_hook_dump_nat`** Alright, the objective is to understand `nfnl_hook_dump_nat`. This is likely a function related to Netfilter (or perhaps the Netlink interface interacting with it), specifically dealing with the "nat" (Network Address Translation) aspect. "Dump" suggests we're retrieving information, probably state tables or rule configurations. "Hook" implies this function is part of a larger process; it's a point where we can intercept and potentially modify network traffic that is being processed by the kernel. I need to figure out exactly *what* it's dumping, where it's called, and how it fits into the overall NAT implementation. Is this user-space or kernel-space? The name suggests kernel-space, interacting with Netfilter's internals directly, but I should confirm that immediately. This could be a critical function for debugging NAT issues, analyzing traffic flows, or even potentially auditing NAT configurations for security vulnerabilities. I'll need to look at the surrounding code to determine its specific context and purpose. I'm going to start by tracing the function's usage, looking for call sites and any associated data structures. This is going to be interesting. |
| 27/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "nfnl_hook_dump_nat",
"PathPrefix": "net/netfilter/nfnetlink_hook.c"
}Results: {
"Output": "net/netfilter/nfnetlink_hook.c=279=nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *dev)\n--\nnet/netfilter/nfnetlink_hook.c-339-\nnet/netfilter/nfnetlink_hook.c:340:static int nfnl_hook_dump_nat(struct sk_buff *nlskb,\nnet/netfilter/nfnetlink_hook.c-341-\t\t\t const struct nfnl_dump_hook_data *ctx,\n--\nnet/netfilter/nfnetlink_hook.c=364=static int nfnl_hook_dump(struct sk_buff *nlskb,\n--\nnet/netfilter/nfnetlink_hook.c-392-\t\tif (ops[i]-\u003ehook_ops_type == NF_HOOK_OP_NAT)\nnet/netfilter/nfnetlink_hook.c:393:\t\t\terr = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,\nnet/netfilter/nfnetlink_hook.c-394-\t\t\t\t\t\t cb-\u003enlh-\u003enlmsg_seq);\n"
} |
| 28/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 36492 output: 39 thoughts: 15 Thoughts: Okay, let's dive into this. Here's my thought process on this: **Analyzing `nft_ct_nat_follow_master`** Right, let's take a look at `nft_ct_nat_follow_master`. This immediately flags something important. I need to understand exactly what this is doing. My experience tells me this is likely related to connection tracking (`ct`) and Network Address Translation (`nat`). The term "follow_master" suggests a dependency or a behavior based on a primary or parent connection. Given my background, I'm thinking about how connections are handled, especially in complex scenarios involving NAT and how the connection tracking module in `nftables` might be managing the relationship between different connections and their NATed counterparts. I want to figure out how this function interacts with the connection tracking table and what implications this specific "follow_master" behavior has on the overall packet flow. Is it making NAT more robust? Does it mean the subsequent connections have similar NAT mappings to the master connection? I'll probably be looking into the nftables documentation and some related source code, if possible, to fully grasp its functionality and intended use. Let's see what's actually going on. |
| 29/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "nft_ct_nat_follow_master",
"PathPrefix": "net/netfilter/nft_ct.c"
}Results: {
"Output": "net/netfilter/nft_ct.c=1285=static int nft_ct_expect_obj_dump(struct sk_buff *skb,\n--\nnet/netfilter/nft_ct.c-1300-#if IS_ENABLED(CONFIG_NF_NAT)\nnet/netfilter/nft_ct.c:1301:static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)\nnet/netfilter/nft_ct.c-1302-{\n--\nnet/netfilter/nft_ct.c=1311=static void nft_ct_expect_obj_eval(struct nft_object *obj,\n--\nnet/netfilter/nft_ct.c-1359-\t\texp-\u003edir = !dir;\nnet/netfilter/nft_ct.c:1360:\t\texp-\u003eexpectfn = nft_ct_nat_follow_master;\nnet/netfilter/nft_ct.c-1361-\t}\n--\nnet/netfilter/nft_ct.c=1397=static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {\nnet/netfilter/nft_ct.c-1398-\t.name = \"nft_ct-follow-master\",\nnet/netfilter/nft_ct.c:1399:\t.expectfn = nft_ct_nat_follow_master,\nnet/netfilter/nft_ct.c-1400-};\n"
} |
| 30/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 37178 output: 75 thoughts: 21 Thoughts: Here's my thought process, as requested: **Checking Network Header Configurations** Okay, time to dive in. My immediate focus is on the `tos_mt_check` and `tcpmss_mt_check` variables. I need to understand what state they're in. Are they enabled, disabled, configured in some custom way? What are their values? What are they *supposed* to be? Are these even relevant to the current investigation? Or should I move on to other areas? I'll probably start by checking their current settings and comparing them to the baseline or expected configuration. Depending on the results, that will direct me, for instance if both are checked and they shouldnt be, or if they are checked and they should be, or if only one is enabled etc. I'll need to know whether any configuration anomaly here can explain the performance behaviour that triggered this investigation. |
| 31/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "tos_mt_check",
"PathPrefix": "net/netfilter/xt_dscp.c"
}Results: {
"Output": "net/netfilter/xt_dscp.c=42=static int dscp_mt_check(const struct xt_mtchk_param *par)\n--\nnet/netfilter/xt_dscp.c-51-\nnet/netfilter/xt_dscp.c:52:static int tos_mt_check(const struct xt_mtchk_param *par)\nnet/netfilter/xt_dscp.c-53-{\n--\nnet/netfilter/xt_dscp.c=74=static struct xt_match dscp_mt_reg[] __read_mostly = {\n--\nnet/netfilter/xt_dscp.c-94-\t\t.family\t\t= NFPROTO_IPV4,\nnet/netfilter/xt_dscp.c:95:\t\t.checkentry\t= tos_mt_check,\nnet/netfilter/xt_dscp.c-96-\t\t.match\t\t= tos_mt,\n--\nnet/netfilter/xt_dscp.c-103-\t\t.family\t\t= NFPROTO_IPV6,\nnet/netfilter/xt_dscp.c:104:\t\t.checkentry\t= tos_mt_check,\nnet/netfilter/xt_dscp.c-105-\t\t.match\t\t= tos_mt,\n"
} |
| 32/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "tcpmss_mt_check",
"PathPrefix": "net/netfilter/xt_tcpmss.c"
}Results: {
"Output": "net/netfilter/xt_tcpmss.c=25=tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)\n--\nnet/netfilter/xt_tcpmss.c-80-\nnet/netfilter/xt_tcpmss.c:81:static int tcpmss_mt_check(const struct xt_mtchk_param *par)\nnet/netfilter/xt_tcpmss.c-82-{\n--\nnet/netfilter/xt_tcpmss.c=93=static struct xt_match tcpmss_mt_reg[] __read_mostly = {\n--\nnet/netfilter/xt_tcpmss.c-96-\t\t.family\t\t= NFPROTO_IPV4,\nnet/netfilter/xt_tcpmss.c:97:\t\t.checkentry\t= tcpmss_mt_check,\nnet/netfilter/xt_tcpmss.c-98-\t\t.match\t\t= tcpmss_mt,\n"
} |
| 33/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38034 output: 41 thoughts: 14 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience and written in the first person: **Checking `nfnl_cthelper_new`** Okay, so I'm focusing in on `nfnl_cthelper_new`. I need to quickly refresh my understanding of its role in the system. Given that name, I'm assuming this is a *new* or modified helper function related to CT (context tracking), presumably within the Netfilter framework. My initial thought is to quickly ascertain: * What's changed in `nfnl_cthelper_new` from the older versions? Is this a complete rewrite, a refactoring, or just an incremental improvement? I need to understand the architectural implications. * What specific context(s) is it *helping* to track? Is this for connection tracking, flow tracking, or something more specific? What are the new edge-cases? * What data structures is it interacting with? Are there any new structures added? Any changes to existing structures? What locking is involved? Is there a risk of race conditions that warrant immediate investigation? * How does it interact with the other Netfilter modules? Is it upstream, downstream, or a direct link? Are there dependencies with other Netfilter hooks or modules, and are they well-defined? * Is it going to handle new protocols? Does this involve SIP, FTP, or other application layer protocols? How do the new protocols improve the existing ones? Ultimately, my goal is to assess the potential impact of this change. Is this a minor tweak, or does it represent a fundamental shift in how we handle CT? That will determine how deep I need to dig into the implementation, and what potential issues I need to keep in mind. |
| 34/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "nfnl_cthelper_new",
"PathPrefix": "net/netfilter/nfnetlink_cthelper.c"
}Results: {
"Output": "net/netfilter/nfnetlink_cthelper.c=391=nfnl_cthelper_update(const struct nlattr * const tb[],\n--\nnet/netfilter/nfnetlink_cthelper.c-425-\nnet/netfilter/nfnetlink_cthelper.c:426:static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,\nnet/netfilter/nfnetlink_cthelper.c-427-\t\t\t const struct nlattr * const tb[])\n--\nnet/netfilter/nfnetlink_cthelper.c=748=static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {\nnet/netfilter/nfnetlink_cthelper.c-749-\t[NFNL_MSG_CTHELPER_NEW]\t= {\nnet/netfilter/nfnetlink_cthelper.c:750:\t\t.call\t\t= nfnl_cthelper_new,\nnet/netfilter/nfnetlink_cthelper.c-751-\t\t.type\t\t= NFNL_CB_MUTEX,\n"
} |
| 35/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38763 output: 39 thoughts: 12 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing `cttimeout_new_timeout`** Alright, let's dive into this. I'm thinking, "Okay, we're talking about `cttimeout_new_timeout`. Right away, my mind starts tracing back through the call stack... what initiated this call? What context is it operating within? Is it handling connection establishment, keep-alives, retransmissions, or something else entirely?" I immediately start mentally mapping the data structures involved: the `cttimeout` structure itself – what fields are relevant here? Timeout value, associated callback, context pointer... Gotta consider potential race conditions if this involves threading or interrupts. Memory allocation, deallocation – are we leaking resources anywhere? The implications are huge. Is there any existing documentation or test cases for this specific function? I'm also considering potential failure modes. What if the allocation fails? What if the timeout value is absurdly large or small? How robust is the error handling? Could this be a bottleneck under heavy load? Gotta check for that. Now, let's get down to the implementation details. Let's see how they do it. |
| 36/2 | 2026/07/02 15:22 | tool | grepper |
0mArgs:{
"Expression": "cttimeout_new_timeout",
"PathPrefix": "net/netfilter/nfnetlink_cttimeout.c"
}Results: {
"Output": "net/netfilter/nfnetlink_cttimeout.c=67=ctnl_timeout_parse_policy(void *timeout,\n--\nnet/netfilter/nfnetlink_cttimeout.c-93-\nnet/netfilter/nfnetlink_cttimeout.c:94:static int cttimeout_new_timeout(struct sk_buff *skb,\nnet/netfilter/nfnetlink_cttimeout.c-95-\t\t\t\t const struct nfnl_info *info,\n--\nnet/netfilter/nfnetlink_cttimeout.c=530=static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {\nnet/netfilter/nfnetlink_cttimeout.c-531-\t[IPCTNL_MSG_TIMEOUT_NEW] = {\nnet/netfilter/nfnetlink_cttimeout.c:532:\t\t.call\t\t= cttimeout_new_timeout,\nnet/netfilter/nfnetlink_cttimeout.c-533-\t\t.type\t\t= NFNL_CB_MUTEX,\n"
} |
| 37/2 | 2026/07/02 15:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 39341 output: 44 thoughts: 16 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Diving into `__nf_conntrack_helper_register`** Okay, so we're looking at `__nf_conntrack_helper_register`. Naturally, my mind immediately jumps to the critical role this function plays within the Netfilter connection tracking framework. I need to refresh my understanding of how a helper actually "registers" itself, beyond the obvious. It's not just a matter of making its presence known. I'm thinking about the data structures involved; the interaction with the connection tracking table, of course. Are we talking about attaching a protocol-specific handler, a port range, or something more nuanced? What's the registration process look like in relation to NAT'ing and how it handles different conntrack states? There's always the concern about race conditions and locking when modifying shared structures. I'll need to remember the call sequence and whether this registration is atomic. I should probably brush up on the relevant RFCs and the exact data structures and their interaction for various protocols. I want to make sure I grasp the finer points of how it integrates with the rest of the Netfilter architecture and its use by a variety of applications. I'm especially interested in how it helps identify and handle specific application-level protocols to facilitate proper connection tracking. |
| 38/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "__nf_conntrack_helper_register",
"PathPrefix": "net/netfilter/nf_conntrack_helper.c"
}Results: {
"Output": "net/netfilter/nf_conntrack_helper.c=366=EXPORT_SYMBOL_GPL(nf_ct_helper_log);\nnet/netfilter/nf_conntrack_helper.c-367-\nnet/netfilter/nf_conntrack_helper.c:368:int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)\nnet/netfilter/nf_conntrack_helper.c-369-{\n--\nnet/netfilter/nf_conntrack_helper.c-406-}\nnet/netfilter/nf_conntrack_helper.c:407:EXPORT_SYMBOL_GPL(__nf_conntrack_helper_register);\nnet/netfilter/nf_conntrack_helper.c-408-\nnet/netfilter/nf_conntrack_helper.c=409=int nf_conntrack_helper_register(struct nf_conntrack_helper *me,\n--\nnet/netfilter/nf_conntrack_helper.c-421-\nnet/netfilter/nf_conntrack_helper.c:422:\terr = __nf_conntrack_helper_register(new_helper);\nnet/netfilter/nf_conntrack_helper.c-423-\tif (err \u003c 0)\n--\nnet/netfilter/nf_conntrack_helper.c=506=int nf_conntrack_helpers_register(struct nf_conntrack_helper *helper,\n--\nnet/netfilter/nf_conntrack_helper.c-522-\nnet/netfilter/nf_conntrack_helper.c:523:\t\terr = __nf_conntrack_helper_register(new_helper);\nnet/netfilter/nf_conntrack_helper.c-524-\t\tif (err \u003c 0) {\n"
} |
| 39/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 40155 output: 41 thoughts: 13 Thoughts: Okay, let's dive into this. Here's my thought process on this specific topic, aimed directly at a fellow expert: **Investigating `nf_ct_helper_init`** Alright, so the first thing I'm thinking is, let's get right to it. I want to take a closer look at `nf_ct_helper_init`. No fluff, no preliminaries, let's get into the details of what this function is doing. I need to understand its role within the broader connection tracking framework. What does it initialize? How does it integrate with the rest of the Netfilter Connection Tracking system? I need a solid mental model of its impact. I'm already formulating questions: Is this a critical initialization function? Does it deal with helper modules, or is it more of a general setup routine? Is this where we're going to get the data structures set up? I'm anticipating potential issues related to memory allocation, resource management, and potential race conditions within a multi-threaded network stack. Okay, let's dig in. |
| 40/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nf_ct_helper_init",
"PathPrefix": "net/netfilter/nf_conntrack_helper.c"
}Results: {
"Output": "net/netfilter/nf_conntrack_helper.c=471=EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);\nnet/netfilter/nf_conntrack_helper.c-472-\nnet/netfilter/nf_conntrack_helper.c:473:void nf_ct_helper_init(struct nf_conntrack_helper *helper,\nnet/netfilter/nf_conntrack_helper.c-474-\t\t u8 l3num, u16 protonum, const char *name,\n--\nnet/netfilter/nf_conntrack_helper.c-503-}\nnet/netfilter/nf_conntrack_helper.c:504:EXPORT_SYMBOL_GPL(nf_ct_helper_init);\nnet/netfilter/nf_conntrack_helper.c-505-\n"
} |
| 41/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 40658 output: 44 thoughts: 16 Thoughts: Okay, let's dive into this. Here's my thought process on this: **Analyzing `__nf_conntrack_helper_find`** Alright, the objective here is to understand the purpose or significance of this function, `__nf_conntrack_helper_find`. My initial thought is to figure out where it fits within the broader context of the conntrack system. This function name strongly suggests its role is related to finding or locating something – likely a "helper" within the connection tracking framework. "Helper" suggests a module that assists the conntrack in understanding or dealing with specific protocols. My expertise tells me that conntrack helpers are usually used to inspect packet payloads to derive information that helps the conntrack module maintain connection state in protocols that don't fit the normal TCP/UDP pattern (like FTP, SIP, etc.). Now I'll need to remember where and how this fits within the entire connection tracking system... Let's see if this function reveals something deeper. |
| 42/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "__nf_conntrack_helper_find",
"PathPrefix": "net/netfilter/nf_conntrack_helper.c"
}Results: {
"Output": "net/netfilter/nf_conntrack_helper.c=55=struct nf_conntrack_helper *\nnet/netfilter/nf_conntrack_helper.c:56:__nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)\nnet/netfilter/nf_conntrack_helper.c-57-{\n--\nnet/netfilter/nf_conntrack_helper.c-75-}\nnet/netfilter/nf_conntrack_helper.c:76:EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find);\nnet/netfilter/nf_conntrack_helper.c-77-\n--\nnet/netfilter/nf_conntrack_helper.c=79=nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)\n--\nnet/netfilter/nf_conntrack_helper.c-84-\nnet/netfilter/nf_conntrack_helper.c:85:\th = __nf_conntrack_helper_find(name, l3num, protonum);\nnet/netfilter/nf_conntrack_helper.c-86-#ifdef CONFIG_MODULES\n--\nnet/netfilter/nf_conntrack_helper.c-90-\t\t\trcu_read_lock();\nnet/netfilter/nf_conntrack_helper.c:91:\t\t\th = __nf_conntrack_helper_find(name, l3num, protonum);\nnet/netfilter/nf_conntrack_helper.c-92-\t\t} else {\n--\nnet/netfilter/nf_conntrack_helper.c=134=nf_nat_helper_try_module_get(const char *name, u16 l3num, u8 protonum)\n--\nnet/netfilter/nf_conntrack_helper.c-141-\trcu_read_lock();\nnet/netfilter/nf_conntrack_helper.c:142:\th = __nf_conntrack_helper_find(name, l3num, protonum);\nnet/netfilter/nf_conntrack_helper.c-143-\tif (!h) {\n"
} |
| 43/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 41494 output: 47 thoughts: 19 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience and presented in the first person: **Investigating `nf_conntrack_helper_try_module_get`** Okay, so I'm diving into the connection tracking helper's module getting function, `nf_conntrack_helper_try_module_get`. My initial thought is to scrutinize this specific function. I need to understand its role in the broader `netfilter` framework. Why are we targeting this? Are we looking for a race condition, a use-after-free, or a potential information leak within the module reference counting? Is there some unexpected module load/unload behavior in a specific use case? Or are we attempting to understand the helper module’s reference counts in relation to connection tracking? The context of why this function has become the focus of my attention will shape the questions I ask. I need to figure out the flow of control that calls this module and which parts are under our control. |
| 44/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nf_conntrack_helper_try_module_get",
"PathPrefix": "net/netfilter/nf_conntrack_helper.c"
}Results: {
"Output": "net/netfilter/nf_conntrack_helper.c=78=struct nf_conntrack_helper *\nnet/netfilter/nf_conntrack_helper.c:79:nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)\nnet/netfilter/nf_conntrack_helper.c-80-{\n--\nnet/netfilter/nf_conntrack_helper.c-107-}\nnet/netfilter/nf_conntrack_helper.c:108:EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get);\nnet/netfilter/nf_conntrack_helper.c-109-\n"
} |
| 45/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 41963 output: 45 thoughts: 17 Thoughts: Here's my take on those thoughts, tailored for an expert audience: **Diving into `nf_nat_helper_try_module_get`** Okay, so we're looking at `nf_nat_helper_try_module_get`. My immediate thought is, let's refresh our understanding of where this sits in the overall NAT helper framework. I'm assuming we're concerned with module loading, reference counting, and the implications for helper registration and unregistration. So, my mind immediately starts cycling through the potential gotchas: race conditions, double-frees (or rather, the lack thereof when things fail). I'm probably thinking about the implications for conntrack, and how we're ensuring that a helper module stays loaded long enough for the conntrack entry to be cleaned up when it's no longer needed. We should really be digging into how robust the error handling is here. I'm especially keen to see how the reference count is managed, and whether there are any potential scenarios where a module could be unloaded prematurely, leaving dangling pointers or undefined behavior in the netfilter stack. Also, checking for potential deadlocks or lock contention when grabbing and releasing module references is a must. Let's see how this works! |
| 46/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nf_nat_helper_try_module_get",
"PathPrefix": "net/netfilter/nf_conntrack_helper.c"
}Results: {
"Output": "net/netfilter/nf_conntrack_helper.c=133=int\nnet/netfilter/nf_conntrack_helper.c:134:nf_nat_helper_try_module_get(const char *name, u16 l3num, u8 protonum)\nnet/netfilter/nf_conntrack_helper.c-135-{\n--\nnet/netfilter/nf_conntrack_helper.c-167-}\nnet/netfilter/nf_conntrack_helper.c:168:EXPORT_SYMBOL_GPL(nf_nat_helper_try_module_get);\nnet/netfilter/nf_conntrack_helper.c-169-\n"
} |
| 47/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 42470 output: 41 thoughts: 15 Thoughts: Okay, let's dive into this. Here's my thought process summarized, assuming I'm already pretty familiar with network security concepts: **Deep Dive into `nfnl_hook_dump_nat`** Alright, the objective is to understand `nfnl_hook_dump_nat`. This is likely a function related to Netfilter (or perhaps the Netlink interface interacting with it), specifically dealing with the "nat" (Network Address Translation) aspect. "Dump" suggests we're retrieving information, probably state tables or rule configurations. "Hook" implies this function is part of a larger process; it's a point where we can intercept and potentially modify network traffic that is being processed by the kernel. I need to figure out exactly *what* it's dumping, where it's called, and how it fits into the overall NAT implementation. Is this user-space or kernel-space? The name suggests kernel-space, interacting with Netfilter's internals directly, but I should confirm that immediately. This could be a critical function for debugging NAT issues, analyzing traffic flows, or even potentially auditing NAT configurations for security vulnerabilities. I'll need to look at the surrounding code to determine its specific context and purpose. I'm going to start by tracing the function's usage, looking for call sites and any associated data structures. This is going to be interesting. |
| 48/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nfnl_hook_dump_nat",
"PathPrefix": "net/netfilter/nfnetlink_hook.c"
}Results: {
"Output": "net/netfilter/nfnetlink_hook.c=279=nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *dev)\n--\nnet/netfilter/nfnetlink_hook.c-339-\nnet/netfilter/nfnetlink_hook.c:340:static int nfnl_hook_dump_nat(struct sk_buff *nlskb,\nnet/netfilter/nfnetlink_hook.c-341-\t\t\t const struct nfnl_dump_hook_data *ctx,\n--\nnet/netfilter/nfnetlink_hook.c=364=static int nfnl_hook_dump(struct sk_buff *nlskb,\n--\nnet/netfilter/nfnetlink_hook.c-392-\t\tif (ops[i]-\u003ehook_ops_type == NF_HOOK_OP_NAT)\nnet/netfilter/nfnetlink_hook.c:393:\t\t\terr = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,\nnet/netfilter/nfnetlink_hook.c-394-\t\t\t\t\t\t cb-\u003enlh-\u003enlmsg_seq);\n"
} |
| 49/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 43119 output: 41 thoughts: 14 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Analyzing `nfnl_cthelper_new`** Okay, let's dive into this `nfnl_cthelper_new` function. I need to quickly ascertain its purpose, the core logic, and any potential areas of concern, particularly regarding its interactions with the Netfilter framework. I'm assuming this is related to connection tracking, given the naming, but a quick scan will confirm. I'll be looking for things like memory allocation patterns, the data structures it uses, and how it interacts with the conntrack table – are there any potential race conditions or locking issues? Does it handle error conditions gracefully, or are there obvious places for resource leaks? Specifically, I'll be watching to see if it's using the new conntrack API or legacy mechanisms. I'm also curious to see if it makes use of any of the per-CPU data structures, and whether it handles CPU affinity correctly. I'll need to pay close attention to the use of any atomic operations, since this is in the kernel. Finally, I'll need to figure out its relationship with the more general connection tracking subsystems to verify that it interacts with them in a consistent and robust way. |
| 50/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nfnl_cthelper_new",
"PathPrefix": "net/netfilter/nfnetlink_cthelper.c"
}Results: {
"Output": "net/netfilter/nfnetlink_cthelper.c=391=nfnl_cthelper_update(const struct nlattr * const tb[],\n--\nnet/netfilter/nfnetlink_cthelper.c-425-\nnet/netfilter/nfnetlink_cthelper.c:426:static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,\nnet/netfilter/nfnetlink_cthelper.c-427-\t\t\t const struct nlattr * const tb[])\n--\nnet/netfilter/nfnetlink_cthelper.c=748=static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {\nnet/netfilter/nfnetlink_cthelper.c-749-\t[NFNL_MSG_CTHELPER_NEW]\t= {\nnet/netfilter/nfnetlink_cthelper.c:750:\t\t.call\t\t= nfnl_cthelper_new,\nnet/netfilter/nfnetlink_cthelper.c-751-\t\t.type\t\t= NFNL_CB_MUTEX,\n"
} |
| 51/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 43741 output: 39 thoughts: 12 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Analyzing `cttimeout_new_timeout`** Alright, let's dive into this. I'm thinking, "Okay, we're talking about `cttimeout_new_timeout`. Right away, my mind starts tracing back through the call stack... what initiated this call? What context is it operating within? Is it handling connection establishment, keep-alives, retransmissions, or something else entirely?" I immediately start mentally mapping the data structures involved: the `cttimeout` structure itself – what fields are relevant here? Timeout value, associated callback, context pointer... Gotta consider potential race conditions if this involves threading or interrupts. Memory allocation, deallocation – are we leaking resources anywhere? The implications are huge. Is there any existing documentation or test cases for this specific function? I'm also considering potential failure modes. What if the allocation fails? What if the timeout value is absurdly large or small? How robust is the error handling? Could this be a bottleneck under heavy load? Gotta check for that. Now, let's get down to the implementation details. Let's see how they do it. |
| 52/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "cttimeout_new_timeout",
"PathPrefix": "net/netfilter/nfnetlink_cttimeout.c"
}Results: {
"Output": "net/netfilter/nfnetlink_cttimeout.c=67=ctnl_timeout_parse_policy(void *timeout,\n--\nnet/netfilter/nfnetlink_cttimeout.c-93-\nnet/netfilter/nfnetlink_cttimeout.c:94:static int cttimeout_new_timeout(struct sk_buff *skb,\nnet/netfilter/nfnetlink_cttimeout.c-95-\t\t\t\t const struct nfnl_info *info,\n--\nnet/netfilter/nfnetlink_cttimeout.c=530=static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {\nnet/netfilter/nfnetlink_cttimeout.c-531-\t[IPCTNL_MSG_TIMEOUT_NEW] = {\nnet/netfilter/nfnetlink_cttimeout.c:532:\t\t.call\t\t= cttimeout_new_timeout,\nnet/netfilter/nfnetlink_cttimeout.c-533-\t\t.type\t\t= NFNL_CB_MUTEX,\n"
} |
| 53/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 44319 output: 36 thoughts: 11 Thoughts: Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and delivered in the first person: **Analyzing `tos_mt_check`** Alright, let's dive into this `tos_mt_check`. First, I need to understand what its purpose is. Based on the naming convention, I’m guessing this is likely a mechanism for checking some kind of terms of service related to machine translation. My experience suggests it probably flags potentially problematic content before processing. I'll need to look deeper into the underlying implementation - Are we talking about a simple blacklist, maybe a regular expression-based filter, or something more sophisticated like a model trained on flagged text? Is this a standalone module, or integrated into a larger pipeline? I'll be looking for signs of sensitivity towards PII, hate speech, or maybe even copyright infringements, all common concerns when dealing with MT. A crucial aspect will be understanding the trade-offs implemented. How strict is this check? Does it err on the side of caution, which could hurt performance, or is it more lenient, potentially introducing risk? I want to see if they are flagging the appropriate texts. Finally, how are the logs handled? Are there any alerts associated with high volumes of flagged content? I will need to delve into the source code and documentation to get the full picture. |
| 54/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "tos_mt_check",
"PathPrefix": "net/netfilter/xt_dscp.c"
}Results: {
"Output": "net/netfilter/xt_dscp.c=42=static int dscp_mt_check(const struct xt_mtchk_param *par)\n--\nnet/netfilter/xt_dscp.c-51-\nnet/netfilter/xt_dscp.c:52:static int tos_mt_check(const struct xt_mtchk_param *par)\nnet/netfilter/xt_dscp.c-53-{\n--\nnet/netfilter/xt_dscp.c=74=static struct xt_match dscp_mt_reg[] __read_mostly = {\n--\nnet/netfilter/xt_dscp.c-94-\t\t.family\t\t= NFPROTO_IPV4,\nnet/netfilter/xt_dscp.c:95:\t\t.checkentry\t= tos_mt_check,\nnet/netfilter/xt_dscp.c-96-\t\t.match\t\t= tos_mt,\n--\nnet/netfilter/xt_dscp.c-103-\t\t.family\t\t= NFPROTO_IPV6,\nnet/netfilter/xt_dscp.c:104:\t\t.checkentry\t= tos_mt_check,\nnet/netfilter/xt_dscp.c-105-\t\t.match\t\t= tos_mt,\n"
} |
| 55/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 44966 output: 39 thoughts: 13 Thoughts: Okay, here's my interpretation of that thought process, assuming I'm an expert in network protocols and TCP performance: **Initial Assessment: TCP MSS and MTU Validation** Right, let's dive in. "Check `tcpmss_mt_check`". That's a clear indicator that I'm focusing on validating the Maximum Segment Size (MSS) within a TCP connection, likely in relation to the Maximum Transmission Unit (MTU) of the underlying network path. This is a critical step in ensuring efficient and reliable data transmission. I'm probably looking at the details of how the check itself is structured. Is it a validation of negotiated MSS values against the path MTU? Is it verifying the MSS values offered in the SYN packets? Is it handling PMTUD (Path MTU Discovery) correctly? The context is what matters here. I will want to understand the approach taken to discover and validate TCP MSS. This matters since fragmenting packets is the worst case scenario. This check is crucial for avoiding fragmentation and reassembly overhead, which can severely impact performance, especially on paths with varying MTU sizes. I need to understand this validation step. |
| 56/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "tcpmss_mt_check",
"PathPrefix": "net/netfilter/xt_tcpmss.c"
}Results: {
"Output": "net/netfilter/xt_tcpmss.c=25=tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)\n--\nnet/netfilter/xt_tcpmss.c-80-\nnet/netfilter/xt_tcpmss.c:81:static int tcpmss_mt_check(const struct xt_mtchk_param *par)\nnet/netfilter/xt_tcpmss.c-82-{\n--\nnet/netfilter/xt_tcpmss.c=93=static struct xt_match tcpmss_mt_reg[] __read_mostly = {\n--\nnet/netfilter/xt_tcpmss.c-96-\t\t.family\t\t= NFPROTO_IPV4,\nnet/netfilter/xt_tcpmss.c:97:\t\t.checkentry\t= tcpmss_mt_check,\nnet/netfilter/xt_tcpmss.c-98-\t\t.match\t\t= tcpmss_mt,\n"
} |
| 57/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 45512 output: 39 thoughts: 15 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert: **Internal Audit - Checking `nft_ct_nat_follow_master`** Right, let's dive in. I need to take a look at the `nft_ct_nat_follow_master` rule. I'm immediately thinking about its implications. Is this a critical piece in the overall NAT and connection tracking strategy? Does it behave as expected, considering the nuances of stateful firewalls and NAT configurations I've seen in the past? My immediate concerns are: what's the use-case for this rule? Is there a performance impact to using this particular rule? Are there any security considerations tied to it? Time to dig into the details... |
| 58/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "nft_ct_nat_follow_master",
"PathPrefix": "net/netfilter/nft_ct.c"
}Results: {
"Output": "net/netfilter/nft_ct.c=1285=static int nft_ct_expect_obj_dump(struct sk_buff *skb,\n--\nnet/netfilter/nft_ct.c-1300-#if IS_ENABLED(CONFIG_NF_NAT)\nnet/netfilter/nft_ct.c:1301:static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)\nnet/netfilter/nft_ct.c-1302-{\n--\nnet/netfilter/nft_ct.c=1311=static void nft_ct_expect_obj_eval(struct nft_object *obj,\n--\nnet/netfilter/nft_ct.c-1359-\t\texp-\u003edir = !dir;\nnet/netfilter/nft_ct.c:1360:\t\texp-\u003eexpectfn = nft_ct_nat_follow_master;\nnet/netfilter/nft_ct.c-1361-\t}\n--\nnet/netfilter/nft_ct.c=1397=static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {\nnet/netfilter/nft_ct.c-1398-\t.name = \"nft_ct-follow-master\",\nnet/netfilter/nft_ct.c:1399:\t.expectfn = nft_ct_nat_follow_master,\nnet/netfilter/nft_ct.c-1400-};\n"
} |
| 59/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 46112 output: 34 thoughts: 23 Thoughts: Here's a summary of my thought process, as requested: **Diving into `ebtables.c`** Okay, so I need to understand how this replacement functionality works within the ebtables framework. The first place I'm going to dig into is the `do_replace` function in `net/bridge/netfilter/ebtables.c`. It's pretty obvious that's where the core replacement logic would reside. Let's see how they've implemented it, what checks they're performing, and how they handle the actual modification of the table entries. I'm especially interested in potential race conditions or security considerations given this is packet filtering. Let's get to it. |
| 60/2 | 2026/07/02 15:23 | tool | grepper |
0mArgs:{
"Expression": "do_replace",
"PathPrefix": "net/bridge/netfilter/ebtables.c"
}Results: {
"Output": "net/bridge/netfilter/ebtables.c=870=static int translate_table(struct net *net, const char *name,\n--\nnet/bridge/netfilter/ebtables.c-921-\tif (udc_cnt) {\nnet/bridge/netfilter/ebtables.c:922:\t\t/* this will get free'd in do_replace()/ebt_register_table()\nnet/bridge/netfilter/ebtables.c-923-\t\t * if an error occurs\n--\nnet/bridge/netfilter/ebtables.c=990=static void get_counters(const struct ebt_counter *oldcounters,\n--\nnet/bridge/netfilter/ebtables.c-1010-\nnet/bridge/netfilter/ebtables.c:1011:static int do_replace_finish(struct net *net, struct ebt_replace *repl,\nnet/bridge/netfilter/ebtables.c-1012-\t\t\t struct ebt_table_info *newinfo)\n--\nnet/bridge/netfilter/ebtables.c-1110-/* replace the table */\nnet/bridge/netfilter/ebtables.c:1111:static int do_replace(struct net *net, sockptr_t arg, unsigned int len)\nnet/bridge/netfilter/ebtables.c-1112-{\n--\nnet/bridge/netfilter/ebtables.c-1154-\nnet/bridge/netfilter/ebtables.c:1155:\tret = do_replace_finish(net, \u0026tmp, newinfo);\nnet/bridge/netfilter/ebtables.c-1156-\tif (ret == 0)\n--\nnet/bridge/netfilter/ebtables.c=2251=static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,\n--\nnet/bridge/netfilter/ebtables.c-2285-\nnet/bridge/netfilter/ebtables.c:2286:static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len)\nnet/bridge/netfilter/ebtables.c-2287-{\n--\nnet/bridge/netfilter/ebtables.c-2296-\t\t/* try real handler in case userland supplied needed padding */\nnet/bridge/netfilter/ebtables.c:2297:\t\tif (ret == -EINVAL \u0026\u0026 do_replace(net, arg, len) == 0)\nnet/bridge/netfilter/ebtables.c-2298-\t\t\tret = 0;\n--\nnet/bridge/netfilter/ebtables.c-2373-\nnet/bridge/netfilter/ebtables.c:2374:\tret = do_replace_finish(net, \u0026tmp, newinfo);\nnet/bridge/netfilter/ebtables.c-2375-\tif (ret == 0)\n--\nnet/bridge/netfilter/ebtables.c=2547=static int do_ebt_set_ctl(struct sock *sk, int cmd, sockptr_t arg,\n--\nnet/bridge/netfilter/ebtables.c-2561-\t\tif (in_compat_syscall())\nnet/bridge/netfilter/ebtables.c:2562:\t\t\tret = compat_do_replace(net, arg, len);\nnet/bridge/netfilter/ebtables.c-2563-\t\telse\nnet/bridge/netfilter/ebtables.c-2564-#endif\nnet/bridge/netfilter/ebtables.c:2565:\t\t\tret = do_replace(net, arg, len);\nnet/bridge/netfilter/ebtables.c-2566-\t\tbreak;\n"
} |
| 61/2 | 2026/07/02 15:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 47238 output: 489 thoughts: 1178 Thoughts: **Analysis of Netfilter and ebtables Patch Series for Fuzzing** Alright, let's break this down. My initial assessment is that this patch series introduces fundamental changes within the netfilter ecosystem, specifically touching connection tracking helpers, NAT hooks, and ebtables. This is a fertile ground for fuzzing. My thinking is to focus on a set of core functions which are likely to be impacted by the changes. These are: `__nf_conntrack_helper_register`, `nf_ct_helper_init`, `__nf_conntrack_helper_find`, `nfnl_hook_dump_nat`, `nfnl_cthelper_new`, `cttimeout_new_timeout`, `tos_mt_check`, `tcpmss_mt_check`, `nft_ct_nat_follow_master`, `do_replace`, and `compat_copy_ebt_replace_from_user`. I need to confirm the reachability of `compat_copy_ebt_replace_from_user`; it appears to be called from `compat_do_replace`. The core logic changes are: modifications to how conntrack helpers are handled (especially removing port-specific defaults), additions of a new `NF_HOOK_OP_NAT` type, corrections to NAT hook dumping, a NAT follow master expectfn for `nft_ct`, and a critical fix for an integer overflow in ebtables' `do_replace`. Additionally, new validation checks have been implemented for `xt_dscp` and `xt_tcpmss` matches. These all represent significant core kernel changes and netfilter logic, making them prime targets. I need to make sure I get the right configs enabled. We're looking at: * `NF_CONNTRACK` * `NF_NAT` * `BRIDGE_NF_EBTABLES` * `NETFILTER_NETLINK_HOOK` * `NF_CT_NETLINK_HELPER` * `NF_CT_NETLINK_TIMEOUT` * `NFT_CT` * `NETFILTER_XT_MATCH_DSCP` * `NETFILTER_XT_MATCH_TCPMSS` * `NETFILTER_XT_MATCH_RECENT` * `NETFILTER_XT_TARGET_TCPOPTSTRIP` * `NF_CONNTRACK_AMANDA` * `NF_CONNTRACK_FTP` * `NF_CONNTRACK_H323` * `NF_CONNTRACK_IRC` * `NF_CONNTRACK_NETBIOS_NS` * `NF_CONNTRACK_SNMP` * `NF_CONNTRACK_PPTP` * `NF_CONNTRACK_SANE` * `NF_CONNTRACK_SIP` * `NF_CONNTRACK_TFTP` * `NF_NAT_SNMP_BASIC` I'm verifying `do_replace` in `net/bridge/netfilter/ebtables.c`. It is a static function. Right, I am ready to submit results. |
| 62/2 | 2026/07/02 15:24 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"NF_CONNTRACK",
"NF_NAT",
"BRIDGE_NF_EBTABLES",
"NETFILTER_NETLINK_HOOK",
"NF_CT_NETLINK_HELPER",
"NF_CT_NETLINK_TIMEOUT",
"NFT_CT",
"NETFILTER_XT_MATCH_DSCP",
"NETFILTER_XT_MATCH_TCPMSS",
"NETFILTER_XT_MATCH_RECENT",
"NETFILTER_XT_TARGET_TCPOPTSTRIP",
"NF_CONNTRACK_AMANDA",
"NF_CONNTRACK_FTP",
"NF_CONNTRACK_H323",
"NF_CONNTRACK_IRC",
"NF_CONNTRACK_NETBIOS_NS",
"NF_CONNTRACK_SNMP",
"NF_CONNTRACK_PPTP",
"NF_CONNTRACK_SANE",
"NF_CONNTRACK_SIP",
"NF_CONNTRACK_TFTP",
"NF_NAT_SNMP_BASIC"
],
"FocusSymbols": [
"__nf_conntrack_helper_register",
"nf_ct_helper_init",
"__nf_conntrack_helper_find",
"nfnl_hook_dump_nat",
"nfnl_cthelper_new",
"cttimeout_new_timeout",
"tos_mt_check",
"tcpmss_mt_check",
"nft_ct_nat_follow_master",
"do_replace",
"compat_copy_ebt_replace_from_user"
],
"Reasoning": "The patch series makes functional changes to netfilter connection tracking helpers, NAT hooks, and ebtables. It changes how conntrack helpers are registered and looked up (removing port-specific defaults), adds a new NF_HOOK_OP_NAT type and fixes NAT hook dumping, adds a NAT follow master expectfn for nft_ct, and fixes an integer overflow in ebtables do_replace. It also adds validation checks for xt_dscp and xt_tcpmss matches. These are reachable core kernel and netfilter logic changes that should be fuzzed.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"NF_CONNTRACK",
"NF_NAT",
"BRIDGE_NF_EBTABLES",
"NETFILTER_NETLINK_HOOK",
"NF_CT_NETLINK_HELPER",
"NF_CT_NETLINK_TIMEOUT",
"NFT_CT",
"NETFILTER_XT_MATCH_DSCP",
"NETFILTER_XT_MATCH_TCPMSS",
"NETFILTER_XT_MATCH_RECENT",
"NETFILTER_XT_TARGET_TCPOPTSTRIP",
"NF_CONNTRACK_AMANDA",
"NF_CONNTRACK_FTP",
"NF_CONNTRACK_H323",
"NF_CONNTRACK_IRC",
"NF_CONNTRACK_NETBIOS_NS",
"NF_CONNTRACK_SNMP",
"NF_CONNTRACK_PPTP",
"NF_CONNTRACK_SANE",
"NF_CONNTRACK_SIP",
"NF_CONNTRACK_TFTP",
"NF_NAT_SNMP_BASIC"
],
"FocusSymbols": [
"__nf_conntrack_helper_register",
"nf_ct_helper_init",
"__nf_conntrack_helper_find",
"nfnl_hook_dump_nat",
"nfnl_cthelper_new",
"cttimeout_new_timeout",
"tos_mt_check",
"tcpmss_mt_check",
"nft_ct_nat_follow_master",
"do_replace",
"compat_copy_ebt_replace_from_user"
],
"Reasoning": "The patch series makes functional changes to netfilter connection tracking helpers, NAT hooks, and ebtables. It changes how conntrack helpers are registered and looked up (removing port-specific defaults), adds a new NF_HOOK_OP_NAT type and fixes NAT hook dumping, adds a NAT follow master expectfn for nft_ct, and fixes an integer overflow in ebtables do_replace. It also adds validation checks for xt_dscp and xt_tcpmss matches. These are reachable core kernel and netfilter logic changes that should be fuzzed.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|