19 #include <libmnl/libmnl.h>
20 #include <libnftnl/ruleset.h>
21 #include <libnftnl/table.h>
22 #include <libnftnl/chain.h>
23 #include <libnftnl/set.h>
24 #include <libnftnl/rule.h>
36 enum nftnl_cmd_type cmd;
37 enum nftnl_ruleset_type type;
42 struct nftnl_set *set;
43 struct nftnl_set_elem *set_elem;
65 EXPORT_SYMBOL(nftnl_ruleset_alloc, nft_ruleset_alloc);
69 if (r->flags & (1 << NFTNL_RULESET_TABLELIST))
70 nftnl_table_list_free(r->table_list);
71 if (r->flags & (1 << NFTNL_RULESET_CHAINLIST))
72 nftnl_chain_list_free(r->chain_list);
73 if (r->flags & (1 << NFTNL_RULESET_SETLIST))
74 nftnl_set_list_free(r->set_list);
75 if (r->flags & (1 << NFTNL_RULESET_RULELIST))
76 nftnl_rule_list_free(r->rule_list);
79 EXPORT_SYMBOL(nftnl_ruleset_free, nft_ruleset_free);
81 bool nftnl_ruleset_is_set(
const struct nftnl_ruleset *r, uint16_t attr)
83 return r->flags & (1 << attr);
85 EXPORT_SYMBOL(nftnl_ruleset_is_set, nft_ruleset_attr_is_set);
87 void nftnl_ruleset_unset(
struct nftnl_ruleset *r, uint16_t attr)
89 if (!(r->flags & (1 << attr)))
93 case NFTNL_RULESET_TABLELIST:
94 nftnl_table_list_free(r->table_list);
97 case NFTNL_RULESET_CHAINLIST:
98 nftnl_chain_list_free(r->chain_list);
101 case NFTNL_RULESET_SETLIST:
102 nftnl_set_list_free(r->set_list);
105 case NFTNL_RULESET_RULELIST:
106 nftnl_rule_list_free(r->rule_list);
110 r->flags &= ~(1 << attr);
112 EXPORT_SYMBOL(nftnl_ruleset_unset, nft_ruleset_attr_unset);
114 void nftnl_ruleset_set(
struct nftnl_ruleset *r, uint16_t attr,
void *data)
117 case NFTNL_RULESET_TABLELIST:
118 nftnl_ruleset_unset(r, NFTNL_RULESET_TABLELIST);
119 r->table_list = data;
121 case NFTNL_RULESET_CHAINLIST:
122 nftnl_ruleset_unset(r, NFTNL_RULESET_CHAINLIST);
123 r->chain_list = data;
125 case NFTNL_RULESET_SETLIST:
126 nftnl_ruleset_unset(r, NFTNL_RULESET_SETLIST);
129 case NFTNL_RULESET_RULELIST:
130 nftnl_ruleset_unset(r, NFTNL_RULESET_RULELIST);
136 r->flags |= (1 << attr);
138 EXPORT_SYMBOL(nftnl_ruleset_set, nft_ruleset_attr_set);
140 void *nftnl_ruleset_get(
const struct nftnl_ruleset *r, uint16_t attr)
142 if (!(r->flags & (1 << attr)))
146 case NFTNL_RULESET_TABLELIST:
147 return r->table_list;
148 case NFTNL_RULESET_CHAINLIST:
149 return r->chain_list;
150 case NFTNL_RULESET_SETLIST:
152 case NFTNL_RULESET_RULELIST:
158 EXPORT_SYMBOL(nftnl_ruleset_get, nft_ruleset_attr_get);
163 case NFTNL_RULESET_TABLE:
164 nftnl_table_free(ctx->table);
166 case NFTNL_RULESET_CHAIN:
167 nftnl_chain_free(ctx->chain);
169 case NFTNL_RULESET_RULE:
170 nftnl_rule_free(ctx->rule);
172 case NFTNL_RULESET_SET:
173 case NFTNL_RULESET_SET_ELEMS:
174 nftnl_set_free(ctx->set);
176 case NFTNL_RULESET_RULESET:
177 case NFTNL_RULESET_UNSPEC:
181 EXPORT_SYMBOL(nftnl_ruleset_ctx_free, nft_ruleset_ctx_free);
183 bool nftnl_ruleset_ctx_is_set(
const struct nftnl_parse_ctx *ctx, uint16_t attr)
185 return ctx->flags & (1 << attr);
187 EXPORT_SYMBOL(nftnl_ruleset_ctx_is_set, nft_ruleset_ctx_is_set);
189 void *nftnl_ruleset_ctx_get(
const struct nftnl_parse_ctx *ctx, uint16_t attr)
191 if (!(ctx->flags & (1 << attr)))
195 case NFTNL_RULESET_CTX_CMD:
196 return (
void *)&ctx->cmd;
197 case NFTNL_RULESET_CTX_TYPE:
198 return (
void *)&ctx->type;
199 case NFTNL_RULESET_CTX_TABLE:
201 case NFTNL_RULESET_CTX_CHAIN:
203 case NFTNL_RULESET_CTX_RULE:
205 case NFTNL_RULESET_CTX_SET:
207 case NFTNL_RULESET_CTX_DATA:
213 EXPORT_SYMBOL(nftnl_ruleset_ctx_get, nft_ruleset_ctx_get);
215 uint32_t nftnl_ruleset_ctx_get_u32(
const struct nftnl_parse_ctx *ctx, uint16_t attr)
217 const void *ret = nftnl_ruleset_ctx_get(ctx, attr);
218 return ret == NULL ? 0 : *((uint32_t *)ret);
220 EXPORT_SYMBOL(nftnl_ruleset_ctx_get_u32, nft_ruleset_ctx_get_u32);
222 #if defined(JSON_PARSING) || defined(XML_PARSING)
223 static void nftnl_ruleset_ctx_set(
struct nftnl_parse_ctx *ctx, uint16_t attr,
227 case NFTNL_RULESET_CTX_CMD:
228 ctx->cmd = *((uint32_t *)data);
230 case NFTNL_RULESET_CTX_TYPE:
231 ctx->type = *((uint32_t *)data);
233 case NFTNL_RULESET_CTX_TABLE:
236 case NFTNL_RULESET_CTX_CHAIN:
239 case NFTNL_RULESET_CTX_RULE:
242 case NFTNL_RULESET_CTX_SET:
245 case NFTNL_RULESET_CTX_DATA:
249 ctx->flags |= (1 << attr);
252 static void nftnl_ruleset_ctx_set_u32(
struct nftnl_parse_ctx *ctx, uint16_t attr,
255 nftnl_ruleset_ctx_set(ctx, attr, &val);
259 struct nftnl_parse_err *err)
263 table = nftnl_table_alloc();
267 switch (ctx->format) {
268 case NFTNL_OUTPUT_JSON:
270 if (nftnl_jansson_parse_table(table, ctx->json, err) < 0)
274 case NFTNL_OUTPUT_XML:
276 if (nftnl_mxml_table_parse(ctx->xml, table, err) < 0)
285 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE, NFTNL_RULESET_TABLE);
286 nftnl_ruleset_ctx_set(ctx, NFTNL_RULESET_CTX_TABLE, table);
287 if (ctx->cb(ctx) < 0)
292 nftnl_table_free(table);
297 struct nftnl_parse_err *err)
301 chain = nftnl_chain_alloc();
305 switch (ctx->format) {
306 case NFTNL_OUTPUT_JSON:
308 if (nftnl_jansson_parse_chain(chain, ctx->json, err) < 0)
312 case NFTNL_OUTPUT_XML:
314 if (nftnl_mxml_chain_parse(ctx->xml, chain, err) < 0)
323 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE, NFTNL_RULESET_CHAIN);
324 nftnl_ruleset_ctx_set(ctx, NFTNL_RULESET_CTX_CHAIN, chain);
325 if (ctx->cb(ctx) < 0)
330 nftnl_chain_free(chain);
335 struct nftnl_set *set, uint32_t type,
336 struct nftnl_parse_err *err)
338 struct nftnl_set *newset;
340 nftnl_set_set_u32(set, NFTNL_SET_ID, ctx->set_id++);
342 newset = nftnl_set_clone(set);
346 nftnl_set_list_add_tail(newset, ctx->set_list);
348 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE, type);
349 nftnl_ruleset_ctx_set(ctx, NFTNL_RULESET_CTX_SET, set);
350 if (ctx->cb(ctx) < 0)
359 struct nftnl_parse_err *err)
361 struct nftnl_set *set;
363 set = nftnl_set_alloc();
367 switch (ctx->format) {
368 case NFTNL_OUTPUT_JSON:
370 if (nftnl_jansson_parse_elem(set, ctx->json, err) < 0)
374 case NFTNL_OUTPUT_XML:
376 if (nftnl_mxml_set_parse(ctx->xml, set, err) < 0)
385 if (nftnl_ruleset_parse_set(ctx, set, NFTNL_RULESET_SET_ELEMS, err) < 0)
395 struct nftnl_parse_err *err)
397 struct nftnl_set *set;
399 set = nftnl_set_alloc();
403 switch (ctx->format) {
404 case NFTNL_OUTPUT_JSON:
406 if (nftnl_jansson_parse_set(set, ctx->json, err) < 0)
410 case NFTNL_OUTPUT_XML:
412 if (nftnl_mxml_set_parse(ctx->xml, set, err) < 0)
421 if (nftnl_ruleset_parse_set(ctx, set, NFTNL_RULESET_SET, err) < 0)
431 struct nftnl_parse_err *err)
435 rule = nftnl_rule_alloc();
439 switch (ctx->format) {
440 case NFTNL_OUTPUT_JSON:
442 if (nftnl_jansson_parse_rule(rule, ctx->json, err,
447 case NFTNL_OUTPUT_XML:
449 if (nftnl_mxml_rule_parse(ctx->xml, rule, err, ctx->set_list) < 0)
458 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE, NFTNL_RULESET_RULE);
459 nftnl_ruleset_ctx_set(ctx, NFTNL_RULESET_CTX_RULE, rule);
460 if (ctx->cb(ctx) < 0)
465 nftnl_rule_free(rule);
471 static int nftnl_ruleset_json_parse_ruleset(
struct nftnl_parse_ctx *ctx,
472 struct nftnl_parse_err *err)
474 json_t *node, *array = ctx->json;
477 len = json_array_size(array);
478 for (i = 0; i < len; i++) {
479 node = json_array_get(array, i);
486 if (nftnl_jansson_node_exist(node,
"table"))
487 ret = nftnl_ruleset_parse_tables(ctx, err);
488 else if (nftnl_jansson_node_exist(node,
"chain"))
489 ret = nftnl_ruleset_parse_chains(ctx, err);
490 else if (nftnl_jansson_node_exist(node,
"set"))
491 ret = nftnl_ruleset_parse_sets(ctx, err);
492 else if (nftnl_jansson_node_exist(node,
"rule"))
493 ret = nftnl_ruleset_parse_rules(ctx, err);
494 else if (nftnl_jansson_node_exist(node,
"element"))
495 ret = nftnl_ruleset_parse_set_elems(ctx, err);
503 if (len == 0 && ctx->cmd == NFTNL_CMD_FLUSH) {
504 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE,
505 NFTNL_RULESET_RULESET);
506 if (ctx->cb(ctx) < 0)
513 static int nftnl_ruleset_json_parse_cmd(
const char *cmd,
514 struct nftnl_parse_err *err,
520 cmdnum = nftnl_str2cmd(cmd);
521 if (cmdnum == NFTNL_CMD_UNSPEC) {
522 err->error = NFTNL_PARSE_EMISSINGNODE;
523 err->node_name = strdup(cmd);
527 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_CMD, cmdnum);
529 nodecmd = json_object_get(ctx->json, cmd);
534 if (nftnl_ruleset_json_parse_ruleset(ctx, err) != 0)
543 static int nftnl_ruleset_json_parse(
const void *json,
544 struct nftnl_parse_err *err,
545 enum nftnl_parse_input input,
546 enum nftnl_parse_type type,
void *arg,
550 json_t *root, *array, *node;
559 ctx.set_list = nftnl_set_list_alloc();
560 if (ctx.set_list == NULL)
564 nftnl_ruleset_ctx_set(&ctx, NFTNL_RULESET_CTX_DATA, arg);
566 root = nftnl_jansson_create_root(json, &error, err, input);
570 array = json_object_get(root,
"nftables");
576 len = json_array_size(array);
577 for (i = 0; i < len; i++) {
578 node = json_array_get(array, i);
584 key = json_object_iter_key(json_object_iter(node));
588 if (nftnl_ruleset_json_parse_cmd(key, err, &ctx) < 0)
592 nftnl_set_list_free(ctx.set_list);
593 nftnl_jansson_free_root(root);
596 nftnl_jansson_free_root(root);
598 nftnl_set_list_free(ctx.set_list);
607 static int nftnl_ruleset_xml_parse_ruleset(
struct nftnl_parse_ctx *ctx,
608 struct nftnl_parse_err *err)
610 const char *node_type;
611 mxml_node_t *node, *array = ctx->xml;
614 for (node = mxmlFindElement(array, array, NULL, NULL, NULL,
617 node = mxmlFindElement(node, array, NULL, NULL, NULL,
620 node_type = node->value.opaque;
622 if (strcmp(node_type,
"table") == 0)
623 ret = nftnl_ruleset_parse_tables(ctx, err);
624 else if (strcmp(node_type,
"chain") == 0)
625 ret = nftnl_ruleset_parse_chains(ctx, err);
626 else if (strcmp(node_type,
"set") == 0)
627 ret = nftnl_ruleset_parse_sets(ctx, err);
628 else if (strcmp(node_type,
"rule") == 0)
629 ret = nftnl_ruleset_parse_rules(ctx, err);
630 else if (strcmp(node_type,
"element") == 0)
631 ret = nftnl_ruleset_parse_set_elems(ctx, err);
639 if (len == 0 && ctx->cmd == NFTNL_CMD_FLUSH) {
640 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_TYPE,
641 NFTNL_RULESET_RULESET);
642 if (ctx->cb(ctx) < 0)
649 static int nftnl_ruleset_xml_parse_cmd(
const char *cmd,
struct nftnl_parse_err *err,
653 mxml_node_t *nodecmd;
655 cmdnum = nftnl_str2cmd(cmd);
656 if (cmdnum == NFTNL_CMD_UNSPEC) {
657 err->error = NFTNL_PARSE_EMISSINGNODE;
658 err->node_name = strdup(cmd);
662 nodecmd = mxmlFindElement(ctx->xml, ctx->xml, cmd, NULL, NULL,
666 nftnl_ruleset_ctx_set_u32(ctx, NFTNL_RULESET_CTX_CMD, cmdnum);
668 if (nftnl_ruleset_xml_parse_ruleset(ctx, err) != 0)
677 static int nftnl_ruleset_xml_parse(
const void *xml,
struct nftnl_parse_err *err,
678 enum nftnl_parse_input input,
679 enum nftnl_parse_type type,
void *arg,
683 mxml_node_t *tree, *nodecmd = NULL;
690 ctx.set_list = nftnl_set_list_alloc();
691 if (ctx.set_list == NULL)
695 nftnl_ruleset_ctx_set(&ctx, NFTNL_RULESET_CTX_DATA, arg);
697 tree = nftnl_mxml_build_tree(xml,
"nftables", err, input);
703 nodecmd = mxmlWalkNext(tree, tree, MXML_DESCEND_FIRST);
704 while (nodecmd != NULL) {
705 cmd = nodecmd->value.opaque;
706 if (nftnl_ruleset_xml_parse_cmd(cmd, err, &ctx) < 0)
708 nodecmd = mxmlWalkNext(tree, tree, MXML_NO_DESCEND);
711 nftnl_set_list_free(ctx.set_list);
717 nftnl_set_list_free(ctx.set_list);
726 nftnl_ruleset_do_parse(
enum nftnl_parse_type type,
const void *data,
727 struct nftnl_parse_err *err,
enum nftnl_parse_input input,
733 case NFTNL_PARSE_XML:
734 ret = nftnl_ruleset_xml_parse(data, err, input, type, arg, cb);
736 case NFTNL_PARSE_JSON:
737 ret = nftnl_ruleset_json_parse(data, err, input, type, arg, cb);
748 int nftnl_ruleset_parse_file_cb(
enum nftnl_parse_type type, FILE *fp,
749 struct nftnl_parse_err *err,
void *data,
752 return nftnl_ruleset_do_parse(type, fp, err, NFTNL_PARSE_FILE, data, cb);
754 EXPORT_SYMBOL(nftnl_ruleset_parse_file_cb, nft_ruleset_parse_file_cb);
756 int nftnl_ruleset_parse_buffer_cb(
enum nftnl_parse_type type,
const char *buffer,
757 struct nftnl_parse_err *err,
void *data,
760 return nftnl_ruleset_do_parse(type, buffer, err, NFTNL_PARSE_BUFFER, data,
763 EXPORT_SYMBOL(nftnl_ruleset_parse_buffer_cb, nft_ruleset_parse_buffer_cb);
769 if (ctx->cmd != NFTNL_CMD_ADD)
773 case NFTNL_RULESET_TABLE:
774 if (r->table_list == NULL) {
775 r->table_list = nftnl_table_list_alloc();
776 if (r->table_list == NULL)
779 nftnl_ruleset_set(r, NFTNL_RULESET_TABLELIST,
782 nftnl_table_list_add_tail(ctx->table, r->table_list);
784 case NFTNL_RULESET_CHAIN:
785 if (r->chain_list == NULL) {
786 r->chain_list = nftnl_chain_list_alloc();
787 if (r->chain_list == NULL)
790 nftnl_ruleset_set(r, NFTNL_RULESET_CHAINLIST,
793 nftnl_chain_list_add_tail(ctx->chain, r->chain_list);
795 case NFTNL_RULESET_SET:
796 if (r->set_list == NULL) {
797 r->set_list = nftnl_set_list_alloc();
798 if (r->set_list == NULL)
801 nftnl_ruleset_set(r, NFTNL_RULESET_SETLIST,
804 nftnl_set_list_add_tail(ctx->set, r->set_list);
806 case NFTNL_RULESET_RULE:
807 if (r->rule_list == NULL) {
808 r->rule_list = nftnl_rule_list_alloc();
809 if (r->rule_list == NULL)
812 nftnl_ruleset_set(r, NFTNL_RULESET_RULELIST,
815 nftnl_rule_list_add_tail(ctx->rule, r->rule_list);
817 case NFTNL_RULESET_RULESET:
826 int nftnl_ruleset_parse(
struct nftnl_ruleset *r,
enum nftnl_parse_type type,
827 const char *data,
struct nftnl_parse_err *err)
829 return nftnl_ruleset_parse_buffer_cb(type, data, err, r, nftnl_ruleset_cb);
831 EXPORT_SYMBOL(nftnl_ruleset_parse, nft_ruleset_parse);
833 int nftnl_ruleset_parse_file(
struct nftnl_ruleset *rs,
enum nftnl_parse_type type,
834 FILE *fp,
struct nftnl_parse_err *err)
836 return nftnl_ruleset_parse_file_cb(type, fp, err, rs, nftnl_ruleset_cb);
838 EXPORT_SYMBOL(nftnl_ruleset_parse_file, nft_ruleset_parse_file);
840 static const char *nftnl_ruleset_o_opentag(uint32_t type)
843 case NFTNL_OUTPUT_XML:
845 case NFTNL_OUTPUT_JSON:
846 return "{\"nftables\":[";
852 static const char *nftnl_ruleset_o_separator(
void *obj, uint32_t type)
858 case NFTNL_OUTPUT_JSON:
860 case NFTNL_OUTPUT_DEFAULT:
867 static const char *nftnl_ruleset_o_closetag(uint32_t type)
870 case NFTNL_OUTPUT_XML:
871 return "</nftables>";
872 case NFTNL_OUTPUT_JSON:
880 nftnl_ruleset_snprintf_table(
char *buf,
size_t size,
886 int ret, len = size, offset = 0;
888 ti = nftnl_table_list_iter_create(rs->table_list);
892 t = nftnl_table_list_iter_next(ti);
894 ret = nftnl_table_snprintf(buf+offset, len, t, type, flags);
895 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
897 t = nftnl_table_list_iter_next(ti);
899 ret = snprintf(buf+offset, len,
"%s",
900 nftnl_ruleset_o_separator(t, type));
901 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
903 nftnl_table_list_iter_destroy(ti);
909 nftnl_ruleset_snprintf_chain(
char *buf,
size_t size,
915 int ret, len = size, offset = 0;
917 ci = nftnl_chain_list_iter_create(rs->chain_list);
921 c = nftnl_chain_list_iter_next(ci);
923 ret = nftnl_chain_snprintf(buf+offset, len, c, type, flags);
924 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
926 c = nftnl_chain_list_iter_next(ci);
928 ret = snprintf(buf+offset, len,
"%s",
929 nftnl_ruleset_o_separator(c, type));
930 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
932 nftnl_chain_list_iter_destroy(ci);
938 nftnl_ruleset_snprintf_set(
char *buf,
size_t size,
944 int ret, len = size, offset = 0;
946 si = nftnl_set_list_iter_create(rs->set_list);
950 s = nftnl_set_list_iter_next(si);
952 ret = nftnl_set_snprintf(buf+offset, len, s, type, flags);
953 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
955 s = nftnl_set_list_iter_next(si);
957 ret = snprintf(buf+offset, len,
"%s",
958 nftnl_ruleset_o_separator(s, type));
959 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
961 nftnl_set_list_iter_destroy(si);
967 nftnl_ruleset_snprintf_rule(
char *buf,
size_t size,
973 int ret, len = size, offset = 0;
975 ri = nftnl_rule_list_iter_create(rs->rule_list);
979 r = nftnl_rule_list_iter_next(ri);
981 ret = nftnl_rule_snprintf(buf+offset, len, r, type, flags);
982 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
984 r = nftnl_rule_list_iter_next(ri);
986 ret = snprintf(buf+offset, len,
"%s",
987 nftnl_ruleset_o_separator(r, type));
988 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
990 nftnl_rule_list_iter_destroy(ri);
996 nftnl_ruleset_do_snprintf(
char *buf,
size_t size,
const struct nftnl_ruleset *rs,
997 uint32_t cmd, uint32_t type, uint32_t flags)
999 int ret, len = size, offset = 0;
1001 uint32_t inner_flags = flags;
1004 inner_flags &= ~NFTNL_OF_EVENT_ANY;
1006 ret = snprintf(buf + offset, len,
"%s", nftnl_ruleset_o_opentag(type));
1007 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1009 ret = nftnl_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
1010 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1012 if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_TABLELIST) &&
1013 (!nftnl_table_list_is_empty(rs->table_list))) {
1014 ret = nftnl_ruleset_snprintf_table(buf+offset, len, rs,
1016 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1019 prev = rs->table_list;
1022 if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_CHAINLIST) &&
1023 (!nftnl_chain_list_is_empty(rs->chain_list))) {
1024 ret = snprintf(buf+offset, len,
"%s",
1025 nftnl_ruleset_o_separator(prev, type));
1026 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1028 ret = nftnl_ruleset_snprintf_chain(buf+offset, len, rs,
1030 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1033 prev = rs->chain_list;
1036 if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_SETLIST) &&
1037 (!nftnl_set_list_is_empty(rs->set_list))) {
1038 ret = snprintf(buf+offset, len,
"%s",
1039 nftnl_ruleset_o_separator(prev, type));
1040 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1042 ret = nftnl_ruleset_snprintf_set(buf+offset, len, rs,
1044 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1047 prev = rs->set_list;
1050 if (nftnl_ruleset_is_set(rs, NFTNL_RULESET_RULELIST) &&
1051 (!nftnl_rule_list_is_empty(rs->rule_list))) {
1052 ret = snprintf(buf+offset, len,
"%s",
1053 nftnl_ruleset_o_separator(prev, type));
1054 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1056 ret = nftnl_ruleset_snprintf_rule(buf+offset, len, rs,
1058 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1061 ret = nftnl_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
1062 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1064 ret = snprintf(buf + offset, len,
"%s", nftnl_ruleset_o_closetag(type));
1065 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1070 static int nftnl_ruleset_cmd_snprintf(
char *buf,
size_t size,
1072 uint32_t type, uint32_t flags)
1075 case NFTNL_OUTPUT_DEFAULT:
1076 case NFTNL_OUTPUT_XML:
1077 case NFTNL_OUTPUT_JSON:
1078 return nftnl_ruleset_do_snprintf(buf, size, r, cmd, type, flags);
1085 int nftnl_ruleset_snprintf(
char *buf,
size_t size,
const struct nftnl_ruleset *r,
1086 uint32_t type, uint32_t flags)
1089 case NFTNL_OUTPUT_DEFAULT:
1090 case NFTNL_OUTPUT_XML:
1091 case NFTNL_OUTPUT_JSON:
1092 return nftnl_ruleset_cmd_snprintf(buf, size, r,
1093 nftnl_flag2cmd(flags), type,
1100 EXPORT_SYMBOL(nftnl_ruleset_snprintf, nft_ruleset_snprintf);
1102 static int nftnl_ruleset_fprintf_tables(FILE *fp,
const struct nftnl_ruleset *rs,
1103 uint32_t type, uint32_t flags)
1105 int len = 0, ret = 0;
1109 ti = nftnl_table_list_iter_create(rs->table_list);
1113 t = nftnl_table_list_iter_next(ti);
1115 ret = nftnl_table_fprintf(fp, t, type, flags);
1121 t = nftnl_table_list_iter_next(ti);
1123 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(t, type));
1129 nftnl_table_list_iter_destroy(ti);
1133 nftnl_table_list_iter_destroy(ti);
1137 static int nftnl_ruleset_fprintf_chains(FILE *fp,
const struct nftnl_ruleset *rs,
1138 uint32_t type, uint32_t flags)
1140 int len = 0, ret = 0;
1144 i = nftnl_chain_list_iter_create(rs->chain_list);
1148 o = nftnl_chain_list_iter_next(i);
1150 ret = nftnl_chain_fprintf(fp, o, type, flags);
1156 o = nftnl_chain_list_iter_next(i);
1158 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(o, type));
1164 nftnl_chain_list_iter_destroy(i);
1168 nftnl_chain_list_iter_destroy(i);
1172 static int nftnl_ruleset_fprintf_sets(FILE *fp,
const struct nftnl_ruleset *rs,
1173 uint32_t type, uint32_t flags)
1175 int len = 0, ret = 0;
1176 struct nftnl_set *o;
1179 i = nftnl_set_list_iter_create(rs->set_list);
1183 o = nftnl_set_list_iter_next(i);
1185 ret = nftnl_set_fprintf(fp, o, type, flags);
1191 o = nftnl_set_list_iter_next(i);
1193 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(o, type));
1199 nftnl_set_list_iter_destroy(i);
1203 nftnl_set_list_iter_destroy(i);
1207 static int nftnl_ruleset_fprintf_rules(FILE *fp,
const struct nftnl_ruleset *rs,
1208 uint32_t type, uint32_t flags)
1210 int len = 0, ret = 0;
1214 i = nftnl_rule_list_iter_create(rs->rule_list);
1218 o = nftnl_rule_list_iter_next(i);
1220 ret = nftnl_rule_fprintf(fp, o, type, flags);
1226 o = nftnl_rule_list_iter_next(i);
1228 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(o, type));
1234 nftnl_rule_list_iter_destroy(i);
1238 nftnl_rule_list_iter_destroy(i);
1242 #define NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len) \
1247 static int nftnl_ruleset_cmd_fprintf(FILE *fp,
const struct nftnl_ruleset *rs,
1248 uint32_t cmd, uint32_t type, uint32_t flags)
1250 int len = 0, ret = 0;
1252 uint32_t inner_flags = flags;
1255 inner_flags &= ~NFTNL_OF_EVENT_ANY;
1257 ret = fprintf(fp,
"%s", nftnl_ruleset_o_opentag(type));
1258 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1260 ret = nftnl_cmd_header_fprintf(fp, cmd, type, flags);
1261 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1263 if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_TABLELIST)) &&
1264 (!nftnl_table_list_is_empty(rs->table_list))) {
1265 ret = nftnl_ruleset_fprintf_tables(fp, rs, type, inner_flags);
1266 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1269 prev = rs->table_list;
1272 if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_CHAINLIST)) &&
1273 (!nftnl_chain_list_is_empty(rs->chain_list))) {
1274 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(prev, type));
1275 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1277 ret = nftnl_ruleset_fprintf_chains(fp, rs, type, inner_flags);
1278 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1281 prev = rs->chain_list;
1284 if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_SETLIST)) &&
1285 (!nftnl_set_list_is_empty(rs->set_list))) {
1286 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(prev, type));
1287 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1289 ret = nftnl_ruleset_fprintf_sets(fp, rs, type, inner_flags);
1290 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1293 prev = rs->set_list;
1296 if ((nftnl_ruleset_is_set(rs, NFTNL_RULESET_RULELIST)) &&
1297 (!nftnl_rule_list_is_empty(rs->rule_list))) {
1298 ret = fprintf(fp,
"%s", nftnl_ruleset_o_separator(prev, type));
1299 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1301 ret = nftnl_ruleset_fprintf_rules(fp, rs, type, inner_flags);
1302 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1305 ret = nftnl_cmd_footer_fprintf(fp, cmd, type, flags);
1306 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1308 ret = fprintf(fp,
"%s", nftnl_ruleset_o_closetag(type));
1309 NFTNL_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1314 int nftnl_ruleset_fprintf(FILE *fp,
const struct nftnl_ruleset *rs, uint32_t type,
1317 return nftnl_ruleset_cmd_fprintf(fp, rs, nftnl_flag2cmd(flags), type,
1320 EXPORT_SYMBOL(nftnl_ruleset_fprintf, nft_ruleset_fprintf);