18 #include <netinet/in.h>
22 #include <libmnl/libmnl.h>
23 #include <linux/netfilter/nfnetlink.h>
24 #include <linux/netfilter/nf_tables.h>
26 #include <libnftnl/set.h>
28 #include "linux_list.h"
29 #include "expr/data_reg.h"
31 struct nft_set *nft_set_alloc(
void)
35 s = calloc(1,
sizeof(
struct nft_set));
39 INIT_LIST_HEAD(&s->element_list);
42 EXPORT_SYMBOL(nft_set_alloc);
44 void nft_set_free(
struct nft_set *s)
46 struct nft_set_elem *elem, *tmp;
53 list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
54 list_del(&elem->head);
55 nft_set_elem_free(elem);
59 EXPORT_SYMBOL(nft_set_free);
61 bool nft_set_attr_is_set(
const struct nft_set *s, uint16_t attr)
63 return s->flags & (1 << attr);
65 EXPORT_SYMBOL(nft_set_attr_is_set);
67 void nft_set_attr_unset(
struct nft_set *s, uint16_t attr)
70 case NFT_SET_ATTR_TABLE:
71 if (s->flags & (1 << NFT_SET_ATTR_TABLE))
77 case NFT_SET_ATTR_NAME:
78 if (s->flags & (1 << NFT_SET_ATTR_NAME))
84 case NFT_SET_ATTR_FLAGS:
85 case NFT_SET_ATTR_KEY_TYPE:
86 case NFT_SET_ATTR_KEY_LEN:
87 case NFT_SET_ATTR_DATA_TYPE:
88 case NFT_SET_ATTR_DATA_LEN:
89 case NFT_SET_ATTR_FAMILY:
96 s->flags &= ~(1 << attr);
98 EXPORT_SYMBOL(nft_set_attr_unset);
100 static uint32_t nft_set_attr_validate[NFT_SET_ATTR_MAX + 1] = {
101 [NFT_SET_ATTR_FLAGS] =
sizeof(uint32_t),
102 [NFT_SET_ATTR_KEY_TYPE] =
sizeof(uint32_t),
103 [NFT_SET_ATTR_KEY_LEN] =
sizeof(uint32_t),
104 [NFT_SET_ATTR_DATA_TYPE] =
sizeof(uint32_t),
105 [NFT_SET_ATTR_DATA_LEN] =
sizeof(uint32_t),
106 [NFT_SET_ATTR_FAMILY] =
sizeof(uint32_t),
109 void nft_set_attr_set_data(
struct nft_set *s, uint16_t attr,
const void *data,
112 if (attr > NFT_SET_ATTR_MAX)
115 nft_assert_validate(data, nft_set_attr_validate, attr, data_len);
118 case NFT_SET_ATTR_TABLE:
122 s->table = strdup(data);
124 case NFT_SET_ATTR_NAME:
128 s->name = strdup(data);
130 case NFT_SET_ATTR_FLAGS:
131 s->set_flags = *((uint32_t *)data);
133 case NFT_SET_ATTR_KEY_TYPE:
134 s->key_type = *((uint32_t *)data);
136 case NFT_SET_ATTR_KEY_LEN:
137 s->key_len = *((uint32_t *)data);
139 case NFT_SET_ATTR_DATA_TYPE:
140 s->data_type = *((uint32_t *)data);
142 case NFT_SET_ATTR_DATA_LEN:
143 s->data_len = *((uint32_t *)data);
145 case NFT_SET_ATTR_FAMILY:
146 s->family = *((uint32_t *)data);
148 case NFT_SET_ATTR_ID:
149 s->id = *((uint32_t *)data);
152 s->flags |= (1 << attr);
154 EXPORT_SYMBOL(nft_set_attr_set_data);
156 void nft_set_attr_set(
struct nft_set *s, uint16_t attr,
const void *data)
158 nft_set_attr_set_data(s, attr, data, nft_set_attr_validate[attr]);
160 EXPORT_SYMBOL(nft_set_attr_set);
162 void nft_set_attr_set_u32(
struct nft_set *s, uint16_t attr, uint32_t val)
164 nft_set_attr_set(s, attr, &val);
166 EXPORT_SYMBOL(nft_set_attr_set_u32);
168 void nft_set_attr_set_str(
struct nft_set *s, uint16_t attr,
const char *str)
170 nft_set_attr_set(s, attr, str);
172 EXPORT_SYMBOL(nft_set_attr_set_str);
174 const void *nft_set_attr_get_data(
struct nft_set *s, uint16_t attr,
177 if (!(s->flags & (1 << attr)))
181 case NFT_SET_ATTR_TABLE:
183 case NFT_SET_ATTR_NAME:
185 case NFT_SET_ATTR_FLAGS:
186 *data_len =
sizeof(uint32_t);
187 return &s->set_flags;
188 case NFT_SET_ATTR_KEY_TYPE:
189 *data_len =
sizeof(uint32_t);
191 case NFT_SET_ATTR_KEY_LEN:
192 *data_len =
sizeof(uint32_t);
194 case NFT_SET_ATTR_DATA_TYPE:
195 *data_len =
sizeof(uint32_t);
196 return &s->data_type;
197 case NFT_SET_ATTR_DATA_LEN:
198 *data_len =
sizeof(uint32_t);
200 case NFT_SET_ATTR_FAMILY:
201 *data_len =
sizeof(uint32_t);
203 case NFT_SET_ATTR_ID:
204 *data_len =
sizeof(uint32_t);
209 EXPORT_SYMBOL(nft_set_attr_get_data);
211 const void *nft_set_attr_get(
struct nft_set *s, uint16_t attr)
214 return nft_set_attr_get_data(s, attr, &data_len);
216 EXPORT_SYMBOL(nft_set_attr_get);
218 const char *nft_set_attr_get_str(
struct nft_set *s, uint16_t attr)
220 return nft_set_attr_get(s, attr);
222 EXPORT_SYMBOL(nft_set_attr_get_str);
224 uint32_t nft_set_attr_get_u32(
struct nft_set *s, uint16_t attr)
227 const uint32_t *val = nft_set_attr_get_data(s, attr, &data_len);
229 nft_assert(val, attr, data_len ==
sizeof(uint32_t));
231 return val ? *val : 0;
233 EXPORT_SYMBOL(nft_set_attr_get_u32);
235 void nft_set_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nft_set *s)
237 if (s->flags & (1 << NFT_SET_ATTR_TABLE))
238 mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
239 if (s->flags & (1 << NFT_SET_ATTR_NAME))
240 mnl_attr_put_strz(nlh, NFTA_SET_NAME, s->name);
241 if (s->flags & (1 << NFT_SET_ATTR_FLAGS))
242 mnl_attr_put_u32(nlh, NFTA_SET_FLAGS, htonl(s->set_flags));
243 if (s->flags & (1 << NFT_SET_ATTR_KEY_TYPE))
244 mnl_attr_put_u32(nlh, NFTA_SET_KEY_TYPE, htonl(s->key_type));
245 if (s->flags & (1 << NFT_SET_ATTR_KEY_LEN))
246 mnl_attr_put_u32(nlh, NFTA_SET_KEY_LEN, htonl(s->key_len));
248 if (s->flags & (1 << NFT_SET_ATTR_DATA_TYPE))
249 mnl_attr_put_u32(nlh, NFTA_SET_DATA_TYPE, htonl(s->data_type));
250 if (s->flags & (1 << NFT_SET_ATTR_DATA_LEN))
251 mnl_attr_put_u32(nlh, NFTA_SET_DATA_LEN, htonl(s->data_len));
252 if (s->flags & (1 << NFT_SET_ATTR_ID))
253 mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
255 EXPORT_SYMBOL(nft_set_nlmsg_build_payload);
257 static int nft_set_parse_attr_cb(
const struct nlattr *attr,
void *data)
259 const struct nlattr **tb = data;
260 int type = mnl_attr_get_type(attr);
262 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
268 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
269 perror(
"mnl_attr_validate");
274 case NFTA_SET_KEY_TYPE:
275 case NFTA_SET_KEY_LEN:
276 case NFTA_SET_DATA_TYPE:
277 case NFTA_SET_DATA_LEN:
279 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
280 perror(
"mnl_attr_validate");
290 int nft_set_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nft_set *s)
292 struct nlattr *tb[NFTA_SET_MAX+1] = {};
293 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
295 if (mnl_attr_parse(nlh,
sizeof(*nfg), nft_set_parse_attr_cb, tb) < 0)
298 if (tb[NFTA_SET_TABLE]) {
299 s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
300 s->flags |= (1 << NFT_SET_ATTR_TABLE);
302 if (tb[NFTA_SET_NAME]) {
303 s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
304 s->flags |= (1 << NFT_SET_ATTR_NAME);
306 if (tb[NFTA_SET_FLAGS]) {
307 s->set_flags = ntohl(mnl_attr_get_u32(tb[NFTA_SET_FLAGS]));
308 s->flags |= (1 << NFT_SET_ATTR_FLAGS);
310 if (tb[NFTA_SET_KEY_TYPE]) {
311 s->key_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_TYPE]));
312 s->flags |= (1 << NFT_SET_ATTR_KEY_TYPE);
314 if (tb[NFTA_SET_KEY_LEN]) {
315 s->key_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_LEN]));
316 s->flags |= (1 << NFT_SET_ATTR_KEY_LEN);
318 if (tb[NFTA_SET_DATA_TYPE]) {
319 s->data_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_TYPE]));
320 s->flags |= (1 << NFT_SET_ATTR_DATA_TYPE);
322 if (tb[NFTA_SET_DATA_LEN]) {
323 s->data_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_LEN]));
324 s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
326 if (tb[NFTA_SET_ID]) {
327 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ID]));
328 s->flags |= (1 << NFT_SET_ATTR_ID);
330 s->family = nfg->nfgen_family;
331 s->flags |= (1 << NFT_SET_ATTR_FAMILY);
335 EXPORT_SYMBOL(nft_set_nlmsg_parse);
338 int nft_jansson_parse_set(
struct nft_set *s, json_t *tree,
339 struct nft_parse_err *err)
341 json_t *root, *array, *json_elem;
342 uint32_t flags, key_type, key_len, data_type, data_len;
344 const char *name, *table;
345 struct nft_set_elem *elem;
347 root = nft_jansson_get_node(tree,
"set", err);
351 name = nft_jansson_parse_str(root,
"name", err);
355 nft_set_attr_set_str(s, NFT_SET_ATTR_NAME, name);
357 table = nft_jansson_parse_str(root,
"table", err);
361 nft_set_attr_set_str(s, NFT_SET_ATTR_TABLE, table);
363 if (nft_jansson_parse_family(root, &family, err) == 0)
364 nft_set_attr_set_u32(s, NFT_SET_ATTR_FAMILY, family);
366 if (nft_jansson_parse_val(root,
"flags", NFT_TYPE_U32, &flags, err) == 0)
367 nft_set_attr_set_u32(s, NFT_SET_ATTR_FLAGS, flags);
369 if (nft_jansson_parse_val(root,
"key_type", NFT_TYPE_U32, &key_type,
371 nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_TYPE, key_type);
373 if (nft_jansson_parse_val(root,
"key_len", NFT_TYPE_U32, &key_len,
375 nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_LEN, key_len);
377 if (nft_jansson_node_exist(root,
"data_type")) {
378 if (nft_jansson_parse_val(root,
"data_type", NFT_TYPE_U32,
379 &data_type, err) < 0)
382 nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_TYPE, data_type);
385 if (nft_jansson_node_exist(root,
"data_len")) {
386 if (nft_jansson_parse_val(root,
"data_len", NFT_TYPE_U32,
390 nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_LEN, data_len);
393 if (nft_jansson_node_exist(root,
"set_elem")) {
394 array = json_object_get(root,
"set_elem");
395 for (i = 0; i < json_array_size(array); i++) {
396 elem = nft_set_elem_alloc();
400 json_elem = json_array_get(array, i);
401 if (json_elem == NULL)
404 if (nft_jansson_set_elem_parse(elem,
408 list_add_tail(&elem->head, &s->element_list);
417 static int nft_set_json_parse(
struct nft_set *s,
const void *json,
418 struct nft_parse_err *err,
419 enum nft_parse_input input)
426 tree = nft_jansson_create_root(json, &error, err, input);
430 ret = nft_jansson_parse_set(s, tree, err);
431 nft_jansson_free_root(tree);
441 int nft_mxml_set_parse(mxml_node_t *tree,
struct nft_set *s,
442 struct nft_parse_err *err)
444 mxml_node_t *node = NULL;
445 struct nft_set_elem *elem;
446 const char *name, *table;
448 uint32_t set_flags, key_type, key_len;
449 uint32_t data_type, data_len;
451 name = nft_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
455 nft_set_attr_set_str(s, NFT_SET_ATTR_NAME, name);
457 table = nft_mxml_str_parse(tree,
"table", MXML_DESCEND_FIRST,
461 nft_set_attr_set_str(s, NFT_SET_ATTR_TABLE, table);
463 family = nft_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
466 nft_set_attr_set_u32(s, NFT_SET_ATTR_FAMILY, family);
468 if (nft_mxml_num_parse(tree,
"flags", MXML_DESCEND_FIRST, BASE_DEC,
469 &set_flags, NFT_TYPE_U32, NFT_XML_MAND,
471 nft_set_attr_set_u32(s, NFT_SET_ATTR_FLAGS, set_flags);
473 if (nft_mxml_num_parse(tree,
"key_type", MXML_DESCEND_FIRST, BASE_DEC,
474 &key_type, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
475 nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_TYPE, key_type);
477 if (nft_mxml_num_parse(tree,
"key_len", MXML_DESCEND_FIRST, BASE_DEC,
478 &key_len, NFT_TYPE_U32, NFT_XML_MAND, err) < 0)
480 nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_LEN, key_len);
482 if (nft_mxml_num_parse(tree,
"data_type", MXML_DESCEND_FIRST, BASE_DEC,
483 &data_type, NFT_TYPE_U32,
484 NFT_XML_OPT, err) == 0) {
485 nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_TYPE, data_type);
487 if (nft_mxml_num_parse(tree,
"data_len", MXML_DESCEND_FIRST,
488 BASE_DEC, &data_len, NFT_TYPE_U32,
489 NFT_XML_MAND, err) == 0)
490 nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_LEN, data_len);
494 for (node = mxmlFindElement(tree, tree,
"set_elem", NULL,
497 node = mxmlFindElement(node, tree,
"set_elem", NULL,
498 NULL, MXML_DESCEND)) {
500 elem = nft_set_elem_alloc();
504 if (nft_mxml_set_elem_parse(node, elem, err) < 0)
507 list_add_tail(&elem->head, &s->element_list);
514 static int nft_set_xml_parse(
struct nft_set *s,
const void *xml,
515 struct nft_parse_err *err,
516 enum nft_parse_input input)
520 mxml_node_t *tree = nft_mxml_build_tree(xml,
"set", err, input);
524 ret = nft_mxml_set_parse(tree, s, err);
533 static int nft_set_do_parse(
struct nft_set *s,
enum nft_parse_type type,
534 const void *data,
struct nft_parse_err *err,
535 enum nft_parse_input input)
538 struct nft_parse_err perr;
542 ret = nft_set_xml_parse(s, data, &perr, input);
545 ret = nft_set_json_parse(s, data, &perr, input);
558 int nft_set_parse(
struct nft_set *s,
enum nft_parse_type type,
559 const char *data,
struct nft_parse_err *err)
561 return nft_set_do_parse(s, type, data, err, NFT_PARSE_BUFFER);
563 EXPORT_SYMBOL(nft_set_parse);
565 int nft_set_parse_file(
struct nft_set *s,
enum nft_parse_type type,
566 FILE *fp,
struct nft_parse_err *err)
568 return nft_set_do_parse(s, type, fp, err, NFT_PARSE_FILE);
570 EXPORT_SYMBOL(nft_set_parse_file);
572 static int nft_set_snprintf_json(
char *buf,
size_t size,
struct nft_set *s,
573 uint32_t type, uint32_t flags)
575 int len = size, offset = 0, ret;
576 struct nft_set_elem *elem;
578 ret = snprintf(buf, len,
"{\"set\":{");
579 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
581 if (s->flags & (1 << NFT_SET_ATTR_NAME)) {
582 ret = snprintf(buf + offset, len,
"\"name\":\"%s\"",
584 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
586 if (s->flags & (1 << NFT_SET_ATTR_TABLE)) {
587 ret = snprintf(buf + offset, len,
",\"table\":\"%s\"",
589 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
591 if (s->flags & (1 << NFT_SET_ATTR_FLAGS)) {
592 ret = snprintf(buf + offset, len,
",\"flags\":%u",
594 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
596 if (s->flags & (1 << NFT_SET_ATTR_FAMILY)) {
597 ret = snprintf(buf + offset, len,
",\"family\":\"%s\"",
598 nft_family2str(s->family));
599 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
601 if (s->flags & (1 << NFT_SET_ATTR_KEY_TYPE)) {
602 ret = snprintf(buf + offset, len,
",\"key_type\":%u",
604 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
606 if (s->flags & (1 << NFT_SET_ATTR_KEY_LEN)) {
607 ret = snprintf(buf + offset, len,
",\"key_len\":%u",
609 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
611 if(s->flags & (1 << NFT_SET_ATTR_DATA_TYPE)) {
612 ret = snprintf(buf + offset, len,
613 ",\"data_type\":%u", s->data_type);
614 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
616 if(s->flags & (1 << NFT_SET_ATTR_DATA_LEN)) {
617 ret = snprintf(buf + offset, len,
",\"data_len\":%u", s->data_len);
618 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
621 if (list_empty(&s->element_list)){
622 ret = snprintf(buf + offset, len,
"}}");
623 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
627 ret = snprintf(buf + offset, len,
",\"set_elem\":[");
628 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
630 list_for_each_entry(elem, &s->element_list, head) {
631 ret = snprintf(buf + offset, len,
"{");
632 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
634 ret = nft_set_elem_snprintf(buf + offset, len, elem, type,
636 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
638 ret = snprintf(buf + offset, len,
"},");
639 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
644 ret = snprintf(buf + offset, len,
"]}}");
645 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
650 static int nft_set_snprintf_default(
char *buf,
size_t size,
struct nft_set *s,
651 uint32_t type, uint32_t flags)
654 int len = size, offset = 0;
655 struct nft_set_elem *elem;
657 ret = snprintf(buf, len,
"%s %s %x",
658 s->name, s->table, s->set_flags);
659 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
662 if (list_empty(&s->element_list))
665 ret = snprintf(buf+offset, len,
"\n");
666 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
668 list_for_each_entry(elem, &s->element_list, head) {
669 ret = snprintf(buf+offset, len,
"\t");
670 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
672 ret = nft_set_elem_snprintf(buf+offset, len, elem, type, flags);
673 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
679 static int nft_set_snprintf_xml(
char *buf,
size_t size,
struct nft_set *s,
683 int len = size, offset = 0;
684 struct nft_set_elem *elem;
686 ret = snprintf(buf, len,
"<set>");
687 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
689 if (s->flags & (1 << NFT_SET_ATTR_FAMILY)) {
690 ret = snprintf(buf + offset, len,
"<family>%s</family>",
691 nft_family2str(s->family));
692 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
695 if (s->flags & (1 << NFT_SET_ATTR_TABLE)) {
696 ret = snprintf(buf + offset, len,
"<table>%s</table>",
698 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
701 if (s->flags & (1 << NFT_SET_ATTR_NAME)) {
702 ret = snprintf(buf + offset, len,
"<name>%s</name>",
704 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
707 if (s->flags & (1 << NFT_SET_ATTR_FLAGS)) {
708 ret = snprintf(buf + offset, len,
"<flags>%u</flags>",
710 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
712 if (s->flags & (1 << NFT_SET_ATTR_KEY_TYPE)) {
713 ret = snprintf(buf + offset, len,
"<key_type>%u</key_type>",
715 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
717 if (s->flags & (1 << NFT_SET_ATTR_KEY_LEN)) {
718 ret = snprintf(buf + offset, len,
"<key_len>%u</key_len>",
720 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
723 if (s->flags & (1 << NFT_SET_ATTR_DATA_TYPE)) {
724 ret = snprintf(buf + offset, len,
"<data_type>%u</data_type>",
726 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
728 if (s->flags & (1 << NFT_SET_ATTR_DATA_LEN)) {
729 ret = snprintf(buf + offset, len,
"<data_len>%u</data_len>",
731 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
734 if (!list_empty(&s->element_list)) {
735 list_for_each_entry(elem, &s->element_list, head) {
736 ret = nft_set_elem_snprintf(buf + offset, len, elem,
737 NFT_OUTPUT_XML, flags);
738 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
742 ret = snprintf(buf + offset, len,
"</set>");
743 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
748 int nft_set_snprintf(
char *buf,
size_t size,
struct nft_set *s,
749 uint32_t type, uint32_t flags)
751 int ret, len = size, offset = 0;
752 uint32_t inner_flags = flags;
755 inner_flags &= ~NFT_OF_EVENT_ANY;
757 ret = nft_event_header_snprintf(buf+offset, len, type, flags);
758 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
761 case NFT_OUTPUT_DEFAULT:
762 ret = nft_set_snprintf_default(buf+offset, len, s, type,
766 ret = nft_set_snprintf_xml(buf+offset, len, s, inner_flags);
768 case NFT_OUTPUT_JSON:
769 ret = nft_set_snprintf_json(buf+offset, len, s, type,
776 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
778 ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
779 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
783 EXPORT_SYMBOL(nft_set_snprintf);
785 static inline int nft_set_do_snprintf(
char *buf,
size_t size,
void *s,
786 uint32_t type, uint32_t flags)
788 return nft_set_snprintf(buf, size, s, type, flags);
791 int nft_set_fprintf(FILE *fp,
struct nft_set *s, uint32_t type,
794 return nft_fprintf(fp, s, type, flags, nft_set_do_snprintf);
796 EXPORT_SYMBOL(nft_set_fprintf);
798 void nft_set_elem_add(
struct nft_set *s,
struct nft_set_elem *elem)
800 list_add_tail(&elem->head, &s->element_list);
802 EXPORT_SYMBOL(nft_set_elem_add);
805 struct list_head list;
816 INIT_LIST_HEAD(&list->list);
820 EXPORT_SYMBOL(nft_set_list_alloc);
824 struct nft_set *s, *tmp;
826 list_for_each_entry_safe(s, tmp, &list->list, head) {
832 EXPORT_SYMBOL(nft_set_list_free);
836 return list_empty(&list->list);
838 EXPORT_SYMBOL(nft_set_list_is_empty);
840 void nft_set_list_add(
struct nft_set *s,
struct nft_set_list *list)
842 list_add(&s->head, &list->list);
844 EXPORT_SYMBOL(nft_set_list_add);
846 void nft_set_list_add_tail(
struct nft_set *s,
struct nft_set_list *list)
848 list_add_tail(&s->head, &list->list);
850 EXPORT_SYMBOL(nft_set_list_add_tail);
852 void nft_set_list_del(
struct nft_set *s)
856 EXPORT_SYMBOL(nft_set_list_del);
859 int (*cb)(
struct nft_set *t,
void *data),
void *data)
861 struct nft_set *cur, *tmp;
864 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
871 EXPORT_SYMBOL(nft_set_list_foreach);
887 iter->cur = list_entry(l->list.next,
struct nft_set, head);
891 EXPORT_SYMBOL(nft_set_list_iter_create);
897 EXPORT_SYMBOL(nft_set_list_iter_cur);
901 struct nft_set *s = iter->cur;
904 iter->cur = list_entry(iter->cur->head.next,
struct nft_set, head);
905 if (&iter->cur->head == iter->list->list.next)
910 EXPORT_SYMBOL(nft_set_list_iter_next);
916 EXPORT_SYMBOL(nft_set_list_iter_destroy);