summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c45
-rw-r--r--src/parser_bison.y18
-rw-r--r--src/rule.c2
-rw-r--r--src/scanner.l1
4 files changed, 64 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 46c97606..cb27f7c2 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2851,6 +2851,47 @@ static int flowtable_evaluate(struct eval_ctx *ctx, struct flowtable *ft)
return 0;
}
+/* Convert rule's handle.index into handle.position. */
+static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule)
+{
+ struct table *table;
+ struct chain *chain;
+ uint64_t index = 0;
+ struct rule *r;
+ int ret;
+
+ /* update cache with CMD_LIST so that rules are fetched, too */
+ ret = cache_update(ctx->nf_sock, ctx->cache, CMD_LIST,
+ ctx->msgs, ctx->debug_mask, ctx->octx);
+ if (ret < 0)
+ return ret;
+
+ table = table_lookup(&rule->handle, ctx->cache);
+ if (!table)
+ return cmd_error(ctx, &rule->handle.table.location,
+ "Could not process rule: %s",
+ strerror(ENOENT));
+
+ chain = chain_lookup(table, &rule->handle);
+ if (!chain)
+ return cmd_error(ctx, &rule->handle.chain.location,
+ "Could not process rule: %s",
+ strerror(ENOENT));
+
+ list_for_each_entry(r, &chain->rules, list) {
+ if (++index < rule->handle.index.id)
+ continue;
+ rule->handle.position.id = r->handle.handle.id;
+ rule->handle.position.location = rule->handle.index.location;
+ break;
+ }
+ if (!rule->handle.position.id)
+ return cmd_error(ctx, &rule->handle.index.location,
+ "Could not process rule: %s",
+ strerror(EINVAL));
+ return 0;
+}
+
static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule)
{
struct stmt *stmt, *tstmt = NULL;
@@ -2879,6 +2920,10 @@ static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule)
return -1;
}
+ if (rule->handle.index.id &&
+ rule_translate_index(ctx, rule))
+ return -1;
+
return 0;
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 174150aa..0e3ee84f 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -485,6 +485,7 @@ int nft_lex(void *, void *, void *);
%token SEED "seed"
%token POSITION "position"
+%token INDEX "index"
%token COMMENT "comment"
%token XML "xml"
@@ -512,8 +513,8 @@ int nft_lex(void *, void *, void *);
%type <cmd> base_cmd add_cmd replace_cmd create_cmd insert_cmd delete_cmd get_cmd list_cmd reset_cmd flush_cmd rename_cmd export_cmd monitor_cmd describe_cmd import_cmd
%destructor { cmd_free($$); } base_cmd add_cmd replace_cmd create_cmd insert_cmd delete_cmd get_cmd list_cmd reset_cmd flush_cmd rename_cmd export_cmd monitor_cmd describe_cmd import_cmd
-%type <handle> table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec
-%destructor { handle_free(&$$); } table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec
+%type <handle> table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec index_spec
+%destructor { handle_free(&$$); } table_spec tableid_spec chain_spec chainid_spec flowtable_spec chain_identifier ruleid_spec handle_spec position_spec rule_position ruleset_spec index_spec
%type <handle> set_spec setid_spec set_identifier flowtable_identifier obj_spec objid_spec obj_identifier
%destructor { handle_free(&$$); } set_spec setid_spec set_identifier obj_spec objid_spec obj_identifier
%type <val> family_spec family_spec_explicit chain_policy prio_spec
@@ -1961,6 +1962,14 @@ position_spec : POSITION NUM
}
;
+index_spec : INDEX NUM
+ {
+ memset(&$$, 0, sizeof($$));
+ $$.index.location = @$;
+ $$.index.id = $2 + 1;
+ }
+ ;
+
rule_position : chain_spec
{
$$ = $1;
@@ -1978,6 +1987,11 @@ rule_position : chain_spec
handle_merge(&$1, &$2);
$$ = $1;
}
+ | chain_spec index_spec
+ {
+ handle_merge(&$1, &$2);
+ $$ = $1;
+ }
;
ruleid_spec : chain_spec handle_spec
diff --git a/src/rule.c b/src/rule.c
index a365876d..279b741b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -60,6 +60,8 @@ void handle_merge(struct handle *dst, const struct handle *src)
dst->handle = src->handle;
if (dst->position.id == 0)
dst->position = src->position;
+ if (dst->index.id == 0)
+ dst->index = src->index;
}
static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
diff --git a/src/scanner.l b/src/scanner.l
index bd641345..6a861cf2 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -285,6 +285,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"monitor" { return MONITOR; }
"position" { return POSITION; }
+"index" { return INDEX; }
"comment" { return COMMENT; }
"constant" { return CONSTANT; }