netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals
@ 2013-10-14 12:46 Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 1/7] netfilter: nf_tables: Fix API documentation on a missing part Tomasz Bursztyka
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Hi, 

First 2 minor fixes:
-------------------

patch 1: don't know why I messed up here in my previous documentation patch, my mistake anyway.
patch 2: an old left-over. Why has priv->len been corrupted before?

And 5 proposals:
---------------

patch 3: Let's expose table's usage (so user might decide if it's worth dumping table's content, it can useful info finally)

patch 4: That one is debatable: NFTA_CHAIN_USE is - imho - not enough self-explanatory.
NFTA_CHAIN_REFS (or NFTA_CHAIN_REFERENCES?) is much better. If there is a time to change such minor details, it's now or never.

patch 5: add a meta key to get dev->addr_len

patch 6: add lshift/rshift to bitwise expression. It's a first shot, which should work pretty well already. Maybe there are improvments which could be done, depending on data length (2 or 4: we could cast to u64 thus reducing shifts by 2).
	At least I tried to keep the API sane, and c/p the byteorder way. sreg, dreg, op, len, mask are mandatory. xor and shift are related to the selected op.

patch 7: patch's commit message says all.

Tomasz Bursztyka (7):
  netfilter: nf_tables: Fix API documentation on a missing part
  netfilter: nf_tables: Use byteorder operands length relevantly
  netfilter: nf_tables: Expose the table's chain usage to the netlink
    API
  netfilter: nf_tables: Use a semantically relevant name on chain's refs
  netfilter: nf_tables: Add a meta key to get the device address length
  netfilter: nf_tables: Add left and right shifts to bitwise expression
  netfilter: nf_tables: Improve payload expression for an extra offset

 include/net/netfilter/nf_tables_core.h   |  1 +
 include/uapi/linux/netfilter/nf_tables.h | 42 +++++++++++++++++--
 net/netfilter/nf_tables_api.c            |  5 ++-
 net/netfilter/nf_tables_core.c           |  6 ++-
 net/netfilter/nft_bitwise.c              | 70 +++++++++++++++++++++++++++-----
 net/netfilter/nft_byteorder.c            |  2 -
 net/netfilter/nft_meta.c                 | 12 +++++-
 net/netfilter/nft_payload.c              | 25 +++++++++---
 8 files changed, 136 insertions(+), 27 deletions(-)

-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 1/7] netfilter: nf_tables: Fix API documentation on a missing part
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 2/7] netfilter: nf_tables: Use byteorder operands length relevantly Tomasz Bursztyka
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Add the documentation for NFTA_BYTEORDER_SIZE attribute which was left
with a non relevant _TODO_.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/uapi/linux/netfilter/nf_tables.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index be8a062..b108548 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -398,7 +398,7 @@ enum nft_byteorder_ops {
  * @NFTA_BYTEORDER_DREG: destination register (NLA_U32: nft_registers)
  * @NFTA_BYTEORDER_OP: operator (NLA_U32: enum nft_byteorder_ops)
  * @NFTA_BYTEORDER_LEN: length of the data (NLA_U32)
- * @NFTA_BYTEORDER_SIZE: _TODO_ (NLA_U32)
+ * @NFTA_BYTEORDER_SIZE: data size in bytes (NLA_U32: 2 or 4)
  */
 enum nft_byteorder_attributes {
 	NFTA_BYTEORDER_UNSPEC,
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 2/7] netfilter: nf_tables: Use byteorder operands length relevantly
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 1/7] netfilter: nf_tables: Fix API documentation on a missing part Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 3/7] netfilter: nf_tables: Expose the table's chain usage to the netlink API Tomasz Bursztyka
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 net/netfilter/nft_byteorder.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index d213b98..c39ed8d 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -110,8 +110,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
 	}
 
 	priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
-	// FIXME: something is corrupting the attribute value
-	priv->len = 4;
 	if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
 		return -EINVAL;
 
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 3/7] netfilter: nf_tables: Expose the table's chain usage to the netlink API
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 1/7] netfilter: nf_tables: Fix API documentation on a missing part Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 2/7] netfilter: nf_tables: Use byteorder operands length relevantly Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 4/7] netfilter: nf_tables: Use a semantically relevant name on chain's refs Tomasz Bursztyka
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

User space can therefore know whether a table is in use or not, and by
how many chains.

