@@ -4,6 +4,7 @@
#include <stdint.h>
#include <nftables.h>
#include <list.h>
+#include <libnftnl/attr.h>
/**
* struct handle - handle for tables, chains, rules and sets
@@ -155,7 +156,7 @@ extern void chain_print_plain(const struct chain *chain);
* @location: location the rule was defined at
* @stmt: list of statements
* @num_stmts: number of statements in stmts list
- * @comment: comment
+ * @udata: user data
*/
struct rule {
struct list_head list;
@@ -163,9 +164,11 @@ struct rule {
struct location location;
struct list_head stmts;
unsigned int num_stmts;
- const char *comment;
+ struct nftnl_attrbuf *udata;
};
+#define RULE_UDATA_MAX_LEN 256
+
extern struct rule *rule_alloc(const struct location *loc,
const struct handle *h);
extern void rule_free(struct rule *rule);
@@ -25,6 +25,7 @@
#include <utils.h>
#include <erec.h>
#include <sys/socket.h>
+#include <libnftnl/attr.h>
struct netlink_parse_ctx {
struct list_head *msgs;
@@ -1738,8 +1739,10 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx,
uint32_t len;
data = nftnl_rule_get_data(nlr, NFTNL_RULE_USERDATA, &len);
- pctx->rule->comment = xmalloc(len);
- memcpy((char *)pctx->rule->comment, data, len);
+ pctx->rule->udata = nftnl_attrbuf_alloc(len);
+ if (!pctx->rule->udata)
+ memory_allocation_error();
+ nftnl_attrbuf_copy_data(pctx->rule->udata, data, len);
}
nftnl_expr_foreach((struct nftnl_rule *)nlr, netlink_parse_expr, pctx);
@@ -21,6 +21,7 @@
#include <netinet/in.h>
#include <linux/netfilter.h>
+#include <libnftnl/attr.h>
struct netlink_linearize_ctx {
@@ -1108,9 +1109,10 @@ void netlink_linearize_rule(struct netlink_ctx *ctx, struct nftnl_rule *nlr,
list_for_each_entry(stmt, &rule->stmts, list)
netlink_gen_stmt(&lctx, stmt);
- if (rule->comment)
+ if (rule->udata)
nftnl_rule_set_data(nlr, NFTNL_RULE_USERDATA,
- rule->comment, strlen(rule->comment) + 1);
+ nftnl_attrbuf_get_data(rule->udata),
+ nftnl_attrbuf_get_len(rule->udata));
netlink_dump_rule(nlr);
}
@@ -24,6 +24,7 @@
#include <netinet/icmp6.h>
#include <libnftnl/common.h>
#include <libnftnl/set.h>
+#include <libnftnl/attr.h>
#include <rule.h>
#include <statement.h>
@@ -1304,7 +1305,21 @@ rule : stmt_list comment_spec
struct stmt *i;
$$ = rule_alloc(&@$, NULL);
- $$->comment = $2;
+
+ if ($2) {
+ if (!($$->udata = nftnl_attrbuf_alloc(RULE_UDATA_MAX_LEN)))
+ memory_allocation_error();
+
+ if (!(nftnl_attr_put_check($$->udata,
+ NFTNL_ATTR_TYPE_COMMENT,
+ strlen($2) + 1, $2))
+ ) {
+ erec_queue(error(&@2, "Comment too long: \"%s\"", $2),
+ state->msgs);
+ YYERROR;
+ }
+ }
+
list_for_each_entry(i, $1, list)
$$->num_stmts++;
list_splice_tail($1, &$$->stmts);
@@ -23,6 +23,7 @@
#include <libnftnl/common.h>
#include <libnftnl/ruleset.h>
+#include <libnftnl/attr.h>
#include <netinet/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter_arp.h>
@@ -366,6 +367,7 @@ struct rule *rule_alloc(const struct location *loc, const struct handle *h)
rule->location = *loc;
init_list_head(&rule->list);
init_list_head(&rule->stmts);
+ rule->udata = NULL;
if (h != NULL)
rule->handle = *h;
return rule;
@@ -375,21 +377,41 @@ void rule_free(struct rule *rule)
{
stmt_list_free(&rule->stmts);
handle_free(&rule->handle);
- xfree(rule->comment);
+ nftnl_attrbuf_free(rule->udata);
xfree(rule);
}
+static int rule_parse_userdata_cb(const struct nftnl_attr *attr,
+ void *data)
+{
+ const struct nftnl_attr **tb = data;
+ uint8_t type = nftnl_attr_get_type(attr);
+
+ tb[type] = attr;
+ return NFTNL_CB_OK;
+}
+
+
void rule_print(const struct rule *rule)
{
const struct stmt *stmt;
+ const struct nftnl_attr *tb[NFTNL_ATTR_TYPE_MAX+1] = {};
+ const struct nftnl_attr *attr;
list_for_each_entry(stmt, &rule->stmts, list) {
stmt->ops->print(stmt);
printf(" ");
}
- if (rule->comment)
- printf("comment \"%s\" ", rule->comment);
+ if (rule->udata) {
+ if (nftnl_attr_parse(rule->udata, rule_parse_userdata_cb, tb)
+ != NFTNL_CB_ERROR
+ ) {
+ attr = tb[NFTNL_ATTR_TYPE_COMMENT];
+ printf("comment \"%s\" ",
+ (char *)nftnl_attr_get_value(attr));
+ }
+ }
if (handle_output > 0)
printf("# handle %" PRIu64, rule->handle.handle);
Now it is possible to store multiple variable length user data into rule. Modify the parser in order to fill the nftnl_attrbuf with the comment, and the print function for extract these commentary and print it to user. Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net> --- include/rule.h | 7 +++++-- src/netlink_delinearize.c | 7 +++++-- src/netlink_linearize.c | 6 ++++-- src/parser_bison.y | 17 ++++++++++++++++- src/rule.c | 28 +++++++++++++++++++++++++--- 5 files changed, 55 insertions(+), 10 deletions(-)