From b2c827223395682ee231504385f692267d1a3bfb Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 26 Feb 2014 01:51:31 +0100 Subject: 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 --- include/rule.h | 2 ++ src/netlink.c | 4 ++++ src/netlink_delinearize.c | 11 +++++++++++ src/parser.y | 18 +++++++++++++++--- src/rule.c | 8 +++++++- src/scanner.l | 1 + 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 identifier string -%destructor { xfree($$); } identifier string +%type identifier string comment_spec +%destructor { xfree($$); } identifier string comment_spec %type 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; } -- cgit v1.2.3