[nftables libnl] libnl: nf_tables: add attribute tracking and test functions for expressions
Patrick McHardy
netfilter-cvslog-bounces at lists.netfilter.org
Wed Apr 8 06:21:29 CEST 2009
Gitweb: http://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnl-nft.git;a=commit;h=2d9fbc9decdd1f6222d31392d9cd71fbc91eaa4f
commit 2d9fbc9decdd1f6222d31392d9cd71fbc91eaa4f
Author: Patrick McHardy <kaber at trash.net>
AuthorDate: Wed Apr 8 06:19:10 2009 +0200
Commit: Patrick McHardy <kaber at trash.net>
CommitDate: Wed Apr 8 06:19:10 2009 +0200
libnl: nf_tables: add attribute tracking and test functions for expressions
Signed-off-by: Patrick McHardy <kaber at trash.net>
via 2d9fbc9decdd1f6222d31392d9cd71fbc91eaa4f (commit)
from 0917b23733f46c65703545f82cc633836436f13b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2d9fbc9decdd1f6222d31392d9cd71fbc91eaa4f
Author: Patrick McHardy <kaber at trash.net>
Date: Wed Apr 8 06:19:10 2009 +0200
libnl: nf_tables: add attribute tracking and test functions for expressions
Signed-off-by: Patrick McHardy <kaber at trash.net>
-----------------------------------------------------------------------
include/netlink/netfilter/nft-expr-modules.h | 2 +
include/netlink/netfilter/nft_expr.h | 58 ++++++++++++++-
lib/netfilter/nft_bitwise_expr.c | 108 ++++++++++++++++++++------
lib/netfilter/nft_byteorder_expr.c | 99 ++++++++++++++++++------
lib/netfilter/nft_cmp_expr.c | 78 ++++++++++++++-----
lib/netfilter/nft_counter_expr.c | 55 +++++++++++--
lib/netfilter/nft_ct_expr.c | 58 +++++++++++---
lib/netfilter/nft_expr_obj.c | 13 +++-
lib/netfilter/nft_exthdr_expr.c | 85 ++++++++++++++++-----
lib/netfilter/nft_immediate_expr.c | 63 ++++++++++++---
lib/netfilter/nft_limit_expr.c | 67 +++++++++++------
lib/netfilter/nft_log_expr.c | 104 +++++++++++++++++--------
lib/netfilter/nft_lookup_expr.c | 65 ++++++++++++----
lib/netfilter/nft_meta_expr.c | 57 +++++++++++---
lib/netfilter/nft_nat_expr.c | 108 ++++++++++++++++++--------
lib/netfilter/nft_payload_expr.c | 86 ++++++++++++++++-----
16 files changed, 848 insertions(+), 258 deletions(-)
Signed-off-by: Patrick McHardy <kaber at trash.net>
diff --git a/include/netlink/netfilter/nft-expr-modules.h b/include/netlink/netfilter/nft-expr-modules.h
index 2e83073..6f91596 100644
--- a/include/netlink/netfilter/nft-expr-modules.h
+++ b/include/netlink/netfilter/nft-expr-modules.h
@@ -59,6 +59,8 @@ struct nft_expr_ops
*/
int (*eo_clone)(struct nfnl_nft_expr *, struct nfnl_nft_expr *);
+ char *(*eo_attrs2str)(int, char *, size_t);
+
/**
* INTERNAL (Do not use)
*/
diff --git a/include/netlink/netfilter/nft_expr.h b/include/netlink/netfilter/nft_expr.h
index b7895f0..0e98e4b 100644
--- a/include/netlink/netfilter/nft_expr.h
+++ b/include/netlink/netfilter/nft_expr.h
@@ -31,76 +31,100 @@ extern int nfnl_nft_expr_build_message(struct nl_msg *,
extern int nfnl_nft_immediate_init(struct nfnl_nft_expr *);
extern void nfnl_nft_immediate_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_immediate_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_immediate_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_immediate_set_data(struct nfnl_nft_expr *,
struct nfnl_nft_data *);
+extern int nfnl_nft_immediate_test_data(const struct nfnl_nft_expr *);
extern struct nfnl_nft_data * nfnl_nft_immediate_get_data(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_bitwise_init(struct nfnl_nft_expr *expr);
extern void nfnl_nft_bitwise_set_sreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_bitwise_test_sreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_bitwise_get_sreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_bitwise_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_bitwise_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_bitwise_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_bitwise_set_len(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_bitwise_test_len(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_bitwise_get_len(const struct nfnl_nft_expr *);
-
extern void nfnl_nft_bitwise_set_mask(struct nfnl_nft_expr *,
struct nfnl_nft_data *);
+extern int nfnl_nft_bitwise_test_mask(const struct nfnl_nft_expr *);
extern struct nfnl_nft_data * nfnl_nft_bitwise_get_mask(const struct nfnl_nft_expr *);
extern void nfnl_nft_bitwise_set_xor(struct nfnl_nft_expr *,
struct nfnl_nft_data *);
+extern int nfnl_nft_bitwise_test_xor(const struct nfnl_nft_expr *);
extern struct nfnl_nft_data * nfnl_nft_bitwise_get_xor(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_byteorder_init(struct nfnl_nft_expr *);
extern void nfnl_nft_byteorder_set_sreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_byteorder_test_sreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_byteorder_get_sreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_byteorder_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_byteorder_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_byteorder_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_byteorder_set_op(struct nfnl_nft_expr *,
enum nft_byteorder_ops);
+extern int nfnl_nft_byteorder_test_op(const struct nfnl_nft_expr *);
extern enum nft_byteorder_ops nfnl_nft_byteorder_get_op(const struct nfnl_nft_expr *);
extern void nfnl_nft_byteorder_set_len(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_byteorder_test_len(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_byteoder_get_len(const struct nfnl_nft_expr *);
extern void nfnl_nft_byteorder_set_size(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_byteorder_test_size(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_byteorder_get_size(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_cmp_init(struct nfnl_nft_expr *);
extern void nfnl_nft_cmp_set_sreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_cmp_test_sreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_cmp_get_sreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_cmp_set_op(struct nfnl_nft_expr *,
enum nft_cmp_ops);
+extern int nfnl_nft_cmp_test_op(const struct nfnl_nft_expr *);
extern enum nft_cmp_ops nfnl_nft_cmp_get_op(const struct nfnl_nft_expr *);
extern void nfnl_nft_cmp_set_data(struct nfnl_nft_expr *,
struct nfnl_nft_data *);
+extern int nfnl_nft_cmp_test_data(const struct nfnl_nft_expr *);
extern struct nfnl_nft_data * nfnl_nft_cmp_get_data(const struct nfnl_nft_expr *);
extern char * nfnl_nft_cmp_op2str(enum nft_cmp_ops, char *, size_t);
extern enum nft_cmp_ops nfnl_nft_cmp_str2op(const char *);
+
extern int nfnl_nft_lookup_init(struct nfnl_nft_expr *);
extern void nfnl_nft_lookup_set_set(struct nfnl_nft_expr *,
const char *);
+extern int nfnl_nft_lookup_test_set(const struct nfnl_nft_expr *);
extern const char * nfnl_nft_lookup_get_set(const struct nfnl_nft_expr *);
extern void nfnl_nft_lookup_set_sreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_lookup_test_sreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_lookup_get_sreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_lookup_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_lookup_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_lookup_get_dreg(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_meta_init(struct nfnl_nft_expr *);
extern void nfnl_nft_meta_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_meta_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_meta_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_meta_set_key(struct nfnl_nft_expr *,
enum nft_meta_keys);
+extern int nfnl_nft_meta_test_key(const struct nfnl_nft_expr *);
extern enum nft_meta_keys nfnl_nft_meta_get_key(const struct nfnl_nft_expr *);
extern char * nfnl_nft_meta_key2str(enum nft_meta_keys,
char *, size_t);
@@ -110,9 +134,11 @@ extern enum nft_meta_keys nfnl_nft_meta_str2key(const char *);
extern int nfnl_nft_ct_init(struct nfnl_nft_expr *);
extern void nfnl_nft_ct_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_ct_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_ct_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_ct_set_key(struct nfnl_nft_expr *,
enum nft_ct_keys);
+extern int nfnl_nft_ct_test_key(const struct nfnl_nft_expr *);
extern enum nft_ct_keys nfnl_nft_ct_get_key(const struct nfnl_nft_expr *);
extern char * nfnl_nft_ct_key2str(enum nft_ct_keys, char *,
size_t);
@@ -122,72 +148,102 @@ extern enum nft_ct_keys nfnl_nft_ct_str2key(const char *);
extern int nfnl_nft_payload_init(struct nfnl_nft_expr *);
extern void nfnl_nft_payload_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_payload_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_payload_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_payload_set_base(struct nfnl_nft_expr *,
enum nft_payload_bases);
+extern int nfnl_nft_payload_test_base(const struct nfnl_nft_expr *);
extern enum nft_payload_bases nfnl_nft_payload_get_base(const struct nfnl_nft_expr *);
extern void nfnl_nft_payload_set_offset(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_payload_test_offset(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_payload_get_offset(const struct nfnl_nft_expr *);
extern void nfnl_nft_payload_set_len(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_payload_test_len(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_payload_get_len(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_exthdr_init(struct nfnl_nft_expr *);
extern void nfnl_nft_exthdr_set_dreg(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_exthdr_test_dreg(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_exthdr_get_dreg(const struct nfnl_nft_expr *);
extern void nfnl_nft_exthdr_set_type(struct nfnl_nft_expr *,
uint8_t type);
+extern int nfnl_nft_exthdr_test_type(const struct nfnl_nft_expr *);
extern uint8_t nfnl_nft_exthdr_get_type(const struct nfnl_nft_expr *);
extern void nfnl_nft_exthdr_set_offset(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_exthdr_test_offset(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_exthdr_get_offset(const struct nfnl_nft_expr *);
extern void nfnl_nft_exthdr_set_len(struct nfnl_nft_expr *,
unsigned int);
+extern int nfnl_nft_exthdr_test_len(const struct nfnl_nft_expr *);
extern unsigned int nfnl_nft_exthdr_get_len(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_counter_init(struct nfnl_nft_expr *);
+extern void nfnl_nft_counter_set_packets(struct nfnl_nft_expr *,
+ uint64_t);
+extern int nfnl_nft_counter_test_packets(const struct nfnl_nft_expr *);
extern uint64_t nfnl_nft_counter_get_packets(const struct nfnl_nft_expr *);
+extern void nfnl_nft_counter_set_bytes(struct nfnl_nft_expr *,
+ uint64_t);
+extern int nfnl_nft_counter_test_bytes(const struct nfnl_nft_expr *);
extern uint64_t nfnl_nft_counter_get_bytes(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_log_init(struct nfnl_nft_expr *);
extern void nfnl_nft_log_set_prefix(struct nfnl_nft_expr *,
const char *);
+extern int nfnl_nft_log_test_prefix(const struct nfnl_nft_expr *);
extern const char * nfnl_nft_log_get_prefix(const struct nfnl_nft_expr *);
extern void nfnl_nft_log_set_group(struct nfnl_nft_expr *,
uint32_t);
+extern int nfnl_nft_log_test_group(const struct nfnl_nft_expr *);
extern uint32_t nfnl_nft_log_get_group(const struct nfnl_nft_expr *);
extern void nfnl_nft_log_set_snaplen(struct nfnl_nft_expr *,
uint32_t);
+extern int nfnl_nft_log_test_snaplen(const struct nfnl_nft_expr *);
extern uint32_t nfnl_nft_log_get_snaplen(const struct nfnl_nft_expr *);
extern void nfnl_nft_log_set_qthreshold(struct nfnl_nft_expr *,
uint32_t);
+extern int nfnl_nft_log_test_qthreshold(const struct nfnl_nft_expr *);
extern uint32_t nfnl_nft_log_get_qthreshold(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_limit_init(struct nfnl_nft_expr *);
extern void nfnl_nft_limit_set_rate(struct nfnl_nft_expr *,
uint64_t);
+extern int nfnl_nft_limit_test_rate(const struct nfnl_nft_expr *);
extern uint64_t nfnl_nft_limit_get_rate(const struct nfnl_nft_expr *);
extern void nfnl_nft_limit_set_depth(struct nfnl_nft_expr *,
uint64_t);
+extern int nfnl_nft_limit_test_depth(const struct nfnl_nft_expr *);
extern uint64_t nfnl_nft_limit_get_depth(const struct nfnl_nft_expr *);
+
extern int nfnl_nft_nat_init(struct nfnl_nft_expr *);
extern void nfnl_nft_nat_set_type(struct nfnl_nft_expr *,
enum nft_nat_types);
+extern int nfnl_nft_nat_test_type(const struct nfnl_nft_expr *);
extern enum nft_nat_types nfnl_nft_nat_get_type(const struct nfnl_nft_expr *);
extern void nfnl_nft_nat_set_sreg_addr_min(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_nat_test_sreg_addr_min(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_nat_get_sreg_addr_min(const struct nfnl_nft_expr *);
extern void nfnl_nft_nat_set_sreg_addr_max(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_nat_test_sreg_addr_max(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_nat_get_sreg_addr_max(const struct nfnl_nft_expr *);
extern void nfnl_nft_nat_set_sreg_proto_min(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_nat_test_sreg_proto_min(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_nat_get_sreg_proto_min(const struct nfnl_nft_expr *);
extern void nfnl_nft_nat_set_sreg_proto_max(struct nfnl_nft_expr *,
enum nft_registers);
+extern int nfnl_nft_nat_test_sreg_proto_max(const struct nfnl_nft_expr *);
extern enum nft_registers nfnl_nft_nat_get_sreg_proto_max(const struct nfnl_nft_expr *);
#ifdef __cplusplus
diff --git a/lib/netfilter/nft_bitwise_expr.c b/lib/netfilter/nft_bitwise_expr.c
index 1fdebaa..ca9d27f 100644
--- a/lib/netfilter/nft_bitwise_expr.c
+++ b/lib/netfilter/nft_bitwise_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -22,6 +22,14 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define BITWISE_ATTR_SREG (1UL << 0)
+#define BITWISE_ATTR_DREG (1UL << 1)
+#define BITWISE_ATTR_LEN (1UL << 2)
+#define BITWISE_ATTR_MASK (1UL << 3)
+#define BITWISE_ATTR_XOR (1UL << 4)
+/** @endcond */
+
struct nft_bitwise_expr {
enum nft_registers sreg;
enum nft_registers dreg;
@@ -72,25 +80,28 @@ static void nft_bitwise_free_data(struct nfnl_nft_expr *expr)
static int nft_bitwise_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
{
struct nft_bitwise_expr *bitwise;
+ struct nfnl_nft_data *data;
bitwise = nft_bitwise_expr_alloc(expr);
if (bitwise == NULL)
return -ENOMEM;
if (tb[NFTA_BITWISE_SREG])
- bitwise->sreg = ntohl(nla_get_u32(tb[NFTA_BITWISE_SREG]));
+ nfnl_nft_bitwise_set_sreg(expr, ntohl(nla_get_u32(tb[NFTA_BITWISE_SREG])));
if (tb[NFTA_BITWISE_DREG])
- bitwise->dreg = ntohl(nla_get_u32(tb[NFTA_BITWISE_DREG]));
+ nfnl_nft_bitwise_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_BITWISE_DREG])));
if (tb[NFTA_BITWISE_LEN])
- bitwise->len = ntohl(nla_get_u32(tb[NFTA_BITWISE_LEN]));
+ nfnl_nft_bitwise_set_len(expr, ntohl(nla_get_u32(tb[NFTA_BITWISE_LEN])));
if (tb[NFTA_BITWISE_MASK]) {
- if (nfnl_nft_data_parse(tb[NFTA_BITWISE_MASK], &bitwise->mask) < 0)
+ if (nfnl_nft_data_parse(tb[NFTA_BITWISE_MASK], &data) < 0)
goto err1;
+ nfnl_nft_bitwise_set_mask(expr, data);
}
if (tb[NFTA_BITWISE_XOR]) {
- if (nfnl_nft_data_parse(tb[NFTA_BITWISE_XOR], &bitwise->xor) < 0)
+ if (nfnl_nft_data_parse(tb[NFTA_BITWISE_XOR], &data) < 0)
goto err2;
+ nfnl_nft_bitwise_set_xor(expr, data);
}
return 0;
@@ -104,20 +115,22 @@ static int nft_bitwise_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_bitwise_expr *bitwise = nft_bitwise(expr);
- if (nla_put_u32(msg, NFTA_BITWISE_SREG, htonl(bitwise->sreg)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_BITWISE_DREG, htonl(bitwise->dreg)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_BITWISE_LEN, htonl(bitwise->len)) < 0)
- goto errout;
-
- if (nfnl_nft_data_put(msg, NFTA_BITWISE_MASK, bitwise->mask) < 0)
- goto errout;
- if (nfnl_nft_data_put(msg, NFTA_BITWISE_XOR, bitwise->xor) < 0)
- goto errout;
+ if (nfnl_nft_bitwise_test_sreg(expr))
+ NLA_PUT_U32(msg, NFTA_BITWISE_SREG, htonl(bitwise->sreg));
+ if (nfnl_nft_bitwise_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_BITWISE_DREG, htonl(bitwise->dreg));
+ if (nfnl_nft_bitwise_test_len(expr))
+ NLA_PUT_U32(msg, NFTA_BITWISE_LEN, htonl(bitwise->len));
+
+ if (nfnl_nft_bitwise_test_mask(expr) &&
+ nfnl_nft_data_put(msg, NFTA_BITWISE_MASK, bitwise->mask) < 0)
+ goto nla_put_failure;
+ if (nfnl_nft_bitwise_test_xor(expr) &&
+ nfnl_nft_data_put(msg, NFTA_BITWISE_XOR, bitwise->xor) < 0)
+ goto nla_put_failure;
return 0;
-errout:
+nla_put_failure:
return -1;
}
@@ -138,9 +151,29 @@ int nfnl_nft_bitwise_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_bitwise_attrs[] = {
+ __ADD(BITWISE_ATTR_SREG, sreg)
+ __ADD(BITWISE_ATTR_DREG, dreg)
+ __ADD(BITWISE_ATTR_LEN, len)
+ __ADD(BITWISE_ATTR_MASK, mask)
+ __ADD(BITWISE_ATTR_XOR, xor)
+};
+
+static char *nft_bitwise_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_bitwise_attrs,
+ ARRAY_SIZE(nft_bitwise_attrs));
+}
+
void nfnl_nft_bitwise_set_sreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_bitwise(expr)->sreg = reg;
+ expr->ce_mask |= BITWISE_ATTR_SREG;
+}
+
+int nfnl_nft_bitwise_test_sreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BITWISE_ATTR_SREG);
}
enum nft_registers nfnl_nft_bitwise_get_sreg(const struct nfnl_nft_expr *expr)
@@ -151,6 +184,12 @@ enum nft_registers nfnl_nft_bitwise_get_sreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_bitwise_set_dreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_bitwise(expr)->dreg = reg;
+ expr->ce_mask |= BITWISE_ATTR_DREG;
+}
+
+int nfnl_nft_bitwise_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BITWISE_ATTR_DREG);
}
enum nft_registers nfnl_nft_bitwise_get_dreg(const struct nfnl_nft_expr *expr)
@@ -161,6 +200,12 @@ enum nft_registers nfnl_nft_bitwise_get_dreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_bitwise_set_len(struct nfnl_nft_expr *expr, unsigned int len)
{
nft_bitwise(expr)->len = len;
+ expr->ce_mask |= BITWISE_ATTR_LEN;
+}
+
+int nfnl_nft_bitwise_test_len(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BITWISE_ATTR_LEN);
}
unsigned int nfnl_nft_bitwise_get_len(const struct nfnl_nft_expr *expr)
@@ -171,6 +216,12 @@ unsigned int nfnl_nft_bitwise_get_len(const struct nfnl_nft_expr *expr)
void nfnl_nft_bitwise_set_mask(struct nfnl_nft_expr *expr, struct nfnl_nft_data *data)
{
nft_bitwise(expr)->mask = data;
+ expr->ce_mask |= BITWISE_ATTR_MASK;
+}
+
+int nfnl_nft_bitwise_test_mask(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BITWISE_ATTR_MASK);
}
struct nfnl_nft_data *nfnl_nft_bitwise_get_mask(const struct nfnl_nft_expr *expr)
@@ -181,6 +232,12 @@ struct nfnl_nft_data *nfnl_nft_bitwise_get_mask(const struct nfnl_nft_expr *expr
void nfnl_nft_bitwise_set_xor(struct nfnl_nft_expr *expr, struct nfnl_nft_data *data)
{
nft_bitwise(expr)->xor = data;
+ expr->ce_mask |= BITWISE_ATTR_XOR;
+}
+
+int nfnl_nft_bitwise_test_xor(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BITWISE_ATTR_XOR);
}
struct nfnl_nft_data *nfnl_nft_bitwise_get_xor(const struct nfnl_nft_expr *expr)
@@ -189,14 +246,15 @@ struct nfnl_nft_data *nfnl_nft_bitwise_get_xor(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops bitwise_expr_ops = {
- .eo_name = "bitwise",
+ .eo_name = "bitwise",
.eo_dump[NL_DUMP_DETAILS] = nft_bitwise_dump,
- .eo_get_opts = nft_bitwise_get_opts,
- .eo_msg_parser = nft_bitwise_msg_parser,
- .eo_free_data = nft_bitwise_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_bitwise_policy,
- .eo_maxattr = NFTA_BITWISE_MAX,
+ .eo_get_opts = nft_bitwise_get_opts,
+ .eo_msg_parser = nft_bitwise_msg_parser,
+ .eo_free_data = nft_bitwise_free_data,
+ .eo_clone = NULL,
+ .eo_attrs2str = nft_bitwise_attrs2str,
+ .eo_policy = nft_bitwise_policy,
+ .eo_maxattr = NFTA_BITWISE_MAX,
};
static void __init nft_bitwise_expr_init(void)
diff --git a/lib/netfilter/nft_byteorder_expr.c b/lib/netfilter/nft_byteorder_expr.c
index 04fc6be..8cf5972 100644
--- a/lib/netfilter/nft_byteorder_expr.c
+++ b/lib/netfilter/nft_byteorder_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -22,6 +22,14 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define BYTEORDER_ATTR_SREG (1UL << 0)
+#define BYTEORDER_ATTR_DREG (1UL << 1)
+#define BYTEORDER_ATTR_OP (1UL << 2)
+#define BYTEORDER_ATTR_LEN (1UL << 3)
+#define BYTEORDER_ATTR_SIZE (1UL << 4)
+/** @endcond */
+
struct nft_byteorder_expr {
enum nft_registers sreg;
enum nft_registers dreg;
@@ -70,15 +78,15 @@ static int nft_byteorder_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *t
return -ENOMEM;
if (tb[NFTA_BYTEORDER_SREG])
- byteorder->sreg = ntohl(nla_get_u32(tb[NFTA_BYTEORDER_SREG]));
+ nfnl_nft_byteorder_set_sreg(expr, ntohl(nla_get_u32(tb[NFTA_BYTEORDER_SREG])));
if (tb[NFTA_BYTEORDER_DREG])
- byteorder->dreg = ntohl(nla_get_u32(tb[NFTA_BYTEORDER_DREG]));
+ nfnl_nft_byteorder_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_BYTEORDER_DREG])));
if (tb[NFTA_BYTEORDER_LEN])
- byteorder->len = ntohl(nla_get_u32(tb[NFTA_BYTEORDER_LEN]));
+ nfnl_nft_byteorder_set_len(expr, ntohl(nla_get_u32(tb[NFTA_BYTEORDER_LEN])));
if (tb[NFTA_BYTEORDER_OP])
- byteorder->op = ntohl(nla_get_u32(tb[NFTA_BYTEORDER_OP]));
+ nfnl_nft_byteorder_set_op(expr, ntohl(nla_get_u32(tb[NFTA_BYTEORDER_OP])));
if (tb[NFTA_BYTEORDER_SIZE])
- byteorder->size = ntohl(nla_get_u32(tb[NFTA_BYTEORDER_SIZE]));
+ nfnl_nft_byteorder_set_size(expr, ntohl(nla_get_u32(tb[NFTA_BYTEORDER_SIZE])));
return 0;
}
@@ -87,19 +95,19 @@ static int nft_byteorder_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr
{
struct nft_byteorder_expr *byteorder = nft_byteorder(expr);
- if (nla_put_u32(msg, NFTA_BYTEORDER_SREG, htonl(byteorder->sreg)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_BYTEORDER_DREG, htonl(byteorder->dreg)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_BYTEORDER_LEN, htonl(byteorder->len) < 0))
- goto errout;
- if (nla_put_u32(msg, NFTA_BYTEORDER_OP, htonl(byteorder->op)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_BYTEORDER_SIZE, htonl(byteorder->size)) < 0)
- goto errout;
+ if (nfnl_nft_byteorder_test_sreg(expr))
+ NLA_PUT_U32(msg, NFTA_BYTEORDER_SREG, htonl(byteorder->sreg));
+ if (nfnl_nft_byteorder_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_BYTEORDER_DREG, htonl(byteorder->dreg));
+ if (nfnl_nft_byteorder_test_len(expr))
+ NLA_PUT_U32(msg, NFTA_BYTEORDER_LEN, htonl(byteorder->len));
+ if (nfnl_nft_byteorder_test_op(expr))
+ NLA_PUT_U32(msg, NFTA_BYTEORDER_OP, htonl(byteorder->op));
+ if (nfnl_nft_byteorder_test_size(expr))
+ NLA_PUT_U32(msg, NFTA_BYTEORDER_SIZE, htonl(byteorder->size));
return 0;
-errout:
+nla_put_failure:
return -1;
}
@@ -123,9 +131,29 @@ int nfnl_nft_byteorder_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_byteorder_attrs[] = {
+ __ADD(BYTEORDER_ATTR_SREG, sreg)
+ __ADD(BYTEORDER_ATTR_DREG, dreg)
+ __ADD(BYTEORDER_ATTR_OP, op)
+ __ADD(BYTEORDER_ATTR_LEN, len)
+ __ADD(BYTEORDER_ATTR_SIZE, size)
+};
+
+static char *nft_byteorder_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_byteorder_attrs,
+ ARRAY_SIZE(nft_byteorder_attrs));
+}
+
void nfnl_nft_byteorder_set_sreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_byteorder(expr)->sreg = reg;
+ expr->ce_mask |= BYTEORDER_ATTR_SREG;
+}
+
+int nfnl_nft_byteorder_test_sreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BYTEORDER_ATTR_SREG);
}
enum nft_registers nfnl_nft_byteorder_get_sreg(const struct nfnl_nft_expr *expr)
@@ -136,6 +164,12 @@ enum nft_registers nfnl_nft_byteorder_get_sreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_byteorder_set_dreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_byteorder(expr)->dreg = reg;
+ expr->ce_mask |= BYTEORDER_ATTR_DREG;
+}
+
+int nfnl_nft_byteorder_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BYTEORDER_ATTR_DREG);
}
enum nft_registers nfnl_nft_byteorder_get_dreg(const struct nfnl_nft_expr *expr)
@@ -146,6 +180,12 @@ enum nft_registers nfnl_nft_byteorder_get_dreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_byteorder_set_op(struct nfnl_nft_expr *expr, enum nft_byteorder_ops op)
{
nft_byteorder(expr)->op = op;
+ expr->ce_mask |= BYTEORDER_ATTR_OP;
+}
+
+int nfnl_nft_byteorder_test_op(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BYTEORDER_ATTR_OP);
}
enum nft_byteorder_ops nfnl_nft_byteorder_get_op(const struct nfnl_nft_expr *expr)
@@ -156,6 +196,12 @@ enum nft_byteorder_ops nfnl_nft_byteorder_get_op(const struct nfnl_nft_expr *exp
void nfnl_nft_byteorder_set_len(struct nfnl_nft_expr *expr, unsigned int len)
{
nft_byteorder(expr)->len = len;
+ expr->ce_mask |= BYTEORDER_ATTR_LEN;
+}
+
+int nfnl_nft_byteorder_test_len(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BYTEORDER_ATTR_LEN);
}
unsigned int nfnl_nft_byteoder_get_len(const struct nfnl_nft_expr *expr)
@@ -166,6 +212,12 @@ unsigned int nfnl_nft_byteoder_get_len(const struct nfnl_nft_expr *expr)
void nfnl_nft_byteorder_set_size(struct nfnl_nft_expr *expr, unsigned int size)
{
nft_byteorder(expr)->size = size;
+ expr->ce_mask |= BYTEORDER_ATTR_SIZE;
+}
+
+int nfnl_nft_byteorder_test_size(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & BYTEORDER_ATTR_SIZE);
}
unsigned int nfnl_nft_byteorder_get_size(const struct nfnl_nft_expr *expr)
@@ -174,13 +226,14 @@ unsigned int nfnl_nft_byteorder_get_size(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops byteorder_expr_ops = {
- .eo_name = "byteorder",
+ .eo_name = "byteorder",
.eo_dump[NL_DUMP_DETAILS] = nft_byteorder_dump,
- .eo_get_opts = nft_byteorder_get_opts,
- .eo_msg_parser = nft_byteorder_msg_parser,
- .eo_clone = NULL,
- .eo_policy = nft_byteorder_policy,
- .eo_maxattr = NFTA_BYTEORDER_MAX,
+ .eo_get_opts = nft_byteorder_get_opts,
+ .eo_msg_parser = nft_byteorder_msg_parser,
+ .eo_clone = NULL,
+ .eo_attrs2str = nft_byteorder_attrs2str,
+ .eo_policy = nft_byteorder_policy,
+ .eo_maxattr = NFTA_BYTEORDER_MAX,
};
static void __init nft_byteorder_expr_init(void)
diff --git a/lib/netfilter/nft_cmp_expr.c b/lib/netfilter/nft_cmp_expr.c
index f3eaefe..3ed9296 100644
--- a/lib/netfilter/nft_cmp_expr.c
+++ b/lib/netfilter/nft_cmp_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -22,6 +22,12 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define CMP_ATTR_SREG (1UL << 0)
+#define CMP_ATTR_OP (1UL << 1)
+#define CMP_ATTR_DATA (1UL << 2)
+/** @endcond */
+
struct nft_cmp_expr {
struct nfnl_nft_data * data;
enum nft_registers sreg;
@@ -67,20 +73,21 @@ static void nft_cmp_free_data(struct nfnl_nft_expr *expr)
static int nft_cmp_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
{
struct nft_cmp_expr *cmp;
+ struct nfnl_nft_data *data;
cmp = nft_cmp_expr_alloc(expr);
if (cmp == NULL)
return -ENOMEM;
if (tb[NFTA_CMP_SREG])
- cmp->sreg = ntohl(nla_get_u32(tb[NFTA_CMP_SREG]));
+ nfnl_nft_cmp_set_sreg(expr, ntohl(nla_get_u32(tb[NFTA_CMP_SREG])));
if (tb[NFTA_CMP_OP])
- cmp->op = ntohl(nla_get_u32(tb[NFTA_CMP_OP]));
+ nfnl_nft_cmp_set_op(expr, ntohl(nla_get_u32(tb[NFTA_CMP_OP])));
if (tb[NFTA_CMP_DATA]) {
- if (nfnl_nft_data_parse(tb[NFTA_CMP_DATA], &cmp->data) < 0)
+ if (nfnl_nft_data_parse(tb[NFTA_CMP_DATA], &data) < 0)
goto errout;
+ nfnl_nft_cmp_set_data(expr, data);
}
-
return 0;
errout:
@@ -91,16 +98,16 @@ static int nft_cmp_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_cmp_expr *cmp = nft_cmp(expr);
- if (nla_put_u32(msg, NFTA_CMP_SREG, htonl(cmp->sreg)) < 0)
- goto errout;
- if (nla_put_u32(msg, NFTA_CMP_OP, htonl(cmp->op)) < 0)
- goto errout;
- if (nfnl_nft_data_put(msg, NFTA_CMP_DATA, cmp->data) < 0)
- goto errout;
-
+ if (nfnl_nft_cmp_test_sreg(expr))
+ NLA_PUT_U32(msg, NFTA_CMP_SREG, htonl(cmp->sreg));
+ if (nfnl_nft_cmp_test_op(expr))
+ NLA_PUT_U32(msg, NFTA_CMP_OP, htonl(cmp->op));
+ if (nfnl_nft_cmp_test_data(expr) &&
+ nfnl_nft_data_put(msg, NFTA_CMP_DATA, cmp->data) < 0)
+ goto nla_put_failure;
return 0;
-errout:
+nla_put_failure:
return -1;
}
@@ -122,9 +129,27 @@ int nfnl_nft_cmp_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_cmp_attrs[] = {
+ __ADD(CMP_ATTR_SREG, sreg)
+ __ADD(CMP_ATTR_OP, op)
+ __ADD(CMP_ATTR_DATA, data)
+};
+
+static char *nft_cmp_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_cmp_attrs,
+ ARRAY_SIZE(nft_cmp_attrs));
+}
+
void nfnl_nft_cmp_set_sreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_cmp(expr)->sreg = reg;
+ expr->ce_mask |= CMP_ATTR_SREG;
+}
+
+int nfnl_nft_cmp_test_sreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & CMP_ATTR_SREG);
}
enum nft_registers nfnl_nft_cmp_get_sreg(const struct nfnl_nft_expr *expr)
@@ -135,6 +160,12 @@ enum nft_registers nfnl_nft_cmp_get_sreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_cmp_set_op(struct nfnl_nft_expr *expr, enum nft_cmp_ops op)
{
nft_cmp(expr)->op = op;
+ expr->ce_mask |= CMP_ATTR_OP;
+}
+
+int nfnl_nft_cmp_test_op(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & CMP_ATTR_OP);
}
enum nft_cmp_ops nfnl_nft_cmp_get_op(const struct nfnl_nft_expr *expr)
@@ -145,6 +176,12 @@ enum nft_cmp_ops nfnl_nft_cmp_get_op(const struct nfnl_nft_expr *expr)
void nfnl_nft_cmp_set_data(struct nfnl_nft_expr *expr, struct nfnl_nft_data *data)
{
nft_cmp(expr)->data = data;
+ expr->ce_mask |= CMP_ATTR_DATA;
+}
+
+int nfnl_nft_cmp_test_data(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & CMP_ATTR_DATA);
}
struct nfnl_nft_data *nfnl_nft_cmp_get_data(const struct nfnl_nft_expr *expr)
@@ -172,14 +209,15 @@ enum nft_cmp_ops nfnl_nft_cmp_str2op(const char *name)
}
static struct nft_expr_ops cmp_expr_ops = {
- .eo_name = "cmp",
+ .eo_name = "cmp",
.eo_dump[NL_DUMP_DETAILS] = nft_cmp_dump,
- .eo_get_opts = nft_cmp_get_opts,
- .eo_msg_parser = nft_cmp_msg_parser,
- .eo_free_data = nft_cmp_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_cmp_policy,
- .eo_maxattr = NFTA_CMP_MAX,
+ .eo_get_opts = nft_cmp_get_opts,
+ .eo_msg_parser = nft_cmp_msg_parser,
+ .eo_free_data = nft_cmp_free_data,
+ .eo_clone = NULL,
+ .eo_attrs2str = nft_cmp_attrs2str,
+ .eo_policy = nft_cmp_policy,
+ .eo_maxattr = NFTA_CMP_MAX,
};
static void __init nft_cmp_expr_init(void)
diff --git a/lib/netfilter/nft_counter_expr.c b/lib/netfilter/nft_counter_expr.c
index c05865d..806341b 100644
--- a/lib/netfilter/nft_counter_expr.c
+++ b/lib/netfilter/nft_counter_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,11 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define COUNTER_ATTR_BYTES (1UL << 0)
+#define COUNTER_ATTR_PACKETS (1UL << 1)
+/** @endcond */
+
#if __BYTE_ORDER == __BIG_ENDIAN
static uint64_t ntohll(uint64_t x)
{
@@ -74,11 +79,9 @@ static int nft_counter_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[
return -ENOMEM;
if (tb[NFTA_COUNTER_BYTES])
- counter->bytes = ntohll(nla_get_u64(tb[NFTA_COUNTER_BYTES]));
-
+ nfnl_nft_counter_set_bytes(expr, ntohll(nla_get_u64(tb[NFTA_COUNTER_BYTES])));
if (tb[NFTA_COUNTER_PACKETS])
- counter->packets = ntohll(nla_get_u64(tb[NFTA_COUNTER_PACKETS]));
-
+ nfnl_nft_counter_set_packets(expr, ntohll(nla_get_u64(tb[NFTA_COUNTER_PACKETS])));
return 0;
}
@@ -101,22 +104,56 @@ int nfnl_nft_counter_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_counter_attrs[] = {
+ __ADD(COUNTER_ATTR_BYTES, bytes)
+ __ADD(COUNTER_ATTR_PACKETS, packets)
+};
+
+static char *nft_counter_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_counter_attrs,
+ ARRAY_SIZE(nft_counter_attrs));
+}
+
+void nfnl_nft_counter_set_packets(struct nfnl_nft_expr *expr, uint64_t packets)
+{
+ nft_counter(expr)->packets = packets;
+ expr->ce_mask |= COUNTER_ATTR_PACKETS;
+}
+
+int nfnl_nft_counter_test_packets(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & COUNTER_ATTR_PACKETS);
+}
+
uint64_t nfnl_nft_counter_get_packets(const struct nfnl_nft_expr *expr)
{
return nft_counter(expr)->packets;
}
+void nfnl_nft_counter_set_bytes(struct nfnl_nft_expr *expr, uint64_t bytes)
+{
+ nft_counter(expr)->bytes = bytes;
+ expr->ce_mask |= COUNTER_ATTR_BYTES;
+}
+
+int nfnl_nft_counter_test_bytes(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & COUNTER_ATTR_BYTES);
+}
+
uint64_t nfnl_nft_counter_get_bytes(const struct nfnl_nft_expr *expr)
{
return nft_counter(expr)->bytes;
}
static struct nft_expr_ops counter_expr_ops = {
- .eo_name = "counter",
+ .eo_name = "counter",
.eo_dump[NL_DUMP_DETAILS] = nft_counter_dump,
- .eo_msg_parser = nft_counter_msg_parser,
- .eo_policy = nft_counter_policy,
- .eo_maxattr = NFTA_COUNTER_MAX,
+ .eo_msg_parser = nft_counter_msg_parser,
+ .eo_attrs2str = nft_counter_attrs2str,
+ .eo_policy = nft_counter_policy,
+ .eo_maxattr = NFTA_COUNTER_MAX,
};
static void __init nft_counter_expr_init(void)
diff --git a/lib/netfilter/nft_ct_expr.c b/lib/netfilter/nft_ct_expr.c
index fa05076..8a11a4c 100644
--- a/lib/netfilter/nft_ct_expr.c
+++ b/lib/netfilter/nft_ct_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,12 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define CT_ATTR_DREG (1UL << 0)
+#define CT_ATTR_KEY (1UL << 1)
+#define CT_ATTR_DIRECTION (1UL << 2)
+/** @endcond */
+
struct nft_ct_expr {
enum nft_ct_keys key;
enum nft_registers dreg;
@@ -63,9 +69,9 @@ static int nft_ct_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
return -ENOMEM;
if (tb[NFTA_CT_DREG])
- ct->dreg = ntohl(nla_get_u32(tb[NFTA_CT_DREG]));
+ nfnl_nft_ct_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_CT_DREG])));
if (tb[NFTA_CT_KEY])
- ct->key = ntohl(nla_get_u32(tb[NFTA_CT_KEY]));
+ nfnl_nft_ct_set_key(expr, ntohl(nla_get_u32(tb[NFTA_CT_KEY])));
return 0;
}
@@ -74,11 +80,14 @@ static int nft_ct_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_ct_expr *ct = nft_ct(expr);
- if (nla_put_u32(msg, NFTA_CT_DREG, htonl(ct->dreg)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_CT_KEY, htonl(ct->key)) < 0)
- return -1;
+ if (nfnl_nft_ct_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_CT_DREG, htonl(ct->dreg));
+ if (nfnl_nft_ct_test_key(expr))
+ NLA_PUT_U32(msg, NFTA_CT_KEY, htonl(ct->key));
return 0;
+
+nla_put_failure:
+ return -1;
}
static struct trans_tbl ct_keys[] = {
@@ -124,9 +133,27 @@ int nfnl_nft_ct_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_ct_attrs[] = {
+ __ADD(CT_ATTR_DREG, dreg)
+ __ADD(CT_ATTR_KEY, key)
+ __ADD(CT_ATTR_DIRECTION, direction)
+};
+
+static char *nft_ct_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_ct_attrs,
+ ARRAY_SIZE(nft_ct_attrs));
+}
+
void nfnl_nft_ct_set_dreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_ct(expr)->dreg = reg;
+ expr->ce_mask |= CT_ATTR_DREG;
+}
+
+int nfnl_nft_ct_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & CT_ATTR_DREG);
}
enum nft_registers nfnl_nft_ct_get_dreg(const struct nfnl_nft_expr *expr)
@@ -137,6 +164,12 @@ enum nft_registers nfnl_nft_ct_get_dreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_ct_set_key(struct nfnl_nft_expr *expr, enum nft_ct_keys key)
{
nft_ct(expr)->key = key;
+ expr->ce_mask |= CT_ATTR_KEY;
+}
+
+int nfnl_nft_ct_test_key(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & CT_ATTR_KEY);
}
enum nft_ct_keys nfnl_nft_ct_get_key(const struct nfnl_nft_expr *expr)
@@ -145,12 +178,13 @@ enum nft_ct_keys nfnl_nft_ct_get_key(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops ct_expr_ops = {
- .eo_name = "ct",
+ .eo_name = "ct",
.eo_dump[NL_DUMP_DETAILS] = nft_ct_dump,
- .eo_get_opts = nft_ct_get_opts,
- .eo_msg_parser = nft_ct_msg_parser,
- .eo_policy = nft_ct_policy,
- .eo_maxattr = NFTA_SET_MAX,
+ .eo_get_opts = nft_ct_get_opts,
+ .eo_msg_parser = nft_ct_msg_parser,
+ .eo_attrs2str = nft_ct_attrs2str,
+ .eo_policy = nft_ct_policy,
+ .eo_maxattr = NFTA_SET_MAX,
};
static void __init nft_ct_expr_init(void)
diff --git a/lib/netfilter/nft_expr_obj.c b/lib/netfilter/nft_expr_obj.c
index 40e2634..b85a6c7 100644
--- a/lib/netfilter/nft_expr_obj.c
+++ b/lib/netfilter/nft_expr_obj.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -52,6 +52,16 @@ static void nft_expr_dump(struct nl_object *obj, struct nl_dump_params *p)
}
}
+static char *nft_expr_attrs2str(int attrs, char *buf, size_t len)
+{
+ struct nl_object *obj = NULL; // FIXME
+ struct nfnl_nft_expr *expr = nl_object_priv(obj);
+
+ if (expr->expr_ops)
+ expr->expr_ops->eo_attrs2str(attrs, buf, len);
+ return NULL;
+}
+
static int nft_expr_compare(struct nl_object *_a, struct nl_object *_b,
uint32_t attrs, int flags)
{
@@ -102,6 +112,7 @@ struct nl_object_ops nft_expr_obj_ops = {
[NL_DUMP_DETAILS] = nft_expr_dump,
[NL_DUMP_STATS] = nft_expr_dump,
},
+ .oo_attrs2str = nft_expr_attrs2str,
.oo_compare = nft_expr_compare,
};
diff --git a/lib/netfilter/nft_exthdr_expr.c b/lib/netfilter/nft_exthdr_expr.c
index bb38434..052b691 100644
--- a/lib/netfilter/nft_exthdr_expr.c
+++ b/lib/netfilter/nft_exthdr_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,13 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define EXTHDR_ATTR_DREG (1UL << 0)
+#define EXTHDR_ATTR_TYPE (1UL << 1)
+#define EXTHDR_ATTR_OFFSET (1UL << 2)
+#define EXTHDR_ATTR_LEN (1UL << 3)
+/** @endcond */
+
struct nft_exthdr_expr {
enum nft_registers dreg;
uint8_t type;
@@ -66,13 +73,13 @@ static int nft_exthdr_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[]
return -ENOMEM;
if (tb[NFTA_EXTHDR_DREG])
- exthdr->dreg = ntohl(nla_get_u32(tb[NFTA_EXTHDR_DREG]));
+ nfnl_nft_exthdr_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_EXTHDR_DREG])));
if (tb[NFTA_EXTHDR_TYPE])
- exthdr->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
+ nfnl_nft_exthdr_set_type(expr, nla_get_u8(tb[NFTA_EXTHDR_TYPE]));
if (tb[NFTA_EXTHDR_OFFSET])
- exthdr->offset = ntohl(nla_get_u32(tb[NFTA_EXTHDR_OFFSET]));
+ nfnl_nft_exthdr_set_offset(expr, ntohl(nla_get_u32(tb[NFTA_EXTHDR_OFFSET])));
if (tb[NFTA_EXTHDR_LEN])
- exthdr->len = ntohl(nla_get_u32(tb[NFTA_EXTHDR_LEN]));
+ nfnl_nft_exthdr_set_len(expr, ntohl(nla_get_u32(tb[NFTA_EXTHDR_LEN])));
return 0;
}
@@ -81,16 +88,18 @@ static int nft_exthdr_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_exthdr_expr *exthdr = nft_exthdr(expr);
- if (nla_put_u32(msg, NFTA_EXTHDR_DREG, htonl(exthdr->dreg)) < 0)
- return -1;
- if (nla_put_u8(msg, NFTA_EXTHDR_TYPE, exthdr->type) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_EXTHDR_OFFSET, htonl(exthdr->offset)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_EXTHDR_LEN, htonl(exthdr->len)) < 0)
- return -1;
-
+ if (nfnl_nft_exthdr_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_EXTHDR_DREG, htonl(exthdr->dreg));
+ if (nfnl_nft_exthdr_test_type(expr))
+ NLA_PUT_U8(msg, NFTA_EXTHDR_TYPE, exthdr->type);
+ if (nfnl_nft_exthdr_test_offset(expr))
+ NLA_PUT_U32(msg, NFTA_EXTHDR_OFFSET, htonl(exthdr->offset));
+ if (nfnl_nft_exthdr_test_len(expr))
+ NLA_PUT_U32(msg, NFTA_EXTHDR_LEN, htonl(exthdr->len));
return 0;
+
+nla_put_failure:
+ return -1;
}
static void nft_exthdr_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p)
@@ -109,10 +118,29 @@ int nfnl_nft_exthdr_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_exthdr_attrs[] = {
+ __ADD(EXTHDR_ATTR_DREG, dreg)
+ __ADD(EXTHDR_ATTR_TYPE, type)
+ __ADD(EXTHDR_ATTR_OFFSET, offset)
+ __ADD(EXTHDR_ATTR_LEN, len)
+};
+
+static char *nft_exthdr_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_exthdr_attrs,
+ ARRAY_SIZE(nft_exthdr_attrs));
+}
+
void nfnl_nft_exthdr_set_dreg(struct nfnl_nft_expr *expr,
enum nft_registers reg)
{
nft_exthdr(expr)->dreg = reg;
+ expr->ce_mask |= EXTHDR_ATTR_DREG;
+}
+
+int nfnl_nft_exthdr_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & EXTHDR_ATTR_DREG);
}
enum nft_registers nfnl_nft_exthdr_get_dreg(const struct nfnl_nft_expr *expr)
@@ -123,6 +151,12 @@ enum nft_registers nfnl_nft_exthdr_get_dreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_exthdr_set_type(struct nfnl_nft_expr *expr, uint8_t type)
{
nft_exthdr(expr)->type = type;
+ expr->ce_mask |= EXTHDR_ATTR_TYPE;
+}
+
+int nfnl_nft_exthdr_test_type(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & EXTHDR_ATTR_TYPE);
}
uint8_t nfnl_nft_exthdr_get_type(const struct nfnl_nft_expr *expr)
@@ -133,6 +167,12 @@ uint8_t nfnl_nft_exthdr_get_type(const struct nfnl_nft_expr *expr)
void nfnl_nft_exthdr_set_offset(struct nfnl_nft_expr *expr, unsigned int offset)
{
nft_exthdr(expr)->offset = offset;
+ expr->ce_mask |= EXTHDR_ATTR_OFFSET;
+}
+
+int nfnl_nft_exthdr_test_offset(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & EXTHDR_ATTR_OFFSET);
}
unsigned int nfnl_nft_exthdr_get_offset(const struct nfnl_nft_expr *expr)
@@ -143,6 +183,12 @@ unsigned int nfnl_nft_exthdr_get_offset(const struct nfnl_nft_expr *expr)
void nfnl_nft_exthdr_set_len(struct nfnl_nft_expr *expr, unsigned int len)
{
nft_exthdr(expr)->len = len;
+ expr->ce_mask |= EXTHDR_ATTR_LEN;
+}
+
+int nfnl_nft_exthdr_test_len(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & EXTHDR_ATTR_LEN);
}
unsigned int nfnl_nft_exthdr_get_len(const struct nfnl_nft_expr *expr)
@@ -151,12 +197,13 @@ unsigned int nfnl_nft_exthdr_get_len(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops exthdr_expr_ops = {
- .eo_name = "exthdr",
+ .eo_name = "exthdr",
.eo_dump[NL_DUMP_DETAILS] = nft_exthdr_dump,
- .eo_get_opts = nft_exthdr_get_opts,
- .eo_msg_parser = nft_exthdr_msg_parser,
- .eo_policy = nft_exthdr_policy,
- .eo_maxattr = NFTA_EXTHDR_MAX,
+ .eo_get_opts = nft_exthdr_get_opts,
+ .eo_msg_parser = nft_exthdr_msg_parser,
+ .eo_attrs2str = nft_exthdr_attrs2str,
+ .eo_policy = nft_exthdr_policy,
+ .eo_maxattr = NFTA_EXTHDR_MAX,
};
static void __init nft_exthdr_expr_init(void)
diff --git a/lib/netfilter/nft_immediate_expr.c b/lib/netfilter/nft_immediate_expr.c
index 32e13b3..19339dc 100644
--- a/lib/netfilter/nft_immediate_expr.c
+++ b/lib/netfilter/nft_immediate_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -22,6 +22,11 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define IMMEDIATE_ATTR_DREG (1UL << 0)
+#define IMMEDIATE_ATTR_DATA (1UL << 1)
+/** @endcond */
+
struct nft_immediate_expr {
struct nfnl_nft_data * data;
enum nft_registers dreg;
@@ -64,6 +69,7 @@ static void nft_immediate_free_data(struct nfnl_nft_expr *expr)
static int nft_immediate_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
{
struct nft_immediate_expr *immediate;
+ struct nfnl_nft_data *data;
int err;
immediate = nft_immediate_expr_alloc(expr);
@@ -71,11 +77,12 @@ static int nft_immediate_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *t
return -ENOMEM;
if (tb[NFTA_IMMEDIATE_DREG])
- immediate->dreg = ntohl(nla_get_u32(tb[NFTA_IMMEDIATE_DREG]));
+ nfnl_nft_immediate_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_IMMEDIATE_DREG])));
if (tb[NFTA_IMMEDIATE_DATA]) {
- err = nfnl_nft_data_parse(tb[NFTA_IMMEDIATE_DATA], &immediate->data);
+ err = nfnl_nft_data_parse(tb[NFTA_IMMEDIATE_DATA], &data);
if (err < 0)
goto errout;
+ nfnl_nft_immediate_set_data(expr, data);
}
return 0;
@@ -88,9 +95,15 @@ static int nft_immediate_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr
{
struct nft_immediate_expr *immediate = nft_immediate(expr);
- if (nla_put_u32(msg, NFTA_IMMEDIATE_DREG, htonl(immediate->dreg)) < 0)
- return -1;
- return nfnl_nft_data_put(msg, NFTA_IMMEDIATE_DATA, immediate->data);
+ if (nfnl_nft_immediate_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_IMMEDIATE_DREG, htonl(immediate->dreg));
+ if (nfnl_nft_immediate_test_data(expr) &&
+ nfnl_nft_data_put(msg, NFTA_IMMEDIATE_DATA, immediate->data) < 0)
+ goto nla_put_failure;
+ return 0;
+
+nla_put_failure:
+ return -1;
}
static void nft_immediate_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p)
@@ -109,10 +122,27 @@ int nfnl_nft_immediate_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_immediate_attrs[] = {
+ __ADD(IMMEDIATE_ATTR_DREG, dreg)
+ __ADD(IMMEDIATE_ATTR_DATA, data)
+};
+
+static char *nft_immediate_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_immediate_attrs,
+ ARRAY_SIZE(nft_immediate_attrs));
+}
+
void nfnl_nft_immediate_set_dreg(struct nfnl_nft_expr *expr,
enum nft_registers reg)
{
nft_immediate(expr)->dreg = reg;
+ expr->ce_mask |= IMMEDIATE_ATTR_DREG;
+}
+
+int nfnl_nft_immediate_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & IMMEDIATE_ATTR_DREG);
}
enum nft_registers nfnl_nft_immediate_get_dreg(const struct nfnl_nft_expr *expr)
@@ -124,6 +154,12 @@ void nfnl_nft_immediate_set_data(struct nfnl_nft_expr *expr,
struct nfnl_nft_data *data)
{
nft_immediate(expr)->data = data;
+ expr->ce_mask |= IMMEDIATE_ATTR_DATA;
+}
+
+int nfnl_nft_immediate_test_data(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & IMMEDIATE_ATTR_DATA);
}
struct nfnl_nft_data *nfnl_nft_immediate_get_data(const struct nfnl_nft_expr *expr)
@@ -132,14 +168,15 @@ struct nfnl_nft_data *nfnl_nft_immediate_get_data(const struct nfnl_nft_expr *ex
}
static struct nft_expr_ops immediate_expr_ops = {
- .eo_name = "immediate",
+ .eo_name = "immediate",
.eo_dump[NL_DUMP_DETAILS] = nft_immediate_dump,
- .eo_get_opts = nft_immediate_get_opts,
- .eo_msg_parser = nft_immediate_msg_parser,
- .eo_free_data = nft_immediate_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_immediate_policy,
- .eo_maxattr = NFTA_IMMEDIATE_MAX,
+ .eo_get_opts = nft_immediate_get_opts,
+ .eo_msg_parser = nft_immediate_msg_parser,
+ .eo_free_data = nft_immediate_free_data,
+ .eo_clone = NULL,
+ .eo_attrs2str = nft_immediate_attrs2str,
+ .eo_policy = nft_immediate_policy,
+ .eo_maxattr = NFTA_IMMEDIATE_MAX,
};
static void __init nft_immediate_expr_init(void)
diff --git a/lib/netfilter/nft_limit_expr.c b/lib/netfilter/nft_limit_expr.c
index a9a43b1..cd49d60 100644
--- a/lib/netfilter/nft_limit_expr.c
+++ b/lib/netfilter/nft_limit_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -43,6 +43,11 @@ static uint64_t htonll(uint64_t x)
}
#endif
+/** @cond SKIP */
+#define LIMIT_ATTR_RATE (1UL << 0)
+#define LIMIT_ATTR_DEPTH (1UL << 1)
+/** @endcond */
+
struct nft_limit_expr {
uint64_t rate;
uint64_t depth;
@@ -84,10 +89,9 @@ static int nft_limit_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
return -ENOMEM;
if (tb[NFTA_LIMIT_RATE])
- limit->rate = ntohll(nla_get_u64(tb[NFTA_LIMIT_RATE]));
+ nfnl_nft_limit_set_rate(expr, ntohll(nla_get_u64(tb[NFTA_LIMIT_RATE])));
if (tb[NFTA_LIMIT_DEPTH])
- limit->depth = ntohll(nla_get_u64(tb[NFTA_LIMIT_DEPTH]));
-
+ nfnl_nft_limit_set_depth(expr, ntohll(nla_get_u64(tb[NFTA_LIMIT_DEPTH])));
return 0;
}
@@ -95,18 +99,13 @@ static int nft_limit_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_limit_expr *limit = nft_limit(expr);
-
- if (limit->rate &&
- nla_put_u64(msg, NFTA_LIMIT_RATE, htonll(limit->rate)) < 0)
- goto errout;
-
- if (limit->depth &&
- nla_put_u64(msg, NFTA_LIMIT_DEPTH, htonll(limit->depth)) < 0)
- goto errout;
-
+ if (nfnl_nft_limit_test_rate(expr))
+ NLA_PUT_U64(msg, NFTA_LIMIT_RATE, htonll(limit->rate));
+ if (nfnl_nft_limit_test_depth(expr))
+ NLA_PUT_U64(msg, NFTA_LIMIT_DEPTH, htonll(limit->depth));
return 0;
-errout:
+nla_put_failure:
return -1;
}
@@ -115,9 +114,9 @@ static void nft_limit_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p)
struct nft_limit_expr *limit = nft_limit(expr);
nl_dump(p, "limit");
- if (limit->rate)
+ if (nfnl_nft_limit_test_rate(expr))
nl_dump(p, " rate %llu", (unsigned long long)limit->rate);
- if (limit->depth)
+ if (nfnl_nft_limit_test_depth(expr))
nl_dump(p, " depth %llu", (unsigned long long)limit->depth);
}
@@ -131,9 +130,26 @@ int nfnl_nft_limit_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_limit_attrs[] = {
+ __ADD(LIMIT_ATTR_RATE, rate)
+ __ADD(LIMIT_ATTR_DEPTH, depth)
+};
+
+static char *nft_limit_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_limit_attrs,
+ ARRAY_SIZE(nft_limit_attrs));
+}
+
void nfnl_nft_limit_set_rate(struct nfnl_nft_expr *expr, uint64_t rate)
{
nft_limit(expr)->rate = rate;
+ expr->ce_mask |= LIMIT_ATTR_RATE;
+}
+
+int nfnl_nft_limit_test_rate(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LIMIT_ATTR_RATE);
}
uint64_t nfnl_nft_limit_get_rate(const struct nfnl_nft_expr *expr)
@@ -144,6 +160,12 @@ uint64_t nfnl_nft_limit_get_rate(const struct nfnl_nft_expr *expr)
void nfnl_nft_limit_set_depth(struct nfnl_nft_expr *expr, uint64_t depth)
{
nft_limit(expr)->depth = depth;
+ expr->ce_mask |= LIMIT_ATTR_DEPTH;
+}
+
+int nfnl_nft_limit_test_depth(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LIMIT_ATTR_DEPTH);
}
uint64_t nfnl_nft_limit_get_depth(const struct nfnl_nft_expr *expr)
@@ -152,14 +174,13 @@ uint64_t nfnl_nft_limit_get_depth(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops limit_expr_ops = {
- .eo_name = "limit",
+ .eo_name = "limit",
.eo_dump[NL_DUMP_DETAILS] = nft_limit_dump,
- .eo_get_opts = nft_limit_get_opts,
- .eo_msg_parser = nft_limit_msg_parser,
- .eo_free_data = NULL, //nft_limit_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_limit_policy,
- .eo_maxattr = NFTA_LIMIT_MAX,
+ .eo_get_opts = nft_limit_get_opts,
+ .eo_msg_parser = nft_limit_msg_parser,
+ .eo_attrs2str = nft_limit_attrs2str,
+ .eo_policy = nft_limit_policy,
+ .eo_maxattr = NFTA_LIMIT_MAX,
};
static void __init nft_limit_expr_init(void)
diff --git a/lib/netfilter/nft_log_expr.c b/lib/netfilter/nft_log_expr.c
index 533d8b8..1906118 100644
--- a/lib/netfilter/nft_log_expr.c
+++ b/lib/netfilter/nft_log_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,13 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define LOG_ATTR_PREFIX (1UL << 0)
+#define LOG_ATTR_GROUP (1UL << 1)
+#define LOG_ATTR_SNAPLEN (1UL << 2)
+#define LOG_ATTR_QTHRESHOLD (1UL << 3)
+/** @endcond */
+
struct nft_log_expr {
char *prefix;
unsigned int group;
@@ -73,14 +80,13 @@ static int nft_log_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
return -ENOMEM;
if (tb[NFTA_LOG_PREFIX])
- log->prefix = nla_strdup(tb[NFTA_LOG_PREFIX]);
+ nfnl_nft_log_set_prefix(expr, nla_strdup(tb[NFTA_LOG_PREFIX]));
if (tb[NFTA_LOG_GROUP])
- log->group = ntohl(nla_get_u32(tb[NFTA_LOG_GROUP]));
+ nfnl_nft_log_set_group(expr, ntohl(nla_get_u32(tb[NFTA_LOG_GROUP])));
if (tb[NFTA_LOG_SNAPLEN])
- log->snaplen = ntohl(nla_get_u32(tb[NFTA_LOG_SNAPLEN]));
+ nfnl_nft_log_set_snaplen(expr, ntohl(nla_get_u32(tb[NFTA_LOG_SNAPLEN])));
if (tb[NFTA_LOG_QTHRESHOLD])
- log->qthreshold = ntohl(nla_get_u32(tb[NFTA_LOG_QTHRESHOLD]));
-
+ nfnl_nft_log_set_qthreshold(expr, ntohl(nla_get_u32(tb[NFTA_LOG_QTHRESHOLD])));
return 0;
}
@@ -88,25 +94,17 @@ static int nft_log_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_log_expr *log = nft_log(expr);
- if (log->prefix != NULL &&
- nla_put_string(msg, NFTA_LOG_PREFIX, log->prefix) < 0)
- goto errout;
-
- if (log->group &&
- nla_put_u32(msg, NFTA_LOG_GROUP, htonl(log->group)) < 0)
- goto errout;
-
- if (log->snaplen &&
- nla_put_u32(msg, NFTA_LOG_SNAPLEN, htonl(log->snaplen)) < 0)
- goto errout;
-
- if (log->qthreshold &&
- nla_put_u32(msg, NFTA_LOG_QTHRESHOLD, htonl(log->qthreshold)) < 0)
- goto errout;
-
+ if (nfnl_nft_log_test_prefix(expr))
+ NLA_PUT_STRING(msg, NFTA_LOG_PREFIX, log->prefix);
+ if (nfnl_nft_log_test_group(expr))
+ NLA_PUT_U32(msg, NFTA_LOG_GROUP, htonl(log->group));
+ if (nfnl_nft_log_test_snaplen(expr))
+ NLA_PUT_U32(msg, NFTA_LOG_SNAPLEN, htonl(log->snaplen));
+ if (nfnl_nft_log_test_qthreshold(expr))
+ NLA_PUT_U32(msg, NFTA_LOG_QTHRESHOLD, htonl(log->qthreshold));
return 0;
-errout:
+nla_put_failure:
return -1;
}
@@ -114,13 +112,13 @@ static void nft_log_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p)
{
struct nft_log_expr *log = nft_log(expr);
- if (log->prefix)
+ if (nfnl_nft_log_test_prefix(expr))
nl_dump(p, " prefix '%s'", log->prefix);
- if (log->group)
+ if (nfnl_nft_log_test_group(expr))
nl_dump(p, " group %u", log->group);
- if (log->snaplen)
+ if (nfnl_nft_log_test_snaplen(expr))
nl_dump(p, " snaplen %u", log->snaplen);
- if (log->qthreshold)
+ if (nfnl_nft_log_test_qthreshold(expr))
nl_dump(p, " qthreshold %u", log->qthreshold);
}
@@ -134,9 +132,28 @@ int nfnl_nft_log_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_log_attrs[] = {
+ __ADD(LOG_ATTR_PREFIX, prefix)
+ __ADD(LOG_ATTR_GROUP, group)
+ __ADD(LOG_ATTR_SNAPLEN, snaplen)
+ __ADD(LOG_ATTR_QTHRESHOLD, qthreshold)
+};
+
+static char *nft_log_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_log_attrs,
+ ARRAY_SIZE(nft_log_attrs));
+}
+
void nfnl_nft_log_set_prefix(struct nfnl_nft_expr *expr, const char *prefix)
{
nft_log(expr)->prefix = strdup(prefix);
+ expr->ce_mask |= LOG_ATTR_PREFIX;
+}
+
+int nfnl_nft_log_test_prefix(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOG_ATTR_PREFIX);
}
const char *nfnl_nft_log_get_prefix(const struct nfnl_nft_expr *expr)
@@ -147,6 +164,12 @@ const char *nfnl_nft_log_get_prefix(const struct nfnl_nft_expr *expr)
void nfnl_nft_log_set_group(struct nfnl_nft_expr *expr, uint32_t group)
{
nft_log(expr)->group = group;
+ expr->ce_mask |= LOG_ATTR_GROUP;
+}
+
+int nfnl_nft_log_test_group(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOG_ATTR_GROUP);
}
uint32_t nfnl_nft_log_get_group(const struct nfnl_nft_expr *expr)
@@ -157,6 +180,12 @@ uint32_t nfnl_nft_log_get_group(const struct nfnl_nft_expr *expr)
void nfnl_nft_log_set_snaplen(struct nfnl_nft_expr *expr, uint32_t snaplen)
{
nft_log(expr)->snaplen = snaplen;
+ expr->ce_mask |= LOG_ATTR_SNAPLEN;
+}
+
+int nfnl_nft_log_test_snaplen(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOG_ATTR_SNAPLEN);
}
uint32_t nfnl_nft_log_get_snaplen(const struct nfnl_nft_expr *expr)
@@ -167,6 +196,12 @@ uint32_t nfnl_nft_log_get_snaplen(const struct nfnl_nft_expr *expr)
void nfnl_nft_log_set_qthreshold(struct nfnl_nft_expr *expr, uint32_t qthreshold)
{
nft_log(expr)->qthreshold = qthreshold;
+ expr->ce_mask |= LOG_ATTR_QTHRESHOLD;
+}
+
+int nfnl_nft_log_test_qthreshold(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOG_ATTR_QTHRESHOLD);
}
uint32_t nfnl_nft_log_get_qthreshold(const struct nfnl_nft_expr *expr)
@@ -175,14 +210,15 @@ uint32_t nfnl_nft_log_get_qthreshold(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops log_expr_ops = {
- .eo_name = "log",
+ .eo_name = "log",
.eo_dump[NL_DUMP_DETAILS] = nft_log_dump,
- .eo_get_opts = nft_log_get_opts,
- .eo_msg_parser = nft_log_msg_parser,
- .eo_free_data = nft_log_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_log_policy,
- .eo_maxattr = NFTA_LOG_MAX,
+ .eo_get_opts = nft_log_get_opts,
+ .eo_msg_parser = nft_log_msg_parser,
+ .eo_free_data = nft_log_free_data,
+ .eo_clone = NULL,
+ .eo_attrs2str = nft_log_attrs2str,
+ .eo_policy = nft_log_policy,
+ .eo_maxattr = NFTA_LOG_MAX,
};
static void __init nft_log_expr_init(void)
diff --git a/lib/netfilter/nft_lookup_expr.c b/lib/netfilter/nft_lookup_expr.c
index 45931dd..6e4d507 100644
--- a/lib/netfilter/nft_lookup_expr.c
+++ b/lib/netfilter/nft_lookup_expr.c
@@ -22,6 +22,12 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define LOOKUP_ATTR_SET (1UL << 0)
+#define LOOKUP_ATTR_SREG (1UL << 1)
+#define LOOKUP_ATTR_DREG (1UL << 2)
+/** @endcond */
+
struct nft_lookup_expr {
char *set;
enum nft_registers sreg;
@@ -67,20 +73,23 @@ static void nft_lookup_free_data(struct nfnl_nft_expr *expr)
static int nft_lookup_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
{
struct nft_lookup_expr *lookup;
+ char *set;
lookup = nft_lookup_expr_alloc(expr);
if (lookup == NULL)
goto err1;
if (tb[NFTA_LOOKUP_SET] != NULL) {
- lookup->set = nla_strdup(tb[NFTA_LOOKUP_SET]);
- if (lookup->set == NULL)
+ set = nla_strdup(tb[NFTA_LOOKUP_SET]);
+ if (set == NULL)
goto err2;
+ nfnl_nft_lookup_set_set(expr, set);
+ free(set);
}
if (tb[NFTA_LOOKUP_SREG] != NULL)
- lookup->sreg = ntohl(nla_get_u32(tb[NFTA_LOOKUP_SREG]));
+ nfnl_nft_lookup_set_sreg(expr, ntohl(nla_get_u32(tb[NFTA_LOOKUP_SREG])));
if (tb[NFTA_LOOKUP_DREG] != NULL)
- lookup->dreg = ntohl(nla_get_u32(tb[NFTA_LOOKUP_DREG]));
+ nfnl_nft_lookup_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_LOOKUP_DREG])));
return 0;
@@ -94,17 +103,12 @@ static int nft_lookup_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_lookup_expr *lookup = nft_lookup(expr);
- if (nla_put_u32(msg, NFTA_LOOKUP_SREG, htonl(lookup->sreg)) < 0)
- goto nla_put_failure;
- if (lookup->set != NULL)
+ if (nfnl_nft_lookup_test_sreg(expr))
+ NLA_PUT_U32(msg, NFTA_LOOKUP_SREG, htonl(lookup->sreg));
+ if (nfnl_nft_lookup_test_set(expr))
NLA_PUT_STRING(msg, NFTA_LOOKUP_SET, lookup->set);
-
-#if 0
- if (lookup->flags & NFT_LOOKUP_MAP) {
- if (nla_put_u32(msg, NFTA_LOOKUP_DREG, htonl(lookup->dreg)) < 0)
- goto errout;
- }
-#endif
+ if (nfnl_nft_lookup_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_LOOKUP_DREG, htonl(lookup->dreg));
return 0;
nla_put_failure:
@@ -116,6 +120,8 @@ static void nft_lookup_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p
struct nft_lookup_expr *lookup = nft_lookup(expr);
nl_dump(p, "reg %u set %s", lookup->sreg, lookup->set);
+ if (expr->ce_mask & LOOKUP_ATTR_DREG)
+ nl_dump(p, " dreg %u", lookup->dreg);
}
int nfnl_nft_lookup_init(struct nfnl_nft_expr *expr)
@@ -125,9 +131,27 @@ int nfnl_nft_lookup_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_lookup_attrs[] = {
+ __ADD(LOOKUP_ATTR_SET, set)
+ __ADD(LOOKUP_ATTR_SREG, sreg)
+ __ADD(LOOKUP_ATTR_DREG, dreg)
+};
+
+static char *nft_lookup_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_lookup_attrs,
+ ARRAY_SIZE(nft_lookup_attrs));
+}
+
void nfnl_nft_lookup_set_set(struct nfnl_nft_expr *expr, const char *set)
{
nft_lookup(expr)->set = strdup(set);
+ expr->ce_mask |= LOOKUP_ATTR_SET;
+}
+
+int nfnl_nft_lookup_test_set(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOOKUP_ATTR_SET);
}
const char *nfnl_nft_lookup_get_set(const struct nfnl_nft_expr *expr)
@@ -138,6 +162,12 @@ const char *nfnl_nft_lookup_get_set(const struct nfnl_nft_expr *expr)
void nfnl_nft_lookup_set_sreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_lookup(expr)->sreg = reg;
+ expr->ce_mask |= LOOKUP_ATTR_SREG;
+}
+
+int nfnl_nft_lookup_test_sreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOOKUP_ATTR_SREG);
}
enum nft_registers nfnl_nft_lookup_get_sreg(const struct nfnl_nft_expr *expr)
@@ -148,6 +178,12 @@ enum nft_registers nfnl_nft_lookup_get_sreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_lookup_set_dreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_lookup(expr)->dreg = reg;
+ expr->ce_mask |= LOOKUP_ATTR_DREG;
+}
+
+int nfnl_nft_lookup_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & LOOKUP_ATTR_DREG);
}
enum nft_registers nfnl_nft_lookup_get_dreg(const struct nfnl_nft_expr *expr)
@@ -162,6 +198,7 @@ static struct nft_expr_ops lookup_expr_ops = {
.eo_msg_parser = nft_lookup_msg_parser,
.eo_free_data = nft_lookup_free_data,
.eo_clone = NULL,
+ .eo_attrs2str = nft_lookup_attrs2str,
.eo_policy = nft_lookup_policy,
.eo_maxattr = NFTA_LOOKUP_MAX,
};
diff --git a/lib/netfilter/nft_meta_expr.c b/lib/netfilter/nft_meta_expr.c
index faf17db..9c81503 100644
--- a/lib/netfilter/nft_meta_expr.c
+++ b/lib/netfilter/nft_meta_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,11 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define META_ATTR_DREG (1UL << 0)
+#define META_ATTR_KEY (1UL << 1)
+/** @endcond */
+
struct nft_meta_expr {
enum nft_meta_keys key;
enum nft_registers dreg;
@@ -62,10 +67,9 @@ static int nft_meta_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
return -ENOMEM;
if (tb[NFTA_META_DREG])
- meta->dreg = ntohl(nla_get_u32(tb[NFTA_META_DREG]));
+ nfnl_nft_meta_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_META_DREG])));
if (tb[NFTA_META_KEY])
- meta->key = ntohl(nla_get_u32(tb[NFTA_META_KEY]));
-
+ nfnl_nft_meta_set_key(expr, ntohl(nla_get_u32(tb[NFTA_META_KEY])));
return 0;
}
@@ -73,11 +77,14 @@ static int nft_meta_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_meta_expr *meta = nft_meta(expr);
- if (nla_put_u32(msg, NFTA_META_DREG, htonl(meta->dreg)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_META_KEY, htonl(meta->key)) < 0)
- return -1;
+ if (nfnl_nft_meta_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_META_DREG, htonl(meta->dreg));
+ if (nfnl_nft_meta_test_key(expr))
+ NLA_PUT_U32(msg, NFTA_META_KEY, htonl(meta->key));
return 0;
+
+nla_put_failure:
+ return -1;
}
static struct trans_tbl meta_keys[] = {
@@ -125,9 +132,26 @@ int nfnl_nft_meta_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_meta_attrs[] = {
+ __ADD(META_ATTR_DREG, dreg)
+ __ADD(META_ATTR_KEY, key)
+};
+
+static char *nft_meta_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_meta_attrs,
+ ARRAY_SIZE(nft_meta_attrs));
+}
+
void nfnl_nft_meta_set_dreg(struct nfnl_nft_expr *expr, enum nft_registers reg)
{
nft_meta(expr)->dreg = reg;
+ expr->ce_mask |= META_ATTR_DREG;
+}
+
+int nfnl_nft_meta_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & META_ATTR_DREG);
}
enum nft_registers nfnl_nft_meta_get_dreg(const struct nfnl_nft_expr *expr)
@@ -138,6 +162,12 @@ enum nft_registers nfnl_nft_meta_get_dreg(const struct nfnl_nft_expr *expr)
void nfnl_nft_meta_set_key(struct nfnl_nft_expr *expr, enum nft_meta_keys key)
{
nft_meta(expr)->key = key;
+ expr->ce_mask |= META_ATTR_KEY;
+}
+
+int nfnl_nft_meta_test_key(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & META_ATTR_KEY);
}
enum nft_meta_keys nfnl_nft_meta_get_key(const struct nfnl_nft_expr *expr)
@@ -146,12 +176,13 @@ enum nft_meta_keys nfnl_nft_meta_get_key(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops meta_expr_ops = {
- .eo_name = "meta",
+ .eo_name = "meta",
.eo_dump[NL_DUMP_DETAILS] = nft_meta_dump,
- .eo_get_opts = nft_meta_get_opts,
- .eo_msg_parser = nft_meta_msg_parser,
- .eo_policy = nft_meta_policy,
- .eo_maxattr = NFTA_SET_MAX,
+ .eo_get_opts = nft_meta_get_opts,
+ .eo_msg_parser = nft_meta_msg_parser,
+ .eo_attrs2str = nft_meta_attrs2str,
+ .eo_policy = nft_meta_policy,
+ .eo_maxattr = NFTA_SET_MAX,
};
static void __init nft_meta_expr_init(void)
diff --git a/lib/netfilter/nft_nat_expr.c b/lib/netfilter/nft_nat_expr.c
index bb6a410..8d92d12 100644
--- a/lib/netfilter/nft_nat_expr.c
+++ b/lib/netfilter/nft_nat_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,14 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define NAT_ATTR_TYPE (1UL << 0)
+#define NAT_ATTR_SREG_ADDR_MIN (1UL << 1)
+#define NAT_ATTR_SREG_ADDR_MAX (1UL << 2)
+#define NAT_ATTR_SREG_PROTO_MIN (1UL << 3)
+#define NAT_ATTR_SREG_PROTO_MAX (1UL << 4)
+/** @endcond */
+
struct nft_nat_expr {
enum nft_nat_types type;
enum nft_registers sreg_addr_min;
@@ -68,17 +76,15 @@ static int nft_nat_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[])
return -ENOMEM;
if (tb[NFTA_NAT_TYPE])
- nat->type = ntohl(nla_get_u32(tb[NFTA_NAT_TYPE]));
-
+ nfnl_nft_nat_set_type(expr, ntohl(nla_get_u32(tb[NFTA_NAT_TYPE])));
if (tb[NFTA_NAT_ADDR_MIN])
- nat->sreg_addr_min = ntohl(nla_get_u32(tb[NFTA_NAT_ADDR_MIN]));
+ nfnl_nft_nat_set_sreg_addr_min(expr, ntohl(nla_get_u32(tb[NFTA_NAT_ADDR_MIN])));
if (tb[NFTA_NAT_ADDR_MAX])
- nat->sreg_addr_max = ntohl(nla_get_u32(tb[NFTA_NAT_ADDR_MAX]));
+ nfnl_nft_nat_set_sreg_addr_max(expr, ntohl(nla_get_u32(tb[NFTA_NAT_ADDR_MAX])));
if (tb[NFTA_NAT_PROTO_MIN])
- nat->sreg_proto_min = ntohl(nla_get_u32(tb[NFTA_NAT_PROTO_MIN]));
+ nfnl_nft_nat_set_sreg_proto_min(expr, ntohl(nla_get_u32(tb[NFTA_NAT_PROTO_MIN])));
if (tb[NFTA_NAT_PROTO_MAX])
- nat->sreg_proto_max = ntohl(nla_get_u32(tb[NFTA_NAT_PROTO_MAX]));
-
+ nfnl_nft_nat_set_sreg_proto_max(expr, ntohl(nla_get_u32(tb[NFTA_NAT_PROTO_MAX])));
return 0;
}
@@ -86,23 +92,20 @@ static int nft_nat_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_nat_expr *nat = nft_nat(expr);
- if (nla_put_u32(msg, NFTA_NAT_TYPE, htonl(nat->type)) < 0)
- return -1;
-
- if (nat->sreg_addr_min &&
- nla_put_u32(msg, NFTA_NAT_ADDR_MIN, htonl(nat->sreg_addr_min)) < 0)
- return -1;
- if (nat->sreg_addr_max &&
- nla_put_u32(msg, NFTA_NAT_ADDR_MAX, htonl(nat->sreg_addr_max)) < 0)
- return -1;
- if (nat->sreg_proto_min &&
- nla_put_u32(msg, NFTA_NAT_PROTO_MIN, htonl(nat->sreg_proto_min)) < 0)
- return -1;
- if (nat->sreg_proto_max &&
- nla_put_u32(msg, NFTA_NAT_PROTO_MAX, htonl(nat->sreg_proto_max)) < 0)
- return -1;
-
+ if (nfnl_nft_nat_test_type(expr))
+ NLA_PUT_U32(msg, NFTA_NAT_TYPE, htonl(nat->type));
+ if (nfnl_nft_nat_test_sreg_addr_min(expr))
+ NLA_PUT_U32(msg, NFTA_NAT_ADDR_MIN, htonl(nat->sreg_addr_min));
+ if (nfnl_nft_nat_test_sreg_addr_max(expr))
+ NLA_PUT_U32(msg, NFTA_NAT_ADDR_MAX, htonl(nat->sreg_addr_max));
+ if (nfnl_nft_nat_test_sreg_proto_min(expr))
+ NLA_PUT_U32(msg, NFTA_NAT_PROTO_MIN, htonl(nat->sreg_proto_min));
+ if (nfnl_nft_nat_test_sreg_proto_min(expr))
+ NLA_PUT_U32(msg, NFTA_NAT_PROTO_MAX, htonl(nat->sreg_proto_max));
return 0;
+
+nla_put_failure:
+ return -1;
}
static void nft_nat_dump(struct nfnl_nft_expr *expr, struct nl_dump_params *p)
@@ -134,9 +137,29 @@ int nfnl_nft_nat_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_nat_attrs[] = {
+ __ADD(NAT_ATTR_TYPE, type)
+ __ADD(NAT_ATTR_SREG_ADDR_MIN, sreg_addr_min)
+ __ADD(NAT_ATTR_SREG_ADDR_MAX, sreg_addr_max)
+ __ADD(NAT_ATTR_SREG_PROTO_MIN, sreg_proto_min)
+ __ADD(NAT_ATTR_SREG_PROTO_MAX, sreg_proto_max)
+};
+
+static char *nft_nat_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_nat_attrs,
+ ARRAY_SIZE(nft_nat_attrs));
+}
+
void nfnl_nft_nat_set_type(struct nfnl_nft_expr *expr, enum nft_nat_types type)
{
nft_nat(expr)->type = type;
+ expr->ce_mask |= NAT_ATTR_TYPE;
+}
+
+int nfnl_nft_nat_test_type(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & NAT_ATTR_TYPE);
}
enum nft_nat_types nfnl_nft_nat_get_type(const struct nfnl_nft_expr *expr)
@@ -148,6 +171,12 @@ void nfnl_nft_nat_set_sreg_addr_min(struct nfnl_nft_expr *expr,
enum nft_registers sreg)
{
nft_nat(expr)->sreg_addr_min = sreg;
+ expr->ce_mask |= NAT_ATTR_SREG_ADDR_MIN;
+}
+
+int nfnl_nft_nat_test_sreg_addr_min(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & NAT_ATTR_SREG_ADDR_MIN);
}
enum nft_registers nfnl_nft_nat_get_sreg_addr_min(const struct nfnl_nft_expr *expr)
@@ -159,6 +188,12 @@ void nfnl_nft_nat_set_sreg_addr_max(struct nfnl_nft_expr *expr,
enum nft_registers sreg)
{
nft_nat(expr)->sreg_addr_max = sreg;
+ expr->ce_mask |= NAT_ATTR_SREG_ADDR_MAX;
+}
+
+int nfnl_nft_nat_test_sreg_addr_max(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & NAT_ATTR_SREG_ADDR_MAX);
}
enum nft_registers nfnl_nft_nat_get_sreg_addr_max(const struct nfnl_nft_expr *expr)
@@ -170,6 +205,12 @@ void nfnl_nft_nat_set_sreg_proto_min(struct nfnl_nft_expr *expr,
enum nft_registers sreg)
{
nft_nat(expr)->sreg_proto_min = sreg;
+ expr->ce_mask |= NAT_ATTR_SREG_PROTO_MIN;
+}
+
+int nfnl_nft_nat_test_sreg_proto_min(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & NAT_ATTR_SREG_PROTO_MIN);
}
enum nft_registers nfnl_nft_nat_get_sreg_proto_min(const struct nfnl_nft_expr *expr)
@@ -181,6 +222,12 @@ void nfnl_nft_nat_set_sreg_proto_max(struct nfnl_nft_expr *expr,
enum nft_registers sreg)
{
nft_nat(expr)->sreg_proto_max = sreg;
+ expr->ce_mask |= NAT_ATTR_SREG_PROTO_MAX;
+}
+
+int nfnl_nft_nat_test_sreg_proto_max(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & NAT_ATTR_SREG_PROTO_MAX);
}
enum nft_registers nfnl_nft_nat_get_sreg_proto_max(const struct nfnl_nft_expr *expr)
@@ -189,14 +236,13 @@ enum nft_registers nfnl_nft_nat_get_sreg_proto_max(const struct nfnl_nft_expr *e
}
static struct nft_expr_ops nat_expr_ops = {
- .eo_name = "nat",
+ .eo_name = "nat",
.eo_dump[NL_DUMP_DETAILS] = nft_nat_dump,
- .eo_get_opts = nft_nat_get_opts,
- .eo_msg_parser = nft_nat_msg_parser,
- .eo_free_data = NULL, //nft_nat_free_data,
- .eo_clone = NULL,
- .eo_policy = nft_nat_policy,
- .eo_maxattr = NFTA_NAT_MAX,
+ .eo_get_opts = nft_nat_get_opts,
+ .eo_msg_parser = nft_nat_msg_parser,
+ .eo_attrs2str = nft_nat_attrs2str,
+ .eo_policy = nft_nat_policy,
+ .eo_maxattr = NFTA_NAT_MAX,
};
static void __init nft_nat_expr_init(void)
diff --git a/lib/netfilter/nft_payload_expr.c b/lib/netfilter/nft_payload_expr.c
index 3154ba6..e4c2cd8 100644
--- a/lib/netfilter/nft_payload_expr.c
+++ b/lib/netfilter/nft_payload_expr.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2008 Patrick McHardy <kaber at trash.net>
+ * Copyright (c) 2008-2009 Patrick McHardy <kaber at trash.net>
*
* Development of this code funded by Astaro AG (http://www.astaro.com/)
*/
@@ -21,6 +21,13 @@
#include <netlink/netfilter/nft_expr.h>
#include <netlink/netfilter/nft-expr-modules.h>
+/** @cond SKIP */
+#define PAYLOAD_ATTR_DREG (1UL << 0)
+#define PAYLOAD_ATTR_BASE (1UL << 1)
+#define PAYLOAD_ATTR_OFFSET (1UL << 2)
+#define PAYLOAD_ATTR_LEN (1UL << 3)
+/** @endcond */
+
struct nft_payload_expr {
enum nft_registers dreg;
enum nft_payload_bases base;
@@ -66,14 +73,13 @@ static int nft_payload_msg_parser(struct nfnl_nft_expr *expr, struct nlattr *tb[
return -ENOMEM;
if (tb[NFTA_PAYLOAD_DREG])
- payload->dreg = ntohl(nla_get_u32(tb[NFTA_PAYLOAD_DREG]));
+ nfnl_nft_payload_set_dreg(expr, ntohl(nla_get_u32(tb[NFTA_PAYLOAD_DREG])));
if (tb[NFTA_PAYLOAD_BASE])
- payload->base = ntohl(nla_get_u32(tb[NFTA_PAYLOAD_BASE]));
+ nfnl_nft_payload_set_base(expr, ntohl(nla_get_u32(tb[NFTA_PAYLOAD_BASE])));
if (tb[NFTA_PAYLOAD_OFFSET])
- payload->offset = ntohl(nla_get_u32(tb[NFTA_PAYLOAD_OFFSET]));
+ nfnl_nft_payload_set_offset(expr, ntohl(nla_get_u32(tb[NFTA_PAYLOAD_OFFSET])));
if (tb[NFTA_PAYLOAD_LEN])
- payload->len = ntohl(nla_get_u32(tb[NFTA_PAYLOAD_LEN]));
-
+ nfnl_nft_payload_set_len(expr, ntohl(nla_get_u32(tb[NFTA_PAYLOAD_LEN])));
return 0;
}
@@ -81,16 +87,18 @@ static int nft_payload_get_opts(struct nl_msg *msg, struct nfnl_nft_expr *expr)
{
struct nft_payload_expr *payload = nft_payload(expr);
- if (nla_put_u32(msg, NFTA_PAYLOAD_DREG, htonl(payload->dreg)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_PAYLOAD_BASE, htonl(payload->base)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_PAYLOAD_OFFSET, htonl(payload->offset)) < 0)
- return -1;
- if (nla_put_u32(msg, NFTA_PAYLOAD_LEN, htonl(payload->len)) < 0)
- return -1;
-
+ if (nfnl_nft_payload_test_dreg(expr))
+ NLA_PUT_U32(msg, NFTA_PAYLOAD_DREG, htonl(payload->dreg));
+ if (nfnl_nft_payload_test_base(expr))
+ NLA_PUT_U32(msg, NFTA_PAYLOAD_BASE, htonl(payload->base));
+ if (nfnl_nft_payload_test_offset(expr))
+ NLA_PUT_U32(msg, NFTA_PAYLOAD_OFFSET, htonl(payload->offset));
+ if (nfnl_nft_payload_test_len(expr))
+ NLA_PUT_U32(msg, NFTA_PAYLOAD_LEN, htonl(payload->len));
return 0;
+
+nla_put_failure:
+ return -1;
}
static const char *nft_payload_base_names[] = {
@@ -115,10 +123,29 @@ int nfnl_nft_payload_init(struct nfnl_nft_expr *expr)
return 0;
}
+static struct trans_tbl nft_payload_attrs[] = {
+ __ADD(PAYLOAD_ATTR_DREG, dreg)
+ __ADD(PAYLOAD_ATTR_BASE, base)
+ __ADD(PAYLOAD_ATTR_OFFSET, offset)
+ __ADD(PAYLOAD_ATTR_LEN, len)
+};
+
+static char *nft_payload_attrs2str(int attrs, char *buf, size_t len)
+{
+ return __flags2str(attrs, buf, len, nft_payload_attrs,
+ ARRAY_SIZE(nft_payload_attrs));
+}
+
void nfnl_nft_payload_set_dreg(struct nfnl_nft_expr *expr,
enum nft_registers reg)
{
nft_payload(expr)->dreg = reg;
+ expr->ce_mask |= PAYLOAD_ATTR_DREG;
+}
+
+int nfnl_nft_payload_test_dreg(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & PAYLOAD_ATTR_DREG);
}
enum nft_registers nfnl_nft_payload_get_dreg(const struct nfnl_nft_expr *expr)
@@ -130,6 +157,12 @@ void nfnl_nft_payload_set_base(struct nfnl_nft_expr *expr,
enum nft_payload_bases base)
{
nft_payload(expr)->base = base;
+ expr->ce_mask |= PAYLOAD_ATTR_BASE;
+}
+
+int nfnl_nft_payload_test_base(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & PAYLOAD_ATTR_BASE);
}
enum nft_payload_bases nfnl_nft_payload_get_base(const struct nfnl_nft_expr *expr)
@@ -140,6 +173,12 @@ enum nft_payload_bases nfnl_nft_payload_get_base(const struct nfnl_nft_expr *exp
void nfnl_nft_payload_set_offset(struct nfnl_nft_expr *expr, unsigned int offset)
{
nft_payload(expr)->offset = offset;
+ expr->ce_mask |= PAYLOAD_ATTR_OFFSET;
+}
+
+int nfnl_nft_payload_test_offset(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & PAYLOAD_ATTR_OFFSET);
}
unsigned int nfnl_nft_payload_get_offset(const struct nfnl_nft_expr *expr)
@@ -150,6 +189,12 @@ unsigned int nfnl_nft_payload_get_offset(const struct nfnl_nft_expr *expr)
void nfnl_nft_payload_set_len(struct nfnl_nft_expr *expr, unsigned int len)
{
nft_payload(expr)->len = len;
+ expr->ce_mask |= PAYLOAD_ATTR_LEN;
+}
+
+int nfnl_nft_payload_test_len(const struct nfnl_nft_expr *expr)
+{
+ return !!(expr->ce_mask & PAYLOAD_ATTR_LEN);
}
unsigned int nfnl_nft_payload_get_len(const struct nfnl_nft_expr *expr)
@@ -158,12 +203,13 @@ unsigned int nfnl_nft_payload_get_len(const struct nfnl_nft_expr *expr)
}
static struct nft_expr_ops payload_expr_ops = {
- .eo_name = "payload",
+ .eo_name = "payload",
.eo_dump[NL_DUMP_DETAILS] = nft_payload_dump,
- .eo_get_opts = nft_payload_get_opts,
- .eo_msg_parser = nft_payload_msg_parser,
- .eo_policy = nft_payload_policy,
- .eo_maxattr = NFTA_PAYLOAD_MAX,
+ .eo_get_opts = nft_payload_get_opts,
+ .eo_msg_parser = nft_payload_msg_parser,
+ .eo_attrs2str = nft_payload_attrs2str,
+ .eo_policy = nft_payload_policy,
+ .eo_maxattr = NFTA_PAYLOAD_MAX,
};
static void __init nft_payload_expr_init(void)
More information about the netfilter-cvslog
mailing list