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 your net-next tree.
Basically, nf_tables updates to add the set extension infrastructure and finish
the transaction for sets from Patrick McHardy. More specifically, they are:

1) Move netns to basechain and use recently added possible_net_t, from
   Patrick McHardy.

2) Use LOGLEVEL_<FOO> from nf_log infrastructure, from Joe Perches.

3) Restore nf_log_trace that was accidentally removed during conflict
   resolution.

4) nft_queue does not depend on NETFILTER_XTABLES, starting from here
   all patches from Patrick McHardy.

5) Use raw_smp_processor_id() in nft_meta.

Then, several patches to prepare ground for the new set extension
infrastructure:

6) Pass object length to the hash callback in rhashtable as needed by
   the new set extension infrastructure.

7) Cleanup patch to restore struct nft_hash as wrapper for struct
   rhashtable

8) Another small source code readability cleanup for nft_hash.

9) Convert nft_hash to rhashtable callbacks.

And finally...

10) Add the new set extension infrastructure.

11) Convert the nft_hash and nft_rbtree sets to use it.

12) Batch set element release to avoid several RCU grace period in a row
    and add new function nft_set_elem_destroy() to consolidate set element
    release.

13) Return the set extension data area from nft_lookup.

14) Refactor existing transaction code to add some helper functions
    and document it.

15) Complete the set transaction support, using similar approach to what we
    already use, to activate/deactivate elements in an atomic fashion.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 29, 2015
2 parents ae7633c + cc02e45 commit 4ef295e
Show file tree
Hide file tree
Showing 16 changed files with 513 additions and 238 deletions.
6 changes: 4 additions & 2 deletions include/linux/rhashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct rhashtable_compare_arg {
};

typedef u32 (*rht_hashfn_t)(const void *data, u32 len, u32 seed);
typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 seed);
typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, u32 seed);
typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
const void *obj);

Expand Down Expand Up @@ -242,7 +242,9 @@ static inline unsigned int rht_head_hashfn(
const char *ptr = rht_obj(ht, he);

return likely(params.obj_hashfn) ?
rht_bucket_index(tbl, params.obj_hashfn(ptr, tbl->hash_rnd)) :
rht_bucket_index(tbl, params.obj_hashfn(ptr, params.key_len ?:
ht->p.key_len,
tbl->hash_rnd)) :
rht_key_hashfn(ht, tbl, ptr + params.key_offset, params);
}