Suggested by Pablo Neira Ayuso.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/uapi/linux/netfilter/nf_tables.h | 2 ++
 net/netfilter/nf_tables_api.c            | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index b108548..28f0ffb 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -110,11 +110,13 @@ enum nft_table_flags {
  *
  * @NFTA_TABLE_NAME: name of the table (NLA_STRING)
  * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
+ * @NFTA_TABLE_CHAINS: number of chains in this table (NLA_U32)
  */
 enum nft_table_attributes {
 	NFTA_TABLE_UNSPEC,
 	NFTA_TABLE_NAME,
 	NFTA_TABLE_FLAGS,
+	NFTA_TABLE_CHAINS,
 	__NFTA_TABLE_MAX
 };
 #define NFTA_TABLE_MAX		(__NFTA_TABLE_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index dcddc49..482b689 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -180,7 +180,8 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, u32 portid, u32 seq,
 	nfmsg->res_id		= 0;
 
 	if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
-	    nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)))
+	    nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
+	    nla_put_be32(skb, NFTA_TABLE_CHAINS, htonl(table->use)))
 		goto nla_put_failure;
 
 	return nlmsg_end(skb, nlh);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 4/7] netfilter: nf_tables: Use a semantically relevant name on chain's refs
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
                   ` (2 preceding siblings ...)
  2013-10-14 12:46 ` [nftables-kernel PATCH 3/7] netfilter: nf_tables: Expose the table's chain usage to the netlink API Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 5/7] netfilter: nf_tables: Add a meta key to get the device address length Tomasz Bursztyka
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

NFTA_CHAIN_USE is less semantically self-explaining than
NFTA_CHAIN_REFS.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/uapi/linux/netfilter/nf_tables.h | 4 ++--
 net/netfilter/nf_tables_api.c            | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 28f0ffb..81eec3b 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -129,7 +129,7 @@ enum nft_table_attributes {
  * @NFTA_CHAIN_NAME: name of the chain (NLA_STRING)
  * @NFTA_CHAIN_HOOK: hook specification for basechains (NLA_NESTED: nft_hook_attributes)
  * @NFTA_CHAIN_POLICY: numeric policy of the chain (NLA_U32)
- * @NFTA_CHAIN_USE: number of references to this chain (NLA_U32)
+ * @NFTA_CHAIN_REFS: number of references to this chain (NLA_U32)
  * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING)
  * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes)
  */
@@ -140,7 +140,7 @@ enum nft_chain_attributes {
 	NFTA_CHAIN_NAME,
 	NFTA_CHAIN_HOOK,
 	NFTA_CHAIN_POLICY,
-	NFTA_CHAIN_USE,
+	NFTA_CHAIN_REFS,
 	NFTA_CHAIN_TYPE,
 	NFTA_CHAIN_COUNTERS,
 	__NFTA_CHAIN_MAX
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 482b689..951c264 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -614,7 +614,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
 			goto nla_put_failure;
 	}
 
-	if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
+	if (nla_put_be32(skb, NFTA_CHAIN_REFS, htonl(chain->use)))
 		goto nla_put_failure;
 
 	return nlmsg_end(skb, nlh);
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 5/7] netfilter: nf_tables: Add a meta key to get the device address length
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
                   ` (3 preceding siblings ...)
  2013-10-14 12:46 ` [nftables-kernel PATCH 4/7] netfilter: nf_tables: Use a semantically relevant name on chain's refs Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 6/7] netfilter: nf_tables: Add left and right shifts to bitwise expression Tomasz Bursztyka
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This will be useful to determine at runtime the position of some data in
the packet.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_meta.c                 | 12 +++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 81eec3b..65f41ff 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -526,6 +526,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_OIFNAME: packet output interface name (dev->name)
  * @NFT_META_IIFTYPE: packet input interface type (dev->type)
  * @NFT_META_OIFTYPE: packet output interface type (dev->type)
+ * @NFT_META_DEV_ADDRLEN: packet interface address length (dev->addr_len)
  * @NFT_META_SKUID: originating socket UID (fsuid)
  * @NFT_META_SKGID: originating socket GID (fsgid)
  * @NFT_META_NFTRACE: packet nftrace bit
