Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8af750d7 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayuso says:

====================
Netfilter/nftables updates for net-next

The following patchset contains Netfilter/nftables updates for net-next,
most relevantly they are:

1) Add set element update notification via netlink, from Arturo Borrero.

2) Put all object updates in one single message batch that is sent to
   kernel-space. Before this patch only rules where included in the batch.
   This series also introduces the generic transaction infrastructure so
   updates to all objects (tables, chains, rules and sets) are applied in
   an all-or-nothing fashion, these series from me.

3) Defer release of objects via call_rcu to reduce the time required to
   commit changes. The assumption is that all objects are destroyed in
   reverse order to ensure that dependencies betweem them are fulfilled
   (ie. rules and sets are destroyed first, then chains, and finally
   tables).

4) Allow to match by bridge port name, from Tomasz Bursztyka. This series
   include two patches to prepare this new feature.

5) Implement the proper set selection based on the characteristics of the
   data. The new infrastructure also allows you to specify your preferences
   in terms of memory and computational complexity so the underlying set
   type is also selected according to your needs, from Patrick McHardy.

6) Several cleanup patches for nft expressions, including one minor possible
   compilation breakage due to missing mark support, also from Patrick.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 758bd61a c7c32e72
Loading
Loading
Loading
Loading
+119 −11
Original line number Diff line number Diff line
@@ -72,21 +72,23 @@ static inline void nft_data_debug(const struct nft_data *data)
 *	struct nft_ctx - nf_tables rule/set context
 *
 *	@net: net namespace
 * 	@skb: netlink skb
 * 	@nlh: netlink message header
 * 	@afi: address family info
 * 	@table: the table the chain is contained in
 * 	@chain: the chain the rule is contained in
 *	@nla: netlink attributes
 *	@portid: netlink portID of the original message
 *	@seq: netlink sequence number
 *	@report: notify via unicast netlink message
 */
struct nft_ctx {
	struct net			*net;
	const struct sk_buff		*skb;
	const struct nlmsghdr		*nlh;
	const struct nft_af_info	*afi;
	const struct nft_table		*table;
	const struct nft_chain		*chain;
	struct nft_af_info		*afi;
	struct nft_table		*table;
	struct nft_chain		*chain;
	const struct nlattr * const 	*nla;
	u32				portid;
	u32				seq;
	bool				report;
};

struct nft_data_desc {
@@ -145,6 +147,44 @@ struct nft_set_iter {
			      const struct nft_set_elem *elem);
};

/**
 *	struct nft_set_desc - description of set elements
 *
 *	@klen: key length
 *	@dlen: data length
 *	@size: number of set elements
 */
struct nft_set_desc {
	unsigned int		klen;
	unsigned int		dlen;
	unsigned int		size;
};

/**
 *	enum nft_set_class - performance class
 *
 *	@NFT_LOOKUP_O_1: constant, O(1)
 *	@NFT_LOOKUP_O_LOG_N: logarithmic, O(log N)
 *	@NFT_LOOKUP_O_N: linear, O(N)
 */
enum nft_set_class {
	NFT_SET_CLASS_O_1,
	NFT_SET_CLASS_O_LOG_N,
	NFT_SET_CLASS_O_N,
};

/**
 *	struct nft_set_estimate - estimation of memory and performance
 *				  characteristics
 *
 *	@size: required memory
 *	@class: lookup performance class
 */
struct nft_set_estimate {
	unsigned int		size;
	enum nft_set_class	class;
};

/**
 *	struct nft_set_ops - nf_tables set operations
 *
@@ -174,7 +214,11 @@ struct nft_set_ops {
						struct nft_set_iter *iter);

	unsigned int			(*privsize)(const struct nlattr * const nla[]);
	bool				(*estimate)(const struct nft_set_desc *desc,
						    u32 features,
						    struct nft_set_estimate *est);
	int				(*init)(const struct nft_set *set,
						const struct nft_set_desc *desc,
						const struct nlattr * const nla[]);
	void				(*destroy)(const struct nft_set *set);

@@ -194,6 +238,8 @@ void nft_unregister_set(struct nft_set_ops *ops);
 * 	@name: name of the set
 * 	@ktype: key type (numeric type defined by userspace, not used in the kernel)
 * 	@dtype: data type (verdict or numeric type defined by userspace)
 * 	@size: maximum set size
 * 	@nelems: number of elements
 * 	@ops: set ops
 * 	@flags: set flags
 * 	@klen: key length
@@ -206,6 +252,8 @@ struct nft_set {
	char				name[IFNAMSIZ];
	u32				ktype;
	u32				dtype;
	u32				size;
	u32				nelems;
	/* runtime data below here */
	const struct nft_set_ops	*ops ____cacheline_aligned;
	u16				flags;
@@ -222,6 +270,8 @@ static inline void *nft_set_priv(const struct nft_set *set)

struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
				     const struct nlattr *nla);
struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
					  const struct nlattr *nla);

/**
 *	struct nft_set_binding - nf_tables set binding
@@ -341,18 +391,75 @@ struct nft_rule {
};

/**
 *	struct nft_rule_trans - nf_tables rule update in transaction
 *	struct nft_trans - nf_tables object update in transaction
 *
 *	@rcu_head: rcu head to defer release of transaction data
 *	@list: used internally
 *	@ctx: rule context
 *	@rule: rule that needs to be updated
 *	@msg_type: message type
 *	@ctx: transaction context
 *	@data: internal information related to the transaction
 */
struct nft_rule_trans {
struct nft_trans {
	struct rcu_head			rcu_head;
	struct list_head		list;
	int				msg_type;
	struct nft_ctx			ctx;
	char				data[0];
};

struct nft_trans_rule {
	struct nft_rule			*rule;
};

#define nft_trans_rule(trans)	\
	(((struct nft_trans_rule *)trans->data)->rule)

struct nft_trans_set {
	struct nft_set	*set;
	u32		set_id;
};

#define nft_trans_set(trans)	\
	(((struct nft_trans_set *)trans->data)->set)
#define nft_trans_set_id(trans)	\
	(((struct nft_trans_set *)trans->data)->set_id)

struct nft_trans_chain {
	bool		update;
	char		name[NFT_CHAIN_MAXNAMELEN];
	struct nft_stats __percpu *stats;
	u8		policy;
};

#define nft_trans_chain_update(trans)	\
	(((struct nft_trans_chain *)trans->data)->update)
#define nft_trans_chain_name(trans)	\
	(((struct nft_trans_chain *)trans->data)->name)
#define nft_trans_chain_stats(trans)	\
	(((struct nft_trans_chain *)trans->data)->stats)
#define nft_trans_chain_policy(trans)	\
	(((struct nft_trans_chain *)trans->data)->policy)

struct nft_trans_table {
	bool		update;
	bool		enable;
};

#define nft_trans_table_update(trans)	\
	(((struct nft_trans_table *)trans->data)->update)
#define nft_trans_table_enable(trans)	\
	(((struct nft_trans_table *)trans->data)->enable)

struct nft_trans_elem {
	struct nft_set		*set;
	struct nft_set_elem	elem;
};

#define nft_trans_elem_set(trans)	\
	(((struct nft_trans_elem *)trans->data)->set)
#define nft_trans_elem(trans)	\
	(((struct nft_trans_elem *)trans->data)->elem)

static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
{
	return (struct nft_expr *)&rule->data[0];
@@ -385,6 +492,7 @@ static inline void *nft_userdata(const struct nft_rule *rule)

enum nft_chain_flags {
	NFT_BASE_CHAIN			= 0x1,
	NFT_CHAIN_INACTIVE		= 0x2,
};

/**
+36 −0
Original line number Diff line number Diff line
#ifndef _NFT_META_H_
#define _NFT_META_H_

struct nft_meta {
	enum nft_meta_keys	key:8;
	union {
		enum nft_registers	dreg:8;
		enum nft_registers	sreg:8;
	};
};

extern const struct nla_policy nft_meta_policy[];

int nft_meta_get_init(const struct nft_ctx *ctx,
		      const struct nft_expr *expr,
		      const struct nlattr * const tb[]);

int nft_meta_set_init(const struct nft_ctx *ctx,
		      const struct nft_expr *expr,
		      const struct nlattr * const tb[]);

int nft_meta_get_dump(struct sk_buff *skb,
		      const struct nft_expr *expr);

int nft_meta_set_dump(struct sk_buff *skb,
		      const struct nft_expr *expr);

void nft_meta_get_eval(const struct nft_expr *expr,
		       struct nft_data data[NFT_REG_MAX + 1],
		       const struct nft_pktinfo *pkt);

void nft_meta_set_eval(const struct nft_expr *expr,
		       struct nft_data data[NFT_REG_MAX + 1],
		       const struct nft_pktinfo *pkt);

#endif
+37 −0
Original line number Diff line number Diff line
@@ -211,6 +211,29 @@ enum nft_set_flags {
	NFT_SET_MAP			= 0x8,
};

/**
 * enum nft_set_policies - set selection policy
 *
 * @NFT_SET_POL_PERFORMANCE: prefer high performance over low memory use
 * @NFT_SET_POL_MEMORY: prefer low memory use over high performance
 */
enum nft_set_policies {
	NFT_SET_POL_PERFORMANCE,
	NFT_SET_POL_MEMORY,
};

/**
 * enum nft_set_desc_attributes - set element description
 *
 * @NFTA_SET_DESC_SIZE: number of elements in set (NLA_U32)
 */
enum nft_set_desc_attributes {
	NFTA_SET_DESC_UNSPEC,
	NFTA_SET_DESC_SIZE,
	__NFTA_SET_DESC_MAX
};
#define NFTA_SET_DESC_MAX	(__NFTA_SET_DESC_MAX - 1)

/**
 * enum nft_set_attributes - nf_tables set netlink attributes
 *
@@ -221,6 +244,9 @@ enum nft_set_flags {
 * @NFTA_SET_KEY_LEN: key data length (NLA_U32)
 * @NFTA_SET_DATA_TYPE: mapping data type (NLA_U32)
 * @NFTA_SET_DATA_LEN: mapping data length (NLA_U32)
 * @NFTA_SET_POLICY: selection policy (NLA_U32)
 * @NFTA_SET_DESC: set description (NLA_NESTED)
 * @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
 */
enum nft_set_attributes {
	NFTA_SET_UNSPEC,
@@ -231,6 +257,9 @@ enum nft_set_attributes {
	NFTA_SET_KEY_LEN,
	NFTA_SET_DATA_TYPE,
	NFTA_SET_DATA_LEN,
	NFTA_SET_POLICY,
	NFTA_SET_DESC,
	NFTA_SET_ID,
	__NFTA_SET_MAX
};
#define NFTA_SET_MAX		(__NFTA_SET_MAX - 1)
@@ -266,12 +295,14 @@ enum nft_set_elem_attributes {
 * @NFTA_SET_ELEM_LIST_TABLE: table of the set to be changed (NLA_STRING)
 * @NFTA_SET_ELEM_LIST_SET: name of the set to be changed (NLA_STRING)
 * @NFTA_SET_ELEM_LIST_ELEMENTS: list of set elements (NLA_NESTED: nft_set_elem_attributes)
 * @NFTA_SET_ELEM_LIST_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
 */
enum nft_set_elem_list_attributes {
	NFTA_SET_ELEM_LIST_UNSPEC,
	NFTA_SET_ELEM_LIST_TABLE,
	NFTA_SET_ELEM_LIST_SET,
	NFTA_SET_ELEM_LIST_ELEMENTS,
	NFTA_SET_ELEM_LIST_SET_ID,
	__NFTA_SET_ELEM_LIST_MAX
};
#define NFTA_SET_ELEM_LIST_MAX	(__NFTA_SET_ELEM_LIST_MAX - 1)
@@ -457,12 +488,14 @@ enum nft_cmp_attributes {
 * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING)
 * @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
 * @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
 * @NFTA_LOOKUP_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
 */
enum nft_lookup_attributes {
	NFTA_LOOKUP_UNSPEC,
	NFTA_LOOKUP_SET,
	NFTA_LOOKUP_SREG,
	NFTA_LOOKUP_DREG,
	NFTA_LOOKUP_SET_ID,
	__NFTA_LOOKUP_MAX
};
#define NFTA_LOOKUP_MAX		(__NFTA_LOOKUP_MAX - 1)
@@ -536,6 +569,8 @@ enum nft_exthdr_attributes {
 * @NFT_META_SECMARK: packet secmark (skb->secmark)
 * @NFT_META_NFPROTO: netfilter protocol
 * @NFT_META_L4PROTO: layer 4 protocol number
 * @NFT_META_BRI_IIFNAME: packet input bridge interface name
 * @NFT_META_BRI_OIFNAME: packet output bridge interface name
 */
enum nft_meta_keys {
	NFT_META_LEN,
@@ -555,6 +590,8 @@ enum nft_meta_keys {
	NFT_META_SECMARK,
	NFT_META_NFPROTO,
	NFT_META_L4PROTO,
	NFT_META_BRI_IIFNAME,
	NFT_META_BRI_OIFNAME,
};

/**
+1 −1
Original line number Diff line number Diff line
@@ -16,4 +16,4 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o

bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o

obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/
obj-$(CONFIG_BRIDGE_NETFILTER) += netfilter/
+13 −1
Original line number Diff line number Diff line
@@ -2,13 +2,25 @@
# Bridge netfilter configuration
#
#
config NF_TABLES_BRIDGE
menuconfig NF_TABLES_BRIDGE
	depends on NF_TABLES
	select BRIDGE_NETFILTER
	tristate "Ethernet Bridge nf_tables support"

if NF_TABLES_BRIDGE

config NFT_BRIDGE_META
	tristate "Netfilter nf_table bridge meta support"
	depends on NFT_META
	help
	  Add support for bridge dedicated meta key.

endif # NF_TABLES_BRIDGE

menuconfig BRIDGE_NF_EBTABLES
	tristate "Ethernet Bridge tables (ebtables) support"
	depends on BRIDGE && NETFILTER
	select BRIDGE_NETFILTER
	select NETFILTER_XTABLES
	help
	  ebtables is a general, extensible frame/packet identification
Loading