Expand Down
190 changes: 176 additions & 14 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,19 +138,12 @@ struct nft_userdata {
/**
* struct nft_set_elem - generic representation of set elements
*
* @cookie: implementation specific element cookie
* @key: element key
* @data: element data (maps only)
* @flags: element flags (end of interval)
*
* The cookie can be used to store a handle to the element for subsequent
* removal.
* @priv: element private data and extensions
*/
struct nft_set_elem {
void *cookie;
struct nft_data key;
struct nft_data data;
u32 flags;
void *priv;
};

struct nft_set;
Expand Down Expand Up @@ -202,28 +195,35 @@ struct nft_set_estimate {
enum nft_set_class class;
};

struct nft_set_ext;

/**
* struct nft_set_ops - nf_tables set operations
*
* @lookup: look up an element within the set
* @insert: insert new element into set
* @activate: activate new element in the next generation
* @deactivate: deactivate element in the next generation
* @remove: remove element from set
* @walk: iterate over all set elemeennts
* @privsize: function to return size of set private data
* @init: initialize private data of new set instance
* @destroy: destroy private data of set instance
* @list: nf_tables_set_ops list node
* @owner: module reference
* @elemsize: element private size
* @features: features supported by the implementation
*/
struct nft_set_ops {
bool (*lookup)(const struct nft_set *set,
const struct nft_data *key,
struct nft_data *data);
int (*get)(const struct nft_set *set,
struct nft_set_elem *elem);
const struct nft_set_ext **ext);
int (*insert)(const struct nft_set *set,
const struct nft_set_elem *elem);
void (*activate)(const struct nft_set *set,
const struct nft_set_elem *elem);
void * (*deactivate)(const struct nft_set *set,
const struct nft_set_elem *elem);
void (*remove)(const struct nft_set *set,
const struct nft_set_elem *elem);
void (*walk)(const struct nft_ctx *ctx,
Expand All @@ -241,6 +241,7 @@ struct nft_set_ops {

struct list_head list;
struct module *owner;
unsigned int elemsize;
u32 features;
};

Expand All @@ -259,6 +260,7 @@ void nft_unregister_set(struct nft_set_ops *ops);
* @nelems: number of elements
* @policy: set parameterization (see enum nft_set_policies)
* @ops: set ops
* @pnet: network namespace
* @flags: set flags
* @klen: key length
* @dlen: data length
Expand All @@ -275,6 +277,7 @@ struct nft_set {
u16 policy;
/* runtime data below here */
const struct nft_set_ops *ops ____cacheline_aligned;
possible_net_t pnet;
u16 flags;
u8 klen;
u8 dlen;
Expand Down Expand Up @@ -311,6 +314,121 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
struct nft_set_binding *binding);

/**
* enum nft_set_extensions - set extension type IDs
*
* @NFT_SET_EXT_KEY: element key
* @NFT_SET_EXT_DATA: mapping data
* @NFT_SET_EXT_FLAGS: element flags
* @NFT_SET_EXT_NUM: number of extension types
*/
enum nft_set_extensions {
NFT_SET_EXT_KEY,
NFT_SET_EXT_DATA,
NFT_SET_EXT_FLAGS,
NFT_SET_EXT_NUM
};

/**
* struct nft_set_ext_type - set extension type
*
* @len: fixed part length of the extension
* @align: alignment requirements of the extension
*/
struct nft_set_ext_type {
u8 len;
u8 align;
};

extern const struct nft_set_ext_type nft_set_ext_types[];

/**
* struct nft_set_ext_tmpl - set extension template
*
* @len: length of extension area
* @offset: offsets of individual extension types
*/
struct nft_set_ext_tmpl {
u16 len;
u8 offset[NFT_SET_EXT_NUM];
};

/**
* struct nft_set_ext - set extensions
*
* @genmask: generation mask
* @offset: offsets of individual extension types
* @data: beginning of extension data
*/
struct nft_set_ext {
u8 genmask;
u8 offset[NFT_SET_EXT_NUM];
char data[0];
};

static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl)
{
memset(tmpl, 0, sizeof(*tmpl));
tmpl->len = sizeof(struct nft_set_ext);
}

static inline void nft_set_ext_add_length(struct nft_set_ext_tmpl *tmpl, u8 id,
unsigned int len)
{
tmpl->len = ALIGN(tmpl->len, nft_set_ext_types[id].align);
BUG_ON(tmpl->len > U8_MAX);
tmpl->offset[id] = tmpl->len;
tmpl->len += nft_set_ext_types[id].len + len;
}

static inline void nft_set_ext_add(struct nft_set_ext_tmpl *tmpl, u8 id)
{
nft_set_ext_add_length(tmpl, id, 0);
}

static inline void nft_set_ext_init(struct nft_set_ext *ext,
const struct nft_set_ext_tmpl *tmpl)
{
memcpy(ext->offset, tmpl->offset, sizeof(ext->offset));
}

static inline bool __nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
{
return !!ext->offset[id];
}

static inline bool nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
{
return ext && __nft_set_ext_exists(ext, id);
}

static inline void *nft_set_ext(const struct nft_set_ext *ext, u8 id)
{
return (void *)ext + ext->offset[id];
}

static inline struct nft_data *nft_set_ext_key(const struct nft_set_ext *ext)
{
return nft_set_ext(ext, NFT_SET_EXT_KEY);
}

static inline struct nft_data *nft_set_ext_data(const struct nft_set_ext *ext)
{
return nft_set_ext(ext, NFT_SET_EXT_DATA);
}

static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
{
return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
}

static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
void *elem)
{
return elem + set->ops->elemsize;
}

void nft_set_elem_destroy(const struct nft_set *set, void *elem);

