Skip to content

Commit

Permalink
netfilter: nf_tables: add set extensions
Browse files Browse the repository at this point in the history
Add simple set extension infrastructure for maintaining variable sized
and optional per element data.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Patrick McHardy authored and Pablo Neira Ayuso committed Mar 25, 2015
1 parent bfd6e32 commit 3ac4c07
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
105 changes: 105 additions & 0 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,111 @@ 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
*
* @offset: offsets of individual extension types
* @data: beginning of extension data
*/
struct nft_set_ext {
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);
}

/**
* struct nft_expr_type - nf_tables expression type
Expand Down
16 changes: 16 additions & 0 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2827,6 +2827,22 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
nf_tables_set_destroy(ctx, set);
}

const struct nft_set_ext_type nft_set_ext_types[] = {
[NFT_SET_EXT_KEY] = {
.len = sizeof(struct nft_data),
.align = __alignof__(struct nft_data),
},
[NFT_SET_EXT_DATA] = {
.len = sizeof(struct nft_data),
.align = __alignof__(struct nft_data),
},
[NFT_SET_EXT_FLAGS] = {
.len = sizeof(u8),
.align = __alignof__(u8),
},
};
EXPORT_SYMBOL_GPL(nft_set_ext_types);

/*
* Set elements
*/
Expand Down

0 comments on commit 3ac4c07

Please sign in to comment.