* [PATCH 00/21] netfilter updates for net-next
@ 2013-01-25 13:54 pablo
2013-01-27 5:56 ` David Miller
0 siblings, 1 reply; 33+ messages in thread
From: pablo @ 2013-01-25 13:54 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Hi David,
This batch contains netfilter updates for you net-next tree, they are:
* The new connlabel extension for x_tables, that allows us to attach
labels to each conntrack flow. The kernel implementation uses a
bitmask and there's a file in user-space that maps the bits with the
corresponding string for each existing label. By now, you can attach
up to 128 overlapping labels. From Florian Westphal.
* A new round of improvements for the netns support for conntrack.
Gao feng has moved many of the initialization code of each module
of the netns init path. He also made several code refactoring, that
code looks cleaner to me now.
* Added documentation for all possible tweaks for nf_conntrack via
sysctl, from Jiri Pirko.
* Cisco 7941/7945 IP phone support for our SIP conntrack helper,
from Kevin Cernekee.
* Missing header file in the snmp helper, from Stephen Hemminger.
* Finally, a couple of fixes to resolve minor issues with these
changes, from myself.
You can pull these changes from:
git://1984.lsi.us.es/nf-next master
Thanks!
Florian Westphal (3):
netfilter: add connlabel conntrack extension
netfilter: ctnetlink: deliver labels to userspace
netfilter: ctnetlink: allow userspace to modify labels
Gao feng (11):
netfilter: nf_conntrack: move initialization out of pernet operations
netfilter: nf_ct_expect: move initialization out of pernet_operations
netfilter: nf_ct_acct: move initialization out of pernet_operations
netfilter: nf_ct_tstamp: move initialization out of pernet_operations
netfilter: nf_ct_ecache: move initialization out of pernet_operations
netfilter: nf_ct_timeout: move initialization out of pernet_operations
netfilter: nf_ct_helper: move initialization out of pernet_operations
netfilter: nf_ct_labels: move initialization out of pernet_operations
netfilter: nf_ct_proto: move initialization out of pernet_operations
netfilter: nf_conntrack: refactor l3proto support for netns
netfilter: nf_conntrack: refactor l4proto support for netns
Jiri Pirko (1):
netfilter: doc: add nf_conntrack sysctl api documentation
Kevin Cernekee (1):
netfilter: nf_ct_sip: support Cisco 7941/7945 IP phones
Pablo Neira Ayuso (3):
netfilter: add missing xt_bpf.h header in installation
netfilter: add missing xt_connlabel.h header in installation
netfilter: nf_conntrack: fix compilation if sysctl are disabled
Willem de Bruijn (1):
netfilter: x_tables: add xt_bpf match
stephen hemminger (1):
netfilter: nf_ct_snmp: add include file
Documentation/networking/nf_conntrack-sysctl.txt | 176 ++++++++++++++++++
include/linux/netfilter/nf_conntrack_sip.h | 3 +
include/net/netfilter/nf_conntrack_acct.h | 6 +-
include/net/netfilter/nf_conntrack_core.h | 15 +-
include/net/netfilter/nf_conntrack_ecache.h | 19 +-
include/net/netfilter/nf_conntrack_expect.h | 7 +-
include/net/netfilter/nf_conntrack_extend.h | 4 +
include/net/netfilter/nf_conntrack_helper.h | 7 +-
include/net/netfilter/nf_conntrack_l3proto.h | 11 +-
include/net/netfilter/nf_conntrack_l4proto.h | 10 +-
include/net/netfilter/nf_conntrack_labels.h | 58 ++++++
include/net/netfilter/nf_conntrack_timeout.h | 8 +-
include/net/netfilter/nf_conntrack_timestamp.h | 21 ++-
include/net/netns/conntrack.h | 4 +
include/uapi/linux/netfilter/Kbuild | 2 +
include/uapi/linux/netfilter/nf_conntrack_common.h | 1 +
include/uapi/linux/netfilter/nfnetlink_conntrack.h | 2 +
include/uapi/linux/netfilter/xt_bpf.h | 17 ++
include/uapi/linux/netfilter/xt_connlabel.h | 12 ++
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 82 ++++++---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 86 ++++++---
net/netfilter/Kconfig | 27 +++
net/netfilter/Makefile | 3 +
net/netfilter/nf_conntrack_acct.c | 36 ++--
net/netfilter/nf_conntrack_core.c | 191 ++++++++++++--------
net/netfilter/nf_conntrack_ecache.c | 37 ++--
net/netfilter/nf_conntrack_expect.c | 53 +++---
net/netfilter/nf_conntrack_helper.c | 53 +++---
net/netfilter/nf_conntrack_labels.c | 112 ++++++++++++
net/netfilter/nf_conntrack_netlink.c | 88 +++++++++
net/netfilter/nf_conntrack_proto.c | 92 ++++------
net/netfilter/nf_conntrack_proto_dccp.c | 43 +++--
net/netfilter/nf_conntrack_proto_gre.c | 23 ++-
net/netfilter/nf_conntrack_proto_sctp.c | 43 +++--
net/netfilter/nf_conntrack_proto_udplite.c | 40 +++-
net/netfilter/nf_conntrack_sip.c | 17 ++
net/netfilter/nf_conntrack_snmp.c | 1 +
net/netfilter/nf_conntrack_standalone.c | 63 ++++---
net/netfilter/nf_conntrack_timeout.c | 23 +--
net/netfilter/nf_conntrack_timestamp.c | 39 ++--
net/netfilter/nf_nat_sip.c | 27 ++-
net/netfilter/xt_bpf.c | 73 ++++++++
net/netfilter/xt_connlabel.c | 99 ++++++++++
43 files changed, 1305 insertions(+), 429 deletions(-)
create mode 100644 Documentation/networking/nf_conntrack-sysctl.txt
create mode 100644 include/net/netfilter/nf_conntrack_labels.h
create mode 100644 include/uapi/linux/netfilter/xt_bpf.h
create mode 100644 include/uapi/linux/netfilter/xt_connlabel.h
create mode 100644 net/netfilter/nf_conntrack_labels.c
create mode 100644 net/netfilter/xt_bpf.c
create mode 100644 net/netfilter/xt_connlabel.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] netfilter updates for net-next
2013-01-25 13:54 [PATCH 00/21] netfilter " pablo
@ 2013-01-27 5:56 ` David Miller
0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2013-01-27 5:56 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: pablo@netfilter.org
Date: Fri, 25 Jan 2013 14:54:32 +0100
> * The new connlabel extension for x_tables, that allows us to attach
> labels to each conntrack flow. The kernel implementation uses a
> bitmask and there's a file in user-space that maps the bits with the
> corresponding string for each existing label. By now, you can attach
> up to 128 overlapping labels. From Florian Westphal.
>
> * A new round of improvements for the netns support for conntrack.
> Gao feng has moved many of the initialization code of each module
> of the netns init path. He also made several code refactoring, that
> code looks cleaner to me now.
>
> * Added documentation for all possible tweaks for nf_conntrack via
> sysctl, from Jiri Pirko.
>
> * Cisco 7941/7945 IP phone support for our SIP conntrack helper,
> from Kevin Cernekee.
>
> * Missing header file in the snmp helper, from Stephen Hemminger.
>
> * Finally, a couple of fixes to resolve minor issues with these
> changes, from myself.
>
> You can pull these changes from:
>
> git://1984.lsi.us.es/nf-next master
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 00/21] Netfilter updates for net-next
@ 2015-04-13 19:29 Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 01/21] netfilter: nf_tables: validate len in nft_validate_data_load() Pablo Neira Ayuso
` (21 more replies)
0 siblings, 22 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
A final pull request, I know it's very late but this time I think it's worth a
bit of rush.
The following patchset contains Netfilter/nf_tables updates for net-next, more
specifically concatenation support and dynamic stateful expression
instantiation.
This also comes with a couple of small patches. One to fix the ebtables.h
userspace header and another to get rid of an obsolete example file in tree
that describes a nf_tables expression.
This time, I decided to paste the original descriptions. This will result in a
rather large commit description, but I think these bytes to keep.
Patrick McHardy says:
====================
netfilter: nf_tables: concatenation support
The following patches add support for concatenations, which allow multi
dimensional exact matches in O(1).
The basic idea is to split the data registers, currently consisting of
4 registers of 16 bytes each, into smaller units, 16 registers of 4
bytes each, and making sure each register store always leaves the
full 32 bit in a well defined state, meaning smaller stores will
zero the remaining bits.
Based on that, we can load multiple adjacent registers with different
values, thereby building a concatenated bigger value, and use that
value for set lookups.
Sets are changed to use variable sized extensions for their key and
data values, removing the fixed limit of 16 bytes while saving memory
if less space is needed.
As a side effect, these patches will allow some nice optimizations in
the future, like using jhash2 in nft_hash, removing the masking in
nft_cmp_fast, optimized data comparison using 32 bit word size etc.
These are not done so far however.
The patches are split up as follows:
* the first five patches add length validation to register loads and
stores to make sure we stay within bounds and prepare the validation
functions for the new addressing mode
* the next patches prepare for changing to 32 bit addressing by
introducing a struct nft_regs, which holds the verdict register as
well as the data registers. The verdict members are moved to a new
struct nft_verdict to allow to pull struct nft_data out of the stack.
* the next patches contain preparatory conversions of expressions and
sets to use 32 bit addressing
* the next patch introduces so far unused register conversion helpers
for parsing and dumping register numbers over netlink
* following is the real conversion to 32 bit addressing, consisting of
replacing struct nft_data in struct nft_regs by an array of u32s and
actually translating and validating the new register numbers.
* the final two patches add support for variable sized data items and
variable sized keys / data in set elements
The patches have been verified to work correctly with nft binaries using
both old and new addressing.
====================
Patrick McHardy says:
====================
netfilter: nf_tables: dynamic stateful expression instantiation
The following patches are the grand finale of my nf_tables set work,
using all the building blocks put in place by the previous patches
to support something like iptables hashlimit, but a lot more powerful.
Sets are extended to allow attaching expressions to set elements.
The dynset expression dynamically instantiates these expressions
based on a template when creating new set elements and evaluates
them for all new or updated set members.
In combination with concatenations this effectively creates state
tables for arbitrary combinations of keys, using the existing
expression types to maintain that state. Regular set GC takes care
of purging expired states.
We currently support two different stateful expressions, counter
and limit. Using limit as a template we can express the functionality
of hashlimit, but completely unrestricted in the combination of keys.
Using counter we can perform accounting for arbitrary flows.
The following examples from patch 5/5 show some possibilities.
Userspace syntax is still WIP, especially the listing of state
tables will most likely be seperated from normal set listings
and use a more structured format:
1. Limit the rate of new SSH connections per host, similar to iptables
hashlimit:
# nft filter input tcp dport ssh ct state new \
flow ip saddr timeout 60s \
limit 10/second \
accept
2. Account network traffic between each set of /24 networks:
# nft filter forward \
flow ip saddr & 255.255.255.0 . ip daddr & 255.255.255.0 \
counter
3. Account traffic to each host per user:
# nft filter output \
flow skuid . ip daddr \
counter
4. Account traffic for each combination of source address and TCP flags:
# nft filter input \
flow ip saddr . tcp flags \
counter
The resulting set content after a Xmas-scan look like this:
{
192.168.122.1 . fin | psh | urg : counter packets 1001 bytes 40040,
192.168.122.1 . ack : counter packets 74 bytes 3848,
192.168.122.1 . psh | ack : counter packets 35 bytes 3144
}
In the future the "expressions attached to elements" will be extended
to also support user created non-stateful expressions to allow to
efficiently select beween a set of parameter sets, f.i. a set of log
statements with different prefixes based on the interface, which currently
require one rule each. This will most likely have to wait until the next
kernel version though.
====================
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master
Thanks!
----------------------------------------------------------------
The following changes since commit e60a9de49c3744aa44128eaaed3aca965911ca2e:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue (2015-04-12 21:36:57 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master
for you to fetch changes up to 97bb43c3e06e9bfdc9e3140a312004df462685b9:
netfilter: nf_tables: get rid of the expression example code (2015-04-13 20:20:09 +0200)
----------------------------------------------------------------
Pablo Neira Ayuso (2):
uapi: ebtables: don't include linux/if.h
netfilter: nf_tables: get rid of the expression example code
Patrick McHardy (19):
netfilter: nf_tables: validate len in nft_validate_data_load()
netfilter: nf_tables: rename nft_validate_data_load()
netfilter: nft_lookup: use nft_validate_register_store() to validate types
netfilter: nf_tables: kill nft_validate_output_register()
netfilter: nf_tables: introduce nft_validate_register_load()
netfilter: nf_tables: get rid of NFT_REG_VERDICT usage
netfilter: nf_tables: use struct nft_verdict within struct nft_data
netfilter: nf_tables: convert expressions to u32 register pointers
netfilter: nf_tables: kill nft_data_cmp()
netfilter: nf_tables: convert sets to u32 data pointers
netfilter: nf_tables: add register parsing/dumping helpers
netfilter: nf_tables: switch registers to 32 bit addressing
netfilter: nf_tables: support variable sized data in nft_data_init()
netfilter: nf_tables: variable sized set element keys / data
netfilter: nf_tables: add helper functions for expression handling
netfilter: nf_tables: prepare for expressions associated to set elements
netfilter: nf_tables: mark stateful expressions
netfilter: nf_tables: add flag to indicate set contains expressions
netfilter: nft_dynset: dynamic stateful expression instantiation
include/linux/netfilter_bridge/ebtables.h | 3 +-
include/net/netfilter/nf_tables.h | 103 ++++++---
include/net/netfilter/nft_meta.h | 4 +-
include/uapi/linux/netfilter/nf_tables.h | 40 +++-
include/uapi/linux/netfilter_bridge/ebtables.h | 2 -
net/bridge/netfilter/nft_meta_bridge.c | 26 +--
net/bridge/netfilter/nft_reject_bridge.c | 6 +-
net/ipv4/netfilter/nft_masq_ipv4.c | 9 +-
net/ipv4/netfilter/nft_redir_ipv4.c | 11 +-
net/ipv4/netfilter/nft_reject_ipv4.c | 4 +-
net/ipv6/netfilter/nft_masq_ipv6.c | 7 +-
net/ipv6/netfilter/nft_redir_ipv6.c | 11 +-
net/ipv6/netfilter/nft_reject_ipv6.c | 4 +-
net/netfilter/nf_tables_api.c | 271 +++++++++++++++++-------
net/netfilter/nf_tables_core.c | 41 ++--
net/netfilter/nft_bitwise.c | 37 ++--
net/netfilter/nft_byteorder.c | 40 ++--
net/netfilter/nft_cmp.c | 44 ++--
net/netfilter/nft_compat.c | 26 +--
net/netfilter/nft_counter.c | 3 +-
net/netfilter/nft_ct.c | 110 ++++++----
net/netfilter/nft_dynset.c | 79 +++++--
net/netfilter/nft_expr_template.c | 94 --------
net/netfilter/nft_exthdr.c | 23 +-
net/netfilter/nft_hash.c | 19 +-
net/netfilter/nft_immediate.c | 18 +-
net/netfilter/nft_limit.c | 5 +-
net/netfilter/nft_log.c | 2 +-
net/netfilter/nft_lookup.c | 31 ++-
net/netfilter/nft_meta.c | 107 +++++-----
net/netfilter/nft_nat.c | 71 ++++---
net/netfilter/nft_payload.c | 24 +--
net/netfilter/nft_queue.c | 4 +-
net/netfilter/nft_rbtree.c | 15 +-
net/netfilter/nft_redir.c | 19 +-
net/netfilter/nft_reject_inet.c | 5 +-
36 files changed, 739 insertions(+), 579 deletions(-)
delete mode 100644 net/netfilter/nft_expr_template.c
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 01/21] netfilter: nf_tables: validate len in nft_validate_data_load()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 02/21] netfilter: nf_tables: rename nft_validate_data_load() Pablo Neira Ayuso
` (20 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
For values spanning multiple registers, we need to validate that enough
space is available from the destination register onwards. Add a len
argument to nft_validate_data_load() and consolidate the existing length
validations in preparation of that.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 +-
net/bridge/netfilter/nft_meta_bridge.c | 5 +++-
net/netfilter/nf_tables_api.c | 18 ++++++++----
net/netfilter/nft_bitwise.c | 8 ++++--
net/netfilter/nft_byteorder.c | 27 +++++++++---------
net/netfilter/nft_ct.c | 48 +++++++++++++++++++++++++++-----
net/netfilter/nft_exthdr.c | 6 ++--
net/netfilter/nft_immediate.c | 3 +-
net/netfilter/nft_meta.c | 19 +++++++++----
net/netfilter/nft_payload.c | 7 ++---
10 files changed, 97 insertions(+), 46 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d6a2f0e..f491243 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -116,7 +116,7 @@ int nft_validate_input_register(enum nft_registers reg);
int nft_validate_output_register(enum nft_registers reg);
int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
const struct nft_data *data,
- enum nft_data_types type);
+ enum nft_data_types type, unsigned int len);
/**
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 4f02109..2011b89 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -53,12 +53,14 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_meta *priv = nft_expr_priv(expr);
+ unsigned int len;
int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
case NFT_META_BRI_IIFNAME:
case NFT_META_BRI_OIFNAME:
+ len = IFNAMSIZ;
break;
default:
return nft_meta_get_init(ctx, expr, tb);
@@ -69,7 +71,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0b96fa0..564f9ed 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2799,7 +2799,8 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
dreg = nft_type_to_reg(set->dtype);
return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext),
set->dtype == NFT_DATA_VERDICT ?
- NFT_DATA_VERDICT : NFT_DATA_VALUE);
+ NFT_DATA_VERDICT : NFT_DATA_VALUE,
+ set->dlen);
}
int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
@@ -3334,7 +3335,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
continue;
err = nft_validate_data_load(&bind_ctx, dreg,
- &data, d2.type);
+ &data, d2.type, d2.len);
if (err < 0)
goto err3;
}
@@ -4162,15 +4163,16 @@ EXPORT_SYMBOL_GPL(nft_validate_output_register);
* @reg: the destination register number
* @data: the data to load
* @type: the data type
+ * @len: the length of the data
*
* Validate that a data load uses the appropriate data type for
- * the destination register. A value of NULL for the data means
- * that its runtime gathered data, which is always of type
- * NFT_DATA_VALUE.
+ * the destination register and the length is within the bounds.
+ * A value of NULL for the data means that its runtime gathered
+ * data, which is always of type NFT_DATA_VALUE.
*/
int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
const struct nft_data *data,
- enum nft_data_types type)
+ enum nft_data_types type, unsigned int len)
{
int err;
@@ -4193,6 +4195,10 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
return 0;
default:
+ if (len == 0)
+ return -EINVAL;
+ if (len > FIELD_SIZEOF(struct nft_data, data))
+ return -ERANGE;
if (data != NULL && type != NFT_DATA_VALUE)
return -EINVAL;
return 0;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 4fb6ee2..fcd951f 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -63,6 +63,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
+ priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+
priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
err = nft_validate_input_register(priv->sreg);
if (err < 0)
@@ -72,12 +74,12 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
if (err < 0)
return err;
- priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
-
err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index c39ed8d..183f133 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -87,19 +87,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
tb[NFTA_BYTEORDER_OP] == NULL)
return -EINVAL;
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
- err = nft_validate_input_register(priv->sreg);
- if (err < 0)
- return err;
-
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
- if (err < 0)
- return err;
-
priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP]));
switch (priv->op) {
case NFT_BYTEORDER_NTOH:
@@ -122,6 +109,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
+ priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
+ err = nft_validate_input_register(priv->sreg);
+ if (err < 0)
+ return err;
+
+ priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
+ err = nft_validate_output_register(priv->dreg);
+ if (err < 0)
+ return err;
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
+ if (err < 0)
+ return err;
+
return 0;
}
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 18d520e..ce368de 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -95,8 +95,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
helper = rcu_dereference(help->helper);
if (helper == NULL)
goto err;
- if (strlen(helper->name) >= sizeof(dest->data))
- goto err;
strncpy((char *)dest->data, helper->name, sizeof(dest->data));
return;
#ifdef CONFIG_NF_CONNTRACK_LABELS
@@ -109,9 +107,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
return;
}
- BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data));
size = labels->words * sizeof(long);
-
memcpy(dest->data, labels->bits, size);
if (size < sizeof(dest->data))
memset(((char *) dest->data) + size, 0,
@@ -228,12 +224,17 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_ct *priv = nft_expr_priv(expr);
+ unsigned int len;
int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
switch (priv->key) {
- case NFT_CT_STATE:
case NFT_CT_DIRECTION:
+ if (tb[NFTA_CT_DIRECTION] != NULL)
+ return -EINVAL;
+ len = sizeof(u8);
+ break;
+ case NFT_CT_STATE:
case NFT_CT_STATUS:
#ifdef CONFIG_NF_CONNTRACK_MARK
case NFT_CT_MARK:
@@ -241,22 +242,54 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
#ifdef CONFIG_NF_CONNTRACK_SECMARK
case NFT_CT_SECMARK:
#endif
+ case NFT_CT_EXPIRATION:
+ if (tb[NFTA_CT_DIRECTION] != NULL)
+ return -EINVAL;
+ len = sizeof(u32);
+ break;
#ifdef CONFIG_NF_CONNTRACK_LABELS
case NFT_CT_LABELS:
+ if (tb[NFTA_CT_DIRECTION] != NULL)
+ return -EINVAL;
+ len = NF_CT_LABELS_MAX_SIZE;
+ break;
#endif
- case NFT_CT_EXPIRATION:
case NFT_CT_HELPER:
if (tb[NFTA_CT_DIRECTION] != NULL)
return -EINVAL;
+ len = NF_CT_HELPER_NAME_LEN;
break;
+
case NFT_CT_L3PROTOCOL:
case NFT_CT_PROTOCOL:
+ if (tb[NFTA_CT_DIRECTION] == NULL)
+ return -EINVAL;
+ len = sizeof(u8);
+ break;
case NFT_CT_SRC:
case NFT_CT_DST:
+ if (tb[NFTA_CT_DIRECTION] == NULL)
+ return -EINVAL;
+
+ switch (ctx->afi->family) {
+ case NFPROTO_IPV4:
+ len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+ src.u3.ip);
+ break;
+ case NFPROTO_IPV6:
+ case NFPROTO_INET:
+ len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+ src.u3.ip6);
+ break;
+ default:
+ return -EAFNOSUPPORT;
+ }
+ break;
case NFT_CT_PROTO_SRC:
case NFT_CT_PROTO_DST:
if (tb[NFTA_CT_DIRECTION] == NULL)
return -EINVAL;
+ len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
break;
default:
return -EOPNOTSUPP;
@@ -278,7 +311,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 55c939f..a0a3227 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -69,15 +69,13 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
- if (priv->len == 0 ||
- priv->len > FIELD_SIZEOF(struct nft_data, data))
- return -EINVAL;
priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG]));
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+ return nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
}
static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 810385e..1970d8d 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -59,7 +59,8 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
return err;
priv->dlen = desc.len;
- err = nft_validate_data_load(ctx, priv->dreg, &priv->data, desc.type);
+ err = nft_validate_data_load(ctx, priv->dreg, &priv->data,
+ desc.type, desc.len);
if (err < 0)
goto err1;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index d79ce88..d4bdd77 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -217,22 +217,23 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_meta *priv = nft_expr_priv(expr);
+ unsigned int len;
int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
- case NFT_META_LEN:
case NFT_META_PROTOCOL:
+ case NFT_META_IIFTYPE:
+ case NFT_META_OIFTYPE:
+ len = sizeof(u16);
+ break;
case NFT_META_NFPROTO:
case NFT_META_L4PROTO:
+ case NFT_META_LEN:
case NFT_META_PRIORITY:
case NFT_META_MARK:
case NFT_META_IIF:
case NFT_META_OIF:
- case NFT_META_IIFNAME:
- case NFT_META_OIFNAME:
- case NFT_META_IIFTYPE:
- case NFT_META_OIFTYPE:
case NFT_META_SKUID:
case NFT_META_SKGID:
#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -246,6 +247,11 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
case NFT_META_IIFGROUP:
case NFT_META_OIFGROUP:
case NFT_META_CGROUP:
+ len = sizeof(u32);
+ break;
+ case NFT_META_IIFNAME:
+ case NFT_META_OIFNAME:
+ len = IFNAMSIZ;
break;
default:
return -EOPNOTSUPP;
@@ -256,7 +262,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 85daa84..7bed3e0 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -72,7 +72,8 @@ static int nft_payload_init(const struct nft_ctx *ctx,
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+ return nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
}
static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
@@ -131,9 +132,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx,
}
offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
- len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
- if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data))
- return ERR_PTR(-EINVAL);
+ len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
base != NFT_PAYLOAD_LL_HEADER)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 02/21] netfilter: nf_tables: rename nft_validate_data_load()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 01/21] netfilter: nf_tables: validate len in nft_validate_data_load() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 03/21] netfilter: nft_lookup: use nft_validate_register_store() to validate types Pablo Neira Ayuso
` (19 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The existing name is ambiguous, data is loaded as well when we read from
a register. Rename to nft_validate_register_store() for clarity and
consistency with the upcoming patch to introduce its counterpart,
nft_validate_register_load().
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 7 ++++---
net/bridge/netfilter/nft_meta_bridge.c | 4 ++--
net/netfilter/nf_tables_api.c | 24 +++++++++++++-----------
net/netfilter/nft_bitwise.c | 4 ++--
net/netfilter/nft_byteorder.c | 4 ++--
net/netfilter/nft_ct.c | 4 ++--
net/netfilter/nft_exthdr.c | 4 ++--
net/netfilter/nft_immediate.c | 4 ++--
net/netfilter/nft_meta.c | 4 ++--
net/netfilter/nft_payload.c | 4 ++--
10 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f491243..7251f20 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -114,9 +114,10 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
int nft_validate_input_register(enum nft_registers reg);
int nft_validate_output_register(enum nft_registers reg);
-int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
- const struct nft_data *data,
- enum nft_data_types type, unsigned int len);
+int nft_validate_register_store(const struct nft_ctx *ctx,
+ enum nft_registers reg,
+ const struct nft_data *data,
+ enum nft_data_types type, unsigned int len);
/**
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 2011b89..ee9e0b7 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -71,8 +71,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, len);
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 564f9ed..a1e4a92 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2797,10 +2797,10 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
enum nft_registers dreg;
dreg = nft_type_to_reg(set->dtype);
- return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext),
- set->dtype == NFT_DATA_VERDICT ?
- NFT_DATA_VERDICT : NFT_DATA_VALUE,
- set->dlen);
+ return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
+ set->dtype == NFT_DATA_VERDICT ?
+ NFT_DATA_VERDICT : NFT_DATA_VALUE,
+ set->dlen);
}
int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
@@ -3334,8 +3334,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (!(binding->flags & NFT_SET_MAP))
continue;
- err = nft_validate_data_load(&bind_ctx, dreg,
- &data, d2.type, d2.len);
+ err = nft_validate_register_store(&bind_ctx, dreg,
+ &data,
+ d2.type, d2.len);
if (err < 0)
goto err3;
}
@@ -4157,7 +4158,7 @@ int nft_validate_output_register(enum nft_registers reg)
EXPORT_SYMBOL_GPL(nft_validate_output_register);
/**
- * nft_validate_data_load - validate an expressions' data load
+ * nft_validate_register_store - validate an expressions' register store
*
* @ctx: context of the expression performing the load
* @reg: the destination register number
@@ -4170,9 +4171,10 @@ EXPORT_SYMBOL_GPL(nft_validate_output_register);
* A value of NULL for the data means that its runtime gathered
* data, which is always of type NFT_DATA_VALUE.
*/
-int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
- const struct nft_data *data,
- enum nft_data_types type, unsigned int len)
+int nft_validate_register_store(const struct nft_ctx *ctx,
+ enum nft_registers reg,
+ const struct nft_data *data,
+ enum nft_data_types type, unsigned int len)
{
int err;
@@ -4204,7 +4206,7 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
return 0;
}
}
-EXPORT_SYMBOL_GPL(nft_validate_data_load);
+EXPORT_SYMBOL_GPL(nft_validate_register_store);
static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
[NFTA_VERDICT_CODE] = { .type = NLA_U32 },
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index fcd951f..afad27c 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -75,8 +75,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, priv->len);
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index 183f133..03bfb75 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -118,8 +118,8 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, priv->len);
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index ce368de..e23ddb6 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -311,8 +311,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, len);
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index a0a3227..ab16a38 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -74,8 +74,8 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- return nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, priv->len);
+ return nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
}
static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 1970d8d..d058a93 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -59,8 +59,8 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
return err;
priv->dlen = desc.len;
- err = nft_validate_data_load(ctx, priv->dreg, &priv->data,
- desc.type, desc.len);
+ err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
+ desc.type, desc.len);
if (err < 0)
goto err1;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index d4bdd77..b733755 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -262,8 +262,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, len);
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 7bed3e0..9c7ad4b 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -72,8 +72,8 @@ static int nft_payload_init(const struct nft_ctx *ctx,
err = nft_validate_output_register(priv->dreg);
if (err < 0)
return err;
- return nft_validate_data_load(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, priv->len);
+ return nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
}
static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 03/21] netfilter: nft_lookup: use nft_validate_register_store() to validate types
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 01/21] netfilter: nf_tables: validate len in nft_validate_data_load() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 02/21] netfilter: nf_tables: rename nft_validate_data_load() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 04/21] netfilter: nf_tables: kill nft_validate_output_register() Pablo Neira Ayuso
` (18 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
In preparation of validating the length of a register store, use
nft_validate_register_store() in nft_lookup instead of open coding the
validation.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 7 ++++---
net/netfilter/nft_lookup.c | 9 ++++-----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a1e4a92..c96070e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4169,7 +4169,7 @@ EXPORT_SYMBOL_GPL(nft_validate_output_register);
* Validate that a data load uses the appropriate data type for
* the destination register and the length is within the bounds.
* A value of NULL for the data means that its runtime gathered
- * data, which is always of type NFT_DATA_VALUE.
+ * data.
*/
int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg,
@@ -4180,10 +4180,11 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
switch (reg) {
case NFT_REG_VERDICT:
- if (data == NULL || type != NFT_DATA_VERDICT)
+ if (type != NFT_DATA_VERDICT)
return -EINVAL;
- if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) {
+ if (data != NULL &&
+ (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP)) {
err = nf_tables_check_loops(ctx, data->chain);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index d8cf86f..3e4d8ef 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -84,11 +84,10 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- if (priv->dreg == NFT_REG_VERDICT) {
- if (set->dtype != NFT_DATA_VERDICT)
- return -EINVAL;
- } else if (set->dtype == NFT_DATA_VERDICT)
- return -EINVAL;
+ err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ set->dtype, set->dlen);
+ if (err < 0)
+ return err;
} else if (set->flags & NFT_SET_MAP)
return -EINVAL;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 04/21] netfilter: nf_tables: kill nft_validate_output_register()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (2 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 03/21] netfilter: nft_lookup: use nft_validate_register_store() to validate types Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 05/21] netfilter: nf_tables: introduce nft_validate_register_load() Pablo Neira Ayuso
` (17 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
All users of nft_validate_register_store() first invoke
nft_validate_output_register(). There is in fact no use for using it
on its own, so simplify the code by folding the functionality into
nft_validate_register_store() and kill it.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 1 -
net/bridge/netfilter/nft_meta_bridge.c | 13 ++-----------
net/netfilter/nf_tables_api.c | 23 +++++------------------
net/netfilter/nft_bitwise.c | 4 ----
net/netfilter/nft_byteorder.c | 11 ++---------
net/netfilter/nft_ct.c | 4 ----
net/netfilter/nft_exthdr.c | 6 +-----
net/netfilter/nft_immediate.c | 6 +-----
net/netfilter/nft_lookup.c | 4 ----
net/netfilter/nft_meta.c | 13 ++-----------
net/netfilter/nft_payload.c | 6 +-----
11 files changed, 14 insertions(+), 77 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 7251f20..a8d4bd3 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -113,7 +113,6 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
}
int nft_validate_input_register(enum nft_registers reg);
-int nft_validate_output_register(enum nft_registers reg);
int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg,
const struct nft_data *data,
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index ee9e0b7..54d9847 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -54,7 +54,6 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int len;
- int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
@@ -67,16 +66,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
}
priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
- err = nft_validate_register_store(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, len);
- if (err < 0)
- return err;
-
- return 0;
+ return nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
}
static struct nft_expr_type nft_meta_bridge_type;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c96070e..f01e89fe 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4140,24 +4140,6 @@ int nft_validate_input_register(enum nft_registers reg)
EXPORT_SYMBOL_GPL(nft_validate_input_register);
/**
- * nft_validate_output_register - validate an expressions' output register
- *
- * @reg: the register number
- *
- * Validate that the output register is one of the general purpose
- * registers or the verdict register.
- */
-int nft_validate_output_register(enum nft_registers reg)
-{
- if (reg < NFT_REG_VERDICT)
- return -EINVAL;
- if (reg > NFT_REG_MAX)
- return -ERANGE;
- return 0;
-}
-EXPORT_SYMBOL_GPL(nft_validate_output_register);
-
-/**
* nft_validate_register_store - validate an expressions' register store
*
* @ctx: context of the expression performing the load
@@ -4198,10 +4180,15 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
return 0;
default:
+ if (reg < NFT_REG_1)
+ return -EINVAL;
+ if (reg > NFT_REG_MAX)
+ return -ERANGE;
if (len == 0)
return -EINVAL;
if (len > FIELD_SIZEOF(struct nft_data, data))
return -ERANGE;
+
if (data != NULL && type != NFT_DATA_VALUE)
return -EINVAL;
return 0;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index afad27c..d312052 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -71,10 +71,6 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
return err;
priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
err = nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
if (err < 0)
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index 03bfb75..848bce0 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -115,15 +115,8 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return err;
priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
- err = nft_validate_register_store(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, priv->len);
- if (err < 0)
- return err;
-
- return 0;
+ return nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, priv->len);
}
static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index e23ddb6..d85f9ad 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -307,10 +307,6 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
}
priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
err = nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, len);
if (err < 0)
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index ab16a38..8c4981c 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -58,7 +58,6 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_exthdr *priv = nft_expr_priv(expr);
- int err;
if (tb[NFTA_EXTHDR_DREG] == NULL ||
tb[NFTA_EXTHDR_TYPE] == NULL ||
@@ -69,11 +68,8 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
+ priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG]));
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
}
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index d058a93..a164c04 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -49,16 +49,12 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA] == NULL)
return -EINVAL;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
priv->dlen = desc.len;
+ priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG]));
err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
desc.type, desc.len);
if (err < 0)
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 3e4d8ef..3574543 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -80,10 +80,6 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
return -EINVAL;
priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
err = nft_validate_register_store(ctx, priv->dreg, NULL,
set->dtype, set->dlen);
if (err < 0)
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index b733755..fbaee1d 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -218,7 +218,6 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int len;
- int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
@@ -258,16 +257,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
}
priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
-
- err = nft_validate_register_store(ctx, priv->dreg, NULL,
- NFT_DATA_VALUE, len);
- if (err < 0)
- return err;
-
- return 0;
+ return nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE, len);
}
EXPORT_SYMBOL_GPL(nft_meta_get_init);
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 9c7ad4b..b2a9ef9 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -62,16 +62,12 @@ static int nft_payload_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_payload *priv = nft_expr_priv(expr);
- int err;
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
+ priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG]));
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- return err;
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 05/21] netfilter: nf_tables: introduce nft_validate_register_load()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (3 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 04/21] netfilter: nf_tables: kill nft_validate_output_register() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 06/21] netfilter: nf_tables: get rid of NFT_REG_VERDICT usage Pablo Neira Ayuso
` (16 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Change nft_validate_input_register() to not only validate the input
register number, but also the length of the load, and rename it to
nft_validate_register_load() to reflect that change.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 3 +--
net/netfilter/nf_tables_api.c | 13 +++++++++----
net/netfilter/nft_bitwise.c | 5 ++---
net/netfilter/nft_byteorder.c | 7 ++-----
net/netfilter/nft_cmp.c | 25 +++++++++++++------------
net/netfilter/nft_ct.c | 4 +++-
net/netfilter/nft_dynset.c | 4 ++--
net/netfilter/nft_lookup.c | 2 +-
net/netfilter/nft_meta.c | 6 +++++-
net/netfilter/nft_nat.c | 26 +++++++++++++++++++-------
net/netfilter/nft_redir.c | 7 +++++--
11 files changed, 62 insertions(+), 40 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index a8d4bd3..9cc3d55 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -112,13 +112,12 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
}
-int nft_validate_input_register(enum nft_registers reg);
+int nft_validate_register_load(enum nft_registers reg, unsigned int len);
int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg,
const struct nft_data *data,
enum nft_data_types type, unsigned int len);
-
/**
* struct nft_userdata - user defined data associated with an object
*
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index f01e89fe..d47f12b 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4122,22 +4122,27 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
}
/**
- * nft_validate_input_register - validate an expressions' input register
+ * nft_validate_register_load - validate a load from a register
*
* @reg: the register number
+ * @len: the length of the data
*
* Validate that the input register is one of the general purpose
- * registers.
+ * registers and that the length of the load is within the bounds.
*/
-int nft_validate_input_register(enum nft_registers reg)
+int nft_validate_register_load(enum nft_registers reg, unsigned int len)
{
if (reg <= NFT_REG_VERDICT)
return -EINVAL;
if (reg > NFT_REG_MAX)
return -ERANGE;
+ if (len == 0)
+ return -EINVAL;
+ if (len > FIELD_SIZEOF(struct nft_data, data))
+ return -ERANGE;
return 0;
}
-EXPORT_SYMBOL_GPL(nft_validate_input_register);
+EXPORT_SYMBOL_GPL(nft_validate_register_load);
/**
* nft_validate_register_store - validate an expressions' register store
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d312052..60050ee 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -63,10 +63,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
- priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
-
+ priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
- err = nft_validate_input_register(priv->sreg);
+ err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index 848bce0..f34bfbd 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -96,10 +96,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
- priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
- if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
- return -EINVAL;
-
priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
switch (priv->size) {
case 2:
@@ -110,7 +106,8 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
}
priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
- err = nft_validate_input_register(priv->sreg);
+ priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+ err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e2b3f51..17e9b8b 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -75,12 +75,15 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct nft_data_desc desc;
int err;
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
- priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
-
err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
+ priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+ err = nft_validate_register_load(priv->sreg, desc.len);
+ if (err < 0)
+ return err;
+
+ priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
priv->len = desc.len;
return 0;
}
@@ -122,13 +125,17 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
u32 mask;
int err;
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
-
err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
- desc.len *= BITS_PER_BYTE;
+ priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+ err = nft_validate_register_load(priv->sreg, desc.len);
+ if (err < 0)
+ return err;
+
+ desc.len *= BITS_PER_BYTE;
mask = nft_cmp_fast_mask(desc.len);
+
priv->data = data.data[0] & mask;
priv->len = desc.len;
return 0;
@@ -167,7 +174,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
{
struct nft_data_desc desc;
struct nft_data data;
- enum nft_registers sreg;
enum nft_cmp_ops op;
int err;
@@ -176,11 +182,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
tb[NFTA_CMP_DATA] == NULL)
return ERR_PTR(-EINVAL);
- sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
- err = nft_validate_input_register(sreg);
- if (err < 0)
- return ERR_PTR(err);
-
op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
switch (op) {
case NFT_CMP_EQ:
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index d85f9ad..6bf6ed7 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -324,12 +324,14 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_ct *priv = nft_expr_priv(expr);
+ unsigned int len;
int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
switch (priv->key) {
#ifdef CONFIG_NF_CONNTRACK_MARK
case NFT_CT_MARK:
+ len = FIELD_SIZEOF(struct nf_conn, mark);
break;
#endif
default:
@@ -337,7 +339,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
}
priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
- err = nft_validate_input_register(priv->sreg);
+ err = nft_validate_register_load(priv->sreg, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index eeb72de..3ea52b7 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -124,7 +124,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
}
priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY]));
- err = nft_validate_input_register(priv->sreg_key);
+ err = nft_validate_register_load(priv->sreg_key, set->klen);;
if (err < 0)
return err;
@@ -135,7 +135,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA]));
- err = nft_validate_input_register(priv->sreg_data);
+ err = nft_validate_register_load(priv->sreg_data, set->dlen);
if (err < 0)
return err;
} else if (set->flags & NFT_SET_MAP)
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 3574543..8fc0d18 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -71,7 +71,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
}
priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG]));
- err = nft_validate_input_register(priv->sreg);
+ err = nft_validate_register_load(priv->sreg, set->klen);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index fbaee1d..0ae6bb7 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -267,20 +267,24 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_meta *priv = nft_expr_priv(expr);
+ unsigned int len;
int err;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
case NFT_META_MARK:
case NFT_META_PRIORITY:
+ len = sizeof(u32);
+ break;
case NFT_META_NFTRACE:
+ len = sizeof(u8);
break;
default:
return -EOPNOTSUPP;
}
priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG]));
- err = nft_validate_input_register(priv->sreg);
+ err = nft_validate_register_load(priv->sreg, len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index a0837c6..0897a80 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -119,6 +119,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
const struct nlattr * const tb[])
{
struct nft_nat *priv = nft_expr_priv(expr);
+ unsigned int alen, plen;
u32 family;
int err;
@@ -146,17 +147,25 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return -EINVAL;
family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
- if (family != AF_INET && family != AF_INET6)
- return -EAFNOSUPPORT;
if (family != ctx->afi->family)
return -EOPNOTSUPP;
+
+ switch (family) {
+ case NFPROTO_IPV4:
+ alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip);
+ break;
+ case NFPROTO_IPV6:
+ alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
+ break;
+ default:
+ return -EAFNOSUPPORT;
+ }
priv->family = family;
if (tb[NFTA_NAT_REG_ADDR_MIN]) {
priv->sreg_addr_min =
ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN]));
-
- err = nft_validate_input_register(priv->sreg_addr_min);
+ err = nft_validate_register_load(priv->sreg_addr_min, alen);
if (err < 0)
return err;
@@ -164,7 +173,8 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
priv->sreg_addr_max =
ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX]));
- err = nft_validate_input_register(priv->sreg_addr_max);
+ err = nft_validate_register_load(priv->sreg_addr_max,
+ alen);
if (err < 0)
return err;
} else {
@@ -172,11 +182,12 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
}
}
+ plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
if (tb[NFTA_NAT_REG_PROTO_MIN]) {
priv->sreg_proto_min =
ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN]));
- err = nft_validate_input_register(priv->sreg_proto_min);
+ err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0)
return err;
@@ -184,7 +195,8 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
priv->sreg_proto_max =
ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX]));
- err = nft_validate_input_register(priv->sreg_proto_max);
+ err = nft_validate_register_load(priv->sreg_proto_max,
+ plen);
if (err < 0)
return err;
} else {
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index d7e9e93..9819466 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -44,17 +44,19 @@ int nft_redir_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[])
{
struct nft_redir *priv = nft_expr_priv(expr);
+ unsigned int plen;
int err;
err = nft_redir_validate(ctx, expr, NULL);
if (err < 0)
return err;
+ plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
priv->sreg_proto_min =
ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
- err = nft_validate_input_register(priv->sreg_proto_min);
+ err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0)
return err;
@@ -62,7 +64,8 @@ int nft_redir_init(const struct nft_ctx *ctx,
priv->sreg_proto_max =
ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]));
- err = nft_validate_input_register(priv->sreg_proto_max);
+ err = nft_validate_register_load(priv->sreg_proto_max,
+ plen);
if (err < 0)
return err;
} else {
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 06/21] netfilter: nf_tables: get rid of NFT_REG_VERDICT usage
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (4 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 05/21] netfilter: nf_tables: introduce nft_validate_register_load() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 07/21] netfilter: nf_tables: use struct nft_verdict within struct nft_data Pablo Neira Ayuso
` (15 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Replace the array of registers passed to expressions by a struct nft_regs,
containing the verdict as a seperate member, which aliases to the
NFT_REG_VERDICT register.
This is needed to seperate the verdict from the data registers completely,
so their size can be changed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 32 +++++++++++++++++++++++++---
include/net/netfilter/nft_meta.h | 4 ++--
net/bridge/netfilter/nft_meta_bridge.c | 8 +++----
net/bridge/netfilter/nft_reject_bridge.c | 6 +++---
net/ipv4/netfilter/nft_masq_ipv4.c | 9 +++-----
net/ipv4/netfilter/nft_redir_ipv4.c | 11 +++++-----
net/ipv4/netfilter/nft_reject_ipv4.c | 4 ++--
net/ipv6/netfilter/nft_masq_ipv6.c | 7 ++----
net/ipv6/netfilter/nft_redir_ipv6.c | 11 +++++-----
net/ipv6/netfilter/nft_reject_ipv6.c | 4 ++--
net/netfilter/nf_tables_core.c | 34 +++++++++++++++---------------
net/netfilter/nft_bitwise.c | 6 +++---
net/netfilter/nft_byteorder.c | 5 +++--
net/netfilter/nft_cmp.c | 6 +++---
net/netfilter/nft_compat.c | 26 +++++++++++------------
net/netfilter/nft_counter.c | 2 +-
net/netfilter/nft_ct.c | 10 ++++-----
net/netfilter/nft_dynset.c | 13 ++++++------
net/netfilter/nft_exthdr.c | 6 +++---
net/netfilter/nft_hash.c | 6 +++---
net/netfilter/nft_immediate.c | 4 ++--
net/netfilter/nft_limit.c | 4 ++--
net/netfilter/nft_log.c | 2 +-
net/netfilter/nft_lookup.c | 9 ++++----
net/netfilter/nft_meta.c | 10 ++++-----
net/netfilter/nft_nat.c | 17 +++++++--------
net/netfilter/nft_payload.c | 6 +++---
net/netfilter/nft_queue.c | 4 ++--
net/netfilter/nft_reject_inet.c | 5 +++--
29 files changed, 146 insertions(+), 125 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 9cc3d55..79582d0 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -36,6 +36,17 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
pkt->xt.family = ops->pf;
}
+/**
+ * struct nft_verdict - nf_tables verdict
+ *
+ * @code: nf_tables/netfilter verdict code
+ * @chain: destination chain for NFT_JUMP/NFT_GOTO
+ */
+struct nft_verdict {
+ u32 code;
+ struct nft_chain *chain;
+};
+
struct nft_data {
union {
u32 data[4];
@@ -46,6 +57,21 @@ struct nft_data {
};
} __attribute__((aligned(__alignof__(u64))));
+/**
+ * struct nft_regs - nf_tables register set
+ *
+ * @data: data registers
+ * @verdict: verdict register
+ *
+ * The first four data registers alias to the verdict register.
+ */
+struct nft_regs {
+ union {
+ struct nft_data data[NFT_REG_MAX + 1];
+ struct nft_verdict verdict;
+ };
+};
+
static inline int nft_data_cmp(const struct nft_data *d1,
const struct nft_data *d2,
unsigned int len)
@@ -221,9 +247,9 @@ struct nft_set_ops {
const struct nft_data *key,
void *(*new)(struct nft_set *,
const struct nft_expr *,
- struct nft_data []),
+ struct nft_regs *),
const struct nft_expr *expr,
- struct nft_data data[],
+ struct nft_regs *regs,
const struct nft_set_ext **ext);
int (*insert)(const struct nft_set *set,
@@ -583,7 +609,7 @@ struct nft_expr_type {
struct nft_expr;
struct nft_expr_ops {
void (*eval)(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt);
unsigned int size;
diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
index 0ee47c3..711887a 100644
--- a/include/net/netfilter/nft_meta.h
+++ b/include/net/netfilter/nft_meta.h
@@ -26,11 +26,11 @@ 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],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt);
void nft_meta_set_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt);
#endif
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 54d9847..f0dfa38 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -19,12 +19,12 @@
#include "../br_private.h"
static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_meta *priv = nft_expr_priv(expr);
const struct net_device *in = pkt->in, *out = pkt->out;
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
const struct net_bridge_port *p;
switch (priv->key) {
@@ -43,9 +43,9 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data));
return;
out:
- return nft_meta_get_eval(expr, data, pkt);
+ return nft_meta_get_eval(expr, regs, pkt);
err:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index ae8141f..858d848 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -257,8 +257,8 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
}
static void nft_reject_bridge_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
- const struct nft_pktinfo *pkt)
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
@@ -310,7 +310,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr,
break;
}
out:
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+ regs->verdict.code = NF_DROP;
}
static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c
index 665de06..40e414c 100644
--- a/net/ipv4/netfilter/nft_masq_ipv4.c
+++ b/net/ipv4/netfilter/nft_masq_ipv4.c
@@ -17,20 +17,17 @@
#include <net/netfilter/ipv4/nf_nat_masquerade.h>
static void nft_masq_ipv4_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_masq *priv = nft_expr_priv(expr);
struct nf_nat_range range;
- unsigned int verdict;
memset(&range, 0, sizeof(range));
range.flags = priv->flags;
- verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
- &range, pkt->out);
-
- data[NFT_REG_VERDICT].verdict = verdict;
+ regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
+ &range, pkt->out);
}
static struct nft_expr_type nft_masq_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
index 6ecfce6..312cf6f 100644
--- a/net/ipv4/netfilter/nft_redir_ipv4.c
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -18,26 +18,25 @@
#include <net/netfilter/nft_redir.h>
static void nft_redir_ipv4_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_ipv4_multi_range_compat mr;
- unsigned int verdict;
memset(&mr, 0, sizeof(mr));
if (priv->sreg_proto_min) {
mr.range[0].min.all =
- *(__be16 *)&data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
mr.range[0].max.all =
- *(__be16 *)&data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
mr.range[0].flags |= priv->flags;
- verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum);
- data[NFT_REG_VERDICT].verdict = verdict;
+ regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr,
+ pkt->ops->hooknum);
}
static struct nft_expr_type nft_redir_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index a7621fa..b07e58b 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -20,7 +20,7 @@
#include <net/netfilter/nft_reject.h>
static void nft_reject_ipv4_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
@@ -37,7 +37,7 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr,
break;
}
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+ regs->verdict.code = NF_DROP;
}
static struct nft_expr_type nft_reject_ipv4_type;
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c
index 529c119..cd1ac16 100644
--- a/net/ipv6/netfilter/nft_masq_ipv6.c
+++ b/net/ipv6/netfilter/nft_masq_ipv6.c
@@ -18,19 +18,16 @@
#include <net/netfilter/ipv6/nf_nat_masquerade.h>
static void nft_masq_ipv6_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_masq *priv = nft_expr_priv(expr);
struct nf_nat_range range;
- unsigned int verdict;
memset(&range, 0, sizeof(range));
range.flags = priv->flags;
- verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
-
- data[NFT_REG_VERDICT].verdict = verdict;
+ regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
}
static struct nft_expr_type nft_masq_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c
index 11820b6..0eed774 100644
--- a/net/ipv6/netfilter/nft_redir_ipv6.c
+++ b/net/ipv6/netfilter/nft_redir_ipv6.c
@@ -18,26 +18,25 @@
#include <net/netfilter/nf_nat_redirect.h>
static void nft_redir_ipv6_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_range range;
- unsigned int verdict;
memset(&range, 0, sizeof(range));
if (priv->sreg_proto_min) {
range.min_proto.all =
- *(__be16 *)&data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
range.max_proto.all =
- *(__be16 *)&data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
range.flags |= priv->flags;
- verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum);
- data[NFT_REG_VERDICT].verdict = verdict;
+ regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range,
+ pkt->ops->hooknum);
}
static struct nft_expr_type nft_redir_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 71c7be5..d0d1540 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -20,7 +20,7 @@
#include <net/netfilter/ipv6/nf_reject.h>
static void nft_reject_ipv6_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
@@ -38,7 +38,7 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr,
break;
}
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+ regs->verdict.code = NF_DROP;
}
static struct nft_expr_type nft_reject_ipv6_type;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 7caf08a..667cdf0 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -65,23 +65,23 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
}
static void nft_cmp_fast_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1])
+ struct nft_regs *regs)
{
const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
u32 mask = nft_cmp_fast_mask(priv->len);
- if ((data[priv->sreg].data[0] & mask) == priv->data)
+ if ((regs->data[priv->sreg].data[0] & mask) == priv->data)
return;
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static bool nft_payload_fast_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
unsigned char *ptr;
if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -116,7 +116,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
const struct nft_rule *rule;
const struct nft_expr *expr, *last;
- struct nft_data data[NFT_REG_MAX + 1];
+ struct nft_regs regs;
unsigned int stackptr = 0;
struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
struct nft_stats *stats;
@@ -127,7 +127,7 @@ do_chain:
rulenum = 0;
rule = list_entry(&chain->rules, struct nft_rule, list);
next_rule:
- data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ regs.verdict.code = NFT_CONTINUE;
list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
/* This rule is not active, skip. */
@@ -138,18 +138,18 @@ next_rule:
nft_rule_for_each_expr(expr, last, rule) {
if (expr->ops == &nft_cmp_fast_ops)
- nft_cmp_fast_eval(expr, data);
+ nft_cmp_fast_eval(expr, ®s);
else if (expr->ops != &nft_payload_fast_ops ||
- !nft_payload_fast_eval(expr, data, pkt))
- expr->ops->eval(expr, data, pkt);
+ !nft_payload_fast_eval(expr, ®s, pkt))
+ expr->ops->eval(expr, ®s, pkt);
- if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE)
+ if (regs.verdict.code != NFT_CONTINUE)
break;
}
- switch (data[NFT_REG_VERDICT].verdict) {
+ switch (regs.verdict.code) {
case NFT_BREAK:
- data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ regs.verdict.code = NFT_CONTINUE;
continue;
case NFT_CONTINUE:
nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
@@ -158,15 +158,15 @@ next_rule:
break;
}
- switch (data[NFT_REG_VERDICT].verdict & NF_VERDICT_MASK) {
+ switch (regs.verdict.code & NF_VERDICT_MASK) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
- return data[NFT_REG_VERDICT].verdict;
+ return regs.verdict.code;
}
- switch (data[NFT_REG_VERDICT].verdict) {
+ switch (regs.verdict.code) {
case NFT_JUMP:
BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE);
jumpstack[stackptr].chain = chain;
@@ -177,7 +177,7 @@ next_rule:
case NFT_GOTO:
nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
- chain = data[NFT_REG_VERDICT].chain;
+ chain = regs.verdict.chain;
goto do_chain;
case NFT_CONTINUE:
rulenum++;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 60050ee..2b8f518 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -26,12 +26,12 @@ struct nft_bitwise {
};
static void nft_bitwise_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_bitwise *priv = nft_expr_priv(expr);
- const struct nft_data *src = &data[priv->sreg];
- struct nft_data *dst = &data[priv->dreg];
+ const struct nft_data *src = ®s->data[priv->sreg];
+ struct nft_data *dst = ®s->data[priv->dreg];
unsigned int i;
for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++) {
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index f34bfbd..48fbfa3 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -26,11 +26,12 @@ struct nft_byteorder {
};
static void nft_byteorder_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_byteorder *priv = nft_expr_priv(expr);
- struct nft_data *src = &data[priv->sreg], *dst = &data[priv->dreg];
+ struct nft_data *src = ®s->data[priv->sreg];
+ struct nft_data *dst = ®s->data[priv->dreg];
union { u32 u32; u16 u16; } *s, *d;
unsigned int i;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index 17e9b8b..59391e6 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -25,13 +25,13 @@ struct nft_cmp_expr {
};
static void nft_cmp_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_cmp_expr *priv = nft_expr_priv(expr);
int d;
- d = nft_data_cmp(&data[priv->sreg], &priv->data, priv->len);
+ d = nft_data_cmp(®s->data[priv->sreg], &priv->data, priv->len);
switch (priv->op) {
case NFT_CMP_EQ:
if (d != 0)
@@ -59,7 +59,7 @@ static void nft_cmp_eval(const struct nft_expr *expr,
return;
mismatch:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_cmp_policy[NFTA_CMP_MAX + 1] = {
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 0d137c1..7f29cfc 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -55,7 +55,7 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
}
static void nft_target_eval_xt(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
void *info = nft_expr_priv(expr);
@@ -72,16 +72,16 @@ static void nft_target_eval_xt(const struct nft_expr *expr,
switch (ret) {
case XT_CONTINUE:
- data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ regs->verdict.code = NFT_CONTINUE;
break;
default:
- data[NFT_REG_VERDICT].verdict = ret;
+ regs->verdict.code = ret;
break;
}
}
static void nft_target_eval_bridge(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
void *info = nft_expr_priv(expr);
@@ -98,19 +98,19 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
switch (ret) {
case EBT_ACCEPT:
- data[NFT_REG_VERDICT].verdict = NF_ACCEPT;
+ regs->verdict.code = NF_ACCEPT;
break;
case EBT_DROP:
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+ regs->verdict.code = NF_DROP;
break;
case EBT_CONTINUE:
- data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ regs->verdict.code = NFT_CONTINUE;
break;
case EBT_RETURN:
- data[NFT_REG_VERDICT].verdict = NFT_RETURN;
+ regs->verdict.code = NFT_RETURN;
break;
default:
- data[NFT_REG_VERDICT].verdict = ret;
+ regs->verdict.code = ret;
break;
}
}
@@ -304,7 +304,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
}
static void nft_match_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
void *info = nft_expr_priv(expr);
@@ -317,16 +317,16 @@ static void nft_match_eval(const struct nft_expr *expr,
ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
if (pkt->xt.hotdrop) {
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+ regs->verdict.code = NF_DROP;
return;
}
switch (ret ? 1 : 0) {
case 1:
- data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+ regs->verdict.code = NFT_CONTINUE;
break;
case 0:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
break;
}
}
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index c89ee48..0f6367e 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -24,7 +24,7 @@ struct nft_counter {
};
static void nft_counter_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_counter *priv = nft_expr_priv(expr);
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 6bf6ed7..077e06b 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -31,11 +31,11 @@ struct nft_ct {
};
static void nft_ct_get_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_ct *priv = nft_expr_priv(expr);
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
enum ip_conntrack_info ctinfo;
const struct nf_conn *ct;
const struct nf_conn_help *help;
@@ -146,17 +146,17 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
}
return;
err:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static void nft_ct_set_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_ct *priv = nft_expr_priv(expr);
struct sk_buff *skb = pkt->skb;
#ifdef CONFIG_NF_CONNTRACK_MARK
- u32 value = data[priv->sreg].data[0];
+ u32 value = regs->data[priv->sreg].data[0];
#endif
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 3ea52b7..e398f6d 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -27,7 +27,7 @@ struct nft_dynset {
};
static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1])
+ struct nft_regs *regs)
{
const struct nft_dynset *priv = nft_expr_priv(expr);
u64 timeout;
@@ -38,7 +38,8 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
timeout = priv->timeout ? : set->timeout;
elem = nft_set_elem_init(set, &priv->tmpl,
- &data[priv->sreg_key], &data[priv->sreg_data],
+ ®s->data[priv->sreg_key],
+ ®s->data[priv->sreg_data],
timeout, GFP_ATOMIC);
if (elem == NULL) {
if (set->size)
@@ -48,7 +49,7 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
}
static void nft_dynset_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_dynset *priv = nft_expr_priv(expr);
@@ -56,8 +57,8 @@ static void nft_dynset_eval(const struct nft_expr *expr,
const struct nft_set_ext *ext;
u64 timeout;
- if (set->ops->update(set, &data[priv->sreg_key], nft_dynset_new,
- expr, data, &ext)) {
+ if (set->ops->update(set, ®s->data[priv->sreg_key], nft_dynset_new,
+ expr, regs, &ext)) {
if (priv->op == NFT_DYNSET_OP_UPDATE &&
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
timeout = priv->timeout ? : set->timeout;
@@ -66,7 +67,7 @@ static void nft_dynset_eval(const struct nft_expr *expr,
}
}
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 8c4981c..2480af7 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -26,11 +26,11 @@ struct nft_exthdr {
};
static void nft_exthdr_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_exthdr *priv = nft_expr_priv(expr);
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
unsigned int offset = 0;
int err;
@@ -43,7 +43,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
goto err;
return;
err:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index bc23806..b1101f7 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -93,9 +93,9 @@ static bool nft_hash_lookup(const struct nft_set *set,
static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
void *(*new)(struct nft_set *,
const struct nft_expr *,
- struct nft_data []),
+ struct nft_regs *regs),
const struct nft_expr *expr,
- struct nft_data data[],
+ struct nft_regs *regs,
const struct nft_set_ext **ext)
{
struct nft_hash *priv = nft_set_priv(set);
@@ -110,7 +110,7 @@ static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
if (he != NULL)
goto out;
- he = new(set, expr, data);
+ he = new(set, expr, regs);
if (he == NULL)
goto err1;
if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index a164c04..29cc739 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -24,12 +24,12 @@ struct nft_immediate_expr {
};
static void nft_immediate_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
- nft_data_copy(&data[priv->dreg], &priv->data);
+ nft_data_copy(®s->data[priv->dreg], &priv->data);
}
static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = {
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index 85da5bd..c862045 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -27,7 +27,7 @@ struct nft_limit {
};
static void nft_limit_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_limit *priv = nft_expr_priv(expr);
@@ -45,7 +45,7 @@ static void nft_limit_eval(const struct nft_expr *expr,
}
spin_unlock_bh(&limit_lock);
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = {
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index e18af9db..a13d6a3 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -27,7 +27,7 @@ struct nft_log {
};
static void nft_log_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_log *priv = nft_expr_priv(expr);
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 8fc0d18..01dba68 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -26,19 +26,20 @@ struct nft_lookup {
};
static void nft_lookup_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_lookup *priv = nft_expr_priv(expr);
const struct nft_set *set = priv->set;
const struct nft_set_ext *ext;
- if (set->ops->lookup(set, &data[priv->sreg], &ext)) {
+ if (set->ops->lookup(set, ®s->data[priv->sreg], &ext)) {
if (set->flags & NFT_SET_MAP)
- nft_data_copy(&data[priv->dreg], nft_set_ext_data(ext));
+ nft_data_copy(®s->data[priv->dreg],
+ nft_set_ext_data(ext));
return;
}
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 0ae6bb7..3f11c0b 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -25,13 +25,13 @@
#include <net/netfilter/nft_meta.h>
void nft_meta_get_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_meta *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
const struct net_device *in = pkt->in, *out = pkt->out;
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
switch (priv->key) {
case NFT_META_LEN:
@@ -177,17 +177,17 @@ void nft_meta_get_eval(const struct nft_expr *expr,
return;
err:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
EXPORT_SYMBOL_GPL(nft_meta_get_eval);
void nft_meta_set_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_meta *meta = nft_expr_priv(expr);
struct sk_buff *skb = pkt->skb;
- u32 value = data[meta->sreg].data[0];
+ u32 value = regs->data[meta->sreg].data[0];
switch (meta->key) {
case NFT_META_MARK:
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index 0897a80..b723311 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -37,7 +37,7 @@ struct nft_nat {
};
static void nft_nat_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_nat *priv = nft_expr_priv(expr);
@@ -49,16 +49,16 @@ static void nft_nat_eval(const struct nft_expr *expr,
if (priv->sreg_addr_min) {
if (priv->family == AF_INET) {
range.min_addr.ip = (__force __be32)
- data[priv->sreg_addr_min].data[0];
+ regs->data[priv->sreg_addr_min].data[0];
range.max_addr.ip = (__force __be32)
- data[priv->sreg_addr_max].data[0];
+ regs->data[priv->sreg_addr_max].data[0];
} else {
memcpy(range.min_addr.ip6,
- data[priv->sreg_addr_min].data,
+ ®s->data[priv->sreg_addr_min].data,
sizeof(struct nft_data));
memcpy(range.max_addr.ip6,
- data[priv->sreg_addr_max].data,
+ ®s->data[priv->sreg_addr_max].data,
sizeof(struct nft_data));
}
range.flags |= NF_NAT_RANGE_MAP_IPS;
@@ -66,16 +66,15 @@ static void nft_nat_eval(const struct nft_expr *expr,
if (priv->sreg_proto_min) {
range.min_proto.all =
- *(__be16 *)&data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
range.max_proto.all =
- *(__be16 *)&data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
range.flags |= priv->flags;
- data[NFT_REG_VERDICT].verdict =
- nf_nat_setup_info(ct, &range, priv->type);
+ regs->verdict.code = nf_nat_setup_info(ct, &range, priv->type);
}
static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index b2a9ef9..14247c5 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -18,12 +18,12 @@
#include <net/netfilter/nf_tables.h>
static void nft_payload_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- struct nft_data *dest = &data[priv->dreg];
+ struct nft_data *dest = ®s->data[priv->dreg];
int offset;
switch (priv->base) {
@@ -47,7 +47,7 @@ static void nft_payload_eval(const struct nft_expr *expr,
goto err;
return;
err:
- data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
index e8ae2f6..96805d2 100644
--- a/net/netfilter/nft_queue.c
+++ b/net/netfilter/nft_queue.c
@@ -28,7 +28,7 @@ struct nft_queue {
};
static void nft_queue_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_queue *priv = nft_expr_priv(expr);
@@ -51,7 +51,7 @@ static void nft_queue_eval(const struct nft_expr *expr,
if (priv->flags & NFT_QUEUE_FLAG_BYPASS)
ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
- data[NFT_REG_VERDICT].verdict = ret;
+ regs->verdict.code = ret;
}
static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index 9287711..62cabee 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -18,7 +18,7 @@
#include <net/netfilter/ipv6/nf_reject.h>
static void nft_reject_inet_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
+ struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
@@ -58,7 +58,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
}
break;
}
- data[NFT_REG_VERDICT].verdict = NF_DROP;
+
+ regs->verdict.code = NF_DROP;
}
static int nft_reject_inet_init(const struct nft_ctx *ctx,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 07/21] netfilter: nf_tables: use struct nft_verdict within struct nft_data
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (5 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 06/21] netfilter: nf_tables: get rid of NFT_REG_VERDICT usage Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 08/21] netfilter: nf_tables: convert expressions to u32 register pointers Pablo Neira Ayuso
` (14 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 7 ++-----
net/netfilter/nf_tables_api.c | 38 ++++++++++++++++++++-----------------
2 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 79582d0..81cd816 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -49,11 +49,8 @@ struct nft_verdict {
struct nft_data {
union {
- u32 data[4];
- struct {
- u32 verdict;
- struct nft_chain *chain;
- };
+ u32 data[4];
+ struct nft_verdict verdict;
};
} __attribute__((aligned(__alignof__(u64))));
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d47f12b..0bb16a1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4049,10 +4049,10 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
return 0;
data = nft_set_ext_data(ext);
- switch (data->verdict) {
+ switch (data->verdict.code) {
case NFT_JUMP:
case NFT_GOTO:
- return nf_tables_check_loops(ctx, data->chain);
+ return nf_tables_check_loops(ctx, data->verdict.chain);
default:
return 0;
}
@@ -4085,10 +4085,11 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
if (data == NULL)
continue;
- switch (data->verdict) {
+ switch (data->verdict.code) {
case NFT_JUMP:
case NFT_GOTO:
- err = nf_tables_check_loops(ctx, data->chain);
+ err = nf_tables_check_loops(ctx,
+ data->verdict.chain);
if (err < 0)
return err;
default:
@@ -4171,15 +4172,17 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
return -EINVAL;
if (data != NULL &&
- (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP)) {
- err = nf_tables_check_loops(ctx, data->chain);
+ (data->verdict.code == NFT_GOTO ||
+ data->verdict.code == NFT_JUMP)) {
+ err = nf_tables_check_loops(ctx, data->verdict.chain);
if (err < 0)
return err;
- if (ctx->chain->level + 1 > data->chain->level) {
+ if (ctx->chain->level + 1 >
+ data->verdict.chain->level) {
if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
return -EMLINK;
- data->chain->level = ctx->chain->level + 1;
+ data->verdict.chain->level = ctx->chain->level + 1;
}
}
@@ -4220,11 +4223,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
if (!tb[NFTA_VERDICT_CODE])
return -EINVAL;
- data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
+ data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
- switch (data->verdict) {
+ switch (data->verdict.code) {
default:
- switch (data->verdict & NF_VERDICT_MASK) {
+ switch (data->verdict.code & NF_VERDICT_MASK) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
@@ -4250,7 +4253,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
return -EOPNOTSUPP;
chain->use++;
- data->chain = chain;
+ data->verdict.chain = chain;
desc->len = sizeof(data);
break;
}
@@ -4261,10 +4264,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
static void nft_verdict_uninit(const struct nft_data *data)
{
- switch (data->verdict) {
+ switch (data->verdict.code) {
case NFT_JUMP:
case NFT_GOTO:
- data->chain->use--;
+ data->verdict.chain->use--;
break;
}
}
@@ -4277,13 +4280,14 @@ static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
if (!nest)
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict)))
+ if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict.code)))
goto nla_put_failure;
- switch (data->verdict) {
+ switch (data->verdict.code) {
case NFT_JUMP:
case NFT_GOTO:
- if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name))
+ if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
+ data->verdict.chain->name))
goto nla_put_failure;
}
nla_nest_end(skb, nest);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 08/21] netfilter: nf_tables: convert expressions to u32 register pointers
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (6 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 07/21] netfilter: nf_tables: use struct nft_verdict within struct nft_data Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 09/21] netfilter: nf_tables: kill nft_data_cmp() Pablo Neira Ayuso
` (13 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Simple conversion to use u32 pointers to the beginning of the registers
to keep follow up patches smaller.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/bridge/netfilter/nft_meta_bridge.c | 4 +--
net/netfilter/nf_tables_core.c | 8 ++---
net/netfilter/nft_bitwise.c | 10 +++---
net/netfilter/nft_byteorder.c | 8 ++---
net/netfilter/nft_ct.c | 38 +++++++++++-----------
net/netfilter/nft_exthdr.c | 4 +--
net/netfilter/nft_meta.c | 54 +++++++++++++++-----------------
net/netfilter/nft_payload.c | 4 +--
8 files changed, 63 insertions(+), 67 deletions(-)
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index f0dfa38..6184b15 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -24,7 +24,7 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
{
const struct nft_meta *priv = nft_expr_priv(expr);
const struct net_device *in = pkt->in, *out = pkt->out;
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
const struct net_bridge_port *p;
switch (priv->key) {
@@ -40,7 +40,7 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
goto out;
}
- strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data));
+ strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
return;
out:
return nft_meta_get_eval(expr, regs, pkt);
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 667cdf0..5ef07d1 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -81,7 +81,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
unsigned char *ptr;
if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -95,11 +95,11 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
return false;
if (priv->len == 2)
- *(u16 *)dest->data = *(u16 *)ptr;
+ *(u16 *)dest = *(u16 *)ptr;
else if (priv->len == 4)
- *(u32 *)dest->data = *(u32 *)ptr;
+ *(u32 *)dest = *(u32 *)ptr;
else
- *(u8 *)dest->data = *(u8 *)ptr;
+ *(u8 *)dest = *(u8 *)ptr;
return true;
}
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 2b8f518..d55b545 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -30,14 +30,12 @@ static void nft_bitwise_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_bitwise *priv = nft_expr_priv(expr);
- const struct nft_data *src = ®s->data[priv->sreg];
- struct nft_data *dst = ®s->data[priv->dreg];
+ const u32 *src = ®s->data[priv->sreg].data[0];
+ u32 *dst = ®s->data[priv->dreg].data[0];
unsigned int i;
- for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++) {
- dst->data[i] = (src->data[i] & priv->mask.data[i]) ^
- priv->xor.data[i];
- }
+ for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
+ dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
}
static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index 48fbfa3..d6290db 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -30,13 +30,13 @@ static void nft_byteorder_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_byteorder *priv = nft_expr_priv(expr);
- struct nft_data *src = ®s->data[priv->sreg];
- struct nft_data *dst = ®s->data[priv->dreg];
+ u32 *src = ®s->data[priv->sreg].data[0];
+ u32 *dst = ®s->data[priv->dreg].data[0];
union { u32 u32; u16 u16; } *s, *d;
unsigned int i;
- s = (void *)src->data;
- d = (void *)dst->data;
+ s = (void *)src;
+ d = (void *)dst;
switch (priv->size) {
case 4:
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 077e06b..0166f28c 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -35,7 +35,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_ct *priv = nft_expr_priv(expr);
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
enum ip_conntrack_info ctinfo;
const struct nf_conn *ct;
const struct nf_conn_help *help;
@@ -54,7 +54,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
state = NF_CT_STATE_UNTRACKED_BIT;
else
state = NF_CT_STATE_BIT(ctinfo);
- dest->data[0] = state;
+ *dest = state;
return;
default:
break;
@@ -65,26 +65,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
switch (priv->key) {
case NFT_CT_DIRECTION:
- dest->data[0] = CTINFO2DIR(ctinfo);
+ *dest = CTINFO2DIR(ctinfo);
return;
case NFT_CT_STATUS:
- dest->data[0] = ct->status;
+ *dest = ct->status;
return;
#ifdef CONFIG_NF_CONNTRACK_MARK
case NFT_CT_MARK:
- dest->data[0] = ct->mark;
+ *dest = ct->mark;
return;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
case NFT_CT_SECMARK:
- dest->data[0] = ct->secmark;
+ *dest = ct->secmark;
return;
#endif
case NFT_CT_EXPIRATION:
diff = (long)jiffies - (long)ct->timeout.expires;
if (diff < 0)
diff = 0;
- dest->data[0] = jiffies_to_msecs(diff);
+ *dest = jiffies_to_msecs(diff);
return;
case NFT_CT_HELPER:
if (ct->master == NULL)
@@ -95,7 +95,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
helper = rcu_dereference(help->helper);
if (helper == NULL)
goto err;
- strncpy((char *)dest->data, helper->name, sizeof(dest->data));
+ strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
return;
#ifdef CONFIG_NF_CONNTRACK_LABELS
case NFT_CT_LABELS: {
@@ -103,15 +103,15 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
unsigned int size;
if (!labels) {
- memset(dest->data, 0, sizeof(dest->data));
+ memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
return;
}
size = labels->words * sizeof(long);
- memcpy(dest->data, labels->bits, size);
- if (size < sizeof(dest->data))
- memset(((char *) dest->data) + size, 0,
- sizeof(dest->data) - size);
+ memcpy(dest, labels->bits, size);
+ if (size < NF_CT_LABELS_MAX_SIZE)
+ memset(((char *) dest) + size, 0,
+ NF_CT_LABELS_MAX_SIZE - size);
return;
}
#endif
@@ -122,24 +122,24 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
tuple = &ct->tuplehash[priv->dir].tuple;
switch (priv->key) {
case NFT_CT_L3PROTOCOL:
- dest->data[0] = nf_ct_l3num(ct);
+ *dest = nf_ct_l3num(ct);
return;
case NFT_CT_SRC:
- memcpy(dest->data, tuple->src.u3.all,
+ memcpy(dest, tuple->src.u3.all,
nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
return;
case NFT_CT_DST:
- memcpy(dest->data, tuple->dst.u3.all,
+ memcpy(dest, tuple->dst.u3.all,
nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
return;
case NFT_CT_PROTOCOL:
- dest->data[0] = nf_ct_protonum(ct);
+ *dest = nf_ct_protonum(ct);
return;
case NFT_CT_PROTO_SRC:
- dest->data[0] = (__force __u16)tuple->src.u.all;
+ *dest = (__force __u16)tuple->src.u.all;
return;
case NFT_CT_PROTO_DST:
- dest->data[0] = (__force __u16)tuple->dst.u.all;
+ *dest = (__force __u16)tuple->dst.u.all;
return;
default:
break;
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 2480af7..a85db75 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -30,7 +30,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
struct nft_exthdr *priv = nft_expr_priv(expr);
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
unsigned int offset = 0;
int err;
@@ -39,7 +39,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
goto err;
offset += priv->offset;
- if (skb_copy_bits(pkt->skb, offset, dest->data, priv->len) < 0)
+ if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
goto err;
return;
err:
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 3f11c0b..a6da806 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -31,56 +31,56 @@ void nft_meta_get_eval(const struct nft_expr *expr,
const struct nft_meta *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
const struct net_device *in = pkt->in, *out = pkt->out;
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
switch (priv->key) {
case NFT_META_LEN:
- dest->data[0] = skb->len;
+ *dest = skb->len;
break;
case NFT_META_PROTOCOL:
- *(__be16 *)dest->data = skb->protocol;
+ *(__be16 *)dest = skb->protocol;
break;
case NFT_META_NFPROTO:
- dest->data[0] = pkt->ops->pf;
+ *dest = pkt->ops->pf;
break;
case NFT_META_L4PROTO:
- dest->data[0] = pkt->tprot;
+ *dest = pkt->tprot;
break;
case NFT_META_PRIORITY:
- dest->data[0] = skb->priority;
+ *dest = skb->priority;
break;
case NFT_META_MARK:
- dest->data[0] = skb->mark;
+ *dest = skb->mark;
break;
case NFT_META_IIF:
if (in == NULL)
goto err;
- dest->data[0] = in->ifindex;
+ *dest = in->ifindex;
break;
case NFT_META_OIF:
if (out == NULL)
goto err;
- dest->data[0] = out->ifindex;
+ *dest = out->ifindex;
break;
case NFT_META_IIFNAME:
if (in == NULL)
goto err;
- strncpy((char *)dest->data, in->name, sizeof(dest->data));
+ strncpy((char *)dest, in->name, IFNAMSIZ);
break;
case NFT_META_OIFNAME:
if (out == NULL)
goto err;
- strncpy((char *)dest->data, out->name, sizeof(dest->data));
+ strncpy((char *)dest, out->name, IFNAMSIZ);
break;
case NFT_META_IIFTYPE:
if (in == NULL)
goto err;
- *(u16 *)dest->data = in->type;
+ *(u16 *)dest = in->type;
break;
case NFT_META_OIFTYPE:
if (out == NULL)
goto err;
- *(u16 *)dest->data = out->type;
+ *(u16 *)dest = out->type;
break;
case NFT_META_SKUID:
if (skb->sk == NULL || !sk_fullsock(skb->sk))
@@ -93,8 +93,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
goto err;
}
- dest->data[0] =
- from_kuid_munged(&init_user_ns,
+ *dest = from_kuid_munged(&init_user_ns,
skb->sk->sk_socket->file->f_cred->fsuid);
read_unlock_bh(&skb->sk->sk_callback_lock);
break;
@@ -108,8 +107,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
read_unlock_bh(&skb->sk->sk_callback_lock);
goto err;
}
- dest->data[0] =
- from_kgid_munged(&init_user_ns,
+ *dest = from_kgid_munged(&init_user_ns,
skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
break;
@@ -119,33 +117,33 @@ void nft_meta_get_eval(const struct nft_expr *expr,
if (dst == NULL)
goto err;
- dest->data[0] = dst->tclassid;
+ *dest = dst->tclassid;
break;
}
#endif
#ifdef CONFIG_NETWORK_SECMARK
case NFT_META_SECMARK:
- dest->data[0] = skb->secmark;
+ *dest = skb->secmark;
break;
#endif
case NFT_META_PKTTYPE:
if (skb->pkt_type != PACKET_LOOPBACK) {
- dest->data[0] = skb->pkt_type;
+ *dest = skb->pkt_type;
break;
}
switch (pkt->ops->pf) {
case NFPROTO_IPV4:
if (ipv4_is_multicast(ip_hdr(skb)->daddr))
- dest->data[0] = PACKET_MULTICAST;
+ *dest = PACKET_MULTICAST;
else
- dest->data[0] = PACKET_BROADCAST;
+ *dest = PACKET_BROADCAST;
break;
case NFPROTO_IPV6:
if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
- dest->data[0] = PACKET_MULTICAST;
+ *dest = PACKET_MULTICAST;
else
- dest->data[0] = PACKET_BROADCAST;
+ *dest = PACKET_BROADCAST;
break;
default:
WARN_ON(1);
@@ -153,22 +151,22 @@ void nft_meta_get_eval(const struct nft_expr *expr,
}
break;
case NFT_META_CPU:
- dest->data[0] = raw_smp_processor_id();
+ *dest = raw_smp_processor_id();
break;
case NFT_META_IIFGROUP:
if (in == NULL)
goto err;
- dest->data[0] = in->group;
+ *dest = in->group;
break;
case NFT_META_OIFGROUP:
if (out == NULL)
goto err;
- dest->data[0] = out->group;
+ *dest = out->group;
break;
case NFT_META_CGROUP:
if (skb->sk == NULL || !sk_fullsock(skb->sk))
goto err;
- dest->data[0] = skb->sk->sk_classid;
+ *dest = skb->sk->sk_classid;
break;
default:
WARN_ON(1);
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 14247c5..6bb0592 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -23,7 +23,7 @@ static void nft_payload_eval(const struct nft_expr *expr,
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- struct nft_data *dest = ®s->data[priv->dreg];
+ u32 *dest = ®s->data[priv->dreg].data[0];
int offset;
switch (priv->base) {
@@ -43,7 +43,7 @@ static void nft_payload_eval(const struct nft_expr *expr,
}
offset += priv->offset;
- if (skb_copy_bits(skb, offset, dest->data, priv->len) < 0)
+ if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
goto err;
return;
err:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 09/21] netfilter: nf_tables: kill nft_data_cmp()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (7 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 08/21] netfilter: nf_tables: convert expressions to u32 register pointers Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 10/21] netfilter: nf_tables: convert sets to u32 data pointers Pablo Neira Ayuso
` (12 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Only needlessly complicates things due to requiring specific argument
types. Use memcmp directly.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 7 -------
net/netfilter/nft_cmp.c | 2 +-
net/netfilter/nft_hash.c | 2 +-
net/netfilter/nft_rbtree.c | 11 +++++------
4 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 81cd816..fca0b5d 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -69,13 +69,6 @@ struct nft_regs {
};
};
-static inline int nft_data_cmp(const struct nft_data *d1,
- const struct nft_data *d2,
- unsigned int len)
-{
- return memcmp(d1->data, d2->data, len);
-}
-
static inline void nft_data_copy(struct nft_data *dst,
const struct nft_data *src)
{
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index 59391e6..b7e1c58 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -31,7 +31,7 @@ static void nft_cmp_eval(const struct nft_expr *expr,
const struct nft_cmp_expr *priv = nft_expr_priv(expr);
int d;
- d = nft_data_cmp(®s->data[priv->sreg], &priv->data, priv->len);
+ d = memcmp(®s->data[priv->sreg], &priv->data, priv->len);
switch (priv->op) {
case NFT_CMP_EQ:
if (d != 0)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index b1101f7..26ba4e1 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -62,7 +62,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
const struct nft_hash_cmp_arg *x = arg->key;
const struct nft_hash_elem *he = ptr;
- if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
+ if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
return 1;
if (nft_set_elem_expired(&he->ext))
return 1;
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index 42d0ca4..b398f1a 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -45,7 +45,7 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
while (parent != NULL) {
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
- d = nft_data_cmp(nft_set_ext_key(&rbe->ext), key, set->klen);
+ d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen);
if (d < 0) {
parent = parent->rb_left;
interval = rbe;
@@ -91,9 +91,9 @@ static int __nft_rbtree_insert(const struct nft_set *set,
while (*p != NULL) {
parent = *p;
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
- d = nft_data_cmp(nft_set_ext_key(&rbe->ext),
- nft_set_ext_key(&new->ext),
- set->klen);
+ d = memcmp(nft_set_ext_key(&rbe->ext),
+ nft_set_ext_key(&new->ext),
+ set->klen);
if (d < 0)
p = &parent->rb_left;
else if (d > 0)
@@ -153,8 +153,7 @@ static void *nft_rbtree_deactivate(const struct nft_set *set,
while (parent != NULL) {
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
- d = nft_data_cmp(nft_set_ext_key(&rbe->ext), &elem->key,
- set->klen);
+ d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key, set->klen);
if (d < 0)
parent = parent->rb_left;
else if (d > 0)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 10/21] netfilter: nf_tables: convert sets to u32 data pointers
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (8 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 09/21] netfilter: nf_tables: kill nft_data_cmp() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 11/21] netfilter: nf_tables: add register parsing/dumping helpers Pablo Neira Ayuso
` (11 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Simple conversion to use u32 pointers to the beginning of the data
area to keep follow up patches smaller.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 4 ++--
net/netfilter/nft_hash.c | 11 +++++------
net/netfilter/nft_rbtree.c | 3 +--
3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index fca0b5d..efcf46d 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -231,10 +231,10 @@ struct nft_expr;
*/
struct nft_set_ops {
bool (*lookup)(const struct nft_set *set,
- const struct nft_data *key,
+ const u32 *key,
const struct nft_set_ext **ext);
bool (*update)(struct nft_set *set,
- const struct nft_data *key,
+ const u32 *key,
void *(*new)(struct nft_set *,
const struct nft_expr *,
struct nft_regs *),
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 26ba4e1..767df41 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -36,7 +36,7 @@ struct nft_hash_elem {
struct nft_hash_cmp_arg {
const struct nft_set *set;
- const struct nft_data *key;
+ const u32 *key;
u8 genmask;
};
@@ -71,8 +71,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
return 0;
}
-static bool nft_hash_lookup(const struct nft_set *set,
- const struct nft_data *key,
+static bool nft_hash_lookup(const struct nft_set *set, const u32 *key,
const struct nft_set_ext **ext)
{
struct nft_hash *priv = nft_set_priv(set);
@@ -90,7 +89,7 @@ static bool nft_hash_lookup(const struct nft_set *set,
return !!he;
}
-static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
+static bool nft_hash_update(struct nft_set *set, const u32 *key,
void *(*new)(struct nft_set *,
const struct nft_expr *,
struct nft_regs *regs),
@@ -134,7 +133,7 @@ static int nft_hash_insert(const struct nft_set *set,
struct nft_hash_cmp_arg arg = {
.genmask = nft_genmask_next(read_pnet(&set->pnet)),
.set = set,
- .key = &elem->key,
+ .key = elem->key.data,
};
return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -158,7 +157,7 @@ static void *nft_hash_deactivate(const struct nft_set *set,
struct nft_hash_cmp_arg arg = {
.genmask = nft_genmask_next(read_pnet(&set->pnet)),
.set = set,
- .key = &elem->key,
+ .key = elem->key.data,
};
rcu_read_lock();
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index b398f1a..b888e0c 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -30,8 +30,7 @@ struct nft_rbtree_elem {
};
-static bool nft_rbtree_lookup(const struct nft_set *set,
- const struct nft_data *key,
+static bool nft_rbtree_lookup(const struct nft_set *set, const u32 *key,
const struct nft_set_ext **ext)
{
const struct nft_rbtree *priv = nft_set_priv(set);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 11/21] netfilter: nf_tables: add register parsing/dumping helpers
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (9 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 10/21] netfilter: nf_tables: convert sets to u32 data pointers Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 12/21] netfilter: nf_tables: switch registers to 32 bit addressing Pablo Neira Ayuso
` (10 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add helper functions to parse and dump register values in netlink attributes.
These helpers will later be changed to take care of translation between the
old 128 bit and the new 32 bit register numbers.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 3 +++
net/bridge/netfilter/nft_meta_bridge.c | 2 +-
net/netfilter/nf_tables_api.c | 12 ++++++++++++
net/netfilter/nft_bitwise.c | 8 ++++----
net/netfilter/nft_byteorder.c | 8 ++++----
net/netfilter/nft_cmp.c | 8 ++++----
net/netfilter/nft_ct.c | 8 ++++----
net/netfilter/nft_dynset.c | 8 ++++----
net/netfilter/nft_exthdr.c | 4 ++--
net/netfilter/nft_immediate.c | 4 ++--
net/netfilter/nft_lookup.c | 8 ++++----
net/netfilter/nft_meta.c | 8 ++++----
net/netfilter/nft_nat.c | 24 ++++++++++++------------
net/netfilter/nft_payload.c | 4 ++--
net/netfilter/nft_redir.c | 12 ++++++------
15 files changed, 68 insertions(+), 53 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index efcf46d..f8f27a4 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -128,6 +128,9 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
}
+unsigned int nft_parse_register(const struct nlattr *attr);
+int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
+
int nft_validate_register_load(enum nft_registers reg, unsigned int len);
int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg,
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 6184b15..99dab70 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -65,7 +65,7 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
return nft_meta_get_init(ctx, expr, tb);
}
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, len);
}
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0bb16a1..a25fd19 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4122,6 +4122,18 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
return 0;
}
+unsigned int nft_parse_register(const struct nlattr *attr)
+{
+ return ntohl(nla_get_be32(attr));
+}
+EXPORT_SYMBOL_GPL(nft_parse_register);
+
+int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
+{
+ return nla_put_be32(skb, attr, htonl(reg));
+}
+EXPORT_SYMBOL_GPL(nft_dump_register);
+
/**
* nft_validate_register_load - validate a load from a register
*
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d55b545..aa11470 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -62,12 +62,12 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
return -EINVAL;
priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
if (err < 0)
@@ -92,9 +92,9 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_bitwise *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_BITWISE_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_BITWISE_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
goto nla_put_failure;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index d6290db..2ee3e57 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -106,13 +106,13 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
}
@@ -121,9 +121,9 @@ static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_byteorder *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_BYTEORDER_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_BYTEORDER_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_BYTEORDER_DREG, priv->dreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op)))
goto nla_put_failure;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index b7e1c58..ffaf214 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -78,7 +78,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
err = nft_validate_register_load(priv->sreg, desc.len);
if (err < 0)
return err;
@@ -92,7 +92,7 @@ static int nft_cmp_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_cmp_expr *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op)))
goto nla_put_failure;
@@ -128,7 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
err = nft_validate_register_load(priv->sreg, desc.len);
if (err < 0)
return err;
@@ -146,7 +146,7 @@ static int nft_cmp_fast_dump(struct sk_buff *skb, const struct nft_expr *expr)
const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
struct nft_data data;
- if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ)))
goto nla_put_failure;
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 0166f28c..fab8e75 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -306,7 +306,7 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
}
}
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, len);
if (err < 0)
@@ -338,7 +338,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
}
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
err = nft_validate_register_load(priv->sreg, len);
if (err < 0)
return err;
@@ -360,7 +360,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_ct *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_CT_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
goto nla_put_failure;
@@ -387,7 +387,7 @@ static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_ct *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
goto nla_put_failure;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index e398f6d..03699d5 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -124,7 +124,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
}
- priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY]));
+ priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
err = nft_validate_register_load(priv->sreg_key, set->klen);;
if (err < 0)
return err;
@@ -135,7 +135,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
if (set->dtype == NFT_DATA_VERDICT)
return -EOPNOTSUPP;
- priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA]));
+ priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
err = nft_validate_register_load(priv->sreg_data, set->dlen);
if (err < 0)
return err;
@@ -173,10 +173,10 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_dynset *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_DYNSET_SREG_KEY, htonl(priv->sreg_key)))
+ if (nft_dump_register(skb, NFTA_DYNSET_SREG_KEY, priv->sreg_key))
goto nla_put_failure;
if (priv->set->flags & NFT_SET_MAP &&
- nla_put_be32(skb, NFTA_DYNSET_SREG_DATA, htonl(priv->sreg_data)))
+ nft_dump_register(skb, NFTA_DYNSET_SREG_DATA, priv->sreg_data))
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op)))
goto nla_put_failure;
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index a85db75..098ffee 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -68,7 +68,7 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
@@ -78,7 +78,7 @@ static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_exthdr *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_EXTHDR_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg))
goto nla_put_failure;
if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type))
goto nla_put_failure;
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 29cc739..0682f60 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -54,7 +54,7 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
return err;
priv->dlen = desc.len;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
desc.type, desc.len);
if (err < 0)
@@ -78,7 +78,7 @@ static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_IMMEDIATE_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg))
goto nla_put_failure;
return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 01dba68..fc7afff 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -71,7 +71,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
return PTR_ERR(set);
}
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
err = nft_validate_register_load(priv->sreg, set->klen);
if (err < 0)
return err;
@@ -80,7 +80,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
if (!(set->flags & NFT_SET_MAP))
return -EINVAL;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, NULL,
set->dtype, set->dlen);
if (err < 0)
@@ -112,10 +112,10 @@ static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr)
if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_LOOKUP_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_LOOKUP_SREG, priv->sreg))
goto nla_put_failure;
if (priv->set->flags & NFT_SET_MAP)
- if (nla_put_be32(skb, NFTA_LOOKUP_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg))
goto nla_put_failure;
return 0;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index a6da806..5f744eb 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -254,7 +254,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
}
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, len);
}
@@ -281,7 +281,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
}
- priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG]));
+ priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
err = nft_validate_register_load(priv->sreg, len);
if (err < 0)
return err;
@@ -297,7 +297,7 @@ int nft_meta_get_dump(struct sk_buff *skb,
if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_META_DREG, htonl(priv->dreg)))
+ if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
goto nla_put_failure;
return 0;
@@ -313,7 +313,7 @@ int nft_meta_set_dump(struct sk_buff *skb,
if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_META_SREG, htonl(priv->sreg)))
+ if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
goto nla_put_failure;
return 0;
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index b723311..065cbda 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -163,14 +163,14 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
if (tb[NFTA_NAT_REG_ADDR_MIN]) {
priv->sreg_addr_min =
- ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN]));
+ nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
err = nft_validate_register_load(priv->sreg_addr_min, alen);
if (err < 0)
return err;
if (tb[NFTA_NAT_REG_ADDR_MAX]) {
priv->sreg_addr_max =
- ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX]));
+ nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]);
err = nft_validate_register_load(priv->sreg_addr_max,
alen);
@@ -184,7 +184,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
if (tb[NFTA_NAT_REG_PROTO_MIN]) {
priv->sreg_proto_min =
- ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN]));
+ nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0)
@@ -192,7 +192,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
if (tb[NFTA_NAT_REG_PROTO_MAX]) {
priv->sreg_proto_max =
- ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX]));
+ nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]);
err = nft_validate_register_load(priv->sreg_proto_max,
plen);
@@ -231,18 +231,18 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
goto nla_put_failure;
if (priv->sreg_addr_min) {
- if (nla_put_be32(skb, NFTA_NAT_REG_ADDR_MIN,
- htonl(priv->sreg_addr_min)) ||
- nla_put_be32(skb, NFTA_NAT_REG_ADDR_MAX,
- htonl(priv->sreg_addr_max)))
+ if (nft_dump_register(skb, NFTA_NAT_REG_ADDR_MIN,
+ priv->sreg_addr_min) ||
+ nft_dump_register(skb, NFTA_NAT_REG_ADDR_MAX,
+ priv->sreg_addr_max))
goto nla_put_failure;
}
if (priv->sreg_proto_min) {
- if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN,
- htonl(priv->sreg_proto_min)) ||
- nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX,
- htonl(priv->sreg_proto_max)))
+ if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_MIN,
+ priv->sreg_proto_min) ||
+ nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX,
+ priv->sreg_proto_max))
goto nla_put_failure;
}
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 6bb0592..5fa9973 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -66,7 +66,7 @@ static int nft_payload_init(const struct nft_ctx *ctx,
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG]));
+ priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, priv->len);
@@ -76,7 +76,7 @@ static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_payload *priv = nft_expr_priv(expr);
- if (nla_put_be32(skb, NFTA_PAYLOAD_DREG, htonl(priv->dreg)) ||
+ if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index 9819466..03f7bf4 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -54,7 +54,7 @@ int nft_redir_init(const struct nft_ctx *ctx,
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
priv->sreg_proto_min =
- ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
+ nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0)
@@ -62,7 +62,7 @@ int nft_redir_init(const struct nft_ctx *ctx,
if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
priv->sreg_proto_max =
- ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]));
+ nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]);
err = nft_validate_register_load(priv->sreg_proto_max,
plen);
@@ -88,11 +88,11 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
const struct nft_redir *priv = nft_expr_priv(expr);
if (priv->sreg_proto_min) {
- if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN,
- htonl(priv->sreg_proto_min)))
+ if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MIN,
+ priv->sreg_proto_min))
goto nla_put_failure;
- if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX,
- htonl(priv->sreg_proto_max)))
+ if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX,
+ priv->sreg_proto_max))
goto nla_put_failure;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 12/21] netfilter: nf_tables: switch registers to 32 bit addressing
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (10 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 11/21] netfilter: nf_tables: add register parsing/dumping helpers Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 13/21] netfilter: nf_tables: support variable sized data in nft_data_init() Pablo Neira Ayuso
` (9 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Switch the nf_tables registers from 128 bit addressing to 32 bit
addressing to support so called concatenations, where multiple values
can be concatenated over multiple registers for O(1) exact matches of
multiple dimensions using sets.
The old register values are mapped to areas of 128 bits for compatibility.
When dumping register numbers, values are expressed using the old values
if they refer to the beginning of a 128 bit area for compatibility.
To support concatenations, register loads of less than a full 32 bit
value need to be padded. This mainly affects the payload and exthdr
expressions, which both unconditionally zero the last word before
copying the data.
Userspace fully passes the testsuite using both old and new register
addressing.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 13 +++----
include/uapi/linux/netfilter/nf_tables.h | 31 ++++++++++++++++-
net/bridge/netfilter/nft_meta_bridge.c | 2 +-
net/ipv4/netfilter/nft_redir_ipv4.c | 4 +--
net/ipv6/netfilter/nft_redir_ipv6.c | 4 +--
net/netfilter/nf_tables_api.c | 54 +++++++++++++++++++++++-------
net/netfilter/nf_tables_core.c | 5 +--
net/netfilter/nft_bitwise.c | 4 +--
net/netfilter/nft_byteorder.c | 4 +--
net/netfilter/nft_ct.c | 4 +--
net/netfilter/nft_exthdr.c | 3 +-
net/netfilter/nft_immediate.c | 2 +-
net/netfilter/nft_lookup.c | 2 +-
net/netfilter/nft_meta.c | 7 ++--
net/netfilter/nft_nat.c | 16 ++++-----
net/netfilter/nft_payload.c | 3 +-
16 files changed, 110 insertions(+), 48 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f8f27a4..1f9b848 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -64,17 +64,15 @@ struct nft_data {
*/
struct nft_regs {
union {
- struct nft_data data[NFT_REG_MAX + 1];
+ u32 data[20];
struct nft_verdict verdict;
};
};
-static inline void nft_data_copy(struct nft_data *dst,
- const struct nft_data *src)
+static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
+ unsigned int len)
{
- BUILD_BUG_ON(__alignof__(*dst) != __alignof__(u64));
- *(u64 *)&dst->data[0] = *(u64 *)&src->data[0];
- *(u64 *)&dst->data[2] = *(u64 *)&src->data[2];
+ memcpy(dst, src, len);
}
static inline void nft_data_debug(const struct nft_data *data)
@@ -502,8 +500,7 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
void *nft_set_elem_init(const struct nft_set *set,
const struct nft_set_ext_tmpl *tmpl,
- const struct nft_data *key,
- const struct nft_data *data,
+ const u32 *key, const u32 *data,
u64 timeout, gfp_t gfp);
void nft_set_elem_destroy(const struct nft_set *set, void *elem);
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 05ee1e0..4221a6c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -5,16 +5,45 @@
#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256
+/**
+ * enum nft_registers - nf_tables registers
+ *
+ * nf_tables used to have five registers: a verdict register and four data
+ * registers of size 16. The data registers have been changed to 16 registers
+ * of size 4. For compatibility reasons, the NFT_REG_[1-4] registers still
+ * map to areas of size 16, the 4 byte registers are addressed using
+ * NFT_REG32_00 - NFT_REG32_15.
+ */
enum nft_registers {
NFT_REG_VERDICT,
NFT_REG_1,
NFT_REG_2,
NFT_REG_3,
NFT_REG_4,
- __NFT_REG_MAX
+ __NFT_REG_MAX,
+
+ NFT_REG32_00 = 8,
+ MFT_REG32_01,
+ NFT_REG32_02,
+ NFT_REG32_03,
+ NFT_REG32_04,
+ NFT_REG32_05,
+ NFT_REG32_06,
+ NFT_REG32_07,
+ NFT_REG32_08,
+ NFT_REG32_09,
+ NFT_REG32_10,
+ NFT_REG32_11,
+ NFT_REG32_12,
+ NFT_REG32_13,
+ NFT_REG32_14,
+ NFT_REG32_15,
};
#define NFT_REG_MAX (__NFT_REG_MAX - 1)
+#define NFT_REG_SIZE 16
+#define NFT_REG32_SIZE 4
+
/**
* enum nft_verdicts - nf_tables internal verdicts
*
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 99dab70..a21269b 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -24,7 +24,7 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
{
const struct nft_meta *priv = nft_expr_priv(expr);
const struct net_device *in = pkt->in, *out = pkt->out;
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
const struct net_bridge_port *p;
switch (priv->key) {
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
index 312cf6f..d8d795d 100644
--- a/net/ipv4/netfilter/nft_redir_ipv4.c
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -27,9 +27,9 @@ static void nft_redir_ipv4_eval(const struct nft_expr *expr,
memset(&mr, 0, sizeof(mr));
if (priv->sreg_proto_min) {
mr.range[0].min.all =
- *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min];
mr.range[0].max.all =
- *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max];
mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c
index 0eed774..effd393 100644
--- a/net/ipv6/netfilter/nft_redir_ipv6.c
+++ b/net/ipv6/netfilter/nft_redir_ipv6.c
@@ -27,9 +27,9 @@ static void nft_redir_ipv6_eval(const struct nft_expr *expr,
memset(&range, 0, sizeof(range));
if (priv->sreg_proto_min) {
range.min_proto.all =
- *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min],
range.max_proto.all =
- *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max],
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a25fd19..03faf76 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3201,8 +3201,7 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
void *nft_set_elem_init(const struct nft_set *set,
const struct nft_set_ext_tmpl *tmpl,
- const struct nft_data *key,
- const struct nft_data *data,
+ const u32 *key, const u32 *data,
u64 timeout, gfp_t gfp)
{
struct nft_set_ext *ext;
@@ -3357,7 +3356,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
}
err = -ENOMEM;
- elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data,
+ elem.priv = nft_set_elem_init(set, &tmpl, elem.key.data, data.data,
timeout, GFP_KERNEL);
if (elem.priv == NULL)
goto err3;
@@ -4122,14 +4121,47 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
return 0;
}
+/**
+ * nft_parse_register - parse a register value from a netlink attribute
+ *
+ * @attr: netlink attribute
+ *
+ * Parse and translate a register value from a netlink attribute.
+ * Registers used to be 128 bit wide, these register numbers will be
+ * mapped to the corresponding 32 bit register numbers.
+ */
unsigned int nft_parse_register(const struct nlattr *attr)
{
- return ntohl(nla_get_be32(attr));
+ unsigned int reg;
+
+ reg = ntohl(nla_get_be32(attr));
+ switch (reg) {
+ case NFT_REG_VERDICT...NFT_REG_4:
+ return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
+ default:
+ return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
+ }
}
EXPORT_SYMBOL_GPL(nft_parse_register);
+/**
+ * nft_dump_register - dump a register value to a netlink attribute
+ *
+ * @skb: socket buffer
+ * @attr: attribute number
+ * @reg: register number
+ *
+ * Construct a netlink attribute containing the register number. For
+ * compatibility reasons, register numbers being a multiple of 4 are
+ * translated to the corresponding 128 bit register numbers.
+ */
int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
{
+ if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
+ reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
+ else
+ reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
+
return nla_put_be32(skb, attr, htonl(reg));
}
EXPORT_SYMBOL_GPL(nft_dump_register);
@@ -4145,14 +4177,13 @@ EXPORT_SYMBOL_GPL(nft_dump_register);
*/
int nft_validate_register_load(enum nft_registers reg, unsigned int len)
{
- if (reg <= NFT_REG_VERDICT)
+ if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
return -EINVAL;
- if (reg > NFT_REG_MAX)
- return -ERANGE;
if (len == 0)
return -EINVAL;
- if (len > FIELD_SIZEOF(struct nft_data, data))
+ if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
return -ERANGE;
+
return 0;
}
EXPORT_SYMBOL_GPL(nft_validate_register_load);
@@ -4200,13 +4231,12 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
return 0;
default:
- if (reg < NFT_REG_1)
+ if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
return -EINVAL;
- if (reg > NFT_REG_MAX)
- return -ERANGE;
if (len == 0)
return -EINVAL;
- if (len > FIELD_SIZEOF(struct nft_data, data))
+ if (reg * NFT_REG32_SIZE + len >
+ FIELD_SIZEOF(struct nft_regs, data))
return -ERANGE;
if (data != NULL && type != NFT_DATA_VALUE)
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 5ef07d1..f153b07 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -70,7 +70,7 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr,
const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
u32 mask = nft_cmp_fast_mask(priv->len);
- if ((regs->data[priv->sreg].data[0] & mask) == priv->data)
+ if ((regs->data[priv->sreg] & mask) == priv->data)
return;
regs->verdict.code = NFT_BREAK;
}
@@ -81,7 +81,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
unsigned char *ptr;
if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -94,6 +94,7 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
if (unlikely(ptr + priv->len >= skb_tail_pointer(skb)))
return false;
+ *dest = 0;
if (priv->len == 2)
*(u16 *)dest = *(u16 *)ptr;
else if (priv->len == 4)
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index aa11470..f1a9be2 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -30,8 +30,8 @@ static void nft_bitwise_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_bitwise *priv = nft_expr_priv(expr);
- const u32 *src = ®s->data[priv->sreg].data[0];
- u32 *dst = ®s->data[priv->dreg].data[0];
+ const u32 *src = ®s->data[priv->sreg];
+ u32 *dst = ®s->data[priv->dreg];
unsigned int i;
for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index 2ee3e57..fde5145 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -30,8 +30,8 @@ static void nft_byteorder_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_byteorder *priv = nft_expr_priv(expr);
- u32 *src = ®s->data[priv->sreg].data[0];
- u32 *dst = ®s->data[priv->dreg].data[0];
+ u32 *src = ®s->data[priv->sreg];
+ u32 *dst = ®s->data[priv->dreg];
union { u32 u32; u16 u16; } *s, *d;
unsigned int i;
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index fab8e75..8cbca34 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -35,7 +35,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
const struct nft_ct *priv = nft_expr_priv(expr);
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
enum ip_conntrack_info ctinfo;
const struct nf_conn *ct;
const struct nf_conn_help *help;
@@ -156,7 +156,7 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
const struct nft_ct *priv = nft_expr_priv(expr);
struct sk_buff *skb = pkt->skb;
#ifdef CONFIG_NF_CONNTRACK_MARK
- u32 value = regs->data[priv->sreg].data[0];
+ u32 value = regs->data[priv->sreg];
#endif
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 098ffee..ba7aed1 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -30,7 +30,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
struct nft_exthdr *priv = nft_expr_priv(expr);
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
unsigned int offset = 0;
int err;
@@ -39,6 +39,7 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
goto err;
offset += priv->offset;
+ dest[priv->len / NFT_REG32_SIZE] = 0;
if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
goto err;
return;
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 0682f60..1e8e412 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -29,7 +29,7 @@ static void nft_immediate_eval(const struct nft_expr *expr,
{
const struct nft_immediate_expr *priv = nft_expr_priv(expr);
- nft_data_copy(®s->data[priv->dreg], &priv->data);
+ nft_data_copy(®s->data[priv->dreg], &priv->data, priv->dlen);
}
static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = {
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index fc7afff..ba14662 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -36,7 +36,7 @@ static void nft_lookup_eval(const struct nft_expr *expr,
if (set->ops->lookup(set, ®s->data[priv->sreg], &ext)) {
if (set->flags & NFT_SET_MAP)
nft_data_copy(®s->data[priv->dreg],
- nft_set_ext_data(ext));
+ nft_set_ext_data(ext), set->dlen);
return;
}
regs->verdict.code = NFT_BREAK;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 5f744eb..52561e1 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -31,13 +31,14 @@ void nft_meta_get_eval(const struct nft_expr *expr,
const struct nft_meta *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
const struct net_device *in = pkt->in, *out = pkt->out;
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
switch (priv->key) {
case NFT_META_LEN:
*dest = skb->len;
break;
case NFT_META_PROTOCOL:
+ *dest = 0;
*(__be16 *)dest = skb->protocol;
break;
case NFT_META_NFPROTO:
@@ -75,11 +76,13 @@ void nft_meta_get_eval(const struct nft_expr *expr,
case NFT_META_IIFTYPE:
if (in == NULL)
goto err;
+ *dest = 0;
*(u16 *)dest = in->type;
break;
case NFT_META_OIFTYPE:
if (out == NULL)
goto err;
+ *dest = 0;
*(u16 *)dest = out->type;
break;
case NFT_META_SKUID:
@@ -185,7 +188,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
{
const struct nft_meta *meta = nft_expr_priv(expr);
struct sk_buff *skb = pkt->skb;
- u32 value = regs->data[meta->sreg].data[0];
+ u32 value = regs->data[meta->sreg];
switch (meta->key) {
case NFT_META_MARK:
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index 065cbda..ee2d717 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -49,26 +49,26 @@ static void nft_nat_eval(const struct nft_expr *expr,
if (priv->sreg_addr_min) {
if (priv->family == AF_INET) {
range.min_addr.ip = (__force __be32)
- regs->data[priv->sreg_addr_min].data[0];
+ regs->data[priv->sreg_addr_min];
range.max_addr.ip = (__force __be32)
- regs->data[priv->sreg_addr_max].data[0];
+ regs->data[priv->sreg_addr_max];
} else {
memcpy(range.min_addr.ip6,
- ®s->data[priv->sreg_addr_min].data,
- sizeof(struct nft_data));
+ ®s->data[priv->sreg_addr_min],
+ sizeof(range.min_addr.ip6));
memcpy(range.max_addr.ip6,
- ®s->data[priv->sreg_addr_max].data,
- sizeof(struct nft_data));
+ ®s->data[priv->sreg_addr_max],
+ sizeof(range.max_addr.ip6));
}
range.flags |= NF_NAT_RANGE_MAP_IPS;
}
if (priv->sreg_proto_min) {
range.min_proto.all =
- *(__be16 *)®s->data[priv->sreg_proto_min].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_min];
range.max_proto.all =
- *(__be16 *)®s->data[priv->sreg_proto_max].data[0];
+ *(__be16 *)®s->data[priv->sreg_proto_max];
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 5fa9973..94fb3b2 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -23,7 +23,7 @@ static void nft_payload_eval(const struct nft_expr *expr,
{
const struct nft_payload *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
- u32 *dest = ®s->data[priv->dreg].data[0];
+ u32 *dest = ®s->data[priv->dreg];
int offset;
switch (priv->base) {
@@ -43,6 +43,7 @@ static void nft_payload_eval(const struct nft_expr *expr,
}
offset += priv->offset;
+ dest[priv->len / NFT_REG32_SIZE] = 0;
if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
goto err;
return;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 13/21] netfilter: nf_tables: support variable sized data in nft_data_init()
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (11 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 12/21] netfilter: nf_tables: switch registers to 32 bit addressing Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 14/21] netfilter: nf_tables: variable sized set element keys / data Pablo Neira Ayuso
` (8 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add a size argument to nft_data_init() and pass in the available space.
This will be used by the following patches to support variable sized
set element data.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 3 ++-
net/netfilter/nf_tables_api.c | 26 ++++++++++++++++----------
net/netfilter/nft_bitwise.c | 6 ++++--
net/netfilter/nft_cmp.c | 9 ++++++---
net/netfilter/nft_immediate.c | 3 ++-
5 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 1f9b848..160577b 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -110,7 +110,8 @@ struct nft_data_desc {
unsigned int len;
};
-int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
+int nft_data_init(const struct nft_ctx *ctx,
+ struct nft_data *data, unsigned int size,
struct nft_data_desc *desc, const struct nlattr *nla);
void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 03faf76..2b3f88f 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3299,7 +3299,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
timeout = set->timeout;
}
- err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]);
+ err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &d1,
+ nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
goto err1;
err = -EINVAL;
@@ -3314,7 +3315,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
}
if (nla[NFTA_SET_ELEM_DATA] != NULL) {
- err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]);
+ err = nft_data_init(ctx, &data, sizeof(data), &d2,
+ nla[NFTA_SET_ELEM_DATA]);
if (err < 0)
goto err2;
@@ -3458,7 +3460,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_KEY] == NULL)
goto err1;
- err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]);
+ err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &desc,
+ nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
goto err1;
@@ -4339,7 +4342,8 @@ nla_put_failure:
return -1;
}
-static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
+static int nft_value_init(const struct nft_ctx *ctx,
+ struct nft_data *data, unsigned int size,
struct nft_data_desc *desc, const struct nlattr *nla)
{
unsigned int len;
@@ -4347,10 +4351,10 @@ static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
len = nla_len(nla);
if (len == 0)
return -EINVAL;
- if (len > sizeof(data->data))
+ if (len > size)
return -EOVERFLOW;
- nla_memcpy(data->data, nla, sizeof(data->data));
+ nla_memcpy(data->data, nla, len);
desc->type = NFT_DATA_VALUE;
desc->len = len;
return 0;
@@ -4363,8 +4367,7 @@ static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
}
static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
- [NFTA_DATA_VALUE] = { .type = NLA_BINARY,
- .len = FIELD_SIZEOF(struct nft_data, data) },
+ [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
[NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
};
@@ -4373,6 +4376,7 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
*
* @ctx: context of the expression using the data
* @data: destination struct nft_data
+ * @size: maximum data length
* @desc: data description
* @nla: netlink attribute containing data
*
@@ -4382,7 +4386,8 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
* The caller can indicate that it only wants to accept data of type
* NFT_DATA_VALUE by passing NULL for the ctx argument.
*/
-int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
+int nft_data_init(const struct nft_ctx *ctx,
+ struct nft_data *data, unsigned int size,
struct nft_data_desc *desc, const struct nlattr *nla)
{
struct nlattr *tb[NFTA_DATA_MAX + 1];
@@ -4393,7 +4398,8 @@ int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
return err;
if (tb[NFTA_DATA_VALUE])
- return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]);
+ return nft_value_init(ctx, data, size, desc,
+ tb[NFTA_DATA_VALUE]);
if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
return -EINVAL;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index f1a9be2..d71cc18 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -73,13 +73,15 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
if (err < 0)
return err;
- err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]);
+ err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
+ tb[NFTA_BITWISE_MASK]);
if (err < 0)
return err;
if (d1.len != priv->len)
return -EINVAL;
- err = nft_data_init(NULL, &priv->xor, &d2, tb[NFTA_BITWISE_XOR]);
+ err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
+ tb[NFTA_BITWISE_XOR]);
if (err < 0)
return err;
if (d2.len != priv->len)
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index ffaf214..e25b35d 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -75,7 +75,8 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct nft_data_desc desc;
int err;
- err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
+ err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc,
+ tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
@@ -125,7 +126,8 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
u32 mask;
int err;
- err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
+ err = nft_data_init(NULL, &data, sizeof(data), &desc,
+ tb[NFTA_CMP_DATA]);
BUG_ON(err < 0);
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
@@ -195,7 +197,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
return ERR_PTR(-EINVAL);
}
- err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
+ err = nft_data_init(NULL, &data, sizeof(data), &desc,
+ tb[NFTA_CMP_DATA]);
if (err < 0)
return ERR_PTR(err);
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 1e8e412..db3b746 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -49,7 +49,8 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA] == NULL)
return -EINVAL;
- err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]);
+ err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc,
+ tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
priv->dlen = desc.len;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 14/21] netfilter: nf_tables: variable sized set element keys / data
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (12 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 13/21] netfilter: nf_tables: support variable sized data in nft_data_init() Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 15/21] uapi: ebtables: don't include linux/if.h Pablo Neira Ayuso
` (7 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
This patch changes sets to support variable sized set element keys / data
up to 64 bytes each by using variable sized set extensions. This allows
to use concatenations with bigger data items suchs as IPv6 addresses.
As a side effect, small keys/data now don't require the full 16 bytes
of struct nft_data anymore but just the space they need.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 5 ++++-
include/uapi/linux/netfilter/nf_tables.h | 3 +++
net/netfilter/nf_tables_api.c | 27 ++++++++++++---------------
net/netfilter/nft_hash.c | 4 ++--
net/netfilter/nft_rbtree.c | 3 ++-
5 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 160577b..cb42da1 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -158,7 +158,10 @@ struct nft_userdata {
* @priv: element private data and extensions
*/
struct nft_set_elem {
- struct nft_data key;
+ union {
+ u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
+ struct nft_data val;
+ } key;
void *priv;
};
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 4221a6c..be8584c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -388,6 +388,9 @@ enum nft_data_attributes {
};
#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
+/* Maximum length of a value */
+#define NFT_DATA_VALUE_MAXLEN 64
+
/**
* enum nft_verdict_attributes - nf_tables verdict netlink attributes
*
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2b3f88f..ed0e70e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2608,7 +2608,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
}
desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
- if (desc.klen == 0 || desc.klen > FIELD_SIZEOF(struct nft_data, data))
+ if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
return -EINVAL;
flags = 0;
@@ -2634,11 +2634,10 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
if (nla[NFTA_SET_DATA_LEN] == NULL)
return -EINVAL;
desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
- if (desc.dlen == 0 ||
- desc.dlen > FIELD_SIZEOF(struct nft_data, data))
+ if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
return -EINVAL;
} else
- desc.dlen = sizeof(struct nft_data);
+ desc.dlen = sizeof(struct nft_verdict);
} else if (flags & NFT_SET_MAP)
return -EINVAL;
@@ -2854,12 +2853,10 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *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),
+ .align = __alignof__(u32),
},
[NFT_SET_EXT_DATA] = {
- .len = sizeof(struct nft_data),
- .align = __alignof__(struct nft_data),
+ .align = __alignof__(u32),
},
[NFT_SET_EXT_FLAGS] = {
.len = sizeof(u8),
@@ -3299,7 +3296,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
timeout = set->timeout;
}
- err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &d1,
+ err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
goto err1;
@@ -3307,7 +3304,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
goto err2;
- nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY);
+ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
if (timeout > 0) {
nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
if (timeout != set->timeout)
@@ -3342,7 +3339,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
goto err3;
}
- nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA);
+ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
}
/* The full maximum length of userdata can exceed the maximum
@@ -3358,7 +3355,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
}
err = -ENOMEM;
- elem.priv = nft_set_elem_init(set, &tmpl, elem.key.data, data.data,
+ elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
timeout, GFP_KERNEL);
if (elem.priv == NULL)
goto err3;
@@ -3393,7 +3390,7 @@ err3:
if (nla[NFTA_SET_ELEM_DATA] != NULL)
nft_data_uninit(&data, d2.type);
err2:
- nft_data_uninit(&elem.key, d1.type);
+ nft_data_uninit(&elem.key.val, d1.type);
err1:
return err;
}
@@ -3460,7 +3457,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_KEY] == NULL)
goto err1;
- err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &desc,
+ err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
goto err1;
@@ -3488,7 +3485,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
err3:
kfree(trans);
err2:
- nft_data_uninit(&elem.key, desc.type);
+ nft_data_uninit(&elem.key.val, desc.type);
err1:
return err;
}
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 767df41..3f9d45d 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -133,7 +133,7 @@ static int nft_hash_insert(const struct nft_set *set,
struct nft_hash_cmp_arg arg = {
.genmask = nft_genmask_next(read_pnet(&set->pnet)),
.set = set,
- .key = elem->key.data,
+ .key = elem->key.val.data,
};
return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -157,7 +157,7 @@ static void *nft_hash_deactivate(const struct nft_set *set,
struct nft_hash_cmp_arg arg = {
.genmask = nft_genmask_next(read_pnet(&set->pnet)),
.set = set,
- .key = elem->key.data,
+ .key = elem->key.val.data,
};
rcu_read_lock();
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index b888e0c..1c30f41 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -152,7 +152,8 @@ static void *nft_rbtree_deactivate(const struct nft_set *set,
while (parent != NULL) {
rbe = rb_entry(parent, struct nft_rbtree_elem, node);
- d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key, set->klen);
+ d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key.val,
+ set->klen);
if (d < 0)
parent = parent->rb_left;
else if (d > 0)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 15/21] uapi: ebtables: don't include linux/if.h
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (13 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 14/21] netfilter: nf_tables: variable sized set element keys / data Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 16/21] netfilter: nf_tables: add helper functions for expression handling Pablo Neira Ayuso
` (6 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
linux/if.h creates conflicts in userspace with net/if.h
By using it here we force userspace to use linux/if.h while
net/if.h may be needed.
Note that:
include/linux/netfilter_ipv4/ip_tables.h and
include/linux/netfilter_ipv6/ip6_tables.h
don't include linux/if.h and they also refer to IFNAMSIZ, so they are
expecting userspace to include use net/if.h from the client program.
Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter_bridge/ebtables.h | 3 ++-
include/uapi/linux/netfilter_bridge/ebtables.h | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 34e7a2b..f1bd396 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -12,9 +12,10 @@
#ifndef __LINUX_BRIDGE_EFF_H
#define __LINUX_BRIDGE_EFF_H
+#include <linux/if.h>
+#include <linux/if_ether.h>
#include <uapi/linux/netfilter_bridge/ebtables.h>
-
/* return values for match() functions */
#define EBT_MATCH 0
#define EBT_NOMATCH 1
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h
index ba99336..773dfe8 100644
--- a/include/uapi/linux/netfilter_bridge/ebtables.h
+++ b/include/uapi/linux/netfilter_bridge/ebtables.h
@@ -12,9 +12,7 @@
#ifndef _UAPI__LINUX_BRIDGE_EFF_H
#define _UAPI__LINUX_BRIDGE_EFF_H
-#include <linux/if.h>
#include <linux/netfilter_bridge.h>
-#include <linux/if_ether.h>
#define EBT_TABLE_MAXNAMELEN 32
#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 16/21] netfilter: nf_tables: add helper functions for expression handling
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (14 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 15/21] uapi: ebtables: don't include linux/if.h Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 17/21] netfilter: nf_tables: prepare for expressions associated to set elements Pablo Neira Ayuso
` (5 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add helper functions for initializing, cloning, dumping and destroying
a single expression that is not part of a rule.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 13 +++++++++
net/netfilter/nf_tables_api.c | 56 +++++++++++++++++++++++++++++++++----
2 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index cb42da1..e21623c 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1,6 +1,7 @@
#ifndef _NET_NF_TABLES_H
#define _NET_NF_TABLES_H
+#include <linux/module.h>
#include <linux/list.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
@@ -641,6 +642,18 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
return (void *)expr->data;
}
+struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
+ const struct nlattr *nla);
+void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
+int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
+ const struct nft_expr *expr);
+
+static inline void nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
+{
+ __module_get(src->ops->type->owner);
+ memcpy(dst, src, src->ops->size);
+}
+
/**
* struct nft_rule - nf_tables rule
*
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index ed0e70e..e97bee5 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1545,6 +1545,23 @@ nla_put_failure:
return -1;
};
+int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
+ const struct nft_expr *expr)
+{
+ struct nlattr *nest;
+
+ nest = nla_nest_start(skb, attr);
+ if (!nest)
+ goto nla_put_failure;
+ if (nf_tables_fill_expr_info(skb, expr) < 0)
+ goto nla_put_failure;
+ nla_nest_end(skb, nest);
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
struct nft_expr_info {
const struct nft_expr_ops *ops;
struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
@@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
module_put(expr->ops->type->owner);
}
+struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
+ const struct nlattr *nla)
+{
+ struct nft_expr_info info;
+ struct nft_expr *expr;
+ int err;
+
+ err = nf_tables_expr_parse(ctx, nla, &info);
+ if (err < 0)
+ goto err1;
+
+ err = -ENOMEM;
+ expr = kzalloc(info.ops->size, GFP_KERNEL);
+ if (expr == NULL)
+ goto err2;
+
+ err = nf_tables_newexpr(ctx, &info, expr);
+ if (err < 0)
+ goto err2;
+
+ return expr;
+err2:
+ module_put(info.ops->type->owner);
+err1:
+ return ERR_PTR(err);
+}
+
+void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
+{
+ nf_tables_expr_destroy(ctx, expr);
+ kfree(expr);
+}
+
/*
* Rules
*/
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
if (list == NULL)
goto nla_put_failure;
nft_rule_for_each_expr(expr, next, rule) {
- struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
- if (elem == NULL)
- goto nla_put_failure;
- if (nf_tables_fill_expr_info(skb, expr) < 0)
+ if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
goto nla_put_failure;
- nla_nest_end(skb, elem);
}
nla_nest_end(skb, list);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 17/21] netfilter: nf_tables: prepare for expressions associated to set elements
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (15 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 16/21] netfilter: nf_tables: add helper functions for expression handling Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 18/21] netfilter: nf_tables: mark stateful expressions Pablo Neira Ayuso
` (4 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Preparation to attach expressions to set elements: add a set extension
type to hold an expression and dump the expression information with the
set element.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 7 +++++++
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 9 +++++++++
3 files changed, 18 insertions(+)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index e21623c..d45a871 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -371,6 +371,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
* @NFT_SET_EXT_TIMEOUT: element timeout
* @NFT_SET_EXT_EXPIRATION: element expiration time
* @NFT_SET_EXT_USERDATA: user data associated with the element
+ * @NFT_SET_EXT_EXPR: expression assiociated with the element
* @NFT_SET_EXT_NUM: number of extension types
*/
enum nft_set_extensions {
@@ -380,6 +381,7 @@ enum nft_set_extensions {
NFT_SET_EXT_TIMEOUT,
NFT_SET_EXT_EXPIRATION,
NFT_SET_EXT_USERDATA,
+ NFT_SET_EXT_EXPR,
NFT_SET_EXT_NUM
};
@@ -491,6 +493,11 @@ static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext
return nft_set_ext(ext, NFT_SET_EXT_USERDATA);
}
+static inline struct nft_expr *nft_set_ext_expr(const struct nft_set_ext *ext)
+{
+ return nft_set_ext(ext, NFT_SET_EXT_EXPR);
+}
+
static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
{
return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index be8584c..f9c5af2 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -322,6 +322,7 @@ enum nft_set_elem_flags {
* @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
* @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
* @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
+ * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
*/
enum nft_set_elem_attributes {
NFTA_SET_ELEM_UNSPEC,
@@ -331,6 +332,7 @@ enum nft_set_elem_attributes {
NFTA_SET_ELEM_TIMEOUT,
NFTA_SET_ELEM_EXPIRATION,
NFTA_SET_ELEM_USERDATA,
+ NFTA_SET_ELEM_EXPR,
__NFTA_SET_ELEM_MAX
};
#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index e97bee5..8830811 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2904,6 +2904,9 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
[NFT_SET_EXT_DATA] = {
.align = __alignof__(u32),
},
+ [NFT_SET_EXT_EXPR] = {
+ .align = __alignof__(struct nft_expr),
+ },
[NFT_SET_EXT_FLAGS] = {
.len = sizeof(u8),
.align = __alignof__(u8),
@@ -2990,6 +2993,10 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
set->dlen) < 0)
goto nla_put_failure;
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
+ nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
+ goto nla_put_failure;
+
if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
htonl(*nft_set_ext_flags(ext))))
@@ -3276,6 +3283,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem)
nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
nft_data_uninit(nft_set_ext_data(ext), set->dtype);
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
+ nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
kfree(elem);
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 18/21] netfilter: nf_tables: mark stateful expressions
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (16 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 17/21] netfilter: nf_tables: prepare for expressions associated to set elements Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 19/21] netfilter: nf_tables: add flag to indicate set contains expressions Pablo Neira Ayuso
` (3 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add a flag to mark stateful expressions.
This is used for dynamic expression instanstiation to limit the usable
expressions. Strictly speaking only the dynset expression can not be
used in order to avoid recursion, but since dynamically instantiating
non-stateful expressions will simply create an identical copy, which
behaves no differently than the original, this limits to expressions
where it actually makes sense to dynamically instantiate them.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 4 ++++
net/netfilter/nft_counter.c | 1 +
net/netfilter/nft_limit.c | 1 +
3 files changed, 6 insertions(+)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d45a871..e6bcf55 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -583,6 +583,7 @@ static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
* @policy: netlink attribute policy
* @maxattr: highest netlink attribute number
* @family: address family for AF-specific types
+ * @flags: expression type flags
*/
struct nft_expr_type {
const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
@@ -594,8 +595,11 @@ struct nft_expr_type {
const struct nla_policy *policy;
unsigned int maxattr;
u8 family;
+ u8 flags;
};
+#define NFT_EXPR_STATEFUL 0x1
+
/**
* struct nft_expr_ops - nf_tables expression operations
*
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index 0f6367e..1759123 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -92,6 +92,7 @@ static struct nft_expr_type nft_counter_type __read_mostly = {
.ops = &nft_counter_ops,
.policy = nft_counter_policy,
.maxattr = NFTA_COUNTER_MAX,
+ .flags = NFT_EXPR_STATEFUL,
.owner = THIS_MODULE,
};
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index c862045..435c1cc 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -98,6 +98,7 @@ static struct nft_expr_type nft_limit_type __read_mostly = {
.ops = &nft_limit_ops,
.policy = nft_limit_policy,
.maxattr = NFTA_LIMIT_MAX,
+ .flags = NFT_EXPR_STATEFUL,
.owner = THIS_MODULE,
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 19/21] netfilter: nf_tables: add flag to indicate set contains expressions
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (17 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 18/21] netfilter: nf_tables: mark stateful expressions Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 20/21] netfilter: nft_dynset: dynamic stateful expression instantiation Pablo Neira Ayuso
` (2 subsequent siblings)
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add a set flag to indicate that the set is used as a state table and
contains expressions for evaluation. This operation is mutually
exclusive with the mapping operation, so sets specifying both are
rejected. The lookup expression also rejects binding to state tables
since it only deals with loopup and map operations.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 8 ++++++--
net/netfilter/nft_lookup.c | 3 +++
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index f9c5af2..4894238 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -238,6 +238,7 @@ enum nft_rule_compat_attributes {
* @NFT_SET_INTERVAL: set contains intervals
* @NFT_SET_MAP: set is used as a dictionary
* @NFT_SET_TIMEOUT: set uses timeouts
+ * @NFT_SET_EVAL: set contains expressions for evaluation
*/
enum nft_set_flags {
NFT_SET_ANONYMOUS = 0x1,
@@ -245,6 +246,7 @@ enum nft_set_flags {
NFT_SET_INTERVAL = 0x4,
NFT_SET_MAP = 0x8,
NFT_SET_TIMEOUT = 0x10,
+ NFT_SET_EVAL = 0x20,
};
/**
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8830811..78af83b 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2661,9 +2661,13 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
if (nla[NFTA_SET_FLAGS] != NULL) {
flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
- NFT_SET_INTERVAL | NFT_SET_MAP |
- NFT_SET_TIMEOUT))
+ NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
+ NFT_SET_MAP | NFT_SET_EVAL))
return -EINVAL;
+ /* Only one of both operations is supported */
+ if ((flags & (NFT_SET_MAP | NFT_SET_EVAL)) ==
+ (NFT_SET_MAP | NFT_SET_EVAL))
+ return -EOPNOTSUPP;
}
dtype = 0;
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index ba14662..b3c31ef 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -71,6 +71,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
return PTR_ERR(set);
}
+ if (set->flags & NFT_SET_EVAL)
+ return -EOPNOTSUPP;
+
priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
err = nft_validate_register_load(priv->sreg, set->klen);
if (err < 0)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 20/21] netfilter: nft_dynset: dynamic stateful expression instantiation
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (18 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 19/21] netfilter: nf_tables: add flag to indicate set contains expressions Pablo Neira Ayuso
@ 2015-04-13 19:29 ` Pablo Neira Ayuso
2015-04-13 19:30 ` [PATCH 21/21] netfilter: nf_tables: get rid of the expression example code Pablo Neira Ayuso
2015-04-14 2:18 ` [PATCH 00/21] Netfilter updates for net-next David Miller
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:29 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Support instantiating stateful expressions based on a template that
are associated with dynamically created set entries. The expressions
are evaluated when adding or updating the set element.
This allows to maintain per flow state using the existing set
infrastructure and expression types, with arbitrary definitions of
a flow.
Usage is currently restricted to anonymous sets, meaning only a single
binding can exist, since the desired semantics of multiple independant
bindings haven't been defined so far.
Examples (userspace syntax is still WIP):
1. Limit the rate of new SSH connections per host, similar to iptables
hashlimit:
flow ip saddr timeout 60s \
limit 10/second \
accept
2. Account network traffic between each set of /24 networks:
flow ip saddr & 255.255.255.0 . ip daddr & 255.255.255.0 \
counter
3. Account traffic to each host per user:
flow skuid . ip daddr \
counter
4. Account traffic for each combination of source address and TCP flags:
flow ip saddr . tcp flags \
counter
The resulting set content after a Xmas-scan look like this:
{
192.168.122.1 . fin | psh | urg : counter packets 1001 bytes 40040,
192.168.122.1 . ack : counter packets 74 bytes 3848,
192.168.122.1 . psh | ack : counter packets 35 bytes 3144
}
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nft_dynset.c | 54 +++++++++++++++++++++++++++---
2 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 4894238..5fa1cd0 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -567,6 +567,7 @@ enum nft_dynset_ops {
* @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
* @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
* @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
+ * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
*/
enum nft_dynset_attributes {
NFTA_DYNSET_UNSPEC,
@@ -576,6 +577,7 @@ enum nft_dynset_attributes {
NFTA_DYNSET_SREG_KEY,
NFTA_DYNSET_SREG_DATA,
NFTA_DYNSET_TIMEOUT,
+ NFTA_DYNSET_EXPR,
__NFTA_DYNSET_MAX,
};
#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 03699d5..513a8ef 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -23,6 +23,7 @@ struct nft_dynset {
enum nft_registers sreg_key:8;
enum nft_registers sreg_data:8;
u64 timeout;
+ struct nft_expr *expr;
struct nft_set_binding binding;
};
@@ -30,6 +31,7 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
struct nft_regs *regs)
{
const struct nft_dynset *priv = nft_expr_priv(expr);
+ struct nft_set_ext *ext;
u64 timeout;
void *elem;
@@ -44,7 +46,13 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
if (elem == NULL) {
if (set->size)
atomic_dec(&set->nelems);
+ return NULL;
}
+
+ ext = nft_set_elem_ext(set, elem);
+ if (priv->expr != NULL)
+ nft_expr_clone(nft_set_ext_expr(ext), priv->expr);
+
return elem;
}
@@ -55,18 +63,27 @@ static void nft_dynset_eval(const struct nft_expr *expr,
const struct nft_dynset *priv = nft_expr_priv(expr);
struct nft_set *set = priv->set;
const struct nft_set_ext *ext;
+ const struct nft_expr *sexpr;
u64 timeout;
if (set->ops->update(set, ®s->data[priv->sreg_key], nft_dynset_new,
expr, regs, &ext)) {
+ sexpr = NULL;
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
+ sexpr = nft_set_ext_expr(ext);
+
if (priv->op == NFT_DYNSET_OP_UPDATE &&
nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
timeout = priv->timeout ? : set->timeout;
*nft_set_ext_expiration(ext) = jiffies + timeout;
- return;
- }
- }
+ } else if (sexpr == NULL)
+ goto out;
+ if (sexpr != NULL)
+ sexpr->ops->eval(sexpr, regs, pkt);
+ return;
+ }
+out:
regs->verdict.code = NFT_BREAK;
}
@@ -77,6 +94,7 @@ static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
[NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
[NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
[NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
+ [NFTA_DYNSET_EXPR] = { .type = NLA_NESTED },
};
static int nft_dynset_init(const struct nft_ctx *ctx,
@@ -142,10 +160,29 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
} else if (set->flags & NFT_SET_MAP)
return -EINVAL;
+ if (tb[NFTA_DYNSET_EXPR] != NULL) {
+ if (!(set->flags & NFT_SET_EVAL))
+ return -EINVAL;
+ if (!(set->flags & NFT_SET_ANONYMOUS))
+ return -EOPNOTSUPP;
+
+ priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
+ if (IS_ERR(priv->expr))
+ return PTR_ERR(priv->expr);
+
+ err = -EOPNOTSUPP;
+ if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
+ goto err1;
+ } else if (set->flags & NFT_SET_EVAL)
+ return -EINVAL;
+
nft_set_ext_prepare(&priv->tmpl);
nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
if (set->flags & NFT_SET_MAP)
nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen);
+ if (priv->expr != NULL)
+ nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_EXPR,
+ priv->expr->ops->size);
if (set->flags & NFT_SET_TIMEOUT) {
if (timeout || set->timeout)
nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
@@ -155,10 +192,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
err = nf_tables_bind_set(ctx, set, &priv->binding);
if (err < 0)
- return err;
+ goto err1;
priv->set = set;
return 0;
+
+err1:
+ if (priv->expr != NULL)
+ nft_expr_destroy(ctx, priv->expr);
+ return err;
}
static void nft_dynset_destroy(const struct nft_ctx *ctx,
@@ -167,6 +209,8 @@ static void nft_dynset_destroy(const struct nft_ctx *ctx,
struct nft_dynset *priv = nft_expr_priv(expr);
nf_tables_unbind_set(ctx, priv->set, &priv->binding);
+ if (priv->expr != NULL)
+ nft_expr_destroy(ctx, priv->expr);
}
static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
@@ -184,6 +228,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
goto nla_put_failure;
if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout)))
goto nla_put_failure;
+ if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
+ goto nla_put_failure;
return 0;
nla_put_failure:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 21/21] netfilter: nf_tables: get rid of the expression example code
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (19 preceding siblings ...)
2015-04-13 19:29 ` [PATCH 20/21] netfilter: nft_dynset: dynamic stateful expression instantiation Pablo Neira Ayuso
@ 2015-04-13 19:30 ` Pablo Neira Ayuso
2015-04-14 2:18 ` [PATCH 00/21] Netfilter updates for net-next David Miller
21 siblings, 0 replies; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-04-13 19:30 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
There's an example net/netfilter/nft_expr_template.c example file in tree that
got out of sync along time, remove it.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/nft_expr_template.c | 94 -------------------------------------
1 file changed, 94 deletions(-)
delete mode 100644 net/netfilter/nft_expr_template.c
diff --git a/net/netfilter/nft_expr_template.c b/net/netfilter/nft_expr_template.c
deleted file mode 100644
index b6eed4d..0000000
--- a/net/netfilter/nft_expr_template.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/netlink.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter/nf_tables.h>
-#include <net/netfilter/nf_tables.h>
-
-struct nft_template {
-
-};
-
-static void nft_template_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
- const struct nft_pktinfo *pkt)
-{
- struct nft_template *priv = nft_expr_priv(expr);
-
-}
-
-static const struct nla_policy nft_template_policy[NFTA_TEMPLATE_MAX + 1] = {
- [NFTA_TEMPLATE_ATTR] = { .type = NLA_U32 },
-};
-
-static int nft_template_init(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nlattr * const tb[])
-{
- struct nft_template *priv = nft_expr_priv(expr);
-
- return 0;
-}
-
-static void nft_template_destroy(const struct nft_ctx *ctx,
- const struct nft_expr *expr)
-{
- struct nft_template *priv = nft_expr_priv(expr);
-
-}
-
-static int nft_template_dump(struct sk_buff *skb, const struct nft_expr *expr)
-{
- const struct nft_template *priv = nft_expr_priv(expr);
-
- NLA_PUT_BE32(skb, NFTA_TEMPLATE_ATTR, priv->field);
- return 0;
-
-nla_put_failure:
- return -1;
-}
-
-static struct nft_expr_type nft_template_type;
-static const struct nft_expr_ops nft_template_ops = {
- .type = &nft_template_type,
- .size = NFT_EXPR_SIZE(sizeof(struct nft_template)),
- .eval = nft_template_eval,
- .init = nft_template_init,
- .destroy = nft_template_destroy,
- .dump = nft_template_dump,
-};
-
-static struct nft_expr_type nft_template_type __read_mostly = {
- .name = "template",
- .ops = &nft_template_ops,
- .policy = nft_template_policy,
- .maxattr = NFTA_TEMPLATE_MAX,
- .owner = THIS_MODULE,
-};
-
-static int __init nft_template_module_init(void)
-{
- return nft_register_expr(&nft_template_type);
-}
-
-static void __exit nft_template_module_exit(void)
-{
- nft_unregister_expr(&nft_template_type);
-}
-
-module_init(nft_template_module_init);
-module_exit(nft_template_module_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_ALIAS_NFT_EXPR("template");
--
1.7.10.4
^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] Netfilter updates for net-next
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
` (20 preceding siblings ...)
2015-04-13 19:30 ` [PATCH 21/21] netfilter: nf_tables: get rid of the expression example code Pablo Neira Ayuso
@ 2015-04-14 2:18 ` David Miller
21 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2015-04-14 2:18 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 13 Apr 2015 21:29:39 +0200
> A final pull request, I know it's very late but this time I think
> it's worth a bit of rush.
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 00/21] Netfilter updates for net-next
@ 2015-05-18 16:25 Pablo Neira Ayuso
2015-05-18 18:48 ` David Miller
0 siblings, 1 reply; 33+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-18 16:25 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi,
The following patchset contains Netfilter updates for net-next. Briefly
speaking, cleanups and minor fixes for ipset from Jozsef Kadlecsik and
Serget Popovich, more incremental updates to make br_netfilter a better
place from Florian Westphal, ARP support to the x_tables mark match /
target from and context Zhang Chunyu and the addition of context to know
that the x_tables runs through nft_compat. More specifically, they are:
1) Fix sparse warning in ipset/ip_set_hash_ipmark.c when fetching the
IPSET_ATTR_MARK netlink attribute, from Jozsef Kadlecsik.
2) Rename STREQ macro to STRNCMP in ipset, also from Jozsef.
3) Use skb->network_header to calculate the transport offset in
ip_set_get_ip{4,6}_port(). From Alexander Drozdov.
4) Reduce memory consumption per element due to size miscalculation,
this patch and follow up patches from Sergey Popovich.
5) Expand nomatch field from 1 bit to 8 bits to allow to simplify
mtype_data_reset_flags(), also from Sergey.
6) Small clean for ipset macro trickery.
7) Fix error reporting when both ip_set_get_hostipaddr4() and
ip_set_get_extensions() from per-set uadt functions.
8) Simplify IPSET_ATTR_PORT netlink attribute validation.
9) Introduce HOST_MASK instead of hardcoded 32 in ipset.
10) Return true/false instead of 0/1 in functions that return boolean
in the ipset code.
11) Validate maximum length of the IPSET_ATTR_COMMENT netlink attribute.
12) Allow to dereference from ext_*() ipset macros.
13) Get rid of incorrect definitions of HKEY_DATALEN.
14) Include linux/netfilter/ipset/ip_set.h in the x_tables set match.
15) Reduce nf_bridge_info size in br_netfilter, from Florian Westphal.
16) Release nf_bridge_info after POSTROUTING since this is only needed
from the physdev match, also from Florian.
17) Reduce size of ipset code by deinlining ip_set_put_extensions(),
from Denys Vlasenko.
18) Oneliner to add ARP support to the x_tables mark match/target, from
Zhang Chunyu.
19) Add context to know if the x_tables extension runs from nft_compat,
to address minor problems with three existing extensions.
20) Correct return value in several seqfile *_show() functions in the
netfilter tree, from Joe Perches.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks!
----------------------------------------------------------------
The following changes since commit 9449c3cd90472141cf081af88181a56163ff7132:
net: make skb_dst_pop routine static (2015-05-12 23:19:49 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master
for you to fetch changes up to 861fb1078fd4ea09b442987b3e20fced0f15eb92:
netfilter: Use correct return for seq_show functions (2015-05-17 17:25:35 +0200)
----------------------------------------------------------------
Alexander Drozdov (1):
netfilter: ipset: make ip_set_get_ip*_port to use skb_network_offset
Denys Vlasenko (1):
netfilter: ipset: deinline ip_set_put_extensions()
Florian Westphal (2):
netfilter: bridge: neigh_head and physoutdev can't be used at same time
netfilter: bridge: free nf_bridge info on xmit
Joe Perches (1):
netfilter: Use correct return for seq_show functions
Jozsef Kadlecsik (3):
netfilter: ipset: Fix sparse warning
netfilter: ipset: Give a better name to a macro in ip_set_core.c
netfilter: ipset: Use better include files in xt_set.c
Pablo Neira Ayuso (1):
netfilter: x_tables: add context to know if extension runs from nft_compat
Sergey Popovich (11):
netfilter: ipset: Properly calculate extensions offsets and total length
netfilter: ipset: No need to make nomatch bitfield
netfilter: ipset: Preprocessor directices cleanup
netfilter: ipset: Return ipset error instead of bool
netfilter: ipset: Check IPSET_ATTR_PORT only once
netfilter: ipset: Use HOST_MASK literal to represent host address CIDR len
netfilter: ipset: Return bool values instead of int
netfilter: ipset: Check for comment netlink attribute length
netfilter: ipset: Fix ext_*() macros
netfilter: ipset: Fix hashing for ipv6 sets
netfilter: ipset: Improve preprocessor macros checks
Zhang Chunyu (1):
netfilter: xt_MARK: Add ARP support
include/linux/netfilter/ipset/ip_set.h | 32 +++-------------
include/linux/netfilter/x_tables.h | 2 +
include/linux/skbuff.h | 8 ++--
net/bridge/br_netfilter.c | 19 +++++++++-
net/bridge/netfilter/ebt_stp.c | 6 ++-
net/ipv4/netfilter/ipt_CLUSTERIP.c | 5 +++
net/netfilter/ipset/ip_set_bitmap_ip.c | 17 ++++++---
net/netfilter/ipset/ip_set_bitmap_ipmac.c | 13 +++++--
net/netfilter/ipset/ip_set_bitmap_port.c | 3 +-
net/netfilter/ipset/ip_set_core.c | 49 ++++++++++++++++++------
net/netfilter/ipset/ip_set_getport.c | 6 ++-
net/netfilter/ipset/ip_set_hash_gen.h | 22 +++++++++--
net/netfilter/ipset/ip_set_hash_ip.c | 33 ++++++++--------
net/netfilter/ipset/ip_set_hash_ipmark.c | 43 ++++++++++-----------
net/netfilter/ipset/ip_set_hash_ipport.c | 49 +++++++++++-------------
net/netfilter/ipset/ip_set_hash_ipportip.c | 40 ++++++++++----------
net/netfilter/ipset/ip_set_hash_ipportnet.c | 40 ++++++++++----------
net/netfilter/ipset/ip_set_hash_mac.c | 11 ++++--
net/netfilter/ipset/ip_set_hash_net.c | 28 ++++++++------
net/netfilter/ipset/ip_set_hash_netiface.c | 29 +++++++-------
net/netfilter/ipset/ip_set_hash_netnet.c | 30 ++++++++++-----
net/netfilter/ipset/ip_set_hash_netport.c | 38 +++++++++----------
net/netfilter/ipset/ip_set_hash_netportnet.c | 52 ++++++++++++++------------
net/netfilter/ipset/ip_set_list_set.c | 3 +-
net/netfilter/nfnetlink_queue_core.c | 2 +-
net/netfilter/nft_compat.c | 2 +
net/netfilter/x_tables.c | 18 +++------
net/netfilter/xt_TCPMSS.c | 6 +++
net/netfilter/xt_mark.c | 1 +
net/netfilter/xt_set.c | 3 +-
30 files changed, 346 insertions(+), 264 deletions(-)
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] Netfilter updates for net-next
2015-05-18 16:25 Pablo Neira Ayuso
@ 2015-05-18 18:48 ` David Miller
0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2015-05-18 18:48 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 18 May 2015 18:25:03 +0200
> The following patchset contains Netfilter updates for net-next. Briefly
> speaking, cleanups and minor fixes for ipset from Jozsef Kadlecsik and
> Serget Popovich, more incremental updates to make br_netfilter a better
> place from Florian Westphal, ARP support to the x_tables mark match /
> target from and context Zhang Chunyu and the addition of context to know
> that the x_tables runs through nft_compat. More specifically, they are:
...
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 00/21] Netfilter updates for net-next
@ 2017-02-12 19:42 Pablo Neira Ayuso
2017-02-13 3:12 ` David Miller
0 siblings, 1 reply; 33+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-12 19:42 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
The following patchset contains Netfilter updates for your net-next
tree, most relevantly they are:
1) Extend nft_exthdr to allow to match TCP options bitfields, from
Manuel Messner.
2) Allow to check if IPv6 extension header is present in nf_tables,
from Phil Sutter.
3) Allow to set and match conntrack zone in nf_tables, patches from
Florian Westphal.
4) Several patches for the nf_tables set infrastructure, this includes
cleanup and preparatory patches to add the new bitmap set type.
5) Add optional ruleset generation ID check to nf_tables and allow to
delete rules that got no public handle yet via NFTA_RULE_ID. These
patches add the missing kernel infrastructure to support rule
deletion by description from userspace.
6) Missing NFT_SET_OBJECT flag to select the right backend when sets
stores an object map.
7) A couple of cleanups for the expectation and SIP helper, from Gao
feng.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks!
----------------------------------------------------------------
The following changes since commit 6e7bc478c9a006c701c14476ec9d389a484b4864:
net: skb_needs_check() accepts CHECKSUM_NONE for tx (2017-02-03 17:33:01 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to 7286ff7fde9f963736c7e575572899d8e16b06b7:
netfilter: nf_tables: honor NFT_SET_OBJECT in set backend selection (2017-02-12 14:45:14 +0100)
----------------------------------------------------------------
Florian Westphal (3):
netfilter: nft_ct: add zone id get support
netfilter: nft_ct: prepare for key-dependent error unwind
netfilter: nft_ct: add zone id set support
Gao Feng (2):
netfilter: nf_ct_sip: Use mod_timer_pending()
netfilter: nf_ct_expect: nf_ct_expect_insert() returns void
Manuel Messner (1):
netfilter: nft_exthdr: add TCP option matching
Pablo Neira Ayuso (14):
netfilter: nf_tables: pass netns to set->ops->remove()
netfilter: nf_tables: use struct nft_set_iter in set element flush
netfilter: nf_tables: rename deactivate_one() to flush()
netfilter: nf_tables: add flush field to struct nft_set_iter
netfilter: nf_tables: rename struct nft_set_estimate class field
netfilter: nf_tables: add space notation to sets
netfilter: nf_tables: add bitmap set type
netfilter: nfnetlink: get rid of u_intX_t types
netfilter: nfnetlink: add nfnetlink_rcv_skb_batch()
netfilter: nfnetlink: allow to check for generation ID
netfilter: nf_tables: add check_genid to the nfnetlink subsystem
netfilter: nf_tables: add NFTA_RULE_ID attribute
netfilter: update MAINTAINERS
netfilter: nf_tables: honor NFT_SET_OBJECT in set backend selection
Phil Sutter (1):
netfilter: nft_exthdr: Add support for existence check
MAINTAINERS | 3 +-
include/linux/netfilter/nfnetlink.h | 1 +
include/net/netfilter/nf_tables.h | 21 ++-
include/uapi/linux/netfilter/nf_tables.h | 27 ++-
include/uapi/linux/netfilter/nfnetlink.h | 12 ++
net/netfilter/Kconfig | 10 +-
net/netfilter/Makefile | 1 +
net/netfilter/nf_conntrack_expect.c | 8 +-
net/netfilter/nf_conntrack_sip.c | 12 +-
net/netfilter/nf_tables_api.c | 89 ++++++---
net/netfilter/nfnetlink.c | 90 ++++++---
net/netfilter/nft_ct.c | 195 +++++++++++++++++--
net/netfilter/nft_exthdr.c | 139 ++++++++++++--
net/netfilter/nft_set_bitmap.c | 314 +++++++++++++++++++++++++++++++
net/netfilter/nft_set_hash.c | 16 +-
net/netfilter/nft_set_rbtree.c | 16 +-
16 files changed, 832 insertions(+), 122 deletions(-)
create mode 100644 net/netfilter/nft_set_bitmap.c
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] Netfilter updates for net-next
2017-02-12 19:42 Pablo Neira Ayuso
@ 2017-02-13 3:12 ` David Miller
0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2017-02-13 3:12 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sun, 12 Feb 2017 20:42:32 +0100
> The following patchset contains Netfilter updates for your net-next
> tree, most relevantly they are:
..
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Pulled, I really like the RULE_ID generation count stuff for
userspace.
Thanks.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 00/21] Netfilter updates for net-next
@ 2018-08-05 21:21 Pablo Neira Ayuso
2018-08-06 0:06 ` David Miller
0 siblings, 1 reply; 33+ messages in thread
From: Pablo Neira Ayuso @ 2018-08-05 21:21 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
The following patchset contains Netfilter updates for your net-next tree:
1) Support for transparent proxying for nf_tables, from Mate Eckl.
2) Patchset to add OS passive fingerprint recognition for nf_tables,
from Fernando Fernandez. This takes common code from xt_osf and
place it into the new nfnetlink_osf module for codebase sharing.
3) Lightweight tunneling support for nf_tables.
4) meta and lookup are likely going to be used in rulesets, make them
direct calls. From Florian Westphal.
A bunch of incremental updates:
5) use PTR_ERR_OR_ZERO() from nft_numgen, from YueHaibing.
6) Use kvmalloc_array() to allocate hashtables, from Li RongQing.
7) Explicit dependencies between nfnetlink_cttimeout and conntrack
timeout extensions, from Harsha Sharma.
8) Simplify NLM_F_CREATE handling in nf_tables.
9) Removed unused variable in the get element command, from
YueHaibing.
10) Expose bridge hook priorities through uapi, from Mate Eckl.
And a few fixes for previous Netfilter batch for net-next:
11) Use per-netns mutex from flowtable event, from Florian Westphal.
12) Remove explicit dependency on iptables CT target from conntrack
zones, from Florian.
13) Fix use-after-free in rmmod nf_conntrack path, also from Florian.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thanks.
----------------------------------------------------------------
The following changes since commit ecbcd689d74a394b711d2360aef7e5d007ec9d98:
Merge tag 'mlx5e-updates-2018-07-26' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux (2018-07-26 21:33:24 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to 483f3fdcc70b3c3a1f314235ab0066f3dbd4cfbe:
netfilter: nft_tunnel: fix sparse errors (2018-08-04 00:53:29 +0200)
----------------------------------------------------------------
Fernando Fernandez Mancera (5):
netfilter: nf_osf: rename nf_osf.c to nfnetlink_osf.c
netfilter: nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c
netfilter: nf_tables: implement Passive OS fingerprint module in nft_osf
netfilter: nf_osf: move nf_osf_fingers to non-uapi header file
netfilter: nfnetlink_osf: rename nf_osf header file to nfnetlink_osf
Florian Westphal (4):
netfilter: nf_tables: handle meta/lookup with direct call
netfilter: nf_tables: flow event notifier must use transaction mutex
netfilter: kconfig: remove ct zone/label dependencies
netfilter: conntrack: avoid use-after free on rmmod
Harsha Sharma (1):
netfilter: cttimeout: Make NF_CT_NETLINK_TIMEOUT depend on NF_CONNTRACK_TIMEOUT
Li RongQing (1):
netfilter: use kvmalloc_array to allocate memory for hashtable
Máté Eckl (3):
netfilter: nf_tables: Add native tproxy support
netfilter: nft_tproxy: Add missing config check
netfilter: bridge: Expose nf_tables bridge hook priorities through uapi
Pablo Neira Ayuso (5):
netfilter: nf_osf: add nf_osf_find()
netfilter: nf_tables: add tunnel support
netfilter: nf_tables: match on tunnel metadata
netfilter: nf_tables: simplify NLM_F_CREATE handling
netfilter: nft_tunnel: fix sparse errors
YueHaibing (2):
netfilter: use PTR_ERR_OR_ZERO()
netfilter: nf_tables: remove unused variable
.../linux/netfilter/{nf_osf.h => nfnetlink_osf.h} | 13 +-
include/linux/netfilter_bridge.h | 11 -
include/net/netfilter/nf_conntrack.h | 2 -
include/net/netfilter/nf_tables_core.h | 7 +
include/uapi/linux/netfilter/nf_tables.h | 107 +++-
.../linux/netfilter/{nf_osf.h => nfnetlink_osf.h} | 9 +
include/uapi/linux/netfilter/xt_osf.h | 11 +-
include/uapi/linux/netfilter_bridge.h | 11 +
net/bridge/br_netfilter_hooks.c | 1 +
net/bridge/netfilter/ebtable_filter.c | 1 +
net/bridge/netfilter/ebtable_nat.c | 1 +
net/core/dst.c | 1 +
net/netfilter/Kconfig | 45 +-
net/netfilter/Makefile | 5 +-
net/netfilter/nf_conntrack_core.c | 29 +-
net/netfilter/nf_conntrack_expect.c | 2 +-
net/netfilter/nf_conntrack_helper.c | 4 +-
net/netfilter/nf_conntrack_proto.c | 7 +-
net/netfilter/nf_nat_core.c | 4 +-
net/netfilter/nf_tables_api.c | 35 +-
net/netfilter/nf_tables_core.c | 16 +-
net/netfilter/nfnetlink_cttimeout.c | 6 -
net/netfilter/{nf_osf.c => nfnetlink_osf.c} | 186 ++++++-
net/netfilter/nft_lookup.c | 6 +-
net/netfilter/nft_meta.c | 6 +-
net/netfilter/nft_numgen.c | 4 +-
net/netfilter/nft_osf.c | 106 ++++
net/netfilter/nft_tproxy.c | 316 ++++++++++++
net/netfilter/nft_tunnel.c | 566 +++++++++++++++++++++
net/netfilter/xt_connlimit.c | 4 +-
net/netfilter/xt_osf.c | 149 +-----
31 files changed, 1417 insertions(+), 254 deletions(-)
rename include/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (74%)
rename include/uapi/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (94%)
rename net/netfilter/{nf_osf.c => nfnetlink_osf.c} (58%)
create mode 100644 net/netfilter/nft_osf.c
create mode 100644 net/netfilter/nft_tproxy.c
create mode 100644 net/netfilter/nft_tunnel.c
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] Netfilter updates for net-next
2018-08-05 21:21 Pablo Neira Ayuso
@ 2018-08-06 0:06 ` David Miller
0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2018-08-06 0:06 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sun, 5 Aug 2018 23:21:20 +0200
> The following patchset contains Netfilter updates for your net-next tree:
...
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 00/21] Netfilter updates for net-next
@ 2020-01-18 20:13 Pablo Neira Ayuso
2020-01-19 9:33 ` David Miller
0 siblings, 1 reply; 33+ messages in thread
From: Pablo Neira Ayuso @ 2020-01-18 20:13 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi,
The following patchset contains Netfilter updates for net-next, they are:
1) Incorrect uapi header comment in bitwise, from Jeremy Sowden.
2) Fetch flow statistics if flow is still active.
3) Restrict flow matching on hardware based on input device.
4) Add nf_flow_offload_work_alloc() helper function.
5) Remove the last client of the FLOW_OFFLOAD_DYING flag, use teardown
instead.
6) Use atomic bitwise operation to operate with flow flags.
7) Add nf_flowtable_hw_offload() helper function to check for the
NF_FLOWTABLE_HW_OFFLOAD flag.
8) Add NF_FLOW_HW_REFRESH to retry hardware offload from the flowtable
software datapath.
9) Remove indirect calls in xt_hashlimit, from Florian Westphal.
10) Add nf_flow_offload_tuple() helper to consolidate code.
11) Add nf_flow_table_offload_cmd() helper function.
12) A few whitespace cleanups in nf_tables in bitwise and the bitmap/hash
set types, from Jeremy Sowden.
13) Cleanup netlink attribute checks in bitwise, from Jeremy Sowden.
14) Replace goto by return in error path of nft_bitwise_dump(), from
Jeremy Sowden.
15) Add bitwise operation netlink attribute, also from Jeremy.
16) Add nft_bitwise_init_bool(), from Jeremy Sowden.
17) Add nft_bitwise_eval_bool(), also from Jeremy.
18) Add nft_bitwise_dump_bool(), from Jeremy Sowden.
19) Disallow hardware offload for other that NFT_BITWISE_BOOL,
from Jeremy Sowden.
20) Add NFTA_BITWISE_DATA netlink attribute, again from Jeremy.
21) Add support for bitwise shift operation, from Jeremy Sowden.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Thank you.
----------------------------------------------------------------
The following changes since commit 6bc8038035267d12df2bf78a8e1a5f07069fabb8:
sfc: remove duplicated include from efx.c (2020-01-16 10:06:18 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD
for you to fetch changes up to 567d746b55bc66d3800c9ae91d50f0c5deb2fd93:
netfilter: bitwise: add support for shifts. (2020-01-16 15:52:02 +0100)
----------------------------------------------------------------
Florian Westphal (1):
netfilter: hashlimit: do not use indirect calls during gc
Jeremy Sowden (11):
netfilter: nft_bitwise: correct uapi header comment.
netfilter: nf_tables: white-space fixes.
netfilter: bitwise: remove NULL comparisons from attribute checks.
netfilter: bitwise: replace gotos with returns.
netfilter: bitwise: add NFTA_BITWISE_OP netlink attribute.
netfilter: bitwise: add helper for initializing boolean operations.
netfilter: bitwise: add helper for evaluating boolean operations.
netfilter: bitwise: add helper for dumping boolean operations.
netfilter: bitwise: only offload boolean operations.
netfilter: bitwise: add NFTA_BITWISE_DATA attribute.
netfilter: bitwise: add support for shifts.
Pablo Neira Ayuso (9):
netfilter: flowtable: fetch stats only if flow is still alive
netfilter: flowtable: restrict flow dissector match on meta ingress device
netfilter: flowtable: add nf_flow_offload_work_alloc()
netfilter: flowtable: remove dying bit, use teardown bit instead
netfilter: flowtable: use atomic bitwise operations for flow flags
netfilter: flowtable: add nf_flowtable_hw_offload() helper function
netfilter: flowtable: refresh flow if hardware offload fails
netfilter: flowtable: add nf_flow_offload_tuple() helper
netfilter: flowtable: add nf_flow_table_offload_cmd()
include/net/netfilter/nf_flow_table.h | 27 ++--
include/uapi/linux/netfilter/nf_tables.h | 26 +++-
net/netfilter/nf_flow_table_core.c | 31 +++--
net/netfilter/nf_flow_table_ip.c | 21 ++-
net/netfilter/nf_flow_table_offload.c | 164 ++++++++++++----------
net/netfilter/nft_bitwise.c | 224 +++++++++++++++++++++++++------
net/netfilter/nft_set_bitmap.c | 4 +-
net/netfilter/nft_set_hash.c | 2 +-
net/netfilter/xt_hashlimit.c | 22 +--
9 files changed, 352 insertions(+), 169 deletions(-)
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH 00/21] Netfilter updates for net-next
2020-01-18 20:13 Pablo Neira Ayuso
@ 2020-01-19 9:33 ` David Miller
0 siblings, 0 replies; 33+ messages in thread
From: David Miller @ 2020-01-19 9:33 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Sat, 18 Jan 2020 21:13:56 +0100
> The following patchset contains Netfilter updates for net-next, they are:
...
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2020-01-19 9:35 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-13 19:29 [PATCH 00/21] Netfilter updates for net-next Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 01/21] netfilter: nf_tables: validate len in nft_validate_data_load() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 02/21] netfilter: nf_tables: rename nft_validate_data_load() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 03/21] netfilter: nft_lookup: use nft_validate_register_store() to validate types Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 04/21] netfilter: nf_tables: kill nft_validate_output_register() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 05/21] netfilter: nf_tables: introduce nft_validate_register_load() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 06/21] netfilter: nf_tables: get rid of NFT_REG_VERDICT usage Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 07/21] netfilter: nf_tables: use struct nft_verdict within struct nft_data Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 08/21] netfilter: nf_tables: convert expressions to u32 register pointers Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 09/21] netfilter: nf_tables: kill nft_data_cmp() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 10/21] netfilter: nf_tables: convert sets to u32 data pointers Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 11/21] netfilter: nf_tables: add register parsing/dumping helpers Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 12/21] netfilter: nf_tables: switch registers to 32 bit addressing Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 13/21] netfilter: nf_tables: support variable sized data in nft_data_init() Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 14/21] netfilter: nf_tables: variable sized set element keys / data Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 15/21] uapi: ebtables: don't include linux/if.h Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 16/21] netfilter: nf_tables: add helper functions for expression handling Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 17/21] netfilter: nf_tables: prepare for expressions associated to set elements Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 18/21] netfilter: nf_tables: mark stateful expressions Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 19/21] netfilter: nf_tables: add flag to indicate set contains expressions Pablo Neira Ayuso
2015-04-13 19:29 ` [PATCH 20/21] netfilter: nft_dynset: dynamic stateful expression instantiation Pablo Neira Ayuso
2015-04-13 19:30 ` [PATCH 21/21] netfilter: nf_tables: get rid of the expression example code Pablo Neira Ayuso
2015-04-14 2:18 ` [PATCH 00/21] Netfilter updates for net-next David Miller
-- strict thread matches above, loose matches on Subject: below --
2020-01-18 20:13 Pablo Neira Ayuso
2020-01-19 9:33 ` David Miller
2018-08-05 21:21 Pablo Neira Ayuso
2018-08-06 0:06 ` David Miller
2017-02-12 19:42 Pablo Neira Ayuso
2017-02-13 3:12 ` David Miller
2015-05-18 16:25 Pablo Neira Ayuso
2015-05-18 18:48 ` David Miller
2013-01-25 13:54 [PATCH 00/21] netfilter " pablo
2013-01-27 5:56 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).