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_ALIAS(nftnl_set_alloc, nft_set_alloc);
43 void nftnl_set_free(
const 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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(nftnl_set_set_str, nft_set_attr_set_str);
199 const void *nftnl_set_get_data(
const 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_ALIAS(nftnl_set_get_data, nft_set_attr_get_data);
248 const void *nftnl_set_get(
const struct nftnl_set *s, uint16_t attr)
251 return nftnl_set_get_data(s, attr, &data_len);
253 EXPORT_SYMBOL_ALIAS(nftnl_set_get, nft_set_attr_get);
255 const char *nftnl_set_get_str(
const struct nftnl_set *s, uint16_t attr)
257 return nftnl_set_get(s, attr);
259 EXPORT_SYMBOL_ALIAS(nftnl_set_get_str, nft_set_attr_get_str);
261 uint32_t nftnl_set_get_u32(
const 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_ALIAS(nftnl_set_get_u32, nft_set_attr_get_u32);
272 uint64_t nftnl_set_get_u64(
const 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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(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_ALIAS(nftnl_set_parse_file, nft_set_parse_file);
774 static int nftnl_set_snprintf_json(
char *buf,
size_t size,
775 const struct nftnl_set *s,
776 uint32_t type, uint32_t flags)
778 int len = size, offset = 0, ret;
779 struct nftnl_set_elem *elem;
781 ret = snprintf(buf, len,
"{\"set\":{");
782 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
784 if (s->flags & (1 << NFTNL_SET_NAME)) {
785 ret = snprintf(buf + offset, len,
"\"name\":\"%s\"",
787 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
789 if (s->flags & (1 << NFTNL_SET_TABLE)) {
790 ret = snprintf(buf + offset, len,
",\"table\":\"%s\"",
792 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
794 if (s->flags & (1 << NFTNL_SET_FLAGS)) {
795 ret = snprintf(buf + offset, len,
",\"flags\":%u",
797 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
799 if (s->flags & (1 << NFTNL_SET_FAMILY)) {
800 ret = snprintf(buf + offset, len,
",\"family\":\"%s\"",
801 nftnl_family2str(s->family));
802 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
804 if (s->flags & (1 << NFTNL_SET_KEY_TYPE)) {
805 ret = snprintf(buf + offset, len,
",\"key_type\":%u",
807 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
809 if (s->flags & (1 << NFTNL_SET_KEY_LEN)) {
810 ret = snprintf(buf + offset, len,
",\"key_len\":%u",
812 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
814 if(s->flags & (1 << NFTNL_SET_DATA_TYPE)) {
815 ret = snprintf(buf + offset, len,
816 ",\"data_type\":%u", s->data_type);
817 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
819 if(s->flags & (1 << NFTNL_SET_DATA_LEN)) {
820 ret = snprintf(buf + offset, len,
",\"data_len\":%u", s->data_len);
821 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
824 if (s->flags & (1 << NFTNL_SET_POLICY)) {
825 ret = snprintf(buf + offset, len,
",\"policy\":%u",
827 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
830 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
831 ret = snprintf(buf + offset, len,
",\"desc_size\":%u",
833 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
837 if (list_empty(&s->element_list)){
838 ret = snprintf(buf + offset, len,
"}}");
839 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
843 ret = snprintf(buf + offset, len,
",\"set_elem\":[");
844 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
846 list_for_each_entry(elem, &s->element_list, head) {
847 ret = snprintf(buf + offset, len,
"{");
848 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
850 ret = nftnl_set_elem_snprintf(buf + offset, len, elem, type,
852 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
854 ret = snprintf(buf + offset, len,
"},");
855 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
860 ret = snprintf(buf + offset, len,
"]}}");
861 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
866 static int nftnl_set_snprintf_default(
char *buf,
size_t size,
867 const struct nftnl_set *s,
868 uint32_t type, uint32_t flags)
871 int len = size, offset = 0;
872 struct nftnl_set_elem *elem;
874 ret = snprintf(buf, len,
"%s %s %x",
875 s->name, s->table, s->set_flags);
876 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
878 if (s->flags & (1 << NFTNL_SET_TIMEOUT)) {
879 ret = snprintf(buf + offset, len,
" timeout %"PRIu64
"ms",
881 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
884 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL)) {
885 ret = snprintf(buf + offset, len,
" gc_interval %ums",
887 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
890 if (s->flags & (1 << NFTNL_SET_POLICY)) {
891 ret = snprintf(buf + offset, len,
" policy %u", s->policy);
892 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
895 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
896 ret = snprintf(buf + offset, len,
" size %u", s->desc.size);
897 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
901 if (list_empty(&s->element_list))
904 ret = snprintf(buf+offset, len,
"\n");
905 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
907 list_for_each_entry(elem, &s->element_list, head) {
908 ret = snprintf(buf+offset, len,
"\t");
909 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
911 ret = nftnl_set_elem_snprintf(buf+offset, len, elem, type, flags);
912 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
918 static int nftnl_set_snprintf_xml(
char *buf,
size_t size,
919 const struct nftnl_set *s, uint32_t flags)
922 int len = size, offset = 0;
923 struct nftnl_set_elem *elem;
925 ret = snprintf(buf, len,
"<set>");
926 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
928 if (s->flags & (1 << NFTNL_SET_FAMILY)) {
929 ret = snprintf(buf + offset, len,
"<family>%s</family>",
930 nftnl_family2str(s->family));
931 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
934 if (s->flags & (1 << NFTNL_SET_TABLE)) {
935 ret = snprintf(buf + offset, len,
"<table>%s</table>",
937 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
940 if (s->flags & (1 << NFTNL_SET_NAME)) {
941 ret = snprintf(buf + offset, len,
"<name>%s</name>",
943 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
946 if (s->flags & (1 << NFTNL_SET_FLAGS)) {
947 ret = snprintf(buf + offset, len,
"<flags>%u</flags>",
949 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
951 if (s->flags & (1 << NFTNL_SET_KEY_TYPE)) {
952 ret = snprintf(buf + offset, len,
"<key_type>%u</key_type>",
954 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
956 if (s->flags & (1 << NFTNL_SET_KEY_LEN)) {
957 ret = snprintf(buf + offset, len,
"<key_len>%u</key_len>",
959 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
962 if (s->flags & (1 << NFTNL_SET_DATA_TYPE)) {
963 ret = snprintf(buf + offset, len,
"<data_type>%u</data_type>",
965 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
967 if (s->flags & (1 << NFTNL_SET_DATA_LEN)) {
968 ret = snprintf(buf + offset, len,
"<data_len>%u</data_len>",
970 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
973 if (s->flags & (1 << NFTNL_SET_POLICY)) {
974 ret = snprintf(buf + offset, len,
"<policy>%u</policy>",
976 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
979 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
980 ret = snprintf(buf + offset, len,
"<desc_size>%u</desc_size>",
982 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
985 if (!list_empty(&s->element_list)) {
986 list_for_each_entry(elem, &s->element_list, head) {
987 ret = nftnl_set_elem_snprintf(buf + offset, len, elem,
988 NFTNL_OUTPUT_XML, flags);
989 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
993 ret = snprintf(buf + offset, len,
"</set>");
994 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
999 static int nftnl_set_cmd_snprintf(
char *buf,
size_t size,
1000 const struct nftnl_set *s, uint32_t cmd,
1001 uint32_t type, uint32_t flags)
1003 int ret, len = size, offset = 0;
1004 uint32_t inner_flags = flags;
1007 inner_flags &= ~NFTNL_OF_EVENT_ANY;
1009 ret = nftnl_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
1010 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1013 case NFTNL_OUTPUT_DEFAULT:
1014 ret = nftnl_set_snprintf_default(buf+offset, len, s, type,
1017 case NFTNL_OUTPUT_XML:
1018 ret = nftnl_set_snprintf_xml(buf+offset, len, s, inner_flags);
1020 case NFTNL_OUTPUT_JSON:
1021 ret = nftnl_set_snprintf_json(buf+offset, len, s, type,
1028 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1030 ret = nftnl_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
1031 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
1036 int nftnl_set_snprintf(
char *buf,
size_t size,
const struct nftnl_set *s,
1037 uint32_t type, uint32_t flags)
1039 return nftnl_set_cmd_snprintf(buf, size, s, nftnl_flag2cmd(flags), type,
1042 EXPORT_SYMBOL_ALIAS(nftnl_set_snprintf, nft_set_snprintf);
1044 static int nftnl_set_do_snprintf(
char *buf,
size_t size,
const void *s,
1045 uint32_t cmd, uint32_t type, uint32_t flags)
1047 return nftnl_set_snprintf(buf, size, s, type, flags);
1050 int nftnl_set_fprintf(FILE *fp,
const struct nftnl_set *s, uint32_t type,
1053 return nftnl_fprintf(fp, s, NFTNL_CMD_UNSPEC, type, flags,
1054 nftnl_set_do_snprintf);
1056 EXPORT_SYMBOL_ALIAS(nftnl_set_fprintf, nft_set_fprintf);
1058 void nftnl_set_elem_add(
struct nftnl_set *s,
struct nftnl_set_elem *elem)
1060 list_add_tail(&elem->head, &s->element_list);
1062 EXPORT_SYMBOL_ALIAS(nftnl_set_elem_add, nft_set_elem_add);
1065 struct list_head list;
1076 INIT_LIST_HEAD(&list->list);
1080 EXPORT_SYMBOL_ALIAS(nftnl_set_list_alloc, nft_set_list_alloc);
1084 struct nftnl_set *s, *tmp;
1086 list_for_each_entry_safe(s, tmp, &list->list, head) {
1092 EXPORT_SYMBOL_ALIAS(nftnl_set_list_free, nft_set_list_free);
1096 return list_empty(&list->list);
1098 EXPORT_SYMBOL_ALIAS(nftnl_set_list_is_empty, nft_set_list_is_empty);
1100 void nftnl_set_list_add(
struct nftnl_set *s,
struct nftnl_set_list *list)
1102 list_add(&s->head, &list->list);
1104 EXPORT_SYMBOL_ALIAS(nftnl_set_list_add, nft_set_list_add);
1106 void nftnl_set_list_add_tail(
struct nftnl_set *s,
struct nftnl_set_list *list)
1108 list_add_tail(&s->head, &list->list);
1110 EXPORT_SYMBOL_ALIAS(nftnl_set_list_add_tail, nft_set_list_add_tail);
1112 void nftnl_set_list_del(
struct nftnl_set *s)
1116 EXPORT_SYMBOL_ALIAS(nftnl_set_list_del, nft_set_list_del);
1119 int (*cb)(
struct nftnl_set *t,
void *data),
void *data)
1121 struct nftnl_set *cur, *tmp;
1124 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
1125 ret = cb(cur, data);
1131 EXPORT_SYMBOL_ALIAS(nftnl_set_list_foreach, nft_set_list_foreach);
1135 struct nftnl_set *cur;
1147 if (nftnl_set_list_is_empty(l))
1150 iter->cur = list_entry(l->list.next,
struct nftnl_set, head);
1154 EXPORT_SYMBOL_ALIAS(nftnl_set_list_iter_create, nft_set_list_iter_create);
1160 EXPORT_SYMBOL_ALIAS(nftnl_set_list_iter_cur, nft_set_list_iter_cur);
1164 struct nftnl_set *s = iter->cur;
1170 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set, head);
1171 if (&iter->cur->head == iter->list->list.next)
1176 EXPORT_SYMBOL_ALIAS(nftnl_set_list_iter_next, nft_set_list_iter_next);
1182 EXPORT_SYMBOL_ALIAS(nftnl_set_list_iter_destroy, nft_set_list_iter_destroy);
1184 static struct nftnl_set *nftnl_set_lookup(
const char *this_set_name,
1188 struct nftnl_set *s;
1189 const char *set_name;
1191 iter = nftnl_set_list_iter_create(set_list);
1195 s = nftnl_set_list_iter_cur(iter);
1197 set_name = nftnl_set_get_str(s, NFTNL_SET_NAME);
1198 if (strcmp(this_set_name, set_name) == 0)
1201 s = nftnl_set_list_iter_next(iter);
1203 nftnl_set_list_iter_destroy(iter);
1208 int nftnl_set_lookup_id(
struct nftnl_expr *e,
1211 const char *set_name;
1212 struct nftnl_set *s;
1214 set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
1215 if (set_name == NULL)
1218 s = nftnl_set_lookup(set_name, set_list);
1222 *set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);