* [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct
@ 2014-08-22 9:16 Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 2/5 v2] nft: alloc bitwise operation for ipv4/ipv6 addresses Giuseppe Longo
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Giuseppe Longo @ 2014-08-22 9:16 UTC (permalink / raw)
To: netfilter-devel; +Cc: Giuseppe Longo
This patch provides the context used to transfer
informaton between different nft_parse_* function calls.
Signed-off-by: Giuseppe Longo <giuseppelng@gmail.com>
---
iptables/nft-arp.c | 16 ++++++++----
iptables/nft-shared.c | 67 ++++++++++++++++++++++++++++++++-------------------
iptables/nft-shared.h | 32 ++++++++++++------------
3 files changed, 70 insertions(+), 45 deletions(-)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index 8c06243..bc25de3 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -370,26 +370,32 @@ void nft_rule_to_arpt_entry(struct nft_rule *r, struct arpt_entry *fw)
struct nft_rule_expr_iter *iter;
struct nft_rule_expr *expr;
int family = nft_rule_attr_get_u32(r, NFT_RULE_ATTR_FAMILY);
+ struct nft_xt_ctx ctx = {
+ .state.fw = fw,
+ .family = family,
+ .flags = 0,
+ };
iter = nft_rule_expr_iter_create(r);
if (iter == NULL)
return;
+ ctx.iter = iter;
expr = nft_rule_expr_iter_next(iter);
while (expr != NULL) {
const char *name =
nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
if (strcmp(name, "counter") == 0)
- nft_parse_counter(expr, iter, &fw->counters);
+ nft_parse_counter(expr, &ctx.state.fw->counters);
else if (strcmp(name, "payload") == 0)
- nft_parse_payload(expr, iter, family, fw);
+ nft_parse_payload(&ctx, expr);
else if (strcmp(name, "meta") == 0)
- nft_parse_meta(expr, iter, family, fw);
+ nft_parse_meta(&ctx, expr);
else if (strcmp(name, "immediate") == 0)
- nft_parse_immediate(expr, iter, family, fw);
+ nft_parse_immediate(&ctx, expr);
else if (strcmp(name, "target") == 0)
- nft_parse_target(expr, iter, family, fw);
+ nft_parse_target(&ctx, expr);
expr = nft_rule_expr_iter_next(iter);
}
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index deb2783..05fb29b 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -277,8 +277,20 @@ void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
}
}
-void nft_parse_target(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data)
+static void *nft_get_data(struct nft_xt_ctx *ctx)
+{
+ switch(ctx->family) {
+ case AF_INET:
+ case AF_INET6:
+ return ctx->state.cs;
+ case NFPROTO_ARP:
+ return ctx->state.fw;
+ default:
+ return NULL;
+ }
+}
+
+void nft_parse_target(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
{
uint32_t tg_len;
const char *targname = nft_rule_expr_get_str(e, NFT_EXPR_TG_NAME);
@@ -287,6 +299,7 @@ void nft_parse_target(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
struct xt_entry_target *t;
struct nft_family_ops *ops;
size_t size;
+ void *data = nft_get_data(ctx);
target = xtables_find_target(targname, XTF_TRY_LOAD);
if (target == NULL)
@@ -306,13 +319,12 @@ void nft_parse_target(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
target->t = t;
- ops = nft_family_ops_lookup(family);
+ ops = nft_family_ops_lookup(ctx->family);
ops->parse_target(target, data);
}
static void
-nft_parse_match(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- struct iptables_command_state *cs)
+nft_parse_match(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
{
uint32_t mt_len;
const char *mt_name = nft_rule_expr_get_str(e, NFT_EXPR_MT_NAME);
@@ -320,7 +332,7 @@ nft_parse_match(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
struct xtables_match *match;
struct xt_entry_match *m;
- match = xtables_find_match(mt_name, XTF_TRY_LOAD, &cs->matches);
+ match = xtables_find_match(mt_name, XTF_TRY_LOAD, &ctx->state.cs->matches);
if (match == NULL)
return;
@@ -380,14 +392,14 @@ void get_cmp_data(struct nft_rule_expr_iter *iter,
}
void
-nft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data)
+nft_parse_meta(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
{
uint8_t key = nft_rule_expr_get_u32(e, NFT_EXPR_META_KEY);
- struct nft_family_ops *ops = nft_family_ops_lookup(family);
+ struct nft_family_ops *ops = nft_family_ops_lookup(ctx->family);
const char *name;
+ void *data = nft_get_data(ctx);
- e = nft_rule_expr_iter_next(iter);
+ e = nft_rule_expr_iter_next(ctx->iter);
if (e == NULL)
return;
@@ -401,34 +413,33 @@ nft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
}
void
-nft_parse_payload(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data)
+nft_parse_payload(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
{
- struct nft_family_ops *ops = nft_family_ops_lookup(family);
+ struct nft_family_ops *ops = nft_family_ops_lookup(ctx->family);
uint32_t offset;
+ void *data = nft_get_data(ctx);
offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET);
- ops->parse_payload(iter, offset, data);
+ ops->parse_payload(ctx->iter, offset, data);
}
void
-nft_parse_counter(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- struct xt_counters *counters)
+nft_parse_counter(struct nft_rule_expr *e, struct xt_counters *counters)
{
counters->pcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS);
counters->bcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES);
}
void
-nft_parse_immediate(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data)
+nft_parse_immediate(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
{
int verdict = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT);
const char *chain = nft_rule_expr_get_str(e, NFT_EXPR_IMM_CHAIN);
struct nft_family_ops *ops;
const char *jumpto = NULL;
bool nft_goto = false;
+ void *data = nft_get_data(ctx);
/* Standard target? */
switch(verdict) {
@@ -448,7 +459,7 @@ nft_parse_immediate(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
break;
}
- ops = nft_family_ops_lookup(family);
+ ops = nft_family_ops_lookup(ctx->family);
ops->parse_immediate(jumpto, nft_goto, data);
}
@@ -458,28 +469,34 @@ void nft_rule_to_iptables_command_state(struct nft_rule *r,
struct nft_rule_expr_iter *iter;
struct nft_rule_expr *expr;
int family = nft_rule_attr_get_u32(r, NFT_RULE_ATTR_FAMILY);
+ struct nft_xt_ctx ctx = {
+ .state.cs = cs,
+ .family = family,
+ .flags = 0,
+ };
iter = nft_rule_expr_iter_create(r);
if (iter == NULL)
return;
+ ctx.iter = iter;
expr = nft_rule_expr_iter_next(iter);
while (expr != NULL) {
const char *name =
nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
if (strcmp(name, "counter") == 0)
- nft_parse_counter(expr, iter, &cs->counters);
+ nft_parse_counter(expr, &ctx.state.cs->counters);
else if (strcmp(name, "payload") == 0)
- nft_parse_payload(expr, iter, family, cs);
+ nft_parse_payload(&ctx, expr);
else if (strcmp(name, "meta") == 0)
- nft_parse_meta(expr, iter, family, cs);
+ nft_parse_meta(&ctx, expr);
else if (strcmp(name, "immediate") == 0)
- nft_parse_immediate(expr, iter, family, cs);
+ nft_parse_immediate(&ctx, expr);
else if (strcmp(name, "match") == 0)
- nft_parse_match(expr, iter, cs);
+ nft_parse_match(&ctx, expr);
else if (strcmp(name, "target") == 0)
- nft_parse_target(expr, iter, family, cs);
+ nft_parse_target(&ctx, expr);
expr = nft_rule_expr_iter_next(iter);
}
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 1c06b5f..c4936dd 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -6,6 +6,8 @@
#include <libnftnl/rule.h>
#include <libnftnl/expr.h>
+#include <linux/netfilter_arp/arp_tables.h>
+
#include "xshared.h"
#if 0
@@ -36,6 +38,16 @@
struct xtables_args;
+struct nft_xt_ctx {
+ union {
+ struct iptables_command_state *cs;
+ struct arpt_entry *fw;
+ } state;
+ struct nft_rule_expr_iter *iter;
+ int family;
+ uint32_t flags;
+};
+
struct nft_family_ops {
int (*add)(struct nft_rule *r, void *data);
bool (*is_same)(const void *data_a,
@@ -88,19 +100,11 @@ void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
void print_proto(uint16_t proto, int invert);
void get_cmp_data(struct nft_rule_expr_iter *iter,
void *data, size_t dlen, bool *inv);
-void nft_parse_target(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data);
-void nft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
- int family, void *data);
-void nft_parse_payload(struct nft_rule_expr *e,
- struct nft_rule_expr_iter *iter,
- int family, void *data);
-void nft_parse_counter(struct nft_rule_expr *e,
- struct nft_rule_expr_iter *iter,
- struct xt_counters *counters);
-void nft_parse_immediate(struct nft_rule_expr *e,
- struct nft_rule_expr_iter *iter,
- int family, void *data);
+void nft_parse_target(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
+void nft_parse_meta(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
+void nft_parse_payload(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
+void nft_parse_counter(struct nft_rule_expr *e, struct xt_counters *counters);
+void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
void nft_rule_to_iptables_command_state(struct nft_rule *r,
struct iptables_command_state *cs);
void print_firewall_details(const struct iptables_command_state *cs,
@@ -182,8 +186,6 @@ struct xtables_args {
extern char *opcodes[];
#define NUMOPCODES 9
-#include <linux/netfilter_arp/arp_tables.h>
-
static inline struct xt_entry_target *nft_arp_get_target(struct arpt_entry *fw)
{
struct xt_entry_target **target;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables-compat PATCH 2/5 v2] nft: alloc bitwise operation for ipv4/ipv6 addresses
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
@ 2014-08-22 9:16 ` Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place Giuseppe Longo
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Giuseppe Longo @ 2014-08-22 9:16 UTC (permalink / raw)
To: netfilter-devel; +Cc: Giuseppe Longo
This patch permits to add a bitwise operation for IPv4/IPv6 address and mask
Signed-off-by: Giuseppe Longo <giuseppelng@gmail.com>
---
iptables/nft-shared.c | 34 ++++++++++++++++++++++++++++++++++
iptables/nft-shared.h | 2 ++
2 files changed, 36 insertions(+)
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 05fb29b..3ffe877 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -82,6 +82,40 @@ void add_bitwise_u16(struct nft_rule *r, int mask, int xor)
nft_rule_add_expr(r, expr);
}
+void add_bitwise_u32(struct nft_rule *r, int mask, int xor)
+{
+ struct nft_rule_expr *expr;
+
+ expr = nft_rule_expr_alloc("bitwise");
+ if (expr == NULL)
+ return;
+
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_SREG, NFT_REG_1);
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_DREG, NFT_REG_1);
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_LEN, sizeof(uint32_t));
+ nft_rule_expr_set(expr, NFT_EXPR_BITWISE_MASK, &mask, sizeof(uint32_t));
+ nft_rule_expr_set(expr, NFT_EXPR_BITWISE_XOR, &xor, sizeof(uint32_t));
+
+ nft_rule_add_expr(r, expr);
+}
+
+void add_bitwise_u128(struct nft_rule *r, uint8_t *mask, uint8_t *xor)
+{
+ struct nft_rule_expr *expr;
+
+ expr = nft_rule_expr_alloc("bitwise");
+ if (expr == NULL)
+ return;
+
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_SREG, NFT_REG_1);
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_DREG, NFT_REG_1);
+ nft_rule_expr_set_u32(expr, NFT_EXPR_BITWISE_LEN, 16);
+ nft_rule_expr_set(expr, NFT_EXPR_BITWISE_MASK, mask, 16);
+ nft_rule_expr_set(expr, NFT_EXPR_BITWISE_XOR, xor, 16);
+
+ nft_rule_add_expr(r, expr);
+}
+
void add_cmp_ptr(struct nft_rule *r, uint32_t op, void *data, size_t len)
{
struct nft_rule_expr *expr;
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index c4936dd..f2896bb 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -75,6 +75,8 @@ struct nft_family_ops {
void add_meta(struct nft_rule *r, uint32_t key);
void add_payload(struct nft_rule *r, int offset, int len);
void add_bitwise_u16(struct nft_rule *r, int mask, int xor);
+void add_bitwise_u32(struct nft_rule *r, int mask, int xor);
+void add_bitwise_u128(struct nft_rule *r, uint8_t *mask, uint8_t *xor);
void add_cmp_ptr(struct nft_rule *r, uint32_t op, void *data, size_t len);
void add_cmp_u8(struct nft_rule *r, uint8_t val, uint32_t op);
void add_cmp_u16(struct nft_rule *r, uint16_t val, uint32_t op);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 2/5 v2] nft: alloc bitwise operation for ipv4/ipv6 addresses Giuseppe Longo
@ 2014-08-22 9:16 ` Giuseppe Longo
2014-08-24 13:30 ` Pablo Neira Ayuso
2014-08-22 9:16 ` [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule Giuseppe Longo
` (2 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Giuseppe Longo @ 2014-08-22 9:16 UTC (permalink / raw)
To: netfilter-devel; +Cc: Giuseppe Longo
Currently the protocol is tested after the ip address,
this fixes the order testing the protocol before the ip address.
Now the code generated is incorrect:
ip filter INPUT 16
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x0100a8c0 ]
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ match name tcp rev 0 ]
[ match name conntrack rev 3 ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
With this patch, the code generated is:
ip filter INPUT 16
[ payload load 1b @ network header + 9 => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp eq reg 1 0x0100a8c0 ]
[ bitwise reg 1 = (reg=1 & 0xffffffff ) ^ 0x00000000 ]
[ match name tcp rev 0 ]
[ match name conntrack rev 3 ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
Signed-off-by: Giuseppe Longo <giuseppelng@gmail.com>
---
iptables/nft-ipv4.c | 8 ++++----
iptables/nft-ipv6.c | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 33bc581..70050ba 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -37,6 +37,10 @@ static int nft_ipv4_add(struct nft_rule *r, void *data)
if (cs->fw.ip.outiface[0] != '\0')
add_outiface(r, cs->fw.ip.outiface, cs->fw.ip.invflags);
+ if (cs->fw.ip.proto != 0)
+ add_proto(r, offsetof(struct iphdr, protocol), 1,
+ cs->fw.ip.proto, cs->fw.ip.invflags);
+
if (cs->fw.ip.src.s_addr != 0)
add_addr(r, offsetof(struct iphdr, saddr),
&cs->fw.ip.src.s_addr, 4, cs->fw.ip.invflags);
@@ -45,10 +49,6 @@ static int nft_ipv4_add(struct nft_rule *r, void *data)
add_addr(r, offsetof(struct iphdr, daddr),
&cs->fw.ip.dst.s_addr, 4, cs->fw.ip.invflags);
- if (cs->fw.ip.proto != 0)
- add_proto(r, offsetof(struct iphdr, protocol), 1,
- cs->fw.ip.proto, cs->fw.ip.invflags);
-
if (cs->fw.ip.flags & IPT_F_FRAG) {
add_payload(r, offsetof(struct iphdr, frag_off), 2);
/* get the 13 bits that contain the fragment offset */
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 00f1bf8..52de5b6 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -34,6 +34,10 @@ static int nft_ipv6_add(struct nft_rule *r, void *data)
if (cs->fw6.ipv6.outiface[0] != '\0')
add_outiface(r, cs->fw6.ipv6.outiface, cs->fw6.ipv6.invflags);
+ if (cs->fw6.ipv6.proto != 0)
+ add_proto(r, offsetof(struct ip6_hdr, ip6_nxt), 1,
+ cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
+
if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src))
add_addr(r, offsetof(struct ip6_hdr, ip6_src),
&cs->fw6.ipv6.src, 16, cs->fw6.ipv6.invflags);
@@ -42,10 +46,6 @@ static int nft_ipv6_add(struct nft_rule *r, void *data)
add_addr(r, offsetof(struct ip6_hdr, ip6_dst),
&cs->fw6.ipv6.dst, 16, cs->fw6.ipv6.invflags);
- if (cs->fw6.ipv6.proto != 0)
- add_proto(r, offsetof(struct ip6_hdr, ip6_nxt), 1,
- cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
-
add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
for (matchp = cs->matches; matchp; matchp = matchp->next) {
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 2/5 v2] nft: alloc bitwise operation for ipv4/ipv6 addresses Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place Giuseppe Longo
@ 2014-08-22 9:16 ` Giuseppe Longo
2014-08-24 14:09 ` Pablo Neira Ayuso
2014-08-22 9:16 ` [iptables-compat PATCH 5/5 v2] nft: adds parse_bitwise function Giuseppe Longo
2014-08-24 14:03 ` [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Pablo Neira Ayuso
4 siblings, 1 reply; 8+ messages in thread
From: Giuseppe Longo @ 2014-08-22 9:16 UTC (permalink / raw)
To: netfilter-devel; +Cc: Giuseppe Longo
This patch adds a bitwise operation to a rule
Signed-off-by: Giuseppe Longo <giuseppelng@gmail.com>
---
iptables/nft-arp.c | 9 +++++----
iptables/nft-ipv4.c | 10 ++++++----
iptables/nft-ipv6.c | 10 ++++++----
iptables/nft-shared.c | 13 +++++++++++--
iptables/nft-shared.h | 4 ++--
5 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index bc25de3..c9dbee6 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -202,8 +202,8 @@ static int nft_arp_add(struct nft_rule *r, void *data)
}
if (fw->arp.src.s_addr != 0)
- add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
- &fw->arp.src.s_addr, 4, flags);
+ add_addr(r, AF_INET, sizeof(struct arphdr) + fw->arp.arhln,
+ &fw->arp.src.s_addr, NULL, 4, flags);
if (fw->arp.tgt_devaddr.addr[0] != '\0') {
add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4, fw->arp.arhln);
@@ -211,8 +211,9 @@ static int nft_arp_add(struct nft_rule *r, void *data)
}
if (fw->arp.tgt.s_addr != 0)
- add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
- &fw->arp.tgt.s_addr, 4, flags);
+ add_addr(r, AF_INET,
+ sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
+ &fw->arp.tgt.s_addr, NULL, 4, flags);
/* Counters need to me added before the target, otherwise they are
* increased for each rule because of the way nf_tables works.
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 70050ba..6e520b2 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -42,12 +42,14 @@ static int nft_ipv4_add(struct nft_rule *r, void *data)
cs->fw.ip.proto, cs->fw.ip.invflags);
if (cs->fw.ip.src.s_addr != 0)
- add_addr(r, offsetof(struct iphdr, saddr),
- &cs->fw.ip.src.s_addr, 4, cs->fw.ip.invflags);
+ add_addr(r, AF_INET, offsetof(struct iphdr, saddr),
+ &cs->fw.ip.src.s_addr, &cs->fw.ip.smsk.s_addr,
+ 4, cs->fw.ip.invflags);
if (cs->fw.ip.dst.s_addr != 0)
- add_addr(r, offsetof(struct iphdr, daddr),
- &cs->fw.ip.dst.s_addr, 4, cs->fw.ip.invflags);
+ add_addr(r, AF_INET, offsetof(struct iphdr, daddr),
+ &cs->fw.ip.dst.s_addr, &cs->fw.ip.dmsk.s_addr,
+ 4, cs->fw.ip.invflags);
if (cs->fw.ip.flags & IPT_F_FRAG) {
add_payload(r, offsetof(struct iphdr, frag_off), 2);
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 52de5b6..662c563 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -39,12 +39,14 @@ static int nft_ipv6_add(struct nft_rule *r, void *data)
cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src))
- add_addr(r, offsetof(struct ip6_hdr, ip6_src),
- &cs->fw6.ipv6.src, 16, cs->fw6.ipv6.invflags);
+ add_addr(r, AF_INET6, offsetof(struct ip6_hdr, ip6_src),
+ &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk,
+ 16, cs->fw6.ipv6.invflags);
if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst))
- add_addr(r, offsetof(struct ip6_hdr, ip6_dst),
- &cs->fw6.ipv6.dst, 16, cs->fw6.ipv6.invflags);
+ add_addr(r, AF_INET6, offsetof(struct ip6_hdr, ip6_dst),
+ &cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk,
+ 16, cs->fw6.ipv6.invflags);
add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 3ffe877..2dcdfd1 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -184,8 +184,8 @@ void add_outiface(struct nft_rule *r, char *iface, int invflags)
add_cmp_ptr(r, op, iface, iface_len + 1);
}
-void add_addr(struct nft_rule *r, int offset,
- void *data, size_t len, int invflags)
+void add_addr(struct nft_rule *r, int family, int offset,
+ void *data, void *mask, size_t len, int invflags)
{
uint32_t op;
@@ -197,6 +197,15 @@ void add_addr(struct nft_rule *r, int offset,
op = NFT_CMP_EQ;
add_cmp_ptr(r, op, data, len);
+
+ if (family == AF_INET) {
+ uint32_t *msk = mask;
+ add_bitwise_u32(r, *msk, 0x00000000);
+ } else {
+ uint8_t mask6[16] = {0};
+ uint8_t xor[16] = {0};
+ add_bitwise_u128(r, mask6, xor);
+ }
}
void add_proto(struct nft_rule *r, int offset, size_t len,
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index f2896bb..e5b6f1d 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -83,8 +83,8 @@ void add_cmp_u16(struct nft_rule *r, uint16_t val, uint32_t op);
void add_cmp_u32(struct nft_rule *r, uint32_t val, uint32_t op);
void add_iniface(struct nft_rule *r, char *iface, int invflags);
void add_outiface(struct nft_rule *r, char *iface, int invflags);
-void add_addr(struct nft_rule *r, int offset,
- void *data, size_t len, int invflags);
+void add_addr(struct nft_rule *r, int family, int offset,
+ void *data, void *mask, size_t len, int invflags);
void add_proto(struct nft_rule *r, int offset, size_t len,
uint8_t proto, int invflags);
void add_compat(struct nft_rule *r, uint32_t proto, bool inv);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables-compat PATCH 5/5 v2] nft: adds parse_bitwise function
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
` (2 preceding siblings ...)
2014-08-22 9:16 ` [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule Giuseppe Longo
@ 2014-08-22 9:16 ` Giuseppe Longo
2014-08-24 14:03 ` [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Pablo Neira Ayuso
4 siblings, 0 replies; 8+ messages in thread
From: Giuseppe Longo @ 2014-08-22 9:16 UTC (permalink / raw)
To: netfilter-devel; +Cc: Giuseppe Longo
This patch adds a function that returns the mask associated to a rule
Signed-off-by: Giuseppe Longo <giuseppelng@gmail.com>
---
iptables/nft-arp.c | 4 +++-
iptables/nft-ipv4.c | 24 +++++++++++++++++++++---
iptables/nft-ipv6.c | 21 ++++++++++++++++++++-
iptables/nft-shared.c | 19 +++++++++++++++----
iptables/nft-shared.h | 8 +++++++-
5 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index c9dbee6..4fff793 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -309,7 +309,8 @@ static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
}
static void nft_arp_parse_payload(struct nft_rule_expr_iter *iter,
- uint32_t offset, void *data)
+ uint32_t offset, void *data,
+ uint32_t *flags)
{
struct arpt_entry *fw = data;
struct in_addr addr;
@@ -695,6 +696,7 @@ struct nft_family_ops nft_family_ops_arp = {
.parse_meta = nft_arp_parse_meta,
.parse_payload = nft_arp_parse_payload,
.parse_immediate = nft_arp_parse_immediate,
+ .parse_bitwise = NULL,
.print_firewall = nft_arp_print_firewall,
.save_firewall = nft_arp_save_firewall,
.save_counters = nft_arp_save_counters,
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 6e520b2..8af1a3c 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -177,7 +177,8 @@ static void nft_ipv4_parse_meta(struct nft_rule_expr *e, uint8_t key,
}
static void nft_ipv4_parse_payload(struct nft_rule_expr_iter *iter,
- uint32_t offset, void *data)
+ uint32_t offset, void *data,
+ uint32_t *flags)
{
struct iptables_command_state *cs = data;
@@ -189,14 +190,14 @@ static void nft_ipv4_parse_payload(struct nft_rule_expr_iter *iter,
case offsetof(struct iphdr, saddr):
get_cmp_data(iter, &addr, sizeof(addr), &inv);
cs->fw.ip.src.s_addr = addr.s_addr;
- cs->fw.ip.smsk.s_addr = 0xffffffff;
+ *flags = NFT_PARSE_SOURCE_MASK;
if (inv)
cs->fw.ip.invflags |= IPT_INV_SRCIP;
break;
case offsetof(struct iphdr, daddr):
get_cmp_data(iter, &addr, sizeof(addr), &inv);
cs->fw.ip.dst.s_addr = addr.s_addr;
- cs->fw.ip.dmsk.s_addr = 0xffffffff;
+ *flags = NFT_PARSE_DESTINATION_MASK;
if (inv)
cs->fw.ip.invflags |= IPT_INV_DSTIP;
break;
@@ -218,6 +219,22 @@ static void nft_ipv4_parse_payload(struct nft_rule_expr_iter *iter,
}
}
+static void nft_ipv4_parse_bitwise(struct nft_rule_expr *e, void *data,
+ uint32_t flags)
+{
+ struct iptables_command_state *cs = data;
+ uint32_t mask;
+
+ mask = nft_rule_expr_get_u32(e, NFT_EXPR_BITWISE_MASK);
+ if (mask == 0)
+ mask = 0xffffffff;
+
+ if (flags & NFT_PARSE_SOURCE_MASK)
+ cs->fw.ip.smsk.s_addr = mask;
+ else if (flags & NFT_PARSE_DESTINATION_MASK)
+ cs->fw.ip.dmsk.s_addr = mask;
+}
+
static void nft_ipv4_parse_immediate(const char *jumpto, bool nft_goto,
void *data)
{
@@ -423,6 +440,7 @@ struct nft_family_ops nft_family_ops_ipv4 = {
.parse_meta = nft_ipv4_parse_meta,
.parse_payload = nft_ipv4_parse_payload,
.parse_immediate = nft_ipv4_parse_immediate,
+ .parse_bitwise = nft_ipv4_parse_bitwise,
.print_firewall = nft_ipv4_print_firewall,
.save_firewall = nft_ipv4_save_firewall,
.save_counters = nft_ipv4_save_counters,
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 662c563..1351823 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -100,7 +100,8 @@ static void nft_ipv6_parse_meta(struct nft_rule_expr *e, uint8_t key,
}
static void nft_ipv6_parse_payload(struct nft_rule_expr_iter *iter,
- uint32_t offset, void *data)
+ uint32_t offset, void *data,
+ uint32_t *flags)
{
struct iptables_command_state *cs = data;
switch (offset) {
@@ -111,12 +112,14 @@ static void nft_ipv6_parse_payload(struct nft_rule_expr_iter *iter,
case offsetof(struct ip6_hdr, ip6_src):
get_cmp_data(iter, &addr, sizeof(addr), &inv);
memcpy(cs->fw6.ipv6.src.s6_addr, &addr, sizeof(addr));
+ *flags |= NFT_PARSE_SOURCE_MASK;
if (inv)
cs->fw6.ipv6.invflags |= IPT_INV_SRCIP;
break;
case offsetof(struct ip6_hdr, ip6_dst):
get_cmp_data(iter, &addr, sizeof(addr), &inv);
memcpy(cs->fw6.ipv6.dst.s6_addr, &addr, sizeof(addr));
+ *flags |= NFT_PARSE_DESTINATION_MASK;
if (inv)
cs->fw6.ipv6.invflags |= IPT_INV_DSTIP;
break;
@@ -143,6 +146,21 @@ static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto,
cs->fw6.ipv6.flags |= IP6T_F_GOTO;
}
+static void nft_ipv6_parse_bitwise(struct nft_rule_expr *e, void *data,
+ uint32_t flags)
+{
+ struct iptables_command_state *cs = data;
+ const void *mask;
+ uint32_t len;
+
+ mask = nft_rule_expr_get(e, NFT_EXPR_BITWISE_MASK, &len);
+
+ if (flags & NFT_PARSE_SOURCE_MASK)
+ memcpy(cs->fw6.ipv6.smsk.s6_addr, mask, len);
+ else if (flags & NFT_PARSE_DESTINATION_MASK)
+ memcpy(cs->fw6.ipv6.dmsk.s6_addr, mask, len);
+}
+
static void print_ipv6_addr(const struct iptables_command_state *cs,
unsigned int format)
{
@@ -345,6 +363,7 @@ struct nft_family_ops nft_family_ops_ipv6 = {
.parse_meta = nft_ipv6_parse_meta,
.parse_payload = nft_ipv6_parse_payload,
.parse_immediate = nft_ipv6_parse_immediate,
+ .parse_bitwise = nft_ipv6_parse_bitwise,
.print_firewall = nft_ipv6_print_firewall,
.save_firewall = nft_ipv6_save_firewall,
.save_counters = nft_ipv6_save_counters,
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 2dcdfd1..de5f018 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -199,10 +199,11 @@ void add_addr(struct nft_rule *r, int family, int offset,
add_cmp_ptr(r, op, data, len);
if (family == AF_INET) {
- uint32_t *msk = mask;
- add_bitwise_u32(r, *msk, 0x00000000);
+ uint32_t *mask4 = mask;
+ uint32_t xor = 0;
+ add_bitwise_u32(r, *mask4, xor);
} else {
- uint8_t mask6[16] = {0};
+ uint8_t *mask6 = mask;
uint8_t xor[16] = {0};
add_bitwise_u128(r, mask6, xor);
}
@@ -464,7 +465,7 @@ nft_parse_payload(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET);
- ops->parse_payload(ctx->iter, offset, data);
+ ops->parse_payload(ctx->iter, offset, data, &ctx->flags);
}
void
@@ -506,6 +507,14 @@ nft_parse_immediate(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
ops->parse_immediate(jumpto, nft_goto, data);
}
+void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
+{
+ struct nft_family_ops *ops = nft_family_ops_lookup(ctx->family);
+ void *data = nft_get_data(ctx);
+
+ ops->parse_bitwise(e, data, ctx->flags);
+}
+
void nft_rule_to_iptables_command_state(struct nft_rule *r,
struct iptables_command_state *cs)
{
@@ -532,6 +541,8 @@ void nft_rule_to_iptables_command_state(struct nft_rule *r,
nft_parse_counter(expr, &ctx.state.cs->counters);
else if (strcmp(name, "payload") == 0)
nft_parse_payload(&ctx, expr);
+ else if (strcmp(name, "bitwise") == 0)
+ nft_parse_bitwise(&ctx, expr);
else if (strcmp(name, "meta") == 0)
nft_parse_meta(&ctx, expr);
else if (strcmp(name, "immediate") == 0)
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index e5b6f1d..834ea32 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -36,6 +36,9 @@
| FMT_NUMERIC | FMT_NOTABLE)
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
+#define NFT_PARSE_SOURCE_MASK (1 << 0)
+#define NFT_PARSE_DESTINATION_MASK (1 << 1)
+
struct xtables_args;
struct nft_xt_ctx {
@@ -57,8 +60,10 @@ struct nft_family_ops {
void (*parse_meta)(struct nft_rule_expr *e, uint8_t key,
void *data);
void (*parse_payload)(struct nft_rule_expr_iter *iter,
- uint32_t offset, void *data);
+ uint32_t offset, void *data, uint32_t *flags);
void (*parse_immediate)(const char *jumpto, bool nft_goto, void *data);
+ void (*parse_bitwise)(struct nft_rule_expr *e, void *data,
+ uint32_t flags);
void (*print_firewall)(struct nft_rule *r, unsigned int num,
unsigned int format);
void (*save_firewall)(const void *data, unsigned int format);
@@ -107,6 +112,7 @@ void nft_parse_meta(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
void nft_parse_payload(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
void nft_parse_counter(struct nft_rule_expr *e, struct xt_counters *counters);
void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
+void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
void nft_rule_to_iptables_command_state(struct nft_rule *r,
struct iptables_command_state *cs);
void print_firewall_details(const struct iptables_command_state *cs,
--
1.8.3.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place
2014-08-22 9:16 ` [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place Giuseppe Longo
@ 2014-08-24 13:30 ` Pablo Neira Ayuso
0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-08-24 13:30 UTC (permalink / raw)
To: Giuseppe Longo; +Cc: netfilter-devel
On Fri, Aug 22, 2014 at 11:16:31AM +0200, Giuseppe Longo wrote:
> Currently the protocol is tested after the ip address,
> this fixes the order testing the protocol before the ip address.
>
> Now the code generated is incorrect:
>
> ip filter INPUT 16
> [ payload load 4b @ network header + 12 => reg 1 ]
> [ cmp eq reg 1 0x0100a8c0 ]
> [ payload load 1b @ network header + 9 => reg 1 ]
> [ cmp eq reg 1 0x00000006 ]
> [ match name tcp rev 0 ]
> [ match name conntrack rev 3 ]
> [ counter pkts 0 bytes 0 ]
> [ immediate reg 0 accept ]
>
> With this patch, the code generated is:
> ip filter INPUT 16
> [ payload load 1b @ network header + 9 => reg 1 ]
> [ cmp eq reg 1 0x00000006 ]
> [ payload load 4b @ network header + 12 => reg 1 ]
> [ cmp eq reg 1 0x0100a8c0 ]
> [ bitwise reg 1 = (reg=1 & 0xffffffff ) ^ 0x00000000 ]
> [ match name tcp rev 0 ]
> [ match name conntrack rev 3 ]
> [ counter pkts 0 bytes 0 ]
> [ immediate reg 0 accept ]
Applied, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
` (3 preceding siblings ...)
2014-08-22 9:16 ` [iptables-compat PATCH 5/5 v2] nft: adds parse_bitwise function Giuseppe Longo
@ 2014-08-24 14:03 ` Pablo Neira Ayuso
4 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-08-24 14:03 UTC (permalink / raw)
To: Giuseppe Longo; +Cc: netfilter-devel
On Fri, Aug 22, 2014 at 11:16:29AM +0200, Giuseppe Longo wrote:
> This patch provides the context used to transfer
> informaton between different nft_parse_* function calls.
Applied, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule
2014-08-22 9:16 ` [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule Giuseppe Longo
@ 2014-08-24 14:09 ` Pablo Neira Ayuso
0 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-08-24 14:09 UTC (permalink / raw)
To: Giuseppe Longo; +Cc: netfilter-devel
On Fri, Aug 22, 2014 at 11:16:32AM +0200, Giuseppe Longo wrote:
> This patch adds a bitwise operation to a rule
Please, merge patches 2, 4 and 5 in one single patch. Those changes
are interdependent. I would also like to see a bit longer description.
This is fixing the network prefixes (eg. /24) in the compat utility
and at least one example, ie. A rule + the netlink code that is generated.
Something similar to what you made your patch 3.
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-08-24 14:08 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-22 9:16 [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 2/5 v2] nft: alloc bitwise operation for ipv4/ipv6 addresses Giuseppe Longo
2014-08-22 9:16 ` [iptables-compat PATCH 3/5 v2] nft: compare layer 4 protocol in first place Giuseppe Longo
2014-08-24 13:30 ` Pablo Neira Ayuso
2014-08-22 9:16 ` [iptables-compat PATCH 4/5 v2] nft: adds a bitwise operation to a rule Giuseppe Longo
2014-08-24 14:09 ` Pablo Neira Ayuso
2014-08-22 9:16 ` [iptables-compat PATCH 5/5 v2] nft: adds parse_bitwise function Giuseppe Longo
2014-08-24 14:03 ` [iptables-compat PATCH 1/5 v2] nft: adds nft_xt_ctx struct Pablo Neira Ayuso
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).