summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-03-31 04:14:26 +0200
committerPatrick McHardy <kaber@trash.net>2009-03-31 04:14:26 +0200
commit53fc2c7a799877c5859298bd16b578711af9cca2 (patch)
tree6fdfd8a4650fcc3a7164a93f9d05003511595005
parent9fe2e9d494a229a3f833add44d7242abe46aa156 (diff)
netlink: move data related functions to netlink.c
Move the data related function to netlink.c as they're going to be needed outside of rule context for set maintenance. Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/netlink.h11
-rw-r--r--src/netlink.c113
-rw-r--r--src/netlink_delinearize.c40
-rw-r--r--src/netlink_linearize.c81
4 files changed, 128 insertions, 117 deletions
diff --git a/include/netlink.h b/include/netlink.h
index cec5247b..ec9a6142 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -30,6 +30,17 @@ extern struct nfnl_nft_rule *alloc_nft_rule(const struct handle *h);
extern struct nfnl_nft_expr *alloc_nft_expr(int (*init)(struct nfnl_nft_expr *));
extern struct nfnl_nft_data *alloc_nft_data(const void *data, unsigned int len);
+extern struct nfnl_nft_data *netlink_gen_data(const struct expr *expr);
+extern struct nfnl_nft_data *netlink_gen_raw_data(const mpz_t value,
+ enum byteorder byteorder,
+ unsigned int len);
+
+extern struct expr *netlink_alloc_value(const struct location *loc,
+ const struct nfnl_nft_data *nld);
+extern struct expr *netlink_alloc_data(const struct location *loc,
+ const struct nfnl_nft_data *nld,
+ enum nft_registers dreg);
+
extern int netlink_linearize_rule(struct netlink_ctx *ctx,
struct nfnl_nft_rule *nlr,
const struct rule *rule);
diff --git a/src/netlink.c b/src/netlink.c
index 548f4fb8..8ef14011 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -20,6 +20,7 @@
#include <nftables.h>
#include <netlink.h>
#include <expression.h>
+#include <gmputil.h>
#include <utils.h>
#include <erec.h>
@@ -133,6 +134,118 @@ struct nfnl_nft_data *alloc_nft_data(const void *data, unsigned int len)
return nld;
}
+struct nfnl_nft_data *netlink_gen_raw_data(const mpz_t value,
+ enum byteorder byteorder,
+ unsigned int len)
+{
+ unsigned char data[len];
+
+ mpz_export_data(data, value, byteorder, len);
+ return alloc_nft_data(data, len);
+}
+
+static struct nfnl_nft_data *netlink_gen_concat_data(const struct expr *expr)
+{
+ const struct expr *i;
+ unsigned int len, offset;
+
+ len = 0;
+ list_for_each_entry(i, &expr->expressions, list)
+ len += i->len;
+
+ if (1) {
+ unsigned char data[len / BITS_PER_BYTE];
+
+ offset = 0;
+ list_for_each_entry(i, &expr->expressions, list) {
+ assert(i->ops->type == EXPR_VALUE);
+ mpz_export_data(data + offset, i->value, i->byteorder,
+ i->len / BITS_PER_BYTE);
+ offset += i->len / BITS_PER_BYTE;
+ }
+
+ return alloc_nft_data(data, len / BITS_PER_BYTE);
+ }
+}
+
+static struct nfnl_nft_data *netlink_gen_constant_data(const struct expr *expr)
+{
+ assert(expr->ops->type == EXPR_VALUE);
+ return netlink_gen_raw_data(expr->value, expr->byteorder,
+ div_round_up(expr->len, BITS_PER_BYTE));
+}
+
+static struct nfnl_nft_data *netlink_gen_verdict(const struct expr *expr)
+{
+ struct nfnl_nft_data *verdict;
+
+ verdict = nfnl_nft_verdict_alloc();
+ nfnl_nft_verdict_set_verdict(verdict, expr->verdict);
+
+ switch (expr->verdict) {
+ case NFT_JUMP:
+ case NFT_GOTO:
+ nfnl_nft_verdict_set_chain(verdict, expr->chain);
+ break;
+ }
+
+ return verdict;
+}
+
+struct nfnl_nft_data *netlink_gen_data(const struct expr *expr)
+{
+ switch (expr->ops->type) {
+ case EXPR_VALUE:
+ return netlink_gen_constant_data(expr);
+ case EXPR_CONCAT:
+ return netlink_gen_concat_data(expr);
+ case EXPR_VERDICT:
+ return netlink_gen_verdict(expr);
+ default:
+ BUG();
+ }
+}
+
+struct expr *netlink_alloc_value(const struct location *loc,
+ const struct nfnl_nft_data *nld)
+{
+ return constant_expr_alloc(loc, &invalid_type, BYTEORDER_INVALID,
+ nfnl_nft_data_get_size(nld) * BITS_PER_BYTE,
+ nfnl_nft_data_get(nld));
+}
+
+static struct expr *netlink_alloc_verdict(const struct location *loc,
+ const struct nfnl_nft_data *nld)
+{
+ unsigned int code;
+ char *chain;
+
+ code = nfnl_nft_verdict_get_verdict(nld);
+ switch (code) {
+ case NFT_JUMP:
+ case NFT_GOTO:
+ chain = xstrdup(nfnl_nft_verdict_get_chain(nld));
+ break;
+ default:
+ chain = NULL;
+ break;
+ }
+
+ return verdict_expr_alloc(loc, code, chain);
+}
+
+struct expr *netlink_alloc_data(const struct location *loc,
+ const struct nfnl_nft_data *nld,
+ enum nft_registers dreg)
+{
+ switch (dreg) {
+ case NFT_REG_VERDICT:
+ return netlink_alloc_verdict(loc, nld);
+ default:
+ return netlink_alloc_value(loc, nld);
+ }
+}
+
int netlink_add_rule(struct netlink_ctx *ctx, const struct handle *h,
const struct rule *rule)
{
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index be2271ce..4b559399 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -66,46 +66,6 @@ static struct expr *netlink_get_register(struct netlink_parse_ctx *ctx,
return expr;
}
-static struct expr *netlink_alloc_value(const struct location *loc,
- const struct nfnl_nft_data *nld)
-{
- return constant_expr_alloc(loc, &invalid_type, BYTEORDER_INVALID,
- nfnl_nft_data_get_size(nld) * BITS_PER_BYTE,
- nfnl_nft_data_get(nld));
-}
-
-static struct expr *netlink_alloc_verdict(const struct location *loc,
- const struct nfnl_nft_data *nld)
-{
- unsigned int code;
- char *chain;
-
- code = nfnl_nft_verdict_get_verdict(nld);
- switch (code) {
- case NFT_JUMP:
- case NFT_GOTO:
- chain = xstrdup(nfnl_nft_verdict_get_chain(nld));
- break;
- default:
- chain = NULL;
- break;
- }
-
- return verdict_expr_alloc(loc, code, chain);
-}
-
-static struct expr *netlink_alloc_data(const struct location *loc,
- const struct nfnl_nft_data *nld,
- enum nft_registers dreg)
-{
- switch (dreg) {
- case NFT_REG_VERDICT:
- return netlink_alloc_verdict(loc, nld);
- default:
- return netlink_alloc_value(loc, nld);
- }
-}
-
static void netlink_parse_immediate(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nfnl_nft_expr *nle)
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0b3f8194..65e4b69b 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -34,79 +34,6 @@ static void release_register(struct netlink_linearize_ctx *ctx)
ctx->reg_low--;
}
-static struct nfnl_nft_data *netlink_gen_mpz_data(const mpz_t value,
- enum byteorder byteorder,
- unsigned int len)
-{
- unsigned char data[len];
-
- mpz_export_data(data, value, byteorder, len);
- return alloc_nft_data(data, len);
-}
-
-static struct nfnl_nft_data *netlink_gen_constant_data(const struct expr *expr)
-{
- assert(expr->ops->type == EXPR_VALUE);
- return netlink_gen_mpz_data(expr->value, expr->byteorder,
- div_round_up(expr->len, BITS_PER_BYTE));
-}
-
-static struct nfnl_nft_data *netlink_gen_concat_data(const struct expr *expr)
-{
- struct nfnl_nft_data *data;
- const struct expr *i;
- void *buf;
- unsigned int len, offset;
-
- len = 0;
- list_for_each_entry(i, &expr->expressions, list)
- len += i->len;
-
- buf = xmalloc(len / BITS_PER_BYTE);
-
- offset = 0;
- list_for_each_entry(i, &expr->expressions, list) {
- assert(i->ops->type == EXPR_VALUE);
- mpz_export_data(buf + offset, i->value, i->byteorder,
- i->len / BITS_PER_BYTE);
- offset += i->len / BITS_PER_BYTE;
- }
-
- data = alloc_nft_data(buf, len / BITS_PER_BYTE);
- xfree(buf);
- return data;
-}
-
-static struct nfnl_nft_data *netlink_gen_verdict(const struct expr *expr)
-{
- struct nfnl_nft_data *verdict;
-
- verdict = nfnl_nft_verdict_alloc();
- nfnl_nft_verdict_set_verdict(verdict, expr->verdict);
-
- switch (expr->verdict) {
- case NFT_JUMP:
- case NFT_GOTO:
- nfnl_nft_verdict_set_chain(verdict, expr->chain);
- }
-
- return verdict;
-}
-
-static struct nfnl_nft_data *netlink_gen_data(const struct expr *expr)
-{
- switch (expr->ops->type) {
- case EXPR_VALUE:
- return netlink_gen_constant_data(expr);
- case EXPR_CONCAT:
- return netlink_gen_concat_data(expr);
- case EXPR_VERDICT:
- return netlink_gen_verdict(expr);
- default:
- BUG();
- }
-}
-
static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg);
@@ -361,7 +288,7 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
mpz_init_set_ui(zero, 0);
nle = alloc_nft_expr(nfnl_nft_bitwise_init);
- nld = netlink_gen_mpz_data(zero, expr->right->byteorder, len);
+ nld = netlink_gen_raw_data(zero, expr->right->byteorder, len);
nfnl_nft_bitwise_set_sreg(nle, sreg);
nfnl_nft_bitwise_set_dreg(nle, sreg);
nfnl_nft_bitwise_set_len(nle, len);
@@ -370,7 +297,7 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
nfnl_nft_rule_add_expr(ctx->nlr, nle);
nle = alloc_nft_expr(nfnl_nft_cmp_init);
- nld = netlink_gen_mpz_data(zero, expr->right->byteorder, len);
+ nld = netlink_gen_raw_data(zero, expr->right->byteorder, len);
nfnl_nft_cmp_set_sreg(nle, sreg);
nfnl_nft_cmp_set_op(nle, NFT_CMP_NEQ);
nfnl_nft_cmp_set_data(nle, nld);
@@ -467,10 +394,10 @@ static void netlink_gen_binop(struct netlink_linearize_ctx *ctx,
nfnl_nft_bitwise_set_dreg(nle, dreg);
nfnl_nft_bitwise_set_len(nle, len);
- nld = netlink_gen_mpz_data(mask, expr->byteorder, len);
+ nld = netlink_gen_raw_data(mask, expr->byteorder, len);
nfnl_nft_bitwise_set_mask(nle, nld);
- nld = netlink_gen_mpz_data(xor, expr->byteorder, len);
+ nld = netlink_gen_raw_data(xor, expr->byteorder, len);
nfnl_nft_bitwise_set_xor(nle, nld);
mpz_clear(tmp);