* @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;
const char *set;
uint64_t handle;
uint64_t position;
+ const char *comment;
};
extern void handle_merge(struct handle *dst, const struct handle *src);
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;
}
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);
%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
}
;
-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);
xfree(h->table);
xfree(h->chain);
xfree(h->set);
+ xfree(h->comment);
}
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)
}
if (handle_output > 0)
printf(" # handle %" PRIu64, rule->handle.handle);
- printf("\n");
}
struct scope *scope_init(struct scope *scope, const struct scope *parent)
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");
}
"export" { return EXPORT; }
"position" { return POSITION; }
+"comment" { return COMMENT; }
"constant" { return CONSTANT; }
"interval" { return INTERVAL; }