@@ -543,6 +544,7 @@ enum nft_meta_keys {
 	NFT_META_OIFNAME,
 	NFT_META_IIFTYPE,
 	NFT_META_OIFTYPE,
+	NFT_META_DEV_ADDRLEN,
 	NFT_META_SKUID,
 	NFT_META_SKGID,
 	NFT_META_NFTRACE,
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 8c28220..8116535 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -30,7 +30,7 @@ static void nft_meta_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;
+	const struct net_device *in = pkt->in, *out = pkt->out, *dev;
 	struct nft_data *dest = &data[priv->dreg];
 
 	switch (priv->key) {
@@ -76,6 +76,15 @@ static void nft_meta_eval(const struct nft_expr *expr,
 			goto err;
 		*(u16 *)dest->data = out->type;
 		break;
+	case NFT_META_DEV_ADDRLEN:
+		if (out != NULL)
+			dev = out;
+		else if (in != NULL)
+			dev = out;
+		else
+			goto err;
+		*(u8 *)dest->data = dev->addr_len;
+		break;
 	case NFT_META_SKUID:
 		if (skb->sk == NULL || skb->sk->sk_state == TCP_TIME_WAIT)
 			goto err;
@@ -159,6 +168,7 @@ static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 	case NFT_META_OIFNAME:
 	case NFT_META_IIFTYPE:
 	case NFT_META_OIFTYPE:
+	case NFT_META_DEV_ADDRLEN:
 	case NFT_META_SKUID:
 	case NFT_META_SKGID:
 #ifdef CONFIG_NET_CLS_ROUTE
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 6/7] netfilter: nf_tables: Add left and right shifts to bitwise expression
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
                   ` (4 preceding siblings ...)
  2013-10-14 12:46 ` [nftables-kernel PATCH 5/7] netfilter: nf_tables: Add a meta key to get the device address length Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:46 ` [nftables-kernel PATCH 7/7] netfilter: nf_tables: Improve payload expression for an extra offset Tomasz Bursztyka
  2013-10-14 12:58 ` [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Pablo Neira Ayuso
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This add left and right shift operators. Thus it is possible to make
logical shifts to nft_data.

A multiplication by 2 can be easily ordered this way and more.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/uapi/linux/netfilter/nf_tables.h | 30 +++++++++++++-
 net/netfilter/nft_bitwise.c              | 70 +++++++++++++++++++++++++++-----
 2 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 65f41ff..8b12b8f 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -351,16 +351,32 @@ enum nft_immediate_attributes {
 #define NFTA_IMMEDIATE_MAX	(__NFTA_IMMEDIATE_MAX - 1)
 
 /**
+ * enum nft_bitwise_ops - nf_tables bitwise operators
+ *
+ * @NFT_BITWISE_XOR: xor operator
+ * @NFT_BITWISE_LSHIFT: left shift operator
+ * @NFT_BITWISE_RSHIFT: right shift operator
+ */
+enum nft_bitwise_ops {
+	NFT_BITWISE_XOR,
+	NFT_BITWISE_LSHIFT,
+	NFT_BITWISE_RSHIFT,
+};
+
+/**
  * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes
  *
  * @NFTA_BITWISE_SREG: source register (NLA_U32: nft_registers)
  * @NFTA_BITWISE_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_BITWISE_OP: operator (NLA_U32: enum nft_bitwise_ops)
  * @NFTA_BITWISE_LEN: length of operands (NLA_U32)
  * @NFTA_BITWISE_MASK: mask value (NLA_NESTED: nft_data_attributes)
  * @NFTA_BITWISE_XOR: xor value (NLA_NESTED: nft_data_attributes)
+ * @NFTA_BITWISE_SHIFT: shift length (NLA_U32)
  *
- * The bitwise expression performs the following operation:
+ * The bitwise expression performs the 3 following operations:
  *
+ * XOR:
  * dreg = (sreg & mask) ^ xor
  *
  * which allow to express all bitwise operations:
@@ -370,14 +386,26 @@ enum nft_immediate_attributes {
  * OR:		0	x
  * XOR:		1	x
  * AND:		x	0
+ *
+ * Then, LSHIFT/RSHIFT.
+ * For instance on LSHIFT:
+ * dreg = sreg << shift | (rest ? rest : 0)
+ *
+ * where rest (internal) is calculated on previous sreg:
+ * rest = (sreg & mask) >> (sizeof_u32 - shift)
+ *
+ * where provided mask is:
+ * ~(UINT32_MAX >> shift)
  */
 enum nft_bitwise_attributes {
 	NFTA_BITWISE_UNSPEC,
 	NFTA_BITWISE_SREG,
 	NFTA_BITWISE_DREG,
+	NFTA_BITWISE_OP,
 	NFTA_BITWISE_LEN,
 	NFTA_BITWISE_MASK,
 	NFTA_BITWISE_XOR,
+	NFTA_BITWISE_SHIFT,
 	__NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX	(__NFTA_BITWISE_MAX - 1)
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 4fb6ee2..d32058c 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -20,9 +20,11 @@
 struct nft_bitwise {
 	enum nft_registers	sreg:8;
 	enum nft_registers	dreg:8;
+	u8			op;
 	u8			len;
 	struct nft_data		mask;
 	struct nft_data		xor;
+	u8			shift;
 };
 
 static void nft_bitwise_eval(const struct nft_expr *expr,
@@ -32,17 +34,43 @@ static void nft_bitwise_eval(const struct nft_expr *expr,
 	const struct nft_bitwise *priv = nft_expr_priv(expr);
 	const struct nft_data *src = &data[priv->sreg];
 	struct nft_data *dst = &data[priv->dreg];
-	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];
+	unsigned int i, r, rest = 0;
+	int cr_shift;
+
+	switch (priv->op) {
+	case NFT_BITWISE_XOR:
+		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];
+		}
+		break;
+	case NFT_BITWISE_LSHIFT:
+		cr_shift = sizeof(unsigned int) - priv->shift;
+		for (i = 0; i < priv->len; i++) {
+			r = (src->data[i] & priv->mask.data[i]) >> cr_shift;
+			dst->data[i] = src->data[i] << priv->shift;
+			if (rest)
+				dst->data[i] |= rest;
+			rest = r;
+		}
+		break;
+	case NFT_BITWISE_RSHIFT:
+		cr_shift = sizeof(unsigned int) - priv->shift;
+		for (i = priv->len - 1; i >= 0; i--) {
+			r = (src->data[i] & priv->mask.data[i]) << cr_shift;
+			dst->data[i] = src->data[i] >> priv->shift;
+			if (rest)
+				dst->data[i] |= rest;
+			rest = r;
+		}
+		break;
 	}
 }
 
 static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
 	[NFTA_BITWISE_SREG]	= { .type = NLA_U32 },
 	[NFTA_BITWISE_DREG]	= { .type = NLA_U32 },
+	[NFTA_BITWISE_OP]	= { .type = NLA_U32 },
 	[NFTA_BITWISE_LEN]	= { .type = NLA_U32 },
 	[NFTA_BITWISE_MASK]	= { .type = NLA_NESTED },
 	[NFTA_BITWISE_XOR]	= { .type = NLA_NESTED },
@@ -58,9 +86,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 
 	if (tb[NFTA_BITWISE_SREG] == NULL ||
 	    tb[NFTA_BITWISE_DREG] == NULL ||
+	    tb[NFTA_BITWISE_OP] == NULL ||
 	    tb[NFTA_BITWISE_LEN] == NULL ||
 	    tb[NFTA_BITWISE_MASK] == NULL ||
-	    tb[NFTA_BITWISE_XOR] == NULL)
+	    (tb[NFTA_BITWISE_XOR] == NULL &&
+	     tb[NFTA_BITWISE_SHIFT] == NULL))
 		return -EINVAL;
 
 	priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
@@ -76,6 +106,20 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 	if (err < 0)
 		return err;
 
+	priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+	switch (priv->op) {
+	case NFT_BITWISE_XOR:
+		if (tb[NFTA_BITWISE_XOR] == NULL)
+			return -EINVAL;
+		break;
+	case NFT_BITWISE_LSHIFT:
+	case NFT_BITWISE_RSHIFT:
+		if (tb[NFTA_BITWISE_SHIFT] != NULL)
+			break;
+	default:
+		return -EINVAL;
+	};
+
 	priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
 
 	err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]);
