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

====================
Netfilter updates for net-next

The following patchset contains Netfilter updates for net-next. This
includes one patch to update ovs and act_ct to use nf_ct_put() instead
of nf_conntrack_put().

1) Add netns_tracker to nfnetlink_log and masquerade, from Eric Dumazet.

2) Remove redundant rcu read-size lock in nf_tables packet path.

3) Replace BUG() by WARN_ON_ONCE() in nft_payload.

4) Consolidate rule verdict tracing.

5) Replace WARN_ON() by WARN_ON_ONCE() in nf_tables core.

6) Make counter support built-in in nf_tables.

7) Add new field to conntrack object to identify locally generated
   traffic, from Florian Westphal.

8) Prevent NAT from shadowing well-known ports, from Florian Westphal.

9) Merge nf_flow_table_{ipv4,ipv6} into nf_flow_table_inet, also from
   Florian.

10) Remove redundant pointer in nft_pipapo AVX2 support, from Colin Ian King.

11) Replace opencoded max() in conntrack, from Jiapeng Chong.

12) Update conntrack to use refcount_t API, from Florian Westphal.

13) Move ip_ct_attach indirection into the nf_ct_hook structure.

14) Constify several pointer object in the netfilter codebase,
    from Florian Westphal.

15) Tree-wide replacement of nf_conntrack_put() by nf_ct_put(), also
    from Florian.

16) Fix egress splat due to incorrect rcu notation, from Florian.

17) Move stateful fields of connlimit, last, quota, numgen and limit
    out of the expression data area.

18) Build a blob to represent the ruleset in nf_tables, this is a
    requirement of the new register tracking infrastructure.

19) Add NFT_REG32_NUM to define the maximum number of 32-bit registers.

20) Add register tracking infrastructure to skip redundant
    store-to-register operations, this includes support for payload,
    meta and bitwise expresssions.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next: (32 commits)
  netfilter: nft_meta: cancel register tracking after meta update
  netfilter: nft_payload: cancel register tracking after payload update
  netfilter: nft_bitwise: track register operations
  netfilter: nft_meta: track register operations
  netfilter: nft_payload: track register operations
  netfilter: nf_tables: add register tracking infrastructure
  netfilter: nf_tables: add NFT_REG32_NUM
  netfilter: nf_tables: add rule blob layout
  netfilter: nft_limit: move stateful fields out of expression data
  netfilter: nft_limit: rename stateful structure
  netfilter: nft_numgen: move stateful fields out of expression data
  netfilter: nft_quota: move stateful fields out of expression data
  netfilter: nft_last: move stateful fields out of expression data
  netfilter: nft_connlimit: move stateful fields out of expression data
  netfilter: egress: avoid a lockdep splat
  net: prefer nf_ct_put instead of nf_conntrack_put
  netfilter: conntrack: avoid useless indirection during conntrack destruction
  netfilter: make function op structures const
  netfilter: core: move ip_ct_attach indirection to struct nf_ct_hook
  netfilter: conntrack: convert to refcount_t api
  ...
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 9f3248c9 4a80e026
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -381,13 +381,13 @@ struct nf_nat_hook {
				  enum ip_conntrack_dir dir);
};

extern struct nf_nat_hook __rcu *nf_nat_hook;
extern const struct nf_nat_hook __rcu *nf_nat_hook;

