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>
39 EXPORT_SYMBOL(nft_ruleset_alloc);
43 if (r->flags & (1 << NFT_RULESET_ATTR_TABLELIST))
44 nft_table_list_free(r->table_list);
45 if (r->flags & (1 << NFT_RULESET_ATTR_CHAINLIST))
46 nft_chain_list_free(r->chain_list);
47 if (r->flags & (1 << NFT_RULESET_ATTR_SETLIST))
48 nft_set_list_free(r->set_list);
49 if (r->flags & (1 << NFT_RULESET_ATTR_RULELIST))
50 nft_rule_list_free(r->rule_list);
53 EXPORT_SYMBOL(nft_ruleset_free);
55 bool nft_ruleset_attr_is_set(
const struct nft_ruleset *r, uint16_t attr)
57 return r->flags & (1 << attr);
59 EXPORT_SYMBOL(nft_ruleset_attr_is_set);
61 void nft_ruleset_attr_unset(
struct nft_ruleset *r, uint16_t attr)
63 if (!(r->flags & (1 << attr)))
67 case NFT_RULESET_ATTR_TABLELIST:
68 nft_table_list_free(r->table_list);
71 case NFT_RULESET_ATTR_CHAINLIST:
72 nft_chain_list_free(r->chain_list);
75 case NFT_RULESET_ATTR_SETLIST:
76 nft_set_list_free(r->set_list);
79 case NFT_RULESET_ATTR_RULELIST:
80 nft_rule_list_free(r->rule_list);
84 r->flags &= ~(1 << attr);
86 EXPORT_SYMBOL(nft_ruleset_attr_unset);
88 void nft_ruleset_attr_set(
struct nft_ruleset *r, uint16_t attr,
void *data)
91 case NFT_RULESET_ATTR_TABLELIST:
92 nft_ruleset_attr_unset(r, NFT_RULESET_ATTR_TABLELIST);
95 case NFT_RULESET_ATTR_CHAINLIST:
96 nft_ruleset_attr_unset(r, NFT_RULESET_ATTR_CHAINLIST);
99 case NFT_RULESET_ATTR_SETLIST:
100 nft_ruleset_attr_unset(r, NFT_RULESET_ATTR_SETLIST);
103 case NFT_RULESET_ATTR_RULELIST:
104 nft_ruleset_attr_unset(r, NFT_RULESET_ATTR_RULELIST);
110 r->flags |= (1 << attr);
112 EXPORT_SYMBOL(nft_ruleset_attr_set);
114 const void *nft_ruleset_attr_get(
const struct nft_ruleset *r, uint16_t attr)
116 if (!(r->flags & (1 << attr)))
120 case NFT_RULESET_ATTR_TABLELIST:
121 return r->table_list;
122 case NFT_RULESET_ATTR_CHAINLIST:
123 return r->chain_list;
124 case NFT_RULESET_ATTR_SETLIST:
126 case NFT_RULESET_ATTR_RULELIST:
132 EXPORT_SYMBOL(nft_ruleset_attr_get);
135 static int nft_ruleset_json_parse_tables(
struct nft_ruleset *rs, json_t *array,
136 struct nft_parse_err *err)
148 len = json_array_size(array);
149 for (i = 0; i < len; i++) {
150 node = json_array_get(array, i);
156 if (!(nft_jansson_node_exist(node,
"table")))
159 o = nft_table_alloc();
165 if (nft_jansson_parse_table(o, node, err) < 0) {
170 nft_table_list_add_tail(o, list);
173 if (!nft_table_list_is_empty(list))
174 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_TABLELIST, list);
176 nft_table_list_free(list);
180 nft_table_list_free(list);
184 static int nft_ruleset_json_parse_chains(
struct nft_ruleset *rs, json_t *array,
185 struct nft_parse_err *err)
197 len = json_array_size(array);
198 for (i = 0; i < len; i++) {
199 node = json_array_get(array, i);
205 if (!(nft_jansson_node_exist(node,
"chain")))
208 o = nft_chain_alloc();
214 if (nft_jansson_parse_chain(o, node, err) < 0) {
219 nft_chain_list_add_tail(o, list);
222 if (!nft_chain_list_is_empty(list))
223 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_CHAINLIST, list);
225 nft_chain_list_free(list);
229 nft_chain_list_free(list);
233 static int nft_ruleset_json_parse_sets(
struct nft_ruleset *rs, json_t *array,
234 struct nft_parse_err *err)
238 struct nft_set *s = NULL;
246 len = json_array_size(array);
247 for (i = 0; i < len; i++) {
248 node = json_array_get(array, i);
254 if (!(nft_jansson_node_exist(node,
"set")))
263 if (nft_jansson_parse_set(s, node, err) < 0) {
268 nft_set_list_add_tail(s, list);
271 if (!nft_set_list_is_empty(list))
272 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_SETLIST, list);
274 nft_set_list_free(list);
278 nft_set_list_free(list);
282 static int nft_ruleset_json_parse_rules(
struct nft_ruleset *rs, json_t *array,
283 struct nft_parse_err *err)
295 len = json_array_size(array);
296 for (i = 0; i < len; i++) {
297 node = json_array_get(array, i);
303 if (!(nft_jansson_node_exist(node,
"rule")))
306 o = nft_rule_alloc();
312 if (nft_jansson_parse_rule(o, node, err) < 0) {
317 nft_rule_list_add_tail(o, list);
320 if (!nft_rule_list_is_empty(list))
321 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_RULELIST, list);
323 nft_rule_list_free(list);
327 nft_rule_list_free(list);
333 static int nft_ruleset_json_parse(
struct nft_ruleset *rs,
const void *json,
334 struct nft_parse_err *err,
enum nft_parse_input input)
337 json_t *root, *array;
340 root = nft_jansson_create_root(json, &error, err, input);
344 array = json_object_get(root,
"nftables");
350 if (nft_ruleset_json_parse_tables(rs, array, err) != 0)
353 if (nft_ruleset_json_parse_chains(rs, array, err) != 0)
356 if (nft_ruleset_json_parse_sets(rs, array, err) != 0)
359 if (nft_ruleset_json_parse_rules(rs, array, err) != 0)
362 nft_jansson_free_root(root);
365 nft_jansson_free_root(root);
375 nft_ruleset_xml_parse_tables(
struct nft_ruleset *rs, mxml_node_t *tree,
376 struct nft_parse_err *err)
381 if (table_list == NULL) {
386 for (node = mxmlFindElement(tree, tree,
"table", NULL, NULL,
389 node = mxmlFindElement(node, tree,
"table", NULL, NULL,
391 t = nft_table_alloc();
395 if (nft_mxml_table_parse(node, t, err) != 0) {
400 nft_table_list_add_tail(t, table_list);
403 if (!nft_table_list_is_empty(table_list))
404 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_TABLELIST,
407 nft_table_list_free(table_list);
411 nft_table_list_free(table_list);
416 nft_ruleset_xml_parse_chains(
struct nft_ruleset *rs, mxml_node_t *tree,
417 struct nft_parse_err *err)
422 if (chain_list == NULL) {
427 for (node = mxmlFindElement(tree, tree,
"chain", NULL, NULL,
430 node = mxmlFindElement(node, tree,
"chain", NULL, NULL,
432 c = nft_chain_alloc();
436 if (nft_mxml_chain_parse(node, c, err) != 0) {
441 nft_chain_list_add_tail(c, chain_list);
444 if (!nft_chain_list_is_empty(chain_list))
445 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_CHAINLIST,
448 nft_chain_list_free(chain_list);
452 nft_chain_list_free(chain_list);
457 nft_ruleset_xml_parse_sets(
struct nft_ruleset *rs, mxml_node_t *tree,
458 struct nft_parse_err *err)
463 if (set_list == NULL) {
468 for (node = mxmlFindElement(tree, tree,
"set", NULL, NULL,
471 node = mxmlFindElement(node, tree,
"set", NULL, NULL,
477 if (nft_mxml_set_parse(node, s, err) != 0) {
482 nft_set_list_add_tail(s, set_list);
485 if (!nft_set_list_is_empty(set_list))
486 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_SETLIST, set_list);
488 nft_set_list_free(set_list);
492 nft_set_list_free(set_list);
497 nft_ruleset_xml_parse_rules(
struct nft_ruleset *rs, mxml_node_t *tree,
498 struct nft_parse_err *err)
503 if (rule_list == NULL) {
508 for (node = mxmlFindElement(tree, tree,
"rule", NULL, NULL,
511 node = mxmlFindElement(node, tree,
"rule", NULL, NULL,
513 r = nft_rule_alloc();
517 if (nft_mxml_rule_parse(node, r, err) != 0) {
522 nft_rule_list_add_tail(r, rule_list);
525 if (!nft_rule_list_is_empty(rule_list))
526 nft_ruleset_attr_set(rs, NFT_RULESET_ATTR_RULELIST, rule_list);
528 nft_rule_list_free(rule_list);
532 nft_rule_list_free(rule_list);
537 static int nft_ruleset_xml_parse(
struct nft_ruleset *rs,
const void *xml,
538 struct nft_parse_err *err,
enum nft_parse_input input)
543 tree = nft_mxml_build_tree(xml,
"nftables", err, input);
547 if (nft_ruleset_xml_parse_tables(rs, tree, err) != 0)
550 if (nft_ruleset_xml_parse_chains(rs, tree, err) != 0)
553 if (nft_ruleset_xml_parse_sets(rs, tree, err) != 0)
556 if (nft_ruleset_xml_parse_rules(rs, tree, err) != 0)
571 nft_ruleset_do_parse(
struct nft_ruleset *r,
enum nft_parse_type type,
572 const void *data,
struct nft_parse_err *err,
573 enum nft_parse_input input)
579 ret = nft_ruleset_xml_parse(r, data, err, input);
582 ret = nft_ruleset_json_parse(r, data, err, input);
593 int nft_ruleset_parse(
struct nft_ruleset *r,
enum nft_parse_type type,
594 const char *data,
struct nft_parse_err *err)
596 return nft_ruleset_do_parse(r, type, data, err, NFT_PARSE_BUFFER);
598 EXPORT_SYMBOL(nft_ruleset_parse);
600 int nft_ruleset_parse_file(
struct nft_ruleset *rs,
enum nft_parse_type type,
601 FILE *fp,
struct nft_parse_err *err)
603 return nft_ruleset_do_parse(rs, type, fp, err, NFT_PARSE_FILE);
605 EXPORT_SYMBOL(nft_ruleset_parse_file);
607 static const char *nft_ruleset_o_opentag(uint32_t type)
612 case NFT_OUTPUT_JSON:
613 return "{\"nftables\":[";
619 static const char *nft_ruleset_o_separator(
void *obj, uint32_t type)
625 case NFT_OUTPUT_JSON:
627 case NFT_OUTPUT_DEFAULT:
634 static const char *nft_ruleset_o_closetag(uint32_t type)
638 return "</nftables>";
639 case NFT_OUTPUT_JSON:
647 nft_ruleset_snprintf_table(
char *buf,
size_t size,
653 int ret, len = size, offset = 0;
655 ti = nft_table_list_iter_create(rs->table_list);
659 t = nft_table_list_iter_next(ti);
661 ret = nft_table_snprintf(buf+offset, len, t, type, flags);
662 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
664 t = nft_table_list_iter_next(ti);
666 ret = snprintf(buf+offset, len,
"%s",
667 nft_ruleset_o_separator(t, type));
668 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
670 nft_table_list_iter_destroy(ti);
676 nft_ruleset_snprintf_chain(
char *buf,
size_t size,
682 int ret, len = size, offset = 0;
684 ci = nft_chain_list_iter_create(rs->chain_list);
688 c = nft_chain_list_iter_next(ci);
690 ret = nft_chain_snprintf(buf+offset, len, c, type, flags);
691 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
693 c = nft_chain_list_iter_next(ci);
695 ret = snprintf(buf+offset, len,
"%s",
696 nft_ruleset_o_separator(c, type));
697 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
699 nft_chain_list_iter_destroy(ci);
705 nft_ruleset_snprintf_set(
char *buf,
size_t size,
711 int ret, len = size, offset = 0;
713 si = nft_set_list_iter_create(rs->set_list);
717 s = nft_set_list_iter_next(si);
719 ret = nft_set_snprintf(buf+offset, len, s, type, flags);
720 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
722 s = nft_set_list_iter_next(si);
724 ret = snprintf(buf+offset, len,
"%s",
725 nft_ruleset_o_separator(s, type));
726 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
728 nft_set_list_iter_destroy(si);
734 nft_ruleset_snprintf_rule(
char *buf,
size_t size,
740 int ret, len = size, offset = 0;
742 ri = nft_rule_list_iter_create(rs->rule_list);
746 r = nft_rule_list_iter_next(ri);
748 ret = nft_rule_snprintf(buf+offset, len, r, type, flags);
749 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
751 r = nft_rule_list_iter_next(ri);
753 ret = snprintf(buf+offset, len,
"%s",
754 nft_ruleset_o_separator(r, type));
755 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
757 nft_rule_list_iter_destroy(ri);
763 nft_ruleset_do_snprintf(
char *buf,
size_t size,
const struct nft_ruleset *rs,
764 uint32_t type, uint32_t flags)
766 int ret, len = size, offset = 0;
768 uint32_t inner_flags = flags;
771 inner_flags &= ~NFT_OF_EVENT_ANY;
773 ret = nft_event_header_snprintf(buf+offset, len, type, flags);
774 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
776 ret = snprintf(buf+offset, len,
"%s", nft_ruleset_o_opentag(type));
777 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
779 if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST) &&
780 (!nft_table_list_is_empty(rs->table_list))) {
781 ret = nft_ruleset_snprintf_table(buf+offset, len, rs,
783 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
786 prev = rs->table_list;
789 if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_CHAINLIST) &&
790 (!nft_chain_list_is_empty(rs->chain_list))) {
791 ret = snprintf(buf+offset, len,
"%s",
792 nft_ruleset_o_separator(prev, type));
793 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
795 ret = nft_ruleset_snprintf_chain(buf+offset, len, rs,
797 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
800 prev = rs->chain_list;
803 if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_SETLIST) &&
804 (!nft_set_list_is_empty(rs->set_list))) {
805 ret = snprintf(buf+offset, len,
"%s",
806 nft_ruleset_o_separator(prev, type));
807 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
809 ret = nft_ruleset_snprintf_set(buf+offset, len, rs,
811 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
817 if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_RULELIST) &&
818 (!nft_rule_list_is_empty(rs->rule_list))) {
819 ret = snprintf(buf+offset, len,
"%s",
820 nft_ruleset_o_separator(prev, type));
821 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
823 ret = nft_ruleset_snprintf_rule(buf+offset, len, rs,
825 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
828 ret = snprintf(buf+offset, len,
"%s", nft_ruleset_o_closetag(type));
829 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
831 ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
832 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
837 int nft_ruleset_snprintf(
char *buf,
size_t size,
const struct nft_ruleset *r,
838 uint32_t type, uint32_t flags)
841 case NFT_OUTPUT_DEFAULT:
843 case NFT_OUTPUT_JSON:
844 return nft_ruleset_do_snprintf(buf, size, r, type, flags);
850 EXPORT_SYMBOL(nft_ruleset_snprintf);
852 static int nft_ruleset_fprintf_tables(FILE *fp,
const struct nft_ruleset *rs,
853 uint32_t type, uint32_t flags)
855 int len = 0, ret = 0;
859 ti = nft_table_list_iter_create(rs->table_list);
863 t = nft_table_list_iter_next(ti);
865 ret = nft_table_fprintf(fp, t, type, flags);
871 t = nft_table_list_iter_next(ti);
873 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(t, type));
879 nft_table_list_iter_destroy(ti);
883 nft_table_list_iter_destroy(ti);
887 static int nft_ruleset_fprintf_chains(FILE *fp,
const struct nft_ruleset *rs,
888 uint32_t type, uint32_t flags)
890 int len = 0, ret = 0;
894 i = nft_chain_list_iter_create(rs->chain_list);
898 o = nft_chain_list_iter_next(i);
900 ret = nft_chain_fprintf(fp, o, type, flags);
906 o = nft_chain_list_iter_next(i);
908 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(o, type));
914 nft_chain_list_iter_destroy(i);
918 nft_chain_list_iter_destroy(i);
922 static int nft_ruleset_fprintf_sets(FILE *fp,
const struct nft_ruleset *rs,
923 uint32_t type, uint32_t flags)
925 int len = 0, ret = 0;
929 i = nft_set_list_iter_create(rs->set_list);
933 o = nft_set_list_iter_next(i);
935 ret = nft_set_fprintf(fp, o, type, flags);
941 o = nft_set_list_iter_next(i);
943 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(o, type));
949 nft_set_list_iter_destroy(i);
953 nft_set_list_iter_destroy(i);
957 static int nft_ruleset_fprintf_rules(FILE *fp,
const struct nft_ruleset *rs,
958 uint32_t type, uint32_t flags)
960 int len = 0, ret = 0;
964 i = nft_rule_list_iter_create(rs->rule_list);
968 o = nft_rule_list_iter_next(i);
970 ret = nft_rule_fprintf(fp, o, type, flags);
976 o = nft_rule_list_iter_next(i);
978 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(o, type));
984 nft_rule_list_iter_destroy(i);
988 nft_rule_list_iter_destroy(i);
992 #define NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len) \
997 int nft_ruleset_fprintf(FILE *fp,
const struct nft_ruleset *rs, uint32_t type,
1000 int len = 0, ret = 0;
1002 uint32_t inner_flags = flags;
1005 inner_flags &= ~NFT_OF_EVENT_ANY;
1007 ret = nft_event_header_fprintf(fp, type, flags);
1008 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1010 ret = fprintf(fp,
"%s", nft_ruleset_o_opentag(type));
1011 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1013 if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST)) &&
1014 (!nft_table_list_is_empty(rs->table_list))) {
1015 ret = nft_ruleset_fprintf_tables(fp, rs, type, inner_flags);
1016 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1019 prev = rs->table_list;
1022 if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_CHAINLIST)) &&
1023 (!nft_chain_list_is_empty(rs->chain_list))) {
1024 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(prev, type));
1025 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1027 ret = nft_ruleset_fprintf_chains(fp, rs, type, inner_flags);
1028 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1031 prev = rs->chain_list;
1034 if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_SETLIST)) &&
1035 (!nft_set_list_is_empty(rs->set_list))) {
1036 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(prev, type));
1037 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1039 ret = nft_ruleset_fprintf_sets(fp, rs, type, inner_flags);
1040 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1043 prev = rs->set_list;
1046 if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_RULELIST)) &&
1047 (!nft_rule_list_is_empty(rs->rule_list))) {
1048 ret = fprintf(fp,
"%s", nft_ruleset_o_separator(prev, type));
1049 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1051 ret = nft_ruleset_fprintf_rules(fp, rs, type, inner_flags);
1052 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1055 ret = fprintf(fp,
"%s", nft_ruleset_o_closetag(type));
1056 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1058 ret = nft_event_footer_fprintf(fp, type, flags);
1059 NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
1063 EXPORT_SYMBOL(nft_ruleset_fprintf);