summaryrefslogtreecommitdiffstats
path: root/src/ct.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2016-01-04 20:53:43 +0100
committerFlorian Westphal <fw@strlen.de>2016-01-04 20:53:43 +0100
commit7ad9e1f8ad4ba637be841d0573bdfdcf397f0815 (patch)
tree1c700561baa465690fb3eb41e1abeab9ac13367d /src/ct.c
parentb99ec85e32947e337681aef8a29eae1c4c10f14e (diff)
ct: add support for directional keys
A few keys in the ct expression are directional, i.e. we need to tell kernel if it should fetch REPLY or ORIGINAL direction. Split ct_keys into ct_keys & ct_keys_dir, the latter are those keys that the kernel rejects unless also given a direction. During postprocessing we also need to invoke ct_expr_update_type, problem is that e.g. ct saddr can be any family (ip, ipv6) so we need to update the expected data type based on the network base. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/ct.c')
-rw-r--r--src/ct.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/ct.c b/src/ct.c
index aa801388..07e7077b 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -207,17 +207,34 @@ static const struct ct_template ct_templates[] = {
static void ct_expr_print(const struct expr *expr)
{
+ const struct symbolic_constant *s;
+
printf("ct %s", ct_templates[expr->ct.key].token);
+
+ if (expr->ct.direction < 0)
+ return;
+
+ for (s = ct_dir_tbl.symbols; s->identifier != NULL; s++) {
+ if (expr->ct.direction == (int) s->value) {
+ printf(" %s", s->identifier);
+ return;
+ }
+ }
+
+ printf(" %d", expr->ct.direction);
}
static bool ct_expr_cmp(const struct expr *e1, const struct expr *e2)
{
- return e1->ct.key == e2->ct.key;
+ if (e1->ct.key != e2->ct.key)
+ return false;
+
+ return e1->ct.direction == e2->ct.direction;
}
static void ct_expr_clone(struct expr *new, const struct expr *expr)
{
- new->ct.key = expr->ct.key;
+ new->ct = expr->ct;
}
static void ct_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
@@ -249,7 +266,23 @@ static const struct expr_ops ct_expr_ops = {
.pctx_update = ct_expr_pctx_update,
};
-struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
+struct error_record *ct_dir_parse(const struct location *loc, const char *str,
+ int8_t *direction)
+{
+ const struct symbolic_constant *s;
+
+ for (s = ct_dir_tbl.symbols; s->identifier != NULL; s++) {
+ if (!strcmp(str, s->identifier)) {
+ *direction = s->value;
+ return NULL;
+ }
+ }
+
+ return error(loc, "Could not parse direction %s", str);
+}
+
+struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key,
+ int8_t direction)
{
const struct ct_template *tmpl = &ct_templates[key];
struct expr *expr;
@@ -257,6 +290,7 @@ struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
expr = expr_alloc(loc, &ct_expr_ops, tmpl->dtype,
tmpl->byteorder, tmpl->len);
expr->ct.key = key;
+ expr->ct.direction = direction;
switch (key) {
case NFT_CT_PROTOCOL: