Commit 3b49e2e9 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: add flow table netlink frontend

This patch introduces a netlink control plane to create, delete and dump
flow tables. Flow tables are identified by name, this name is used from
rules to refer to an specific flow table. Flow tables use the rhashtable
class and a generic garbage collector to remove expired entries.

This also adds the infrastructure to add different flow table types, so
we can add one for each layer 3 protocol family.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 90964016
#ifndef _NF_FLOW_TABLE_H
#define _NF_FLOW_TABLE_H
#include <linux/rhashtable.h>
struct nf_flowtable;
struct nf_flowtable_type {
struct list_head list;
int family;
void (*gc)(struct work_struct *work);
const struct rhashtable_params *params;
nf_hookfn *hook;
struct module *owner;
};
struct nf_flowtable {
struct rhashtable rhashtable;
const struct nf_flowtable_type *type;
struct delayed_work gc_work;
};
#endif /* _FLOW_OFFLOAD_H */
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/netfilter/x_tables.h> #include <linux/netfilter/x_tables.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <linux/u64_stats_sync.h> #include <linux/u64_stats_sync.h>
#include <net/netfilter/nf_flow_table.h>
#include <net/netlink.h> #include <net/netlink.h>
#define NFT_JUMP_STACK_SIZE 16 #define NFT_JUMP_STACK_SIZE 16
...@@ -943,6 +944,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); ...@@ -943,6 +944,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
* @chains: chains in the table * @chains: chains in the table
* @sets: sets in the table * @sets: sets in the table
* @objects: stateful objects in the table * @objects: stateful objects in the table
* @flowtables: flow tables in the table
* @hgenerator: handle generator state * @hgenerator: handle generator state
* @use: number of chain references to this table * @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags) * @flags: table flag (see enum nft_table_flags)
...@@ -954,6 +956,7 @@ struct nft_table { ...@@ -954,6 +956,7 @@ struct nft_table {
struct list_head chains; struct list_head chains;
struct list_head sets; struct list_head sets;
struct list_head objects; struct list_head objects;
struct list_head flowtables;
u64 hgenerator; u64 hgenerator;
u32 use; u32 use;
u16 flags:14, u16 flags:14,
...@@ -1084,6 +1087,44 @@ struct nft_object_ops { ...@@ -1084,6 +1087,44 @@ struct nft_object_ops {
int nft_register_obj(struct nft_object_type *obj_type); int nft_register_obj(struct nft_object_type *obj_type);
void nft_unregister_obj(struct nft_object_type *obj_type); void nft_unregister_obj(struct nft_object_type *obj_type);
/**
* struct nft_flowtable - nf_tables flow table
*
* @list: flow table list node in table list
* @table: the table the flow table is contained in
* @name: name of this flow table
* @hooknum: hook number
* @priority: hook priority
* @ops_len: number of hooks in array
* @genmask: generation mask
* @use: number of references to this flow table
* @data: rhashtable and garbage collector
* @ops: array of hooks
*/
struct nft_flowtable {
struct list_head list;
struct nft_table *table;
char *name;
int hooknum;
int priority;
int ops_len;
u32 genmask:2,
use:30;
/* runtime data below here */
struct nf_hook_ops *ops ____cacheline_aligned;
struct nf_flowtable data;
};
struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table,
const struct nlattr *nla,
u8 genmask);
void nft_flow_table_iterate(struct net *net,
void (*iter)(struct nf_flowtable *flowtable, void *data),
void *data);
void nft_register_flowtable_type(struct nf_flowtable_type *type);
void nft_unregister_flowtable_type(struct nf_flowtable_type *type);
/** /**
* struct nft_traceinfo - nft tracing information and state * struct nft_traceinfo - nft tracing information and state
* *
...@@ -1317,4 +1358,11 @@ struct nft_trans_obj { ...@@ -1317,4 +1358,11 @@ struct nft_trans_obj {
#define nft_trans_obj(trans) \ #define nft_trans_obj(trans) \
(((struct nft_trans_obj *)trans->data)->obj) (((struct nft_trans_obj *)trans->data)->obj)
struct nft_trans_flowtable {
struct nft_flowtable *flowtable;
};
#define nft_trans_flowtable(trans) \
(((struct nft_trans_flowtable *)trans->data)->flowtable)
#endif /* _NET_NF_TABLES_H */ #endif /* _NET_NF_TABLES_H */
...@@ -92,6 +92,9 @@ enum nft_verdicts { ...@@ -92,6 +92,9 @@ enum nft_verdicts {
* @NFT_MSG_GETOBJ: get 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) * @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes)
* @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes) * @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes)
* @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes)
* @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes)
* @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes)
*/ */
enum nf_tables_msg_types { enum nf_tables_msg_types {
NFT_MSG_NEWTABLE, NFT_MSG_NEWTABLE,
...@@ -116,6 +119,9 @@ enum nf_tables_msg_types { ...@@ -116,6 +119,9 @@ enum nf_tables_msg_types {
NFT_MSG_GETOBJ, NFT_MSG_GETOBJ,
NFT_MSG_DELOBJ, NFT_MSG_DELOBJ,
NFT_MSG_GETOBJ_RESET, NFT_MSG_GETOBJ_RESET,
NFT_MSG_NEWFLOWTABLE,
NFT_MSG_GETFLOWTABLE,
NFT_MSG_DELFLOWTABLE,
NFT_MSG_MAX, NFT_MSG_MAX,
}; };
...@@ -1309,6 +1315,53 @@ enum nft_object_attributes { ...@@ -1309,6 +1315,53 @@ enum nft_object_attributes {
}; };
#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
/**
* enum nft_flowtable_attributes - nf_tables flow table netlink attributes
*
* @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING)
* @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING)
* @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)
* @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)
*/
enum nft_flowtable_attributes {
NFTA_FLOWTABLE_UNSPEC,
NFTA_FLOWTABLE_TABLE,
NFTA_FLOWTABLE_NAME,
NFTA_FLOWTABLE_HOOK,
NFTA_FLOWTABLE_USE,
__NFTA_FLOWTABLE_MAX
};
#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1)
/**
* enum nft_flowtable_hook_attributes - nf_tables flow table hook netlink attributes
*
* @NFTA_FLOWTABLE_HOOK_NUM: netfilter hook number (NLA_U32)
* @NFTA_FLOWTABLE_HOOK_PRIORITY: netfilter hook priority (NLA_U32)
* @NFTA_FLOWTABLE_HOOK_DEVS: input devices this flow table is bound to (NLA_NESTED)
*/
enum nft_flowtable_hook_attributes {
NFTA_FLOWTABLE_HOOK_UNSPEC,
NFTA_FLOWTABLE_HOOK_NUM,
NFTA_FLOWTABLE_HOOK_PRIORITY,
NFTA_FLOWTABLE_HOOK_DEVS,
__NFTA_FLOWTABLE_HOOK_MAX
};
#define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1)
/**
* enum nft_device_attributes - nf_tables device netlink attributes
*
* @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
*/
enum nft_devices_attributes {
NFTA_DEVICE_UNSPEC,
NFTA_DEVICE_NAME,
__NFTA_DEVICE_MAX
};
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
/** /**
* enum nft_trace_attributes - nf_tables trace netlink attributes * 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