static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
{
#if IS_ENABLED(CONFIG_NF_NAT)
	struct nf_nat_hook *nat_hook;
	const struct nf_nat_hook *nat_hook;

	rcu_read_lock();
	nat_hook = rcu_dereference(nf_nat_hook);
@@ -440,7 +440,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <linux/netfilter/nf_conntrack_zones_common.h>

extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
struct nf_conntrack_tuple;
bool nf_ct_get_tuple_skb(struct nf_conntrack_tuple *dst_tuple,
@@ -463,8 +462,9 @@ struct nf_ct_hook {
	void (*destroy)(struct nf_conntrack *);
	bool (*get_tuple_skb)(struct nf_conntrack_tuple *,
			      const struct sk_buff *);
	void (*attach)(struct sk_buff *nskb, const struct sk_buff *skb);
};
extern struct nf_ct_hook __rcu *nf_ct_hook;
extern const struct nf_ct_hook __rcu *nf_ct_hook;

struct nlattr;

@@ -479,7 +479,7 @@ struct nfnl_ct_hook {
	void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
			   enum ip_conntrack_info ctinfo, s32 off);
};
extern struct nfnl_ct_hook __rcu *nfnl_ct_hook;
extern const struct nfnl_ct_hook __rcu *nfnl_ct_hook;

/**
 * nf_skb_duplicated - TEE target has sent a packet
+6 −4
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
#ifndef _NF_CONNTRACK_COMMON_H
#define _NF_CONNTRACK_COMMON_H

#include <linux/atomic.h>
#include <linux/refcount.h>
#include <uapi/linux/netfilter/nf_conntrack_common.h>

struct ip_conntrack_stat {
@@ -25,19 +25,21 @@ struct ip_conntrack_stat {
#define NFCT_PTRMASK	~(NFCT_INFOMASK)

struct nf_conntrack {
	atomic_t use;
	refcount_t use;
};

void nf_conntrack_destroy(struct nf_conntrack *nfct);

/* like nf_ct_put, but without module dependency on nf_conntrack */
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{
	if (nfct && atomic_dec_and_test(&nfct->use))
	if (nfct && refcount_dec_and_test(&nfct->use))
		nf_conntrack_destroy(nfct);
}
static inline void nf_conntrack_get(struct nf_conntrack *nfct)
{
	if (nfct)
		atomic_inc(&nfct->use);
		refcount_inc(&nfct->use);
}

#endif /* _NF_CONNTRACK_COMMON_H */
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ static inline struct sk_buff *nf_hook_egress(struct sk_buff *skb, int *rc,
		return skb;
#endif

	e = rcu_dereference(dev->nf_hooks_egress);
	e = rcu_dereference_check(dev->nf_hooks_egress, rcu_read_lock_bh_held());
	if (!e)
		return skb;

+8 −3
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ struct nf_conn {
	 * Hint, SKB address this struct and refcnt via skb->_nfct and
	 * helpers nf_conntrack_get() and nf_conntrack_put().
	 * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
	 * except that the latter uses internal indirection and does not
	 * result in a conntrack module dependency.
	 * beware nf_ct_get() is different and don't inc refcnt.
	 */
	struct nf_conntrack ct_general;
@@ -95,6 +97,7 @@ struct nf_conn {
	unsigned long status;

	u16		cpu;
	u16		local_origin:1;
	possible_net_t ct_net;

#if IS_ENABLED(CONFIG_NF_NAT)
@@ -169,11 +172,13 @@ nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
	return (struct nf_conn *)(nfct & NFCT_PTRMASK);
}

void nf_ct_destroy(struct nf_conntrack *nfct);

/* decrement reference count on a conntrack */
static inline void nf_ct_put(struct nf_conn *ct)
{
	WARN_ON(!ct);
	nf_conntrack_put(&ct->ct_general);
	if (ct && refcount_dec_and_test(&ct->ct_general.use))
		nf_ct_destroy(&ct->ct_general);
}

/* Protocol module loading */
@@ -278,7 +283,7 @@ static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
{
	s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;

	return timeout > 0 ? timeout : 0;
	return max(timeout, 0);
}

static inline bool nf_ct_is_expired(const struct nf_conn *ct)
+35 −5
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ struct nft_data {
	};
} __attribute__((aligned(__alignof__(u64))));

#define NFT_REG32_NUM		20

/**
 *	struct nft_regs - nf_tables register set
 *
@@ -115,11 +117,21 @@ struct nft_data {
 */
struct nft_regs {
	union {
		u32			data[20];
		u32			data[NFT_REG32_NUM];
		struct nft_verdict	verdict;
	};
};

struct nft_regs_track {
	struct {
		const struct nft_expr		*selector;
		const struct nft_expr		*bitwise;
	} regs[NFT_REG32_NUM];

	const struct nft_expr			*cur;
	const struct nft_expr			*last;
};

/* Store/load an u8, u16 or u64 integer to/from the u32 data register.
 *
 * Note, when using concatenations, register allocation happens at 32-bit
@@ -346,6 +358,8 @@ int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src);
void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
		  const struct nft_expr *expr);
bool nft_expr_reduce_bitwise(struct nft_regs_track *track,
			     const struct nft_expr *expr);

struct nft_set_ext;

@@ -884,6 +898,8 @@ struct nft_expr_ops {
	int				(*validate)(const struct nft_ctx *ctx,
						    const struct nft_expr *expr,
						    const struct nft_data **data);
	bool				(*reduce)(struct nft_regs_track *track,
						  const struct nft_expr *expr);
	bool				(*gc)(struct net *net,
					      const struct nft_expr *expr);
	int				(*offload)(struct nft_offload_ctx *ctx,
@@ -974,6 +990,20 @@ static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,

#define NFT_CHAIN_POLICY_UNSET		U8_MAX

struct nft_rule_dp {
	u64				is_last:1,
					dlen:12,
					handle:42;	/* for tracing */
	unsigned char			data[]
		__attribute__((aligned(__alignof__(struct nft_expr))));
};

struct nft_rule_blob {
	unsigned long			size;
	unsigned char			data[]
		__attribute__((aligned(__alignof__(struct nft_rule_dp))));
};

/**
 *	struct nft_chain - nf_tables chain
 *
@@ -987,8 +1017,8 @@ static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
 *	@name: name of the chain
 */
struct nft_chain {
	struct nft_rule			*__rcu *rules_gen_0;
	struct nft_rule			*__rcu *rules_gen_1;
	struct nft_rule_blob		__rcu *blob_gen_0;
	struct nft_rule_blob		__rcu *blob_gen_1;
	struct list_head		rules;
	struct list_head		list;
	struct rhlist_head		rhlhead;
@@ -1003,7 +1033,7 @@ struct nft_chain {
	u8				*udata;

	/* Only used during control plane commit phase: */
	struct nft_rule			**rules_next;
	struct nft_rule_blob		*blob_next;
};

int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
@@ -1321,7 +1351,7 @@ struct nft_traceinfo {
	const struct nft_pktinfo	*pkt;
	const struct nft_base_chain	*basechain;
	const struct nft_chain		*chain;
	const struct nft_rule		*rule;
	const struct nft_rule_dp	*rule;
	const struct nft_verdict	*verdict;
	enum nft_trace_types		type;
	bool				packet_dumped;
Loading