Commit fd31cb0c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

1) Fix bogus compilter warning in nfnetlink_queue, from Florian Westphal.

2) Don't run conntrack on vrf with !dflt qdisc, from Nicolas Dichtel.

3) Fix nft_pipapo bucket load in AVX2 lookup routine for six 8-bit
   groups, from Stefano Brivio.

4) Break rule evaluation on malformed TCP options.

5) Use socat instead of nc in selftests/netfilter/nft_zones_many.sh,
   also from Florian

6) Fix KCSAN data-race in conntrack timeout updates, from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf:
  netfilter: conntrack: annotate data-races around ct->timeout
  selftests: netfilter: switch zone stress to socat
  netfilter: nft_exthdr: break evaluation if setting TCP option fails
  selftests: netfilter: Add correctness test for mac,net set type
  nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups
  vrf: don't run conntrack on vrf with !dflt qdisc
  netfilter: nfnetlink_queue: silence bogus compiler warning
====================

Link: https://lore.kernel.org/r/20211209000847.102598-1-pablo@netfilter.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b5b6b6ba 802a7dc5
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -770,8 +770,6 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,

	skb->dev = vrf_dev;

	vrf_nf_set_untracked(skb);

	err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk,
		      skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);

@@ -792,6 +790,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
	if (rt6_need_strict(&ipv6_hdr(skb)->daddr))
		return skb;

	vrf_nf_set_untracked(skb);

	if (qdisc_tx_is_default(vrf_dev) ||
	    IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
		return vrf_ip6_out_direct(vrf_dev, sk, skb);
@@ -1000,8 +1000,6 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,

	skb->dev = vrf_dev;

	vrf_nf_set_untracked(skb);

	err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk,
		      skb, NULL, vrf_dev, vrf_ip_out_direct_finish);

@@ -1023,6 +1021,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
	    ipv4_is_lbcast(ip_hdr(skb)->daddr))
		return skb;

	vrf_nf_set_untracked(skb);

	if (qdisc_tx_is_default(vrf_dev) ||
	    IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
		return vrf_ip_out_direct(vrf_dev, sk, skb);
+3 −3
Original line number Diff line number Diff line
@@ -276,14 +276,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
/* jiffies until ct expires, 0 if already expired */
static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
{
	s32 timeout = ct->timeout - nfct_time_stamp;
	s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;

	return timeout > 0 ? timeout : 0;
}

static inline bool nf_ct_is_expired(const struct nf_conn *ct)
{
	return (__s32)(ct->timeout - nfct_time_stamp) <= 0;
	return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0;
}

/* use after obtaining a reference count */
@@ -302,7 +302,7 @@ static inline bool nf_ct_should_gc(const struct nf_conn *ct)
static inline void nf_ct_offload_timeout(struct nf_conn *ct)
{
	if (nf_ct_expires(ct) < NF_CT_DAY / 2)
		ct->timeout = nfct_time_stamp + NF_CT_DAY;
		WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
}

struct kernel_param;
+3 −3
Original line number Diff line number Diff line
@@ -684,7 +684,7 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)

	tstamp = nf_conn_tstamp_find(ct);
	if (tstamp) {
		s32 timeout = ct->timeout - nfct_time_stamp;
		s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;

		tstamp->stop = ktime_get_real_ns();
		if (timeout < 0)
@@ -1036,7 +1036,7 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx)
	}

	/* We want the clashing entry to go away real soon: 1 second timeout. */
	loser_ct->timeout = nfct_time_stamp + HZ;
	WRITE_ONCE(loser_ct->timeout, nfct_time_stamp + HZ);

	/* IPS_NAT_CLASH removes the entry automatically on the first
	 * reply.  Also prevents UDP tracker from moving the entry to
@@ -1560,7 +1560,7 @@ __nf_conntrack_alloc(struct net *net,
	/* save hash for reusing when confirming */
	*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
	ct->status = 0;
	ct->timeout = 0;
	WRITE_ONCE(ct->timeout, 0);
	write_pnet(&ct->ct_net, net);
	memset(&ct->__nfct_init_offset, 0,
	       offsetof(struct nf_conn, proto) -
+1 −1
Original line number Diff line number Diff line
@@ -1998,7 +1998,7 @@ static int ctnetlink_change_timeout(struct nf_conn *ct,

	if (timeout > INT_MAX)
		timeout = INT_MAX;
	ct->timeout = nfct_time_stamp + (u32)timeout;
	WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);

	if (test_bit(IPS_DYING_BIT, &ct->status))
		return -ETIME;
+2 −2
Original line number Diff line number Diff line
@@ -201,8 +201,8 @@ static void flow_offload_fixup_ct_timeout(struct nf_conn *ct)
	if (timeout < 0)
		timeout = 0;

	if (nf_flow_timeout_delta(ct->timeout) > (__s32)timeout)
		ct->timeout = nfct_time_stamp + timeout;
	if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
		WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout);
}

static void flow_offload_fixup_ct_state(struct nf_conn *ct)
Loading