/**
* struct nft_expr_type - nf_tables expression type
Expand Down Expand Up @@ -449,7 +567,6 @@ enum nft_chain_flags {
*
* @rules: list of rules in the chain
* @list: used internally
* @net: net namespace that this chain belongs to
* @table: table that this chain belongs to
* @handle: chain handle
* @use: number of jump references to this chain
Expand All @@ -460,7 +577,6 @@ enum nft_chain_flags {
struct nft_chain {
struct list_head rules;
struct list_head list;
struct net *net;
struct nft_table *table;
u64 handle;
u32 use;
Expand Down Expand Up @@ -512,13 +628,15 @@ struct nft_stats {
* struct nft_base_chain - nf_tables base chain
*
* @ops: netfilter hook ops
* @pnet: net namespace that this chain belongs to
* @type: chain type
* @policy: default policy
* @stats: per-cpu chain stats
* @chain: the chain
*/
struct nft_base_chain {
struct nf_hook_ops ops[NFT_HOOK_OPS_MAX];
possible_net_t pnet;
const struct nf_chain_type *type;
u8 policy;
struct nft_stats __percpu *stats;
Expand Down Expand Up @@ -605,6 +723,50 @@ void nft_unregister_expr(struct nft_expr_type *);
#define MODULE_ALIAS_NFT_SET() \
MODULE_ALIAS("nft-set")

/*
* The gencursor defines two generations, the currently active and the
* next one. Objects contain a bitmask of 2 bits specifying the generations
* they're active in. A set bit means they're inactive in the generation
* represented by that bit.
*
* New objects start out as inactive in the current and active in the
* next generation. When committing the ruleset the bitmask is cleared,
* meaning they're active in all generations. When removing an object,
* it is set inactive in the next generation. After committing the ruleset,
* the objects are removed.
*/
static inline unsigned int nft_gencursor_next(const struct net *net)
{
return net->nft.gencursor + 1 == 1 ? 1 : 0;
}

static inline u8 nft_genmask_next(const struct net *net)
{
return 1 << nft_gencursor_next(net);
}

static inline u8 nft_genmask_cur(const struct net *net)
{
/* Use ACCESS_ONCE() to prevent refetching the value for atomicity */
return 1 << ACCESS_ONCE(net->nft.gencursor);
}

/*
* Set element transaction helpers
*/

static inline bool nft_set_elem_active(const struct nft_set_ext *ext,
u8 genmask)
{
return !(ext->genmask & genmask);
}

static inline void nft_set_elem_change_active(const struct nft_set *set,
struct nft_set_ext *ext)
{
ext->genmask ^= nft_genmask_next(read_pnet(&set->pnet));
}

/**
* struct nft_trans - nf_tables object update in transaction
*
Expand Down
2 changes: 1 addition & 1 deletion lib/rhashtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
* struct rhash_head node;
* };
*
* u32 my_hash_fn(const void *data, u32 seed)
* u32 my_hash_fn(const void *data, u32 len, u32 seed)
* {
* struct test_obj *obj = data;
*
Expand Down
4 changes: 3 additions & 1 deletion net/ipv4/netfilter/nf_log_arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
Expand All @@ -27,7 +29,7 @@ static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 5,
.level = LOGLEVEL_NOTICE,
.logflags = NF_LOG_MASK,
},
},
Expand Down
4 changes: 3 additions & 1 deletion net/ipv4/netfilter/nf_log_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
Expand All @@ -26,7 +28,7 @@ static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 5,
.level = LOGLEVEL_NOTICE,
.logflags = NF_LOG_MASK,
},
},
Expand Down
5 changes: 4 additions & 1 deletion net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/capability.h>
#include <linux/in.h>
#include <linux/skbuff.h>
Expand Down Expand Up @@ -234,7 +237,7 @@ static struct nf_loginfo trace_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 4,
.level = LOGLEVEL_WARNING,
.logflags = NF_LOG_MASK,
},
},
Expand Down
4 changes: 3 additions & 1 deletion net/ipv6/netfilter/nf_log_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
Expand All @@ -27,7 +29,7 @@ static struct nf_loginfo default_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 5,
.level = LOGLEVEL_NOTICE,
.logflags = NF_LOG_MASK,
},
},
Expand Down
Loading

0 comments on commit 4ef295e

Please sign in to comment.