19 #include <netinet/in.h>
23 #include <libmnl/libmnl.h>
24 #include <linux/netfilter/nfnetlink.h>
25 #include <linux/netfilter/nf_tables.h>
27 #include <libnftnl/set.h>
28 #include <libnftnl/expr.h>
30 struct nftnl_set *nftnl_set_alloc(
void)
34 s = calloc(1,
sizeof(
struct nftnl_set));
38 INIT_LIST_HEAD(&s->element_list);
41 EXPORT_SYMBOL(nftnl_set_alloc, nft_set_alloc);
43 void nftnl_set_free(
struct nftnl_set *s)
45 struct nftnl_set_elem *elem, *tmp;
52 list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
53 list_del(&elem->head);
54 nftnl_set_elem_free(elem);
58 EXPORT_SYMBOL(nftnl_set_free, nft_set_free);
60 bool nftnl_set_is_set(
const struct nftnl_set *s, uint16_t attr)
62 return s->flags & (1 << attr);
64 EXPORT_SYMBOL(nftnl_set_is_set, nft_set_attr_is_set);
66 void nftnl_set_unset(
struct nftnl_set *s, uint16_t attr)
70 if (s->flags & (1 << NFTNL_SET_TABLE))
77 if (s->flags & (1 << NFTNL_SET_NAME))
84 case NFTNL_SET_KEY_TYPE:
85 case NFTNL_SET_KEY_LEN:
86 case NFTNL_SET_DATA_TYPE:
87 case NFTNL_SET_DATA_LEN:
88 case NFTNL_SET_FAMILY:
90 case NFTNL_SET_POLICY:
91 case NFTNL_SET_DESC_SIZE:
92 case NFTNL_SET_TIMEOUT:
93 case NFTNL_SET_GC_INTERVAL:
99 s->flags &= ~(1 << attr);
101 EXPORT_SYMBOL(nftnl_set_unset, nft_set_attr_unset);
103 static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
104 [NFTNL_SET_FLAGS] =
sizeof(uint32_t),
105 [NFTNL_SET_KEY_TYPE] =
sizeof(uint32_t),
106 [NFTNL_SET_KEY_LEN] =
sizeof(uint32_t),
107 [NFTNL_SET_DATA_TYPE] =
sizeof(uint32_t),
108 [NFTNL_SET_DATA_LEN] =
sizeof(uint32_t),
109 [NFTNL_SET_FAMILY] =
sizeof(uint32_t),
110 [NFTNL_SET_POLICY] =
sizeof(uint32_t),
111 [NFTNL_SET_DESC_SIZE] =
sizeof(uint32_t),
112 [NFTNL_SET_TIMEOUT] =
sizeof(uint64_t),
113 [NFTNL_SET_GC_INTERVAL] =
sizeof(uint32_t),
116 void nftnl_set_set_data(
struct nftnl_set *s, uint16_t attr,
const void *data,
119 if (attr > NFTNL_SET_MAX)
122 nftnl_assert_validate(data, nftnl_set_validate, attr, data_len);
125 case NFTNL_SET_TABLE:
129 s->table = strdup(data);
135 s->name = strdup(data);
137 case NFTNL_SET_FLAGS:
138 s->set_flags = *((uint32_t *)data);
140 case NFTNL_SET_KEY_TYPE:
141 s->key_type = *((uint32_t *)data);
143 case NFTNL_SET_KEY_LEN:
144 s->key_len = *((uint32_t *)data);
146 case NFTNL_SET_DATA_TYPE:
147 s->data_type = *((uint32_t *)data);
149 case NFTNL_SET_DATA_LEN:
150 s->data_len = *((uint32_t *)data);
152 case NFTNL_SET_FAMILY:
153 s->family = *((uint32_t *)data);
156 s->id = *((uint32_t *)data);
158 case NFTNL_SET_POLICY:
159 s->policy = *((uint32_t *)data);
161 case NFTNL_SET_DESC_SIZE:
162 s->desc.size = *((uint32_t *)data);
164 case NFTNL_SET_TIMEOUT:
165 s->timeout = *((uint64_t *)data);
167 case NFTNL_SET_GC_INTERVAL:
168 s->gc_interval = *((uint32_t *)data);
171 s->flags |= (1 << attr);
173 EXPORT_SYMBOL(nftnl_set_set_data, nft_set_attr_set_data);
175 void nftnl_set_set(
struct nftnl_set *s, uint16_t attr,
const void *data)
177 nftnl_set_set_data(s, attr, data, nftnl_set_validate[attr]);
179 EXPORT_SYMBOL(nftnl_set_set, nft_set_attr_set);
181 void nftnl_set_set_u32(
struct nftnl_set *s, uint16_t attr, uint32_t val)
183 nftnl_set_set(s, attr, &val);
185 EXPORT_SYMBOL(nftnl_set_set_u32, nft_set_attr_set_u32);
187 void nftnl_set_set_u64(
struct nftnl_set *s, uint16_t attr, uint64_t val)
189 nftnl_set_set(s, attr, &val);
191 EXPORT_SYMBOL(nftnl_set_set_u64, nft_set_attr_set_u64);
193 void nftnl_set_set_str(
struct nftnl_set *s, uint16_t attr,
const char *str)
195 nftnl_set_set(s, attr, str);
197 EXPORT_SYMBOL(nftnl_set_set_str, nft_set_attr_set_str);
199 const void *nftnl_set_get_data(
struct nftnl_set *s, uint16_t attr,
202 if (!(s->flags & (1 << attr)))
206 case NFTNL_SET_TABLE:
210 case NFTNL_SET_FLAGS:
211 *data_len =
sizeof(uint32_t);
212 return &s->set_flags;
213 case NFTNL_SET_KEY_TYPE:
214 *data_len =
sizeof(uint32_t);
216 case NFTNL_SET_KEY_LEN:
217 *data_len =
sizeof(uint32_t);
219 case NFTNL_SET_DATA_TYPE:
220 *data_len =
sizeof(uint32_t);
221 return &s->data_type;
222 case NFTNL_SET_DATA_LEN:
223 *data_len =
sizeof(uint32_t);
225 case NFTNL_SET_FAMILY:
226 *data_len =
sizeof(uint32_t);
229 *data_len =
sizeof(uint32_t);
231 case NFTNL_SET_POLICY:
232 *data_len =
sizeof(uint32_t);
234 case NFTNL_SET_DESC_SIZE:
235 *data_len =
sizeof(uint32_t);
236 return &s->desc.size;
237 case NFTNL_SET_TIMEOUT:
238 *data_len =
sizeof(uint64_t);
240 case NFTNL_SET_GC_INTERVAL:
241 *data_len =
sizeof(uint32_t);
242 return &s->gc_interval;
246 EXPORT_SYMBOL(nftnl_set_get_data, nft_set_attr_get_data);
248 const void *nftnl_set_get(
struct nftnl_set *s, uint16_t attr)
251 return nftnl_set_get_data(s, attr, &data_len);
253 EXPORT_SYMBOL(nftnl_set_get, nft_set_attr_get);
255 const char *nftnl_set_get_str(
struct nftnl_set *s, uint16_t attr)
257 return nftnl_set_get(s, attr);
259 EXPORT_SYMBOL(nftnl_set_get_str, nft_set_attr_get_str);
261 uint32_t nftnl_set_get_u32(
struct nftnl_set *s, uint16_t attr)
264 const uint32_t *val = nftnl_set_get_data(s, attr, &data_len);
266 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
268 return val ? *val : 0;
270 EXPORT_SYMBOL(nftnl_set_get_u32, nft_set_attr_get_u32);
272 uint64_t nftnl_set_get_u64(
struct nftnl_set *s, uint16_t attr)
275 const uint64_t *val = nftnl_set_get_data(s, attr, &data_len);
277 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
279 return val ? *val : 0;
281 EXPORT_SYMBOL(nftnl_set_get_u64, nft_set_attr_get_u64);
283 struct nftnl_set *nftnl_set_clone(
const struct nftnl_set *set)
285 struct nftnl_set *newset;
286 struct nftnl_set_elem *elem, *newelem;
288 newset = nftnl_set_alloc();
292 memcpy(newset, set,
sizeof(*set));
294 if (set->flags & (1 << NFTNL_SET_TABLE))
295 newset->table = strdup(set->table);
296 if (set->flags & (1 << NFTNL_SET_NAME))
297 newset->name = strdup(set->name);
299 INIT_LIST_HEAD(&newset->element_list);
300 list_for_each_entry(elem, &set->element_list, head) {
301 newelem = nftnl_set_elem_clone(elem);
305 list_add_tail(&newelem->head, &newset->element_list);
310 nftnl_set_free(newset);
315 nftnl_set_nlmsg_build_desc_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
319 nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC);
320 mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
321 mnl_attr_nest_end(nlh, nest);
324 void nftnl_set_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
326 if (s->flags & (1 << NFTNL_SET_TABLE))
327 mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
328 if (s->flags & (1 << NFTNL_SET_NAME))
329 mnl_attr_put_strz(nlh, NFTA_SET_NAME, s->name);
330 if (s->flags & (1 << NFTNL_SET_FLAGS))
331 mnl_attr_put_u32(nlh, NFTA_SET_FLAGS, htonl(s->set_flags));
332 if (s->flags & (1 << NFTNL_SET_KEY_TYPE))
333 mnl_attr_put_u32(nlh, NFTA_SET_KEY_TYPE, htonl(s->key_type));
334 if (s->flags & (1 << NFTNL_SET_KEY_LEN))
335 mnl_attr_put_u32(nlh, NFTA_SET_KEY_LEN, htonl(s->key_len));
337 if (s->flags & (1 << NFTNL_SET_DATA_TYPE))
338 mnl_attr_put_u32(nlh, NFTA_SET_DATA_TYPE, htonl(s->data_type));
339 if (s->flags & (1 << NFTNL_SET_DATA_LEN))
340 mnl_attr_put_u32(nlh, NFTA_SET_DATA_LEN, htonl(s->data_len));
341 if (s->flags & (1 << NFTNL_SET_ID))
342 mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
343 if (s->flags & (1 << NFTNL_SET_POLICY))
344 mnl_attr_put_u32(nlh, NFTA_SET_POLICY, htonl(s->policy));
345 if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
346 nftnl_set_nlmsg_build_desc_payload(nlh, s);
347 if (s->flags & (1 << NFTNL_SET_TIMEOUT))
348 mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
349 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL))
350 mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
352 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload, nft_set_nlmsg_build_payload);
354 static int nftnl_set_parse_attr_cb(
const struct nlattr *attr,
void *data)
356 const struct nlattr **tb = data;
357 int type = mnl_attr_get_type(attr);
359 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
365 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
369 case NFTA_SET_KEY_TYPE:
370 case NFTA_SET_KEY_LEN:
371 case NFTA_SET_DATA_TYPE:
372 case NFTA_SET_DATA_LEN:
374 case NFTA_SET_POLICY:
375 case NFTA_SET_GC_INTERVAL:
376 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
379 case NFTA_SET_TIMEOUT:
380 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
384 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
393 static int nftnl_set_desc_parse_attr_cb(
const struct nlattr *attr,
void *data)
395 const struct nlattr **tb = data;
396 int type = mnl_attr_get_type(attr);
398 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
402 case NFTA_SET_DESC_SIZE:
403 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
412 static int nftnl_set_desc_parse(
struct nftnl_set *s,
413 const struct nlattr *attr)
415 struct nlattr *tb[NFTA_SET_DESC_MAX + 1] = {};
417 if (mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, tb) < 0)
420 if (tb[NFTA_SET_DESC_SIZE]) {
421 s->desc.size = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DESC_SIZE]));
422 s->flags |= (1 << NFTNL_SET_DESC_SIZE);
428 int nftnl_set_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
430 struct nlattr *tb[NFTA_SET_MAX+1] = {};
431 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
434 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
437 if (tb[NFTA_SET_TABLE]) {
439 s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
440 s->flags |= (1 << NFTNL_SET_TABLE);
442 if (tb[NFTA_SET_NAME]) {
444 s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
445 s->flags |= (1 << NFTNL_SET_NAME);
447 if (tb[NFTA_SET_FLAGS]) {
448 s->set_flags = ntohl(mnl_attr_get_u32(tb[NFTA_SET_FLAGS]));
449 s->flags |= (1 << NFTNL_SET_FLAGS);
451 if (tb[NFTA_SET_KEY_TYPE]) {
452 s->key_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_TYPE]));
453 s->flags |= (1 << NFTNL_SET_KEY_TYPE);
455 if (tb[NFTA_SET_KEY_LEN]) {
456 s->key_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_LEN]));
457 s->flags |= (1 << NFTNL_SET_KEY_LEN);
459 if (tb[NFTA_SET_DATA_TYPE]) {
460 s->data_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_TYPE]));
461 s->flags |= (1 << NFTNL_SET_DATA_TYPE);
463 if (tb[NFTA_SET_DATA_LEN]) {
464 s->data_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_LEN]));
465 s->flags |= (1 << NFTNL_SET_DATA_LEN);
467 if (tb[NFTA_SET_ID]) {
468 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ID]));
469 s->flags |= (1 << NFTNL_SET_ID);
471 if (tb[NFTA_SET_POLICY]) {
472 s->policy = ntohl(mnl_attr_get_u32(tb[NFTA_SET_POLICY]));
473 s->flags |= (1 << NFTNL_SET_POLICY);
475 if (tb[NFTA_SET_TIMEOUT]) {
476 s->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_TIMEOUT]));
477 s->flags |= (1 << NFTNL_SET_TIMEOUT);
479 if (tb[NFTA_SET_GC_INTERVAL]) {
480 s->gc_interval = ntohl(mnl_attr_get_u32(tb[NFTA_SET_GC_INTERVAL]));
481 s->flags |= (1 << NFTNL_SET_GC_INTERVAL);
483 if (tb[NFTA_SET_DESC])
484 ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
486 s->family = nfg->nfgen_family;
487 s->flags |= (1 << NFTNL_SET_FAMILY);
491 EXPORT_SYMBOL(nftnl_set_nlmsg_parse, nft_set_nlmsg_parse);
494 static int nftnl_jansson_parse_set_info(
struct nftnl_set *s, json_t *tree,
495 struct nftnl_parse_err *err)
497 json_t *root = tree, *array, *json_elem;
498 uint32_t flags, key_type, key_len, data_type, data_len, policy, size;
500 const char *name, *table;
501 struct nftnl_set_elem *elem;
503 name = nftnl_jansson_parse_str(root,
"name", err);
507 nftnl_set_set_str(s, NFTNL_SET_NAME, name);
509 table = nftnl_jansson_parse_str(root,
"table", err);
513 nftnl_set_set_str(s, NFTNL_SET_TABLE, table);
515 if (nftnl_jansson_parse_family(root, &family, err) == 0)
516 nftnl_set_set_u32(s, NFTNL_SET_FAMILY, family);
518 if (nftnl_jansson_parse_val(root,
"flags", NFTNL_TYPE_U32, &flags, err) == 0)
519 nftnl_set_set_u32(s, NFTNL_SET_FLAGS, flags);
521 if (nftnl_jansson_parse_val(root,
"key_type", NFTNL_TYPE_U32, &key_type,
523 nftnl_set_set_u32(s, NFTNL_SET_KEY_TYPE, key_type);
525 if (nftnl_jansson_parse_val(root,
"key_len", NFTNL_TYPE_U32, &key_len,
527 nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, key_len);
529 if (nftnl_jansson_node_exist(root,
"data_type")) {
530 if (nftnl_jansson_parse_val(root,
"data_type", NFTNL_TYPE_U32,
531 &data_type, err) < 0)
534 nftnl_set_set_u32(s, NFTNL_SET_DATA_TYPE, data_type);
537 if (nftnl_jansson_node_exist(root,
"data_len")) {
538 if (nftnl_jansson_parse_val(root,
"data_len", NFTNL_TYPE_U32,
542 nftnl_set_set_u32(s, NFTNL_SET_DATA_LEN, data_len);
545 if (nftnl_jansson_node_exist(root,
"policy")) {
546 if (nftnl_jansson_parse_val(root,
"policy", NFTNL_TYPE_U32,
550 nftnl_set_set_u32(s, NFTNL_SET_POLICY, policy);
553 if (nftnl_jansson_node_exist(root,
"desc_size")) {
554 if (nftnl_jansson_parse_val(root,
"desc_size", NFTNL_TYPE_U32,
558 nftnl_set_set_u32(s, NFTNL_SET_DESC_SIZE, size);
561 if (nftnl_jansson_node_exist(root,
"set_elem")) {
562 array = json_object_get(root,
"set_elem");
563 for (i = 0; i < json_array_size(array); i++) {
564 elem = nftnl_set_elem_alloc();
568 json_elem = json_array_get(array, i);
569 if (json_elem == NULL)
572 if (nftnl_jansson_set_elem_parse(elem,
576 list_add_tail(&elem->head, &s->element_list);
584 int nftnl_jansson_parse_set(
struct nftnl_set *s, json_t *tree,
585 struct nftnl_parse_err *err)
589 root = nftnl_jansson_get_node(tree,
"set", err);
593 return nftnl_jansson_parse_set_info(s, root, err);
596 int nftnl_jansson_parse_elem(
struct nftnl_set *s, json_t *tree,
597 struct nftnl_parse_err *err)
601 root = nftnl_jansson_get_node(tree,
"element", err);
605 return nftnl_jansson_parse_set_info(s, root, err);
609 static int nftnl_set_json_parse(
struct nftnl_set *s,
const void *json,
610 struct nftnl_parse_err *err,
611 enum nftnl_parse_input input)
618 tree = nftnl_jansson_create_root(json, &error, err, input);
622 ret = nftnl_jansson_parse_set(s, tree, err);
623 nftnl_jansson_free_root(tree);
633 int nftnl_mxml_set_parse(mxml_node_t *tree,
struct nftnl_set *s,
634 struct nftnl_parse_err *err)
636 mxml_node_t *node = NULL;
637 struct nftnl_set_elem *elem;
638 const char *name, *table;
640 uint32_t set_flags, key_type, key_len;
641 uint32_t data_type, data_len, policy, size;
643 name = nftnl_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
644 NFTNL_XML_MAND, err);
647 nftnl_set_set_str(s, NFTNL_SET_NAME, name);
649 table = nftnl_mxml_str_parse(tree,
"table", MXML_DESCEND_FIRST,
650 NFTNL_XML_MAND, err);
653 nftnl_set_set_str(s, NFTNL_SET_TABLE, table);
655 family = nftnl_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
656 NFTNL_XML_MAND, err);
658 nftnl_set_set_u32(s, NFTNL_SET_FAMILY, family);
660 if (nftnl_mxml_num_parse(tree,
"flags", MXML_DESCEND_FIRST, BASE_DEC,
661 &set_flags, NFTNL_TYPE_U32, NFTNL_XML_MAND,
663 nftnl_set_set_u32(s, NFTNL_SET_FLAGS, set_flags);
665 if (nftnl_mxml_num_parse(tree,
"key_type", MXML_DESCEND_FIRST, BASE_DEC,
666 &key_type, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
667 nftnl_set_set_u32(s, NFTNL_SET_KEY_TYPE, key_type);
669 if (nftnl_mxml_num_parse(tree,
"key_len", MXML_DESCEND_FIRST, BASE_DEC,
670 &key_len, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) < 0)
672 nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, key_len);
674 if (nftnl_mxml_num_parse(tree,
"data_type", MXML_DESCEND_FIRST, BASE_DEC,
675 &data_type, NFTNL_TYPE_U32,
676 NFTNL_XML_OPT, err) == 0) {
677 nftnl_set_set_u32(s, NFTNL_SET_DATA_TYPE, data_type);
679 if (nftnl_mxml_num_parse(tree,
"data_len", MXML_DESCEND_FIRST,
680 BASE_DEC, &data_len, NFTNL_TYPE_U32,
681 NFTNL_XML_MAND, err) == 0)
682 nftnl_set_set_u32(s, NFTNL_SET_DATA_LEN, data_len);
686 if (nftnl_mxml_num_parse(tree,
"policy", MXML_DESCEND_FIRST,
687 BASE_DEC, &policy, NFTNL_TYPE_U32,
688 NFTNL_XML_OPT, err) == 0)
689 nftnl_set_set_u32(s, NFTNL_SET_POLICY, policy);
691 if (nftnl_mxml_num_parse(tree,
"desc_size", MXML_DESCEND_FIRST,
692 BASE_DEC, &size, NFTNL_TYPE_U32,
693 NFTNL_XML_OPT, err) == 0)
694 nftnl_set_set_u32(s, NFTNL_SET_DESC_SIZE, policy);
696 for (node = mxmlFindElement(tree, tree,
"set_elem", NULL,
699 node = mxmlFindElement(node, tree,
"set_elem", NULL,
700 NULL, MXML_DESCEND)) {
702 elem = nftnl_set_elem_alloc();
706 if (nftnl_mxml_set_elem_parse(node, elem, err) < 0)
709 list_add_tail(&elem->head, &s->element_list);
716 static int nftnl_set_xml_parse(
struct nftnl_set *s,
const void *xml,
717 struct nftnl_parse_err *err,
718 enum nftnl_parse_input input)
722 mxml_node_t *tree = nftnl_mxml_build_tree(xml,
"set", err, input);
726 ret = nftnl_mxml_set_parse(tree, s, err);
735 static int nftnl_set_do_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
736 const void *data,
struct nftnl_parse_err *err,
737 enum nftnl_parse_input input)
740 struct nftnl_parse_err perr;
743 case NFTNL_PARSE_XML:
744 ret = nftnl_set_xml_parse(s, data, &perr, input);
746 case NFTNL_PARSE_JSON:
747 ret = nftnl_set_json_parse(s, data, &perr, input);
760 int nftnl_set_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
761 const char *data,
struct nftnl_parse_err *err)
763 return nftnl_set_do_parse(s, type, data, err, NFTNL_PARSE_BUFFER);
765 EXPORT_SYMBOL(nftnl_set_parse, nft_set_parse);
767 int nftnl_set_parse_file(
struct nftnl_set *s,
enum nftnl_parse_type type,
768 FILE *fp,
struct nftnl_parse_err *err)
770 return nftnl_set_do_parse(s, type, fp, err, NFTNL_PARSE_FILE);
772 EXPORT_SYMBOL(nftnl_set_parse_file, nft_set_parse_file);
774 static int nftnl_set_snprintf_json(
char *buf,
size_t size,
struct nftnl_set *s,
775 uint32_t type, uint32_t flags)
777 int len = size, offset = 0, ret;
778 struct nftnl_set_elem *elem;
780 ret = snprintf(buf, len,
"{\"set\":{");
781 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
783 if (s->flags & (1 << NFTNL_SET_NAME)) {
784 ret = snprintf(buf + offset, len,
"\"name\":\"%s\"",
786 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
788 if (s->flags & (1 << NFTNL_SET_TABLE)) {
789 ret = snprintf(buf + offset, len,
",\"table\":\"%s\"",
791 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
793 if (s->flags & (1 << NFTNL_SET_FLAGS)) {
794 ret = snprintf(buf + offset, len,
",\"flags\":%u",
796 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
798 if (s->flags & (1 << NFTNL_SET_FAMILY)) {
799 ret = snprintf(buf + offset, len,
",\"family\":\"%s\"",
800 nftnl_family2str(s->family));
801 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
803 if (s->flags & (1 << NFTNL_SET_KEY_TYPE)) {
804 ret = snprintf(buf + offset, len,
",\"key_type\":%u",
806 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
808 if (s->flags & (1 << NFTNL_SET_KEY_LEN)) {
809 ret = snprintf(buf + offset, len,
",\"key_len\":%u",
811 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
813 if(s->flags & (1 << NFTNL_SET_DATA_TYPE)) {
814 ret = snprintf(buf + offset, len,
815 ",\"data_type\":%u", s->data_type);
816 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
818 if(s->flags & (1 << NFTNL_SET_DATA_LEN)) {
819 ret = snprintf(buf + offset, len,
",\"data_len\":%u", s->data_len);
820 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
823 if (s->flags & (1 << NFTNL_SET_POLICY)) {
824 ret = snprintf(buf + offset, len,
",\"policy\":%u",
826 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
829 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
830 ret = snprintf(buf + offset, len,
",\"desc_size\":%u",
832 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
836 if (list_empty(&s->element_list)){
837 ret = snprintf(buf + offset, len,
"}}");
838 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
842 ret = snprintf(buf + offset, len,
",\"set_elem\":[");
843 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
845 list_for_each_entry(elem, &s->element_list, head) {
846 ret = snprintf(buf + offset, len,
"{");
847 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
849 ret = nftnl_set_elem_snprintf(buf + offset, len, elem, type,
851 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
853 ret = snprintf(buf + offset, len,
"},");
854 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
859 ret = snprintf(buf + offset, len,
"]}}");
860 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
865 static int nftnl_set_snprintf_default(
char *buf,
size_t size,
struct nftnl_set *s,
866 uint32_t type, uint32_t flags)
869 int len = size, offset = 0;
870 struct nftnl_set_elem *elem;
872 ret = snprintf(buf, len,
"%s %s %x",
873 s->name, s->table, s->set_flags);
874 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
876 if (s->flags & (1 << NFTNL_SET_TIMEOUT)) {
877 ret = snprintf(buf + offset, len,
" timeout %"PRIu64
"ms",
879 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
882 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL)) {
883 ret = snprintf(buf + offset, len,
" gc_interval %ums",
885 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
888 if (s->flags & (1 << NFTNL_SET_POLICY)) {
889 ret = snprintf(buf + offset, len,
" policy %u", s->policy);
890 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
893 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
894 ret = snprintf(buf + offset, len,
" size %u", s->desc.size);
895 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
899 if (list_empty(&s->element_list))
902 ret = snprintf(buf+offset, len,
"\n");
903 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
905 list_for_each_entry(elem, &s->element_list, head) {
906 ret = snprintf(buf+offset, len,
"\t");
907 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
909 ret = nftnl_set_elem_snprintf(buf+offset, len, elem, type, flags);
910 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
916 static int nftnl_set_snprintf_xml(
char *buf,
size_t size,
struct nftnl_set *s,
920 int len = size, offset = 0;
921 struct nftnl_set_elem *elem;
923 ret = snprintf(buf, len,
"<set>");
924 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
926 if (s->flags & (1 << NFTNL_SET_FAMILY)) {
927 ret = snprintf(buf + offset, len,
"<family>%s</family>",
928 nftnl_family2str(s->family));
929 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
932 if (s->flags & (1 << NFTNL_SET_TABLE)) {
933 ret = snprintf(buf + offset, len,
"<table>%s</table>",
935 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
938 if (s->flags & (1 << NFTNL_SET_NAME)) {
939 ret = snprintf(buf + offset, len,
"<name>%s</name>",
941 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
944 if (s->flags & (1 << NFTNL_SET_FLAGS)) {
945 ret = snprintf(buf + offset, len,
"<flags>%u</flags>",
947 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
949 if (s->flags & (1 << NFTNL_SET_KEY_TYPE)) {
950 ret = snprintf(buf + offset, len,
"<key_type>%u</key_type>",
952 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
954 if (s->flags & (1 << NFTNL_SET_KEY_LEN)) {
955 ret = snprintf(buf + offset, len,
"<key_len>%u</key_len>",
957 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
960 if (s->flags & (1 << NFTNL_SET_DATA_TYPE)) {
961 ret = snprintf(buf + offset, len,
"<data_type>%u</data_type>",
963 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
965 if (s->flags & (1 << NFTNL_SET_DATA_LEN)) {
966 ret = snprintf(buf + offset, len,
"<data_len>%u</data_len>",
968 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
971 if (s->flags & (1 << NFTNL_SET_POLICY)) {
972 ret = snprintf(buf + offset, len,
"<policy>%u</policy>",
974 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
977 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
978 ret = snprintf(buf + offset, len,
"<desc_size>%u</desc_size>",
980 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
983 if (!list_empty(&s->element_list)) {
984 list_for_each_entry(elem, &s->element_list, head) {
985 ret = nftnl_set_elem_snprintf(buf + offset, len, elem,
986 NFTNL_OUTPUT_XML, flags);
987 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
991 ret = snprintf(buf + offset, len,
"</set>");
992 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
997 static int nftnl_set_cmd_snprintf(
char *buf,
size_t size,
struct nftnl_set *s,
998 uint32_t cmd, uint32_t type, uint32_t flags)
1000 int ret, len = size, offset = 0;
1001 uint32_t inner_flags = flags;
1004 inner_flags &= ~NFTNL_OF_EVENT_ANY;
1006 ret = nftnl_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
1007 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1010 case NFTNL_OUTPUT_DEFAULT:
1011 ret = nftnl_set_snprintf_default(buf+offset, len, s, type,
1014 case NFTNL_OUTPUT_XML:
1015 ret = nftnl_set_snprintf_xml(buf+offset, len, s, inner_flags);
1017 case NFTNL_OUTPUT_JSON:
1018 ret = nftnl_set_snprintf_json(buf+offset, len, s, type,
1025 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1027 ret = nftnl_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
1028 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1033 int nftnl_set_snprintf(
char *buf,
size_t size,
struct nftnl_set *s,
1034 uint32_t type, uint32_t flags)
1036 return nftnl_set_cmd_snprintf(buf, size, s, nftnl_flag2cmd(flags), type,
1039 EXPORT_SYMBOL(nftnl_set_snprintf, nft_set_snprintf);
1041 static inline int nftnl_set_do_snprintf(
char *buf,
size_t size,
void *s,
1042 uint32_t cmd, uint32_t type,
1045 return nftnl_set_snprintf(buf, size, s, type, flags);
1048 int nftnl_set_fprintf(FILE *fp,
struct nftnl_set *s, uint32_t type,
1051 return nftnl_fprintf(fp, s, NFTNL_CMD_UNSPEC, type, flags,
1052 nftnl_set_do_snprintf);
1054 EXPORT_SYMBOL(nftnl_set_fprintf, nft_set_fprintf);
1056 void nftnl_set_elem_add(
struct nftnl_set *s,
struct nftnl_set_elem *elem)
1058 list_add_tail(&elem->head, &s->element_list);
1060 EXPORT_SYMBOL(nftnl_set_elem_add, nft_set_elem_add);
1063 struct list_head list;
1074 INIT_LIST_HEAD(&list->list);
1078 EXPORT_SYMBOL(nftnl_set_list_alloc, nft_set_list_alloc);
1082 struct nftnl_set *s, *tmp;
1084 list_for_each_entry_safe(s, tmp, &list->list, head) {
1090 EXPORT_SYMBOL(nftnl_set_list_free, nft_set_list_free);
1094 return list_empty(&list->list);
1096 EXPORT_SYMBOL(nftnl_set_list_is_empty, nft_set_list_is_empty);
1098 void nftnl_set_list_add(
struct nftnl_set *s,
struct nftnl_set_list *list)
1100 list_add(&s->head, &list->list);
1102 EXPORT_SYMBOL(nftnl_set_list_add, nft_set_list_add);
1104 void nftnl_set_list_add_tail(
struct nftnl_set *s,
struct nftnl_set_list *list)
1106 list_add_tail(&s->head, &list->list);
1108 EXPORT_SYMBOL(nftnl_set_list_add_tail, nft_set_list_add_tail);
1110 void nftnl_set_list_del(
struct nftnl_set *s)
1114 EXPORT_SYMBOL(nftnl_set_list_del, nft_set_list_del);
1117 int (*cb)(
struct nftnl_set *t,
void *data),
void *data)
1119 struct nftnl_set *cur, *tmp;
1122 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
1123 ret = cb(cur, data);
1129 EXPORT_SYMBOL(nftnl_set_list_foreach, nft_set_list_foreach);
1133 struct nftnl_set *cur;
1145 if (nftnl_set_list_is_empty(l))
1148 iter->cur = list_entry(l->list.next,
struct nftnl_set, head);
1152 EXPORT_SYMBOL(nftnl_set_list_iter_create, nft_set_list_iter_create);
1158 EXPORT_SYMBOL(nftnl_set_list_iter_cur, nft_set_list_iter_cur);
1162 struct nftnl_set *s = iter->cur;
1168 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set, head);
1169 if (&iter->cur->head == iter->list->list.next)
1174 EXPORT_SYMBOL(nftnl_set_list_iter_next, nft_set_list_iter_next);
1180 EXPORT_SYMBOL(nftnl_set_list_iter_destroy, nft_set_list_iter_destroy);
1182 static struct nftnl_set *nftnl_set_lookup(
const char *this_set_name,
1186 struct nftnl_set *s;
1187 const char *set_name;
1189 iter = nftnl_set_list_iter_create(set_list);
1193 s = nftnl_set_list_iter_cur(iter);
1195 set_name = nftnl_set_get_str(s, NFTNL_SET_NAME);
1196 if (strcmp(this_set_name, set_name) == 0)
1199 s = nftnl_set_list_iter_next(iter);
1201 nftnl_set_list_iter_destroy(iter);
1206 int nftnl_set_lookup_id(
struct nftnl_expr *e,
1209 const char *set_name;
1210 struct nftnl_set *s;
1212 set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
1213 if (set_name == NULL)
1216 s = nftnl_set_lookup(set_name, set_list);
1220 *set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);