History

Merge tag 'nf-26-06-23' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf

Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Add a workaround to avoid a possible crash if nf_nat and nft_chain_nat are compiled built-in and nf_nat fails to register, allowing nft_chain_nat to access the incorrect pernetns area. This is crash specific of all built-in compilation. From Matias Krause. 2) Revisit conncount GC optimization for confirmed conntracks, skip GC round if IPS_ASSURED is set on. This is addressing an issue for corner case use case scenario involving locally generated traffic. No crash, just a functionality fix. From Fernando F. Mancera. 3) Validate iph->ihl in flowtable IPIP tunnel support, from Lorenzo Bianconi. This a sanity check to bounces back malformed IPIP packets to classic forwarding path. 4) Kdoc fixes for x_tables.h, from Randy Dunlap. 5) Use info->options so nft_synproxy_tcp_options() stays on the same local snapshot, otherwise eval path can observe inconsistent mix of mss and timestamps. From Runyu Xiao. 6) Add conntrack_sctp_collision.sh to cover for SCTP INIT collisions. From Yi Chen. 7) Do not allow NFPROTO_UNSPEC targets if family is NFPROTO_BRIDGE in nft_compat. This allows to use non-sense targets such as xt_nat leading to crash. From Florian Westphal. 8) Add a selftest queueing from bridge family. From Florian Westphal. 9) Do not allow to reset a conntrack helper via ctnetlink. This feature antedates the creation of the conntrack-tools, and it is not used I don't have a usecase for it, I prefer to remove than fixing it. 10) Add deprecation warning for IPv4 only conntrack helpers for PPTP and IRC. From Florian Westphal. 11) Store the master tuple in the expectation object and use it, otherwise SLAB_TYPESAFE_RCU rules allow to display incorrect master tuple information through ctnetlink. 12) Run expectation eviction when inserting an expectation with no helper, this is a fix for the nft_ct custom expectation support. 13) Fix nft_ct custom expectation timeouts, userspace provides a timeout in milliseconds but kernel assumes this comes in seconds. From Florian Westphal. 14) Cap maximum number of expectations per class to 255 expectations per master conntrack at helper registration. This is a fix to restrict the maximum number of expectations per master conntrack which can be a issue for the new lazy GC expectation approach. * tag 'nf-26-06-23' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_conntrack_helper: cap maximum number of expectation at helper registration netfilter: nft_ct: expectation timeouts are passed in milliseconds netfilter: nf_conntrack_expect: run expectation eviction with no helper netfilter: nf_conntrack_expect: store master_tuple in expectation netfilter: conntrack: add deprecation warnings for irc and pptp trackers netfilter: ctnetlink: do not allow to reset helper on existing conntrack selftests: nft_queue.sh: add a bridge queue test netfilter: nft_compat: ebtables emulation must reject non-bridge targets selftests: netfilter: conntrack_sctp_collision.sh: Introduce SCTP INIT collision test netfilter: nft_synproxy: stop bypassing the priv->info snapshot netfilter: x_tables.h: fix all kernel-doc warnings netfilter: flowtable: Validate iph->ihl in nf_flow_ip4_tunnel_proto() netfilter: nf_conncount: prevent connlimit drops for early confirmed ct netfilter: nf_nat: avoid invalid nat_net pointer use on failed nf_nat_init() ====================

Jakub Kicinski committed 4 months ago

Commit 02f144f2 parents 620839b 397c83018 files · +246 −86Browse files

Unified · Split

18 files
  1. include/linux/netfilter/x_tables.h +21 −8
  2. include/net/netfilter/nf_conntrack_expect.h +1 −0
  3. include/net/netfilter/nf_conntrack_helper.h +4 −0
  4. net/netfilter/Kconfig +6 −5
  5. net/netfilter/nf_conncount.c +5 −6
  6. net/netfilter/nf_conntrack_broadcast.c +1 −0
  7. net/netfilter/nf_conntrack_expect.c +10 −2
  8. net/netfilter/nf_conntrack_helper.c +7 −2
  9. net/netfilter/nf_conntrack_irc.c +2 −0
  10. net/netfilter/nf_conntrack_netlink.c +4 −19
  11. net/netfilter/nf_conntrack_pptp.c +2 −0
  12. net/netfilter/nf_flow_table_ip.c +5 −3
  13. net/netfilter/nf_nat_core.c +10 −0
  14. net/netfilter/nft_compat.c +21 −3
  15. net/netfilter/nft_ct.c +18 −3
  16. net/netfilter/nft_synproxy.c +4 −5
  17. tools/testing/selftests/net/netfilter/conntrack_sctp_collision.sh +67 −22
  18. tools/testing/selftests/net/netfilter/nft_queue.sh +58 −8
