summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-02-26 01:51:31 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-02-27 17:10:26 +0100
commitb2c827223395682ee231504385f692267d1a3bfb (patch)
tree6489771dd4cd450799c9d59b9ecde6bedbd45df0
parente61e363e5603352322b59f7c09c968392ba1cef6 (diff)
src: add support for rule human-readable comments
This patch adds support for human-readable comments: nft add rule filter input accept comment \"accept all traffic\" Note that comments *always* come at the end of the rule. This uses the new data area that allows you to attach information to the rule via netlink. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/rule.h2
-rw-r--r--src/netlink.c4
-rw-r--r--src/netlink_delinearize.c11
-rw-r--r--src/parser.y18
-rw-r--r--src/rule.c8
-rw-r--r--src/scanner.l1
6 files changed, 40 insertions, 4 deletions
diff --git a/include/rule.h b/include/rule.h
index e06444eb..ecf801fb 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -14,6 +14,7 @@
* @set: set name (sets only)
* @handle: rule handle (rules only)
* @position: rule position (rules only)
+ * @comment: human-readable comment (rules only)
*/
struct handle {
uint32_t family;
@@ -22,6 +23,7 @@ struct handle {
const char *set;
uint64_t handle;
uint64_t position;
+ const char *comment;
};
extern void handle_merge(struct handle *dst, const struct handle *src);
diff --git a/src/netlink.c b/src/netlink.c
index b036dcef..b2bd3c5c 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -120,6 +120,10 @@ struct nft_rule *alloc_nft_rule(const struct handle *h)
nft_rule_attr_set_u64(nlr, NFT_RULE_ATTR_HANDLE, h->handle);
if (h->position)
nft_rule_attr_set_u64(nlr, NFT_RULE_ATTR_POSITION, h->position);
+ if (h->comment) {
+ nft_rule_attr_set_data(nlr, NFT_RULE_ATTR_USERDATA,
+ h->comment, strlen(h->comment) + 1);
+ }
return nlr;
}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 5eec6cfb..ca720913 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -884,9 +884,20 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx,
h.table = xstrdup(nft_rule_attr_get_str(nlr, NFT_RULE_ATTR_TABLE));
h.chain = xstrdup(nft_rule_attr_get_str(nlr, NFT_RULE_ATTR_CHAIN));
h.handle = nft_rule_attr_get_u64(nlr, NFT_RULE_ATTR_HANDLE);
+
if (nft_rule_attr_is_set(nlr, NFT_RULE_ATTR_POSITION))
h.position = nft_rule_attr_get_u64(nlr, NFT_RULE_ATTR_POSITION);
+ if (nft_rule_attr_is_set(nlr, NFT_RULE_ATTR_USERDATA)) {
+ uint32_t len;
+ const void *data;
+
+ data = nft_rule_attr_get_data(nlr, NFT_RULE_ATTR_USERDATA,
+ &len);
+ h.comment = xmalloc(len);
+ memcpy((char *)h.comment, data, len);
+ }
+
pctx->rule = rule_alloc(&netlink_location, &h);
pctx->table = table_lookup(&h);
assert(pctx->table != NULL);
diff --git a/src/parser.y b/src/parser.y
index b3acc748..dd09fb44 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -351,12 +351,13 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token OPTIONS "options"
%token POSITION "position"
+%token COMMENT "comment"
%token XML "xml"
%token JSON "json"
-%type <string> identifier string
-%destructor { xfree($$); } identifier string
+%type <string> identifier string comment_spec
+%destructor { xfree($$); } identifier string comment_spec
%type <cmd> line
%destructor { cmd_free($$); } line
@@ -1020,11 +1021,22 @@ ruleid_spec : chain_spec handle_spec position_spec
}
;
-rule : stmt_list
+comment_spec : /* empty */
+ {
+ $$ = NULL;
+ }
+ | COMMENT string
+ {
+ $$ = $2;
+ }
+ ;
+
+rule : stmt_list comment_spec
{
struct stmt *i;
$$ = rule_alloc(&@$, NULL);
+ $$->handle.comment = $2;
list_for_each_entry(i, $1, list)
$$->num_stmts++;
list_splice_tail($1, &$$->stmts);
diff --git a/src/rule.c b/src/rule.c
index ab96e62e..0e04282e 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -31,6 +31,7 @@ void handle_free(struct handle *h)
xfree(h->table);
xfree(h->chain);
xfree(h->set);
+ xfree(h->comment);
}
void handle_merge(struct handle *dst, const struct handle *src)
@@ -47,6 +48,8 @@ void handle_merge(struct handle *dst, const struct handle *src)
dst->handle = src->handle;
if (dst->position == 0)
dst->position = src->position;
+ if (dst->comment == NULL && src->comment != NULL)
+ dst->comment = xstrdup(src->comment);
}
struct set *set_alloc(const struct location *loc)
@@ -154,7 +157,6 @@ void rule_print(const struct rule *rule)
}
if (handle_output > 0)
printf(" # handle %" PRIu64, rule->handle.handle);
- printf("\n");
}
struct scope *scope_init(struct scope *scope, const struct scope *parent)
@@ -351,6 +353,10 @@ static void chain_print(const struct chain *chain)
list_for_each_entry(rule, &chain->rules, list) {
printf("\t\t");
rule_print(rule);
+ if (rule->handle.comment)
+ printf(" comment \"%s\"\n", rule->handle.comment);
+ else
+ printf("\n");
}
printf("\t}\n");
}
diff --git a/src/scanner.l b/src/scanner.l
index 45c64763..47c5933c 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -258,6 +258,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"export" { return EXPORT; }
"position" { return POSITION; }
+"comment" { return COMMENT; }
"constant" { return CONSTANT; }
"interval" { return INTERVAL; }