@@ -84,11 +128,15 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 	if (d1.len != priv->len)
 		return -EINVAL;
 
-	err = nft_data_init(NULL, &priv->xor, &d2, tb[NFTA_BITWISE_XOR]);
-	if (err < 0)
-		return err;
-	if (d2.len != priv->len)
-		return -EINVAL;
+	if (priv->op == NFT_BITWISE_XOR) {
+		err = nft_data_init(NULL, &priv->xor,
+				    &d2, tb[NFTA_BITWISE_XOR]);
+		if (err < 0)
+			return err;
+		if (d2.len != priv->len)
+			return -EINVAL;
+	} else
+		priv->shift = ntohl(nla_get_be32(tb[NFTA_BITWISE_SHIFT]));
 
 	return 0;
 }
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [nftables-kernel PATCH 7/7] netfilter: nf_tables: Improve payload expression for an extra offset
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
                   ` (5 preceding siblings ...)
  2013-10-14 12:46 ` [nftables-kernel PATCH 6/7] netfilter: nf_tables: Add left and right shifts to bitwise expression Tomasz Bursztyka
@ 2013-10-14 12:46 ` Tomasz Bursztyka
  2013-10-14 12:58 ` [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Pablo Neira Ayuso
  7 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 12:46 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Payload expression gets a new attribute: NFTA_PAYLOAD_SREG_EXTRA
This attribute will permit to provide a source register where an extra
offset will be added to the fixed offset of the expression.

This will be useful where some information cannot be found at a
pre-determined place. Such as the protocol address of an ARP-ETH packet:
its position is determined by the hardware address length.

Thus, in this example, a meta expression NFT_META_DEV_ADDRLEN will load
the value of the hardware length and put it into a register: such register,
as a NFTA_PAYLOAD_SREG_EXTRA in following payload expression, will be used
to add the hardware length to the fixed offset.

Suggested by Pablo Neira Ayuso.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/net/netfilter/nf_tables_core.h   |  1 +
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nf_tables_core.c           |  6 +++++-
 net/netfilter/nft_payload.c              | 25 +++++++++++++++++++------
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h
index fe7b162..5962528 100644
--- a/include/net/netfilter/nf_tables_core.h
+++ b/include/net/netfilter/nf_tables_core.h
@@ -31,6 +31,7 @@ struct nft_payload {
 	enum nft_payload_bases	base:8;
 	u8			offset;
 	u8			len;
+	enum nft_registers      sreg:8;
 	enum nft_registers	dreg:8;
 };
 
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 8b12b8f..a8d8aa6 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -511,6 +511,7 @@ enum nft_payload_bases {
  * @NFTA_PAYLOAD_DREG: destination register to load data into (NLA_U32: nft_registers)
  * @NFTA_PAYLOAD_BASE: payload base (NLA_U32: nft_payload_bases)
  * @NFTA_PAYLOAD_OFFSET: payload offset relative to base (NLA_U32)
+ * @NFTA_PAYLOAD_SREG_EXTRA: source register of an extra offset (NLA_U32: nft_registers)
  * @NFTA_PAYLOAD_LEN: payload length (NLA_U32)
  */
 enum nft_payload_attributes {
@@ -518,6 +519,7 @@ enum nft_payload_attributes {
 	NFTA_PAYLOAD_DREG,
 	NFTA_PAYLOAD_BASE,
 	NFTA_PAYLOAD_OFFSET,
+	NFTA_PAYLOAD_SREG_EXTRA,
 	NFTA_PAYLOAD_LEN,
 	__NFTA_PAYLOAD_MAX
 };
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 2324dd8..e9200e7 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -40,6 +40,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 = &data[priv->dreg];
+	int extra_offset = 0;
 	unsigned char *ptr;
 
 	if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -47,7 +48,10 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
 	else
 		ptr = skb_network_header(skb) + pkt->xt.thoff;
 
-	ptr += priv->offset;
+	if (priv->sreg)
+		extra_offset = (int) *data[priv->sreg].data;
+
+	ptr += extra_offset + priv->offset;
 
 	if (unlikely(ptr + priv->len >= skb_tail_pointer(skb)))
 		return false;
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index a2aeb31..41d3f21 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -24,7 +24,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 = &data[priv->dreg];
-	int offset;
+	int offset, extra_offset = 0;
 
 	switch (priv->base) {
 	case NFT_PAYLOAD_LL_HEADER:
@@ -41,7 +41,11 @@ static void nft_payload_eval(const struct nft_expr *expr,
 	default:
 		BUG();
 	}
-	offset += priv->offset;
+
+	if (priv->sreg)
+		extra_offset = (int) *data[priv->sreg].data;
+
+	offset += extra_offset + priv->offset;
 
 	if (skb_copy_bits(skb, offset, dest->data, priv->len) < 0)
 		goto err;
@@ -51,10 +55,11 @@ err:
 }
 
 static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
-	[NFTA_PAYLOAD_DREG]	= { .type = NLA_U32 },
-	[NFTA_PAYLOAD_BASE]	= { .type = NLA_U32 },
-	[NFTA_PAYLOAD_OFFSET]	= { .type = NLA_U32 },
-	[NFTA_PAYLOAD_LEN]	= { .type = NLA_U32 },
+	[NFTA_PAYLOAD_DREG]		= { .type = NLA_U32 },
+	[NFTA_PAYLOAD_BASE]		= { .type = NLA_U32 },
+	[NFTA_PAYLOAD_OFFSET]		= { .type = NLA_U32 },
+	[NFTA_PAYLOAD_SREG_EXTRA]	= { .type = NLA_U32 },
+	[NFTA_PAYLOAD_LEN]		= { .type = NLA_U32 },
 };
 
 static int nft_payload_init(const struct nft_ctx *ctx,
@@ -68,6 +73,14 @@ static int nft_payload_init(const struct nft_ctx *ctx,
 	priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
 	priv->len    = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
 
+	if (tb[NFTA_PAYLOAD_SREG_EXTRA]) {
+		priv->sreg = ntohl(nla_get_be32(
+					tb[NFTA_PAYLOAD_SREG_EXTRA]));
+		err = nft_validate_input_register(priv->sreg);
+		if (err < 0)
+			return err;
+	}
+
 	priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG]));
 	err = nft_validate_output_register(priv->dreg);
 	if (err < 0)
-- 
1.8.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals
  2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
                   ` (6 preceding siblings ...)
  2013-10-14 12:46 ` [nftables-kernel PATCH 7/7] netfilter: nf_tables: Improve payload expression for an extra offset Tomasz Bursztyka
@ 2013-10-14 12:58 ` Pablo Neira Ayuso
  2013-10-14 13:50   ` Tomasz Bursztyka
  7 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2013-10-14 12:58 UTC (permalink / raw)
  To: Tomasz Bursztyka; +Cc: netfilter-devel

On Mon, Oct 14, 2013 at 03:46:49PM +0300, Tomasz Bursztyka wrote:
> Hi, 
> 
> First 2 minor fixes:
> -------------------
> 
> patch 1: don't know why I messed up here in my previous documentation patch, my mistake anyway.
> patch 2: an old left-over. Why has priv->len been corrupted before?

Will pick these two.

> And 5 proposals:
> ---------------
> 
> patch 3: Let's expose table's usage (so user might decide if it's worth dumping table's content, it can useful info finally)

Call it _USE.

> patch 4: That one is debatable: NFTA_CHAIN_USE is - imho - not enough self-explanatory.
> NFTA_CHAIN_REFS (or NFTA_CHAIN_REFERENCES?) is much better. If there is a time to change such minor details, it's now or never.

We're using _USE in other parts of the netfilter code, that can be
document, really I don't think it's worth to discuss this renaming
thing.

> patch 5: add a meta key to get dev->addr_len
> 
> patch 6: add lshift/rshift to bitwise expression. It's a first shot, which should work pretty well already. Maybe there are improvments which could be done, depending on data length (2 or 4: we could cast to u64 thus reducing shifts by 2).
> 	At least I tried to keep the API sane, and c/p the byteorder way. sreg, dreg, op, len, mask are mandatory. xor and shift are related to the selected op.
> 
> patch 7: patch's commit message says all.

Code for user-space is missing, won't take these until finished.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals
  2013-10-14 12:58 ` [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Pablo Neira Ayuso
@ 2013-10-14 13:50   ` Tomasz Bursztyka
  0 siblings, 0 replies; 10+ messages in thread
From: Tomasz Bursztyka @ 2013-10-14 13:50 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Hi Pablo,

> Code for user-space is missing, won't take these until finished.

Sure, that's why I put them as "proposal" so it could be quickly 
reviewed, at least for the API part. (patch 6 and 7 mostly)

Tomasz

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-10-14 13:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-14 12:46 [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 1/7] netfilter: nf_tables: Fix API documentation on a missing part Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 2/7] netfilter: nf_tables: Use byteorder operands length relevantly Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 3/7] netfilter: nf_tables: Expose the table's chain usage to the netlink API Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 4/7] netfilter: nf_tables: Use a semantically relevant name on chain's refs Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 5/7] netfilter: nf_tables: Add a meta key to get the device address length Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 6/7] netfilter: nf_tables: Add left and right shifts to bitwise expression Tomasz Bursztyka
2013-10-14 12:46 ` [nftables-kernel PATCH 7/7] netfilter: nf_tables: Improve payload expression for an extra offset Tomasz Bursztyka
2013-10-14 12:58 ` [nftables-kernel PATCH 0/7] API minor fixes and improvement proposals Pablo Neira Ayuso
2013-10-14 13:50   ` Tomasz Bursztyka

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).