include/linux/netfilter/x_tables.h+21−8
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 * @match: the match extension
1919 * @target: the target extension
2020 * @matchinfo: per-match data
21− * @targetinfo: per-target data
21+ * @targinfo: per-target data
2222 * @state: pointer to hook state this packet came from
2323 * @fragoff: packet is a fragment, this is the data offset
2424 * @thoff: position of transport header relative to skb->data
@@ -77,7 +77,9 @@ static inline u_int8_t xt_family(const struct xt_action_param *par) · 52 unmodified lines
7777 * @match: struct xt_match through which this function was invoked
7878 * @matchinfo: per-match data
7979 * @hook_mask: via which hooks the new rule is reachable
80− * Other fields as above.
80+ * @family: actual NFPROTO_* through which the function is invoked
81+ * (helpful when match->family == NFPROTO_UNSPEC)
82+ * @nft_compat: running from the nft compat layer if true
8183 */
8284 struct xt_mtchk_param {
8385 struct net *net;
@@ -91,8 +93,13 @@ struct xt_mtchk_param { · 7 unmodified lines
9193 };
9294
9395 /**
94− * struct xt_mdtor_param - match destructor parameters
95− * Fields as above.
96+ * struct xt_mtdtor_param - match destructor parameters
97+ *
98+ * @net: network namespace through which the check was invoked
99+ * @match: struct xt_match through which this function was invoked
100+ * @matchinfo: per-match data
101+ * @family: actual NFPROTO_* through which the function is invoked
102+ * (helpful when match->family == NFPROTO_UNSPEC)
96103 */
97104 struct xt_mtdtor_param {
98105 struct net *net;
@@ -105,10 +112,16 @@ struct xt_mtdtor_param { · 6 unmodified lines
105112 * struct xt_tgchk_param - parameters for target extensions'
106113 * checkentry functions
107114 *
115+ * @net: network namespace through which the check was invoked
116+ * @table: table the rule is tried to be inserted into
108117 * @entryinfo: the family-specific rule data
109118 * (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry)
110− *
111− * Other fields see above.
119+ * @target: the target extension
120+ * @targinfo: per-target data
121+ * @hook_mask: via which hooks the new rule is reachable
122+ * @family: actual NFPROTO_* through which the function is invoked
123+ * (helpful when match->family == NFPROTO_UNSPEC)
124+ * @nft_compat: running from the nft compat layer if true
112125 */
113126 struct xt_tgchk_param {
114127 struct net *net;
@@ -336,9 +349,9 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size); · 221 unmodified lines
336349 void xt_free_table_info(struct xt_table_info *info);
337350
338351 /**
339− * xt_recseq - recursive seqcount for netfilter use
352+ * var xt_recseq - recursive seqcount for netfilter use
340353 *
341− * Packet processing changes the seqcount only if no recursion happened
354+ * Packet processing changes the seqcount only if no recursion happened.
342355 * get_counters() can use read_seqcount_begin()/read_seqcount_retry(),
343356 * because we use the normal seqcount convention :
344357 * Low order bit set to 1 if a writer is active.
include/net/netfilter/nf_conntrack_expect.h+1−0
@@ -26,6 +26,7 @@ struct nf_conntrack_expect { · 25 unmodified lines
2626 possible_net_t net;
2727
2828 /* We expect this tuple, with the following mask */
29+ struct nf_conntrack_tuple master_tuple;
2930 struct nf_conntrack_tuple tuple;
3031 struct nf_conntrack_tuple_mask mask;
3132
include/net/netfilter/nf_conntrack_helper.h+4−0
@@ -114,6 +114,10 @@ int nf_conntrack_helpers_register(struct nf_conntrack_helper *, unsigned int, · 113 unmodified lines
114114 void nf_conntrack_helpers_unregister(struct nf_conntrack_helper **,
115115 unsigned int);
116116
117+#define nf_conntrack_helper_deprecated(name) \
118+ pr_warn("The %s conntrack helper is scheduled for removal.\n" \
119+ "Please contact the netfilter-devel mailing list if you still need this.\n", name)
120+
117121 struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
118122
119123 int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
net/netfilter/Kconfig+6−5
@@ -256,8 +256,7 @@ config NF_CONNTRACK_H323 · 255 unmodified lines
256256 To compile it as a module, choose M here. If unsure, say N.
257257
258258 config NF_CONNTRACK_IRC
259− tristate "IRC protocol support"
260− default m if NETFILTER_ADVANCED=n
259+ tristate "IRC DCC protocol support (obsolete)"
261260 help
262261 There is a commonly-used extension to IRC called
263262 Direct Client-to-Client Protocol (DCC). This enables users to send
@@ -267,6 +266,8 @@ config NF_CONNTRACK_IRC · 3 unmodified lines
267266 using NAT, this extension will enable you to send files and initiate
268267 chats. Note that you do NOT need this extension to get files or
269268 have others initiate chats, or everything else in IRC.
269+ DCC tracking behind NAT requires plaintext (unencrypted) IRC, so
270+ this helper is of limited use these days.
270271
271272 To compile it as a module, choose M here. If unsure, say N.
272273
@@ -308,17 +309,17 @@ config NF_CONNTRACK_SNMP · 35 unmodified lines
308309 To compile it as a module, choose M here. If unsure, say N.
309310
310311 config NF_CONNTRACK_PPTP
311− tristate "PPtP protocol support"
312+ tristate "PPtP protocol support (deprecated)"
312313 depends on NETFILTER_ADVANCED
313314 select NF_CT_PROTO_GRE
314315 help
315316 This module adds support for PPTP (Point to Point Tunnelling
316317 Protocol, RFC2637) connection tracking and NAT.
317318
318− If you are running PPTP sessions over a stateful firewall or NAT
319+ If you are still running PPTP sessions over a stateful firewall or NAT
319320 box, you may want to enable this feature.
320321
321− Please note that not all PPTP modes of operation are supported yet.
322+ Please note that not all PPTP modes of operation are supported.
322323 Specifically these limitations exist:
323324 - Blindly assumes that control connections are always established
324325 in PNS->PAC direction. This is a violation of RFC2637.
net/netfilter/nf_conncount.c+5−6
@@ -183,17 +183,16 @@ static int __nf_conncount_add(struct net *net, · 182 unmodified lines
183183 return -ENOENT;
184184
185185 if (ct && nf_ct_is_confirmed(ct)) {
186− /* local connections are confirmed in postrouting so confirmation
187− * might have happened before hitting connlimit
186+ /* Connection is confirmed but might still be in the setup phase.
187+ * Only skip the tracking if it is fully assured. This guarantees
188+ * that setup packets or retransmissions are properly counted and
189+ * deduplicated.
188190 */
189− if (skb->skb_iif != LOOPBACK_IFINDEX) {
191+ if (test_bit(IPS_ASSURED_BIT, &ct->status)) {
190192 err = -EEXIST;
191193 goto out_put;
192194 }
193195
194− /* this is likely a local connection, skip optimization to avoid
195− * adding duplicates from a 'packet train'
196− */
197196 goto check_connections;
198197 }
199198
net/netfilter/nf_conntrack_broadcast.c+1−0
@@ -62,6 +62,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, · 61 unmodified lines
6262 if (exp == NULL)
6363 goto out;
6464
65+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
6566 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
6667
6768 helper = rcu_dereference(help->helper);
net/netfilter/nf_conntrack_expect.c+10−2
@@ -355,6 +355,8 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, · 354 unmodified lines
355355 exp->tuple.src.l3num = family;
356356 exp->tuple.dst.protonum = proto;
357357
358+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
359+
358360 if (saddr) {
359361 memcpy(&exp->tuple.src.u3, saddr, len);
360362 if (sizeof(exp->tuple.src.u3) > len)
@@ -494,9 +496,15 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect, · 133 unmodified lines
494496 lockdep_is_held(&nf_conntrack_expect_lock));
495497 if (helper) {
496498 p = &helper->expect_policy[expect->class];
497− if (p->max_expected &&
498− master_help->expecting[expect->class] >= p->max_expected)
499+ if (master_help->expecting[expect->class] >= p->max_expected)
499500 evict_oldest_expect(master_help, expect, p);
501+ } else {
502+ const struct nf_conntrack_expect_policy default_exp_policy = {
503+ .max_expected = NF_CT_EXPECT_MAX_CNT,
504+ };
505+
506+ if (master_help->expecting[expect->class] >= default_exp_policy.max_expected)
507+ evict_oldest_expect(master_help, expect, &default_exp_policy);
500508 }
501509
502510 cnet = nf_ct_pernet(net);
net/netfilter/nf_conntrack_helper.c+7−2
@@ -374,8 +374,13 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me) · 373 unmodified lines
374374 if (!nf_ct_helper_hash)
375375 return -ENOENT;
376376
377− if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT)
378− return -EINVAL;
377+ for (i = 0; i <= me->expect_class_max; i++) {
378+ if (!me->expect_policy[i].max_expected)
379+ me->expect_policy[i].max_expected = NF_CT_EXPECT_MAX_CNT;
380+
381+ if (me->expect_policy[i].max_expected > NF_CT_EXPECT_MAX_CNT)
382+ return -EINVAL;
383+ }
379384
380385 mutex_lock(&nf_ct_helper_mutex);
381386 for (i = 0; i < nf_ct_helper_hsize; i++) {
net/netfilter/nf_conntrack_irc.c+2−0
@@ -262,6 +262,8 @@ static int __init nf_conntrack_irc_init(void) · 261 unmodified lines
262262 {
263263 int i, ret;
264264
265+ nf_conntrack_helper_deprecated(HELPER_NAME);
266+
265267 if (max_dcc_channels < 1) {
266268 pr_err("max_dcc_channels must not be zero\n");
267269 return -EINVAL;
net/netfilter/nf_conntrack_netlink.c+4−19
@@ -1953,19 +1953,6 @@ static int ctnetlink_change_helper(struct nf_conn *ct, · 1952 unmodified lines
19531953 return err;
19541954 }
19551955
1956− if (!strcmp(helpname, "") && help) {
1957− helper = rcu_dereference(help->helper);
1958− if (helper) {
1959− /* we had a helper before ... */
1960− nf_ct_remove_expectations(ct);
1961− RCU_INIT_POINTER(help->helper, NULL);
1962− if (refcount_dec_and_test(&helper->ct_refcnt))
1963− kfree_rcu(helper, rcu);
1964− }
1965− rcu_read_unlock();
1966− return 0;
1967− }
1968−
19691956 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
19701957 nf_ct_protonum(ct));
19711958 if (helper == NULL) {
@@ -3015,7 +3002,6 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, · 1043 unmodified lines
30153002 const struct nf_conntrack_expect *exp)
30163003 {
30173004 __s32 timeout = (__s32)(READ_ONCE(exp->timeout) - nfct_time_stamp) / HZ;
3018− struct nf_conn *master = exp->master;
30193005 struct nf_conntrack_helper *helper;
30203006 #if IS_ENABLED(CONFIG_NF_NAT)
30213007 struct nlattr *nest_parms;
@@ -3030,9 +3016,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, · 8 unmodified lines
30303016 goto nla_put_failure;
30313017 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
30323018 goto nla_put_failure;
3033− if (ctnetlink_exp_dump_tuple(skb,
3034− &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
3035− CTA_EXPECT_MASTER) < 0)
3019+ if (ctnetlink_exp_dump_tuple(skb, &exp->master_tuple, CTA_EXPECT_MASTER) < 0)
30363020 goto nla_put_failure;
30373021
30383022 #if IS_ENABLED(CONFIG_NF_NAT)
@@ -3045,9 +3029,9 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, · 6 unmodified lines
30453029 if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)))
30463030 goto nla_put_failure;
30473031
3048− nat_tuple.src.l3num = nf_ct_l3num(master);
3032+ nat_tuple.src.l3num = exp->master_tuple.src.l3num;
30493033 nat_tuple.src.u3 = exp->saved_addr;
3050− nat_tuple.dst.protonum = nf_ct_protonum(master);
3034+ nat_tuple.dst.protonum = exp->master_tuple.dst.protonum;
30513035 nat_tuple.src.u = exp->saved_proto;
30523036
30533037 if (ctnetlink_exp_dump_tuple(skb, &nat_tuple,
@@ -3589,6 +3573,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, · 535 unmodified lines
35893573 #endif
35903574 rcu_assign_pointer(exp->helper, helper);
35913575 rcu_assign_pointer(exp->assign_helper, assign_helper);
3576+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
35923577 exp->tuple = *tuple;
35933578 exp->mask.src.u3 = mask->src.u3;
35943579 exp->mask.src.u.all = mask->src.u.all;
net/netfilter/nf_conntrack_pptp.c+2−0
@@ -545,6 +545,8 @@ static int __init nf_conntrack_pptp_init(void) · 544 unmodified lines
545545
546546 pptp.destroy = gre_pptp_destroy_siblings;
547547
548+ nf_conntrack_helper_deprecated(pptp.name);
549+
548550 return nf_conntrack_helper_register(&pptp, &pptp_ptr);
549551 }
550552
net/netfilter/nf_flow_table_ip.c+5−3
@@ -326,8 +326,10 @@ static bool nf_flow_ip4_tunnel_proto(struct nf_flowtable_ctx *ctx, · 325 unmodified lines
326326 return false;
327327
328328 iph = (struct iphdr *)(skb_network_header(skb) + ctx->offset);
329− size = iph->ihl << 2;
329+ if (iph->ihl < 5)
330+ return false;
330331
332+ size = iph->ihl << 2;
331333 if (ip_is_fragment(iph) || unlikely(ip_has_options(size)))
332334 return false;
333335
@@ -335,9 +337,9 @@ static bool nf_flow_ip4_tunnel_proto(struct nf_flowtable_ctx *ctx, · 1 unmodified line
335337 return false;
336338
337339 if (iph->protocol == IPPROTO_IPIP) {
338− ctx->tun.proto = IPPROTO_IPIP;
340+ ctx->tun.proto = iph->protocol;
339341 ctx->tun.hdr_size = size;
340− ctx->offset += size;
342+ ctx->offset += ctx->tun.hdr_size;
341343 }
342344
343345 return true;
net/netfilter/nf_nat_core.c+10−0
@@ -1181,6 +1181,16 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, · 1180 unmodified lines
11811181 struct nf_hook_ops *nat_ops;
11821182 int i, ret;
11831183
1184+#ifndef MODULE
1185+ /* If nf_nat_core is built-in and nf_nat_init() fails, dependent
1186+ * modules like nft_chain_nat.ko may still call this function.
1187+ * However, nat_net would be invalid, likely pointing to some other
1188+ * per-net structure.
1189+ */
1190+ if (WARN_ON_ONCE(!nf_nat_hook))
1191+ return -EOPNOTSUPP;
1192+#endif
1193+
11841194 if (WARN_ON_ONCE(pf >= ARRAY_SIZE(nat_net->nat_proto_net)))
11851195 return -EINVAL;
11861196
net/netfilter/nft_compat.c+21−3
@@ -397,6 +397,22 @@ static int nft_target_validate(const struct nft_ctx *ctx, · 396 unmodified lines
397397 return 0;
398398 }
399399
400+static int nft_target_bridge_validate(const struct nft_ctx *ctx,
401+ const struct nft_expr *expr)
402+{
403+ struct xt_target *target = expr->ops->data;
404+
405+ /* Do not allow UNSPEC to stand-in for NFPROTO_BRIDGE
406+ * targets: they are incompatible. ebtables targets return
407+ * EBT_ACCEPT, DROP and so on which are not compatible with
408+ * NF_ACCEPT, NF_DROP and so on.
409+ */
410+ if (target->family != NFPROTO_BRIDGE)
411+ return -ENOENT;
412+
413+ return nft_target_validate(ctx, expr);
414+}
415+
400416 static void __nft_match_eval(const struct nft_expr *expr,
401417 struct nft_regs *regs,
402418 const struct nft_pktinfo *pkt,
@@ -932,13 +948,15 @@ nft_target_select_ops(const struct nft_ctx *ctx, · 529 unmodified lines
932948 ops->init = nft_target_init;
933949 ops->destroy = nft_target_destroy;
934950 ops->dump = nft_target_dump;
935− ops->validate = nft_target_validate;
936951 ops->data = target;
937952
938− if (family == NFPROTO_BRIDGE)
953+ if (family == NFPROTO_BRIDGE) {
939954 ops->eval = nft_target_eval_bridge;
940− else
955+ ops->validate = nft_target_bridge_validate;
956+ } else {
941957 ops->eval = nft_target_eval_xt;
958+ ops->validate = nft_target_validate;
959+ }
942960
943961 return ops;
944962 err:
net/netfilter/nft_ct.c+18−3
@@ -1215,11 +1215,23 @@ struct nft_ct_expect_obj { · 1214 unmodified lines
12151215 u32 timeout;
12161216 };
12171217
1218+static int nft_ct_expect_timeout_get(const struct nlattr *attr, u32 *val)
1219+{
1220+ unsigned long jiffies_val = msecs_to_jiffies(nla_get_u32(attr));
1221+
1222+ if (jiffies_val > UINT_MAX)
1223+ return -ERANGE;
1224+
1225+ *val = jiffies_val;
1226+ return 0;
1227+}
1228+
12181229 static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
12191230 const struct nlattr * const tb[],
12201231 struct nft_object *obj)
12211232 {
12221233 struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1234+ int err;
12231235
12241236 if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
12251237 !tb[NFTA_CT_EXPECT_DPORT] ||
@@ -1254,8 +1266,11 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, · 28 unmodified lines
12541266 return -EOPNOTSUPP;
12551267 }
12561268
1269+ err = nft_ct_expect_timeout_get(tb[NFTA_CT_EXPECT_TIMEOUT], &priv->timeout);
1270+ if (err)
1271+ return err;
1272+
12571273 priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]);
1258− priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
12591274 priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]);
12601275
12611276 return nf_ct_netns_get(ctx->net, ctx->family);
@@ -1275,7 +1290,7 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb, · 13 unmodified lines
12751290 if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
12761291 nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
12771292 nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
1278− nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout) ||
1293+ nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, jiffies_to_msecs(priv->timeout)) ||
12791294 nla_put_u8(skb, NFTA_CT_EXPECT_SIZE, priv->size))
12801295 return -1;
12811296
@@ -1325,7 +1340,7 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj, · 43 unmodified lines
13251340 &ct->tuplehash[!dir].tuple.src.u3,
13261341 &ct->tuplehash[!dir].tuple.dst.u3,
13271342 priv->l4proto, NULL, &priv->dport);
1328− exp->timeout += priv->timeout * HZ;
1343+ exp->timeout += priv->timeout;
13291344
13301345 if (nf_ct_expect_related(exp, 0) != 0)
13311346 regs->verdict.code = NF_DROP;
net/netfilter/nft_synproxy.c+4−5
@@ -24,14 +24,13 @@ static const struct nla_policy nft_synproxy_policy[NFTA_SYNPROXY_MAX + 1] = { · 23 unmodified lines
2424 static void nft_synproxy_tcp_options(struct synproxy_options *opts,
2525 const struct tcphdr *tcp,
2626 struct synproxy_net *snet,
27− struct nf_synproxy_info *info,
28− const struct nft_synproxy *priv)
27+ struct nf_synproxy_info *info)
2928 {
3029 this_cpu_inc(snet->stats->syn_received);
3130 if (tcp->ece && tcp->cwr)
3231 opts->options |= NF_SYNPROXY_OPT_ECN;
3332
34− opts->options &= priv->info.options;
33+ opts->options &= info->options;
3534 opts->mss_encode = opts->mss_option;
3635 opts->mss_option = info->mss;
3736 if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP)
@@ -56,7 +55,7 @@ static void nft_synproxy_eval_v4(const struct nft_synproxy *priv, · 18 unmodified lines
5655
5756 if (tcp->syn) {
5857 /* Initial SYN from client */
59− nft_synproxy_tcp_options(opts, tcp, snet, &info, priv);
58+ nft_synproxy_tcp_options(opts, tcp, snet, &info);
6059 synproxy_send_client_synack(net, skb, tcp, opts);
6160 consume_skb(skb);
6261 regs->verdict.code = NF_STOLEN;
@@ -87,7 +86,7 @@ static void nft_synproxy_eval_v6(const struct nft_synproxy *priv, · 24 unmodified lines
8786
8887 if (tcp->syn) {
8988 /* Initial SYN from client */
90− nft_synproxy_tcp_options(opts, tcp, snet, &info, priv);
89+ nft_synproxy_tcp_options(opts, tcp, snet, &info);
9190 synproxy_send_client_synack_ipv6(net, skb, tcp, opts);
9291 consume_skb(skb);
9392 regs->verdict.code = NF_STOLEN;
tools/testing/selftests/net/netfilter/conntrack_sctp_collision.sh+67−22
@@ -2,18 +2,32 @@ · 1 unmodified line
22 # SPDX-License-Identifier: GPL-2.0
33 #
44 # Testing For SCTP COLLISION SCENARIO as Below:
5−#
5+# 1. Stale INIT_ACK capture:
66 # 14:35:47.655279 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT] [init tag: 2017837359]
77 # 14:35:48.353250 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT] [init tag: 1187206187]
88 # 14:35:48.353275 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT ACK] [init tag: 2017837359]
99 # 14:35:48.353283 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [COOKIE ECHO]
1010 # 14:35:48.353977 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [COOKIE ACK]
1111 # 14:35:48.855335 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT ACK] [init tag: 164579970]
12+# (Delayed)
13+#
14+# 2. Stale INIT capture:
15+# 14:35:48.353250 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT] [init tag: 1187206187]
16+# 14:35:48.353275 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT ACK] [init tag: 2017837359]
17+# 14:35:48.353283 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [COOKIE ECHO]
18+# 14:35:48.353977 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [COOKIE ACK]
19+# 14:35:47.655279 IP CLIENT_IP.PORT > SERVER_IP.PORT: sctp (1) [INIT] [init tag: 2017837359]
20+# (Delayed)
21+# 14:35:48.855335 IP SERVER_IP.PORT > CLIENT_IP.PORT: sctp (1) [INIT ACK] [init tag: 164579970]
1222 #
1323 # TOPO: SERVER_NS (link0)<--->(link1) ROUTER_NS (link2)<--->(link3) CLIENT_NS
1424
1525 source lib.sh
1626
27+checktool "nft --version" "run test without nft"
28+checktool "tc -h" "run test without tc"
29+checktool "modprobe -q sctp" "load sctp module"
30+
1731 CLIENT_IP="198.51.200.1"
1832 CLIENT_PORT=1234
1933
@@ -24,7 +38,8 @@ CLIENT_GW="198.51.200.2" · 4 unmodified lines
2438 SERVER_GW="198.51.100.2"
2539
2640 # setup the topo
27−setup() {
41+topo_setup() {
42+ # setup_ns cleans up existing net namespaces first.
2843 setup_ns CLIENT_NS SERVER_NS ROUTER_NS
2944 ip -n "$SERVER_NS" link add link0 type veth peer name link1 netns "$ROUTER_NS"
3045 ip -n "$CLIENT_NS" link add link3 type veth peer name link2 netns "$ROUTER_NS"
@@ -38,35 +53,53 @@ setup() { · 7 unmodified lines
3853 ip -n "$ROUTER_NS" addr add $SERVER_GW/24 dev link1
3954 ip -n "$ROUTER_NS" addr add $CLIENT_GW/24 dev link2
4055 ip net exec "$ROUTER_NS" sysctl -wq net.ipv4.ip_forward=1
56+ sysctl -wq net.netfilter.nf_log_all_netns=1
4157
4258 ip -n "$CLIENT_NS" link set link3 up
4359 ip -n "$CLIENT_NS" addr add $CLIENT_IP/24 dev link3
4460 ip -n "$CLIENT_NS" route add $SERVER_IP dev link3 via $CLIENT_GW
61+}
62+
63+conf_delay()
64+{
65+ # simulate the delay on OVS upcall by setting up a delay for INIT_ACK/INIT with
66+ local ns=$1
67+ local link=$2
68+ local chunk_type=$3
4569
46− # simulate the delay on OVS upcall by setting up a delay for INIT_ACK with
47− # tc on $SERVER_NS side
48− tc -n "$SERVER_NS" qdisc add dev link0 root handle 1: htb r2q 64
49− tc -n "$SERVER_NS" class add dev link0 parent 1: classid 1:1 htb rate 100mbit
50− tc -n "$SERVER_NS" filter add dev link0 parent 1: protocol ip u32 match ip protocol 132 \
51− 0xff match u8 2 0xff at 32 flowid 1:1
52− if ! tc -n "$SERVER_NS" qdisc add dev link0 parent 1:1 handle 10: netem delay 1200ms; then
70+ # use a smaller number for assoc's max_retrans to reproduce the issue
71+ ip net exec "$CLIENT_NS" sysctl -wq net.sctp.association_max_retrans=3
72+
73+ tc -n "$ns" qdisc add dev "$link" root handle 1: htb r2q 64
74+ tc -n "$ns" class add dev "$link" parent 1: classid 1:1 htb rate 100mbit
75+ tc -n "$ns" filter add dev "$link" parent 1: protocol ip \
76+ u32 match ip protocol 132 0xff match u8 "$chunk_type" 0xff at 32 flowid 1:1
77+ if ! tc -n "$ns" qdisc add dev "$link" parent 1:1 handle 10: netem delay 1200ms; then
5378 echo "SKIP: Cannot add netem qdisc"
54− exit $ksft_skip
79+ return $ksft_skip
5580 fi
5681
5782 # simulate the ctstate check on OVS nf_conntrack
58− ip net exec "$ROUTER_NS" iptables -A FORWARD -m state --state INVALID,UNTRACKED -j DROP
59− ip net exec "$ROUTER_NS" iptables -A INPUT -p sctp -j DROP
60−
61− # use a smaller number for assoc's max_retrans to reproduce the issue
62− modprobe -q sctp
63− ip net exec "$CLIENT_NS" sysctl -wq net.sctp.association_max_retrans=3
83+ ip net exec "$ROUTER_NS" nft -f - <<-EOF
84+ table ip t {
85+ chain forward {
86+ type filter hook forward priority filter; policy accept;
87+ meta l4proto icmp counter accept
88+ ct state new counter accept
89+ ct state established,related counter accept
90+ ct state invalid log flags all counter drop comment \
91+ "Expect to drop stale INIT/INIT_ACK chunks"
92+ counter
93+ }
94+ }
95+ EOF
96+ return 0
6497 }
6598
6699 cleanup() {
67− ip net exec "$CLIENT_NS" pkill sctp_collision >/dev/null 2>&1
68− ip net exec "$SERVER_NS" pkill sctp_collision >/dev/null 2>&1
100+ # cleanup_all_ns terminates running processes in the namespaces.
69101 cleanup_all_ns
102+ sysctl -wq net.netfilter.nf_log_all_netns=0
70103 }
71104
72105 do_test() {
@@ -81,7 +114,19 @@ do_test() { · 8 unmodified lines
81114
82115 # run the test case
83116 trap cleanup EXIT
84−setup && \
85−echo "Test for SCTP Collision in nf_conntrack:" && \
86−do_test && echo "PASS!"
87−exit $?
117+
118+echo "Test for SCTP INIT_ACK Collision in nf_conntrack:"
119+topo_setup || exit $?
120+conf_delay $SERVER_NS link0 2 || exit $?
121+
122+if ! do_test; then
123+ exit $ksft_fail
124+fi
125+
126+echo "Test for SCTP INIT Collision in nf_conntrack:"
127+topo_setup || exit $?
128+conf_delay $CLIENT_NS link3 1 || exit $?
129+
130+if ! do_test; then
131+ exit $ksft_fail
132+fi
tools/testing/selftests/net/netfilter/nft_queue.sh+58−8
@@ -85,11 +85,12 @@ ip -net "$ns3" route add default via 10.0.3.1 · 84 unmodified lines
8585 ip -net "$ns3" route add default via dead:3::1
8686
8787 load_ruleset() {
88− local name=$1
89− local prio=$2
88+ local family=$1
89+ local name=$2
90+ local prio=$3
9091
9192 ip netns exec "$nsrouter" nft -f /dev/stdin <<EOF
92−table inet $name {
93+table $family $name {
9394 chain nfq {
9495 ip protocol icmp queue bypass
9596 icmpv6 type { "echo-request", "echo-reply" } queue num 1 bypass
@@ -228,6 +229,7 @@ nf_queue_wait() · 132 unmodified lines
228229 test_queue()
229230 {
230231 local expected="$1"
232+ local family="$2"
231233 local last=""
232234
233235 # spawn nf_queue listeners
@@ -255,11 +257,13 @@ test_queue() · 21 unmodified lines
255257 if [ x"$last" != x"$expected packets total" ]; then
256258 echo "FAIL: Expected $expected packets total, but got $last" 1>&2
257259 ip netns exec "$nsrouter" nft list ruleset
260+ echo -n "$TMPFILE0: ";cat "$TMPFILE0"
261+ echo -n "$TMPFILE1: ";cat "$TMPFILE1"
258262 exit 1
259263 fi
260264 done
261265
262− echo "PASS: Expected and received $last"
266+ echo "PASS: Expected and received $last ($family)"
263267 }
264268
265269 listener_ready()
@@ -400,6 +404,8 @@ EOF · 134 unmodified lines
400404
401405 kill "$nfqpid"
402406 echo "PASS: icmp+nfqueue via vrf"
407+ ip -net "$ns1" link del tvrf
408+ ip netns exec "$ns1" nft flush ruleset
403409 }
404410
405411 sctp_listener_ready()
@@ -814,12 +820,53 @@ EOF · 408 unmodified lines
814820 check_tainted "queue program exiting while packets queued"
815821 }
816822
823+test_queue_bridge()
824+{
825+ ip -net "$nsrouter" addr flush dev veth0
826+ ip -net "$nsrouter" addr flush dev veth1
827+
828+ ip -net "$nsrouter" link add br0 type bridge
829+ ip -net "$nsrouter" link set veth0 master br0
830+ ip -net "$nsrouter" link set veth1 master br0
831+
832+ ip -net "$nsrouter" link set br0 up
833+
834+ ip -net "$nsrouter" addr add 10.0.2.1/16 dev br0
835+ ip -net "$nsrouter" addr add dead:2::1/64 dev br0 nodad
836+
837+ ip -net "$ns1" addr flush dev eth0
838+ ip -net "$ns2" addr flush dev eth0
839+
840+ ip -net "$ns1" addr add 10.0.1.1/16 dev eth0
841+ ip -net "$ns1" addr add dead:2::2/64 dev eth0 nodad
842+
843+ ip -net "$ns2" addr add 10.0.2.99/16 dev eth0
844+ ip -net "$ns2" addr add dead:2::99/64 dev eth0 nodad
845+
846+ ip netns exec "$nsrouter" nft flush ruleset
847+
848+ ip netns exec "$nsrouter" sysctl net.ipv6.conf.all.forwarding=0 > /dev/null
849+ ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth0.forwarding=0 > /dev/null
850+ ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth1.forwarding=0 > /dev/null
851+
852+ if ! test_ping;then
853+ echo "FAIL: netns bridge connectivity" 1>&2
854+ exit $ret
855+ fi
856+
857+ load_ruleset "bridge" "filter" 10
858+ test_queue 10 "bridge"
859+
860+ load_ruleset "bridge" "filter2" 20
861+ test_queue 20 "bridge"
862+}
863+
817864 ip netns exec "$nsrouter" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
818865 ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
819866 ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
820867 ip netns exec "$nsrouter" sysctl net.ipv4.conf.veth2.forwarding=1 > /dev/null
821868
822−load_ruleset "filter" 0
869+load_ruleset "inet" "filter" 0
823870
824871 if test_ping; then
825872 # queue bypass works (rules were skipped, no listener)
@@ -842,11 +889,11 @@ load_counter_ruleset 10 · 16 unmodified lines
842889 # 1x icmp prerouting,forward,postrouting -> 3 queue events (6 incl. reply).
843890 # 1x icmp prerouting,input,output postrouting -> 4 queue events incl. reply.
844891 # so we expect that userspace program receives 10 packets.
845−test_queue 10
892+test_queue 10 "inet"
846893
847894 # same. We queue to a second program as well.
848−load_ruleset "filter2" 20
849−test_queue 20
895+load_ruleset "inet" "filter2" 20
896+test_queue 20 "inet"
850897 ip netns exec "$ns1" nft flush ruleset
851898
852899 test_tcp_forward
@@ -863,4 +910,7 @@ test_queue_stress · 10 unmodified lines
863910 test_icmp_vrf
864911 test_queue_removal
865912
913+# turns router into a bridge
914+test_queue_bridge
915+
866916 exit $ret