Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jan 9, 2022
2 parents 9f3248c + 4a80e02 commit 77bbcb6
Show file tree
Hide file tree
Showing 44 changed files with 887 additions and 404 deletions.
10 changes: 5 additions & 5 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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;

Expand All @@ -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
Expand Down
10 changes: 6 additions & 4 deletions include/linux/netfilter/nf_conntrack_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 */
2 changes: 1 addition & 1 deletion include/linux/netfilter_netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
11 changes: 8 additions & 3 deletions include/net/netfilter/nf_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
40 changes: 35 additions & 5 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ struct nft_data {
};
} __attribute__((aligned(__alignof__(u64))));

#define NFT_REG32_NUM 20

/**
* struct nft_regs - nf_tables register set
*
Expand All @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
*
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions include/net/netfilter/nf_tables_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

extern struct nft_expr_type nft_imm_type;
extern struct nft_expr_type nft_cmp_type;
extern struct nft_expr_type nft_counter_type;
extern struct nft_expr_type nft_lookup_type;
extern struct nft_expr_type nft_bitwise_type;
extern struct nft_expr_type nft_byteorder_type;
Expand All @@ -21,6 +22,7 @@ extern struct nft_expr_type nft_last_type;
#ifdef CONFIG_NETWORK_SECMARK
extern struct nft_object_type nft_secmark_obj_type;
#endif
extern struct nft_object_type nft_counter_obj_type;

int nf_tables_core_module_init(void);
void nf_tables_core_module_exit(void);
Expand Down Expand Up @@ -120,6 +122,8 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
bool nft_pipapo_avx2_lookup(const struct net *net, const struct nft_set *set,
const u32 *key, const struct nft_set_ext **ext);

void nft_counter_init_seqcount(void);

struct nft_expr;
struct nft_regs;
struct nft_pktinfo;
Expand All @@ -143,4 +147,6 @@ void nft_dynset_eval(const struct nft_expr *expr,
struct nft_regs *regs, const struct nft_pktinfo *pkt);
void nft_rt_get_eval(const struct nft_expr *expr,
struct nft_regs *regs, const struct nft_pktinfo *pkt);
void nft_counter_eval(const struct nft_expr *expr, struct nft_regs *regs,
const struct nft_pktinfo *pkt);
#endif /* _NET_NF_TABLES_CORE_H */
20 changes: 20 additions & 0 deletions net/bridge/netfilter/nft_meta_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,33 @@ static const struct nft_expr_ops nft_meta_bridge_get_ops = {
.dump = nft_meta_get_dump,
};

static bool nft_meta_bridge_set_reduce(struct nft_regs_track *track,
const struct nft_expr *expr)
{
int i;

for (i = 0; i < NFT_REG32_NUM; i++) {
if (!track->regs[i].selector)
continue;

if (track->regs[i].selector->ops != &nft_meta_bridge_get_ops)
continue;

track->regs[i].selector = NULL;
track->regs[i].bitwise = NULL;
}

return false;
}

static const struct nft_expr_ops nft_meta_bridge_set_ops = {
.type = &nft_meta_bridge_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
.eval = nft_meta_set_eval,
.init = nft_meta_set_init,
.destroy = nft_meta_set_destroy,
.dump = nft_meta_set_dump,
.reduce = nft_meta_bridge_set_reduce,
.validate = nft_meta_set_validate,
};

Expand Down
8 changes: 2 additions & 6 deletions net/ipv4/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,8 @@ config NF_TABLES_ARP
endif # NF_TABLES

config NF_FLOW_TABLE_IPV4
tristate "Netfilter flow table IPv4 module"
depends on NF_FLOW_TABLE
help
This option adds the flow table IPv4 support.

To compile it as a module, choose M here.
tristate
select NF_FLOW_TABLE_INET

config NF_DUP_IPV4
tristate "Netfilter IPv4 packet duplication to alternate destination"
Expand Down
3 changes: 0 additions & 3 deletions net/ipv4/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o

# flow table support
obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o

# generic IP tables
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o

Expand Down
37 changes: 0 additions & 37 deletions net/ipv4/netfilter/nf_flow_table_ipv4.c
Original file line number Diff line number Diff line change
@@ -1,37 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_tables.h>

static struct nf_flowtable_type flowtable_ipv4 = {
.family = NFPROTO_IPV4,
.init = nf_flow_table_init,
.setup = nf_flow_table_offload_setup,
.action = nf_flow_rule_route_ipv4,
.free = nf_flow_table_free,
.hook = nf_flow_offload_ip_hook,
.owner = THIS_MODULE,
};

static int __init nf_flow_ipv4_module_init(void)
{
nft_register_flowtable_type(&flowtable_ipv4);

return 0;
}

static void __exit nf_flow_ipv4_module_exit(void)
{
nft_unregister_flowtable_type(&flowtable_ipv4);
}

module_init(nf_flow_ipv4_module_init);
module_exit(nf_flow_ipv4_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <[email protected]>");
MODULE_ALIAS_NF_FLOWTABLE(AF_INET);
MODULE_DESCRIPTION("Netfilter flow table support");
8 changes: 2 additions & 6 deletions net/ipv6/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ endif # NF_TABLES_IPV6
endif # NF_TABLES

config NF_FLOW_TABLE_IPV6
tristate "Netfilter flow table IPv6 module"
depends on NF_FLOW_TABLE
help
This option adds the flow table IPv6 support.

To compile it as a module, choose M here.
tristate
select NF_FLOW_TABLE_INET

config NF_DUP_IPV6
tristate "Netfilter IPv6 packet duplication to alternate destination"
Expand Down
Loading

0 comments on commit 77bbcb6

Please sign in to comment.