Commit e5009240 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: add stateful objects

This patch augments nf_tables to support stateful objects. This new
infrastructure allows you to create, dump and delete stateful objects,
that are identified by a user-defined name.

This patch adds the generic infrastructure, follow up patches add
support for two stateful objects: counters and quotas.

This patch provides a native infrastructure for nf_tables to replace
nfacct, the extended accounting infrastructure for iptables.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 3bf32761
......@@ -875,6 +875,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
* @list: used internally
* @chains: chains in the table
* @sets: sets in the table
* @objects: stateful objects in the table
* @hgenerator: handle generator state
* @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags)
......@@ -885,6 +886,7 @@ struct nft_table {
struct list_head list;
struct list_head chains;
struct list_head sets;
struct list_head objects;
u64 hgenerator;
u32 use;
u16 flags:14,
......@@ -934,6 +936,73 @@ void nft_unregister_expr(struct nft_expr_type *);
int nft_verdict_dump(struct sk_buff *skb, int type,
const struct nft_verdict *v);
/**
* struct nft_object - nf_tables stateful object
*
* @list: table stateful object list node
* @type: pointer to object type
* @data: pointer to object data
* @name: name of this stateful object
* @genmask: generation mask
* @use: number of references to this stateful object
* @data: object data, layout depends on type
*/
struct nft_object {
struct list_head list;
char name[NFT_OBJ_MAXNAMELEN];
u32 genmask:2,
use:30;
/* runtime data below here */
const struct nft_object_type *type ____cacheline_aligned;
unsigned char data[]
__attribute__((aligned(__alignof__(u64))));
};
static inline void *nft_obj_data(const struct nft_object *obj)
{
return (void *)obj->data;
}
#define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr))
struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
const struct nlattr *nla, u32 objtype,
u8 genmask);
/**
* struct nft_object_type - stateful object type
*
* @eval: stateful object evaluation function
* @list: list node in list of object types
* @type: stateful object numeric type
* @size: stateful object size
* @owner: module owner
* @maxattr: maximum netlink attribute
* @policy: netlink attribute policy
* @init: initialize object from netlink attributes
* @destroy: release existing stateful object
* @dump: netlink dump stateful object
*/
struct nft_object_type {
void (*eval)(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt);
struct list_head list;
u32 type;
unsigned int size;
unsigned int maxattr;
struct module *owner;
const struct nla_policy *policy;
int (*init)(const struct nlattr * const tb[],
struct nft_object *obj);
void (*destroy)(struct nft_object *obj);
int (*dump)(struct sk_buff *skb,
const struct nft_object *obj);
};
int nft_register_obj(struct nft_object_type *obj_type);
void nft_unregister_obj(struct nft_object_type *obj_type);
/**
* struct nft_traceinfo - nft tracing information and state
*
......@@ -981,6 +1050,9 @@ void nft_trace_notify(struct nft_traceinfo *info);
#define MODULE_ALIAS_NFT_SET() \
MODULE_ALIAS("nft-set")
#define MODULE_ALIAS_NFT_OBJ(type) \
MODULE_ALIAS("nft-obj-" __stringify(type))
/*
* The gencursor defines two generations, the currently active and the
* next one. Objects contain a bitmask of 2 bits specifying the generations
......@@ -1157,4 +1229,11 @@ struct nft_trans_elem {
#define nft_trans_elem(trans) \
(((struct nft_trans_elem *)trans->data)->elem)
struct nft_trans_obj {
struct nft_object *obj;
};
#define nft_trans_obj(trans) \
(((struct nft_trans_obj *)trans->data)->obj)
#endif /* _NET_NF_TABLES_H */
......@@ -4,6 +4,7 @@
#define NFT_TABLE_MAXNAMELEN 32
#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_SET_MAXNAMELEN 32
#define NFT_OBJ_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256
/**
......@@ -85,6 +86,9 @@ enum nft_verdicts {
* @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes)
* @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes)
* @NFT_MSG_TRACE: trace event (enum nft_trace_attributes)
* @NFT_MSG_NEWOBJ: create a stateful object (enum nft_obj_attributes)
* @NFT_MSG_GETOBJ: get a stateful object (enum nft_obj_attributes)
* @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes)
*/
enum nf_tables_msg_types {
NFT_MSG_NEWTABLE,
......@@ -105,6 +109,9 @@ enum nf_tables_msg_types {
NFT_MSG_NEWGEN,
NFT_MSG_GETGEN,
NFT_MSG_TRACE,
NFT_MSG_NEWOBJ,
NFT_MSG_GETOBJ,
NFT_MSG_DELOBJ,
NFT_MSG_MAX,
};
......@@ -1178,6 +1185,28 @@ enum nft_fib_flags {
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
};
#define NFT_OBJECT_UNSPEC 0
/**
* enum nft_object_attributes - nf_tables stateful object netlink attributes
*
* @NFTA_OBJ_TABLE: name of the table containing the expression (NLA_STRING)
* @NFTA_OBJ_NAME: name of this expression type (NLA_STRING)
* @NFTA_OBJ_TYPE: stateful object type (NLA_U32)
* @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)
* @NFTA_OBJ_USE: number of references to this expression (NLA_U32)
*/
enum nft_object_attributes {
NFTA_OBJ_UNSPEC,
NFTA_OBJ_TABLE,
NFTA_OBJ_NAME,
NFTA_OBJ_TYPE,
NFTA_OBJ_DATA,
NFTA_OBJ_USE,
__NFTA_OBJ_MAX
};
#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
/**
* enum nft_trace_attributes - nf_tables trace netlink attributes
*
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment