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);
43 void nftnl_set_free(
const struct nftnl_set *s)
45 struct nftnl_set_elem *elem, *tmp;
47 if (s->flags & (1 << NFTNL_SET_TABLE))
49 if (s->flags & (1 << NFTNL_SET_NAME))
51 if (s->flags & (1 << NFTNL_SET_USERDATA))
54 list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
55 list_del(&elem->head);
56 nftnl_set_elem_free(elem);
60 EXPORT_SYMBOL(nftnl_set_free);
62 bool nftnl_set_is_set(
const struct nftnl_set *s, uint16_t attr)
64 return s->flags & (1 << attr);
66 EXPORT_SYMBOL(nftnl_set_is_set);
68 void nftnl_set_unset(
struct nftnl_set *s, uint16_t attr)
70 if (!(s->flags & (1 << attr)))
81 case NFTNL_SET_KEY_TYPE:
82 case NFTNL_SET_KEY_LEN:
83 case NFTNL_SET_DATA_TYPE:
84 case NFTNL_SET_DATA_LEN:
85 case NFTNL_SET_OBJ_TYPE:
86 case NFTNL_SET_FAMILY:
88 case NFTNL_SET_POLICY:
89 case NFTNL_SET_DESC_SIZE:
90 case NFTNL_SET_TIMEOUT:
91 case NFTNL_SET_GC_INTERVAL:
93 case NFTNL_SET_USERDATA:
100 s->flags &= ~(1 << attr);
102 EXPORT_SYMBOL(nftnl_set_unset);
104 static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
105 [NFTNL_SET_FLAGS] =
sizeof(uint32_t),
106 [NFTNL_SET_KEY_TYPE] =
sizeof(uint32_t),
107 [NFTNL_SET_KEY_LEN] =
sizeof(uint32_t),
108 [NFTNL_SET_DATA_TYPE] =
sizeof(uint32_t),
109 [NFTNL_SET_DATA_LEN] =
sizeof(uint32_t),
110 [NFTNL_SET_OBJ_TYPE] =
sizeof(uint32_t),
111 [NFTNL_SET_FAMILY] =
sizeof(uint32_t),
112 [NFTNL_SET_POLICY] =
sizeof(uint32_t),
113 [NFTNL_SET_DESC_SIZE] =
sizeof(uint32_t),
114 [NFTNL_SET_TIMEOUT] =
sizeof(uint64_t),
115 [NFTNL_SET_GC_INTERVAL] =
sizeof(uint32_t),
118 int nftnl_set_set_data(
struct nftnl_set *s, uint16_t attr,
const void *data,
121 nftnl_assert_attr_exists(attr, NFTNL_SET_MAX);
122 nftnl_assert_validate(data, nftnl_set_validate, attr, data_len);
125 case NFTNL_SET_TABLE:
126 if (s->flags & (1 << NFTNL_SET_TABLE))
129 s->table = strdup(data);
134 if (s->flags & (1 << NFTNL_SET_NAME))
137 s->name = strdup(data);
141 case NFTNL_SET_FLAGS:
142 s->set_flags = *((uint32_t *)data);
144 case NFTNL_SET_KEY_TYPE:
145 s->key_type = *((uint32_t *)data);
147 case NFTNL_SET_KEY_LEN:
148 s->key_len = *((uint32_t *)data);
150 case NFTNL_SET_DATA_TYPE:
151 s->data_type = *((uint32_t *)data);
153 case NFTNL_SET_DATA_LEN:
154 s->data_len = *((uint32_t *)data);
156 case NFTNL_SET_OBJ_TYPE:
157 s->obj_type = *((uint32_t *)data);
159 case NFTNL_SET_FAMILY:
160 s->family = *((uint32_t *)data);
163 s->id = *((uint32_t *)data);
165 case NFTNL_SET_POLICY:
166 s->policy = *((uint32_t *)data);
168 case NFTNL_SET_DESC_SIZE:
169 s->desc.size = *((uint32_t *)data);
171 case NFTNL_SET_TIMEOUT:
172 s->timeout = *((uint64_t *)data);
174 case NFTNL_SET_GC_INTERVAL:
175 s->gc_interval = *((uint32_t *)data);
177 case NFTNL_SET_USERDATA:
178 if (s->flags & (1 << NFTNL_SET_USERDATA))
181 s->user.data = malloc(data_len);
184 memcpy(s->user.data, data, data_len);
185 s->user.len = data_len;
188 s->flags |= (1 << attr);
191 EXPORT_SYMBOL(nftnl_set_set_data);
193 int nftnl_set_set(
struct nftnl_set *s, uint16_t attr,
const void *data)
195 return nftnl_set_set_data(s, attr, data, nftnl_set_validate[attr]);
197 EXPORT_SYMBOL(nftnl_set_set);
199 void nftnl_set_set_u32(
struct nftnl_set *s, uint16_t attr, uint32_t val)
201 nftnl_set_set(s, attr, &val);
203 EXPORT_SYMBOL(nftnl_set_set_u32);
205 void nftnl_set_set_u64(
struct nftnl_set *s, uint16_t attr, uint64_t val)
207 nftnl_set_set(s, attr, &val);
209 EXPORT_SYMBOL(nftnl_set_set_u64);
211 int nftnl_set_set_str(
struct nftnl_set *s, uint16_t attr,
const char *str)
213 return nftnl_set_set_data(s, attr, str, strlen(str) + 1);
215 EXPORT_SYMBOL(nftnl_set_set_str);
217 const void *nftnl_set_get_data(
const struct nftnl_set *s, uint16_t attr,
220 if (!(s->flags & (1 << attr)))
224 case NFTNL_SET_TABLE:
225 *data_len = strlen(s->table) + 1;
228 *data_len = strlen(s->name) + 1;
230 case NFTNL_SET_FLAGS:
231 *data_len =
sizeof(uint32_t);
232 return &s->set_flags;
233 case NFTNL_SET_KEY_TYPE:
234 *data_len =
sizeof(uint32_t);
236 case NFTNL_SET_KEY_LEN:
237 *data_len =
sizeof(uint32_t);
239 case NFTNL_SET_DATA_TYPE:
240 *data_len =
sizeof(uint32_t);
241 return &s->data_type;
242 case NFTNL_SET_DATA_LEN:
243 *data_len =
sizeof(uint32_t);
245 case NFTNL_SET_OBJ_TYPE:
246 *data_len =
sizeof(uint32_t);
248 case NFTNL_SET_FAMILY:
249 *data_len =
sizeof(uint32_t);
252 *data_len =
sizeof(uint32_t);
254 case NFTNL_SET_POLICY:
255 *data_len =
sizeof(uint32_t);
257 case NFTNL_SET_DESC_SIZE:
258 *data_len =
sizeof(uint32_t);
259 return &s->desc.size;
260 case NFTNL_SET_TIMEOUT:
261 *data_len =
sizeof(uint64_t);
263 case NFTNL_SET_GC_INTERVAL:
264 *data_len =
sizeof(uint32_t);
265 return &s->gc_interval;
266 case NFTNL_SET_USERDATA:
267 *data_len = s->user.len;
272 EXPORT_SYMBOL(nftnl_set_get_data);
274 const void *nftnl_set_get(
const struct nftnl_set *s, uint16_t attr)
277 return nftnl_set_get_data(s, attr, &data_len);
279 EXPORT_SYMBOL(nftnl_set_get);
281 const char *nftnl_set_get_str(
const struct nftnl_set *s, uint16_t attr)
283 return nftnl_set_get(s, attr);
285 EXPORT_SYMBOL(nftnl_set_get_str);
287 uint32_t nftnl_set_get_u32(
const struct nftnl_set *s, uint16_t attr)
290 const uint32_t *val = nftnl_set_get_data(s, attr, &data_len);
292 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
294 return val ? *val : 0;
296 EXPORT_SYMBOL(nftnl_set_get_u32);
298 uint64_t nftnl_set_get_u64(
const struct nftnl_set *s, uint16_t attr)
301 const uint64_t *val = nftnl_set_get_data(s, attr, &data_len);
303 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
305 return val ? *val : 0;
307 EXPORT_SYMBOL(nftnl_set_get_u64);
309 struct nftnl_set *nftnl_set_clone(
const struct nftnl_set *set)
311 struct nftnl_set *newset;
312 struct nftnl_set_elem *elem, *newelem;
314 newset = nftnl_set_alloc();
318 memcpy(newset, set,
sizeof(*set));
320 if (set->flags & (1 << NFTNL_SET_TABLE)) {
321 newset->table = strdup(set->table);
325 if (set->flags & (1 << NFTNL_SET_NAME)) {
326 newset->name = strdup(set->name);
331 INIT_LIST_HEAD(&newset->element_list);
332 list_for_each_entry(elem, &set->element_list, head) {
333 newelem = nftnl_set_elem_clone(elem);
337 list_add_tail(&newelem->head, &newset->element_list);
342 nftnl_set_free(newset);
347 nftnl_set_nlmsg_build_desc_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
351 nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC);
352 mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
353 mnl_attr_nest_end(nlh, nest);
356 void nftnl_set_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
358 if (s->flags & (1 << NFTNL_SET_TABLE))
359 mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
360 if (s->flags & (1 << NFTNL_SET_NAME))
361 mnl_attr_put_strz(nlh, NFTA_SET_NAME, s->name);
362 if (s->flags & (1 << NFTNL_SET_FLAGS))
363 mnl_attr_put_u32(nlh, NFTA_SET_FLAGS, htonl(s->set_flags));
364 if (s->flags & (1 << NFTNL_SET_KEY_TYPE))
365 mnl_attr_put_u32(nlh, NFTA_SET_KEY_TYPE, htonl(s->key_type));
366 if (s->flags & (1 << NFTNL_SET_KEY_LEN))
367 mnl_attr_put_u32(nlh, NFTA_SET_KEY_LEN, htonl(s->key_len));
369 if (s->flags & (1 << NFTNL_SET_DATA_TYPE))
370 mnl_attr_put_u32(nlh, NFTA_SET_DATA_TYPE, htonl(s->data_type));
371 if (s->flags & (1 << NFTNL_SET_DATA_LEN))
372 mnl_attr_put_u32(nlh, NFTA_SET_DATA_LEN, htonl(s->data_len));
373 if (s->flags & (1 << NFTNL_SET_OBJ_TYPE))
374 mnl_attr_put_u32(nlh, NFTA_SET_OBJ_TYPE, htonl(s->obj_type));
375 if (s->flags & (1 << NFTNL_SET_ID))
376 mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
377 if (s->flags & (1 << NFTNL_SET_POLICY))
378 mnl_attr_put_u32(nlh, NFTA_SET_POLICY, htonl(s->policy));
379 if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
380 nftnl_set_nlmsg_build_desc_payload(nlh, s);
381 if (s->flags & (1 << NFTNL_SET_TIMEOUT))
382 mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
383 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL))
384 mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
385 if (s->flags & (1 << NFTNL_SET_USERDATA))
386 mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
388 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload);
390 static int nftnl_set_parse_attr_cb(
const struct nlattr *attr,
void *data)
392 const struct nlattr **tb = data;
393 int type = mnl_attr_get_type(attr);
395 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
401 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
405 case NFTA_SET_KEY_TYPE:
406 case NFTA_SET_KEY_LEN:
407 case NFTA_SET_DATA_TYPE:
408 case NFTA_SET_DATA_LEN:
410 case NFTA_SET_POLICY:
411 case NFTA_SET_GC_INTERVAL:
412 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
415 case NFTA_SET_USERDATA:
416 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
419 case NFTA_SET_TIMEOUT:
420 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
424 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
433 static int nftnl_set_desc_parse_attr_cb(
const struct nlattr *attr,
void *data)
435 const struct nlattr **tb = data;
436 int type = mnl_attr_get_type(attr);
438 if (mnl_attr_type_valid(attr, NFTA_SET_DESC_MAX) < 0)
442 case NFTA_SET_DESC_SIZE:
443 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
452 static int nftnl_set_desc_parse(
struct nftnl_set *s,
453 const struct nlattr *attr)
455 struct nlattr *tb[NFTA_SET_DESC_MAX + 1] = {};
457 if (mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, tb) < 0)
460 if (tb[NFTA_SET_DESC_SIZE]) {
461 s->desc.size = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DESC_SIZE]));
462 s->flags |= (1 << NFTNL_SET_DESC_SIZE);
468 int nftnl_set_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
470 struct nlattr *tb[NFTA_SET_MAX+1] = {};
471 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
474 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
477 if (tb[NFTA_SET_TABLE]) {
478 if (s->flags & (1 << NFTNL_SET_TABLE))
480 s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
483 s->flags |= (1 << NFTNL_SET_TABLE);
485 if (tb[NFTA_SET_NAME]) {
486 if (s->flags & (1 << NFTNL_SET_NAME))
488 s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
491 s->flags |= (1 << NFTNL_SET_NAME);
493 if (tb[NFTA_SET_FLAGS]) {
494 s->set_flags = ntohl(mnl_attr_get_u32(tb[NFTA_SET_FLAGS]));
495 s->flags |= (1 << NFTNL_SET_FLAGS);
497 if (tb[NFTA_SET_KEY_TYPE]) {
498 s->key_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_TYPE]));
499 s->flags |= (1 << NFTNL_SET_KEY_TYPE);
501 if (tb[NFTA_SET_KEY_LEN]) {
502 s->key_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_LEN]));
503 s->flags |= (1 << NFTNL_SET_KEY_LEN);
505 if (tb[NFTA_SET_DATA_TYPE]) {
506 s->data_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_TYPE]));
507 s->flags |= (1 << NFTNL_SET_DATA_TYPE);
509 if (tb[NFTA_SET_DATA_LEN]) {
510 s->data_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_LEN]));
511 s->flags |= (1 << NFTNL_SET_DATA_LEN);
513 if (tb[NFTA_SET_OBJ_TYPE]) {
514 s->obj_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_OBJ_TYPE]));
515 s->flags |= (1 << NFTNL_SET_OBJ_TYPE);
517 if (tb[NFTA_SET_ID]) {
518 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ID]));
519 s->flags |= (1 << NFTNL_SET_ID);
521 if (tb[NFTA_SET_POLICY]) {
522 s->policy = ntohl(mnl_attr_get_u32(tb[NFTA_SET_POLICY]));
523 s->flags |= (1 << NFTNL_SET_POLICY);
525 if (tb[NFTA_SET_TIMEOUT]) {
526 s->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_TIMEOUT]));
527 s->flags |= (1 << NFTNL_SET_TIMEOUT);
529 if (tb[NFTA_SET_GC_INTERVAL]) {
530 s->gc_interval = ntohl(mnl_attr_get_u32(tb[NFTA_SET_GC_INTERVAL]));
531 s->flags |= (1 << NFTNL_SET_GC_INTERVAL);
533 if (tb[NFTA_SET_USERDATA]) {
534 ret = nftnl_set_set_data(s, NFTNL_SET_USERDATA,
535 mnl_attr_get_payload(tb[NFTA_SET_USERDATA]),
536 mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]));
540 if (tb[NFTA_SET_DESC]) {
541 ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
546 s->family = nfg->nfgen_family;
547 s->flags |= (1 << NFTNL_SET_FAMILY);
551 EXPORT_SYMBOL(nftnl_set_nlmsg_parse);
554 static int nftnl_jansson_parse_set_info(
struct nftnl_set *s, json_t *tree,
555 struct nftnl_parse_err *err)
557 json_t *root = tree, *array, *json_elem;
558 uint32_t flags, key_type, key_len, data_type, data_len, policy, size;
560 const char *name, *table;
561 struct nftnl_set_elem *elem;
563 name = nftnl_jansson_parse_str(root,
"name", err);
567 nftnl_set_set_str(s, NFTNL_SET_NAME, name);
569 table = nftnl_jansson_parse_str(root,
"table", err);
573 nftnl_set_set_str(s, NFTNL_SET_TABLE, table);
575 if (nftnl_jansson_parse_family(root, &family, err) == 0)
576 nftnl_set_set_u32(s, NFTNL_SET_FAMILY, family);
578 if (nftnl_jansson_parse_val(root,
"flags", NFTNL_TYPE_U32, &flags, err) == 0)
579 nftnl_set_set_u32(s, NFTNL_SET_FLAGS, flags);
581 if (nftnl_jansson_parse_val(root,
"key_type", NFTNL_TYPE_U32, &key_type,
583 nftnl_set_set_u32(s, NFTNL_SET_KEY_TYPE, key_type);
585 if (nftnl_jansson_parse_val(root,
"key_len", NFTNL_TYPE_U32, &key_len,
587 nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, key_len);
589 if (nftnl_jansson_node_exist(root,
"data_type")) {
590 if (nftnl_jansson_parse_val(root,
"data_type", NFTNL_TYPE_U32,
591 &data_type, err) < 0)
594 nftnl_set_set_u32(s, NFTNL_SET_DATA_TYPE, data_type);
597 if (nftnl_jansson_node_exist(root,
"data_len")) {
598 if (nftnl_jansson_parse_val(root,
"data_len", NFTNL_TYPE_U32,
602 nftnl_set_set_u32(s, NFTNL_SET_DATA_LEN, data_len);
605 if (nftnl_jansson_node_exist(root,
"obj_type")) {
606 if (nftnl_jansson_parse_val(root,
"obj_type", NFTNL_TYPE_U32,
607 &data_type, err) < 0)
610 nftnl_set_set_u32(s, NFTNL_SET_OBJ_TYPE, data_type);
613 if (nftnl_jansson_node_exist(root,
"policy")) {
614 if (nftnl_jansson_parse_val(root,
"policy", NFTNL_TYPE_U32,
618 nftnl_set_set_u32(s, NFTNL_SET_POLICY, policy);
621 if (nftnl_jansson_node_exist(root,
"desc_size")) {
622 if (nftnl_jansson_parse_val(root,
"desc_size", NFTNL_TYPE_U32,
626 nftnl_set_set_u32(s, NFTNL_SET_DESC_SIZE, size);
629 if (nftnl_jansson_node_exist(root,
"set_elem")) {
630 array = json_object_get(root,
"set_elem");
631 for (i = 0; i < json_array_size(array); i++) {
632 elem = nftnl_set_elem_alloc();
636 json_elem = json_array_get(array, i);
637 if (json_elem == NULL ||
638 nftnl_jansson_set_elem_parse(elem,
639 json_elem, err) < 0) {
644 list_add_tail(&elem->head, &s->element_list);
652 int nftnl_jansson_parse_set(
struct nftnl_set *s, json_t *tree,
653 struct nftnl_parse_err *err)
657 root = nftnl_jansson_get_node(tree,
"set", err);
661 return nftnl_jansson_parse_set_info(s, root, err);
664 int nftnl_jansson_parse_elem(
struct nftnl_set *s, json_t *tree,
665 struct nftnl_parse_err *err)
669 root = nftnl_jansson_get_node(tree,
"element", err);
673 return nftnl_jansson_parse_set_info(s, root, err);
677 static int nftnl_set_json_parse(
struct nftnl_set *s,
const void *json,
678 struct nftnl_parse_err *err,
679 enum nftnl_parse_input input)
686 tree = nftnl_jansson_create_root(json, &error, err, input);
690 ret = nftnl_jansson_parse_set(s, tree, err);
691 nftnl_jansson_free_root(tree);
700 static int nftnl_set_do_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
701 const void *data,
struct nftnl_parse_err *err,
702 enum nftnl_parse_input input)
705 struct nftnl_parse_err perr = {};
708 case NFTNL_PARSE_JSON:
709 ret = nftnl_set_json_parse(s, data, &perr, input);
711 case NFTNL_PARSE_XML:
723 int nftnl_set_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
724 const char *data,
struct nftnl_parse_err *err)
726 return nftnl_set_do_parse(s, type, data, err, NFTNL_PARSE_BUFFER);
728 EXPORT_SYMBOL(nftnl_set_parse);
730 int nftnl_set_parse_file(
struct nftnl_set *s,
enum nftnl_parse_type type,
731 FILE *fp,
struct nftnl_parse_err *err)
733 return nftnl_set_do_parse(s, type, fp, err, NFTNL_PARSE_FILE);
735 EXPORT_SYMBOL(nftnl_set_parse_file);
737 static int nftnl_set_snprintf_json(
char *buf,
size_t size,
738 const struct nftnl_set *s,
739 uint32_t type, uint32_t flags)
741 int remain = size, offset = 0, ret;
742 struct nftnl_set_elem *elem;
744 ret = snprintf(buf, remain,
"{\"set\":{");
745 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
747 if (s->flags & (1 << NFTNL_SET_NAME)) {
748 ret = snprintf(buf + offset, remain,
"\"name\":\"%s\"",
750 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
752 if (s->flags & (1 << NFTNL_SET_TABLE)) {
753 ret = snprintf(buf + offset, remain,
",\"table\":\"%s\"",
755 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
757 if (s->flags & (1 << NFTNL_SET_FLAGS)) {
758 ret = snprintf(buf + offset, remain,
",\"flags\":%u",
760 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
762 if (s->flags & (1 << NFTNL_SET_FAMILY)) {
763 ret = snprintf(buf + offset, remain,
",\"family\":\"%s\"",
764 nftnl_family2str(s->family));
765 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
767 if (s->flags & (1 << NFTNL_SET_KEY_TYPE)) {
768 ret = snprintf(buf + offset, remain,
",\"key_type\":%u",
770 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
772 if (s->flags & (1 << NFTNL_SET_KEY_LEN)) {
773 ret = snprintf(buf + offset, remain,
",\"key_len\":%u",
775 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
777 if(s->flags & (1 << NFTNL_SET_DATA_TYPE)) {
778 ret = snprintf(buf + offset, remain,
779 ",\"data_type\":%u", s->data_type);
780 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
782 if(s->flags & (1 << NFTNL_SET_DATA_LEN)) {
783 ret = snprintf(buf + offset, remain,
",\"data_len\":%u",
785 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
787 if (s->flags & (1 << NFTNL_SET_OBJ_TYPE)) {
788 ret = snprintf(buf + offset, remain,
789 ",\"obj_type\":%u", s->obj_type);
790 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
793 if (s->flags & (1 << NFTNL_SET_POLICY)) {
794 ret = snprintf(buf + offset, remain,
",\"policy\":%u",
796 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
799 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
800 ret = snprintf(buf + offset, remain,
",\"desc_size\":%u",
802 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
806 if (list_empty(&s->element_list)){
807 ret = snprintf(buf + offset, remain,
"}}");
808 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
812 ret = snprintf(buf + offset, remain,
",\"set_elem\":[");
813 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
815 list_for_each_entry(elem, &s->element_list, head) {
816 ret = snprintf(buf + offset, remain,
"{");
817 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
819 ret = nftnl_set_elem_snprintf(buf + offset, remain, elem, type,
821 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
823 ret = snprintf(buf + offset, remain,
"},");
824 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
829 ret = snprintf(buf + offset, remain,
"]}}");
830 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
835 static int nftnl_set_snprintf_default(
char *buf,
size_t size,
836 const struct nftnl_set *s,
837 uint32_t type, uint32_t flags)
840 int remain = size, offset = 0;
841 struct nftnl_set_elem *elem;
843 ret = snprintf(buf, remain,
"%s %s %x",
844 s->name, s->table, s->set_flags);
845 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
847 if (s->flags & (1 << NFTNL_SET_TIMEOUT)) {
848 ret = snprintf(buf + offset, remain,
" timeout %"PRIu64
"ms",
850 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
853 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL)) {
854 ret = snprintf(buf + offset, remain,
" gc_interval %ums",
856 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
859 if (s->flags & (1 << NFTNL_SET_POLICY)) {
860 ret = snprintf(buf + offset, remain,
" policy %u", s->policy);
861 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
864 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
865 ret = snprintf(buf + offset, remain,
" size %u", s->desc.size);
866 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
870 if (list_empty(&s->element_list))
873 ret = snprintf(buf + offset, remain,
"\n");
874 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
876 list_for_each_entry(elem, &s->element_list, head) {
877 ret = snprintf(buf + offset, remain,
"\t");
878 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
880 ret = nftnl_set_elem_snprintf(buf + offset, remain, elem, type,
882 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
888 static int nftnl_set_cmd_snprintf(
char *buf,
size_t size,
889 const struct nftnl_set *s, uint32_t cmd,
890 uint32_t type, uint32_t flags)
892 int ret, remain = size, offset = 0;
893 uint32_t inner_flags = flags;
895 if (type == NFTNL_OUTPUT_XML)
899 inner_flags &= ~NFTNL_OF_EVENT_ANY;
901 ret = nftnl_cmd_header_snprintf(buf + offset, remain, cmd, type, flags);
902 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
905 case NFTNL_OUTPUT_DEFAULT:
906 ret = nftnl_set_snprintf_default(buf + offset, remain, s, type,
909 case NFTNL_OUTPUT_JSON:
910 ret = nftnl_set_snprintf_json(buf + offset, remain, s, type,
917 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
919 ret = nftnl_cmd_footer_snprintf(buf + offset, remain, cmd, type, flags);
920 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
925 int nftnl_set_snprintf(
char *buf,
size_t size,
const struct nftnl_set *s,
926 uint32_t type, uint32_t flags)
931 return nftnl_set_cmd_snprintf(buf, size, s, nftnl_flag2cmd(flags), type,
934 EXPORT_SYMBOL(nftnl_set_snprintf);
936 static int nftnl_set_do_snprintf(
char *buf,
size_t size,
const void *s,
937 uint32_t cmd, uint32_t type, uint32_t flags)
939 return nftnl_set_snprintf(buf, size, s, type, flags);
942 int nftnl_set_fprintf(FILE *fp,
const struct nftnl_set *s, uint32_t type,
945 return nftnl_fprintf(fp, s, NFTNL_CMD_UNSPEC, type, flags,
946 nftnl_set_do_snprintf);
948 EXPORT_SYMBOL(nftnl_set_fprintf);
950 void nftnl_set_elem_add(
struct nftnl_set *s,
struct nftnl_set_elem *elem)
952 list_add_tail(&elem->head, &s->element_list);
954 EXPORT_SYMBOL(nftnl_set_elem_add);
957 struct list_head list;
968 INIT_LIST_HEAD(&list->list);
972 EXPORT_SYMBOL(nftnl_set_list_alloc);
976 struct nftnl_set *s, *tmp;
978 list_for_each_entry_safe(s, tmp, &list->list, head) {
984 EXPORT_SYMBOL(nftnl_set_list_free);
988 return list_empty(&list->list);
990 EXPORT_SYMBOL(nftnl_set_list_is_empty);
992 void nftnl_set_list_add(
struct nftnl_set *s,
struct nftnl_set_list *list)
994 list_add(&s->head, &list->list);
996 EXPORT_SYMBOL(nftnl_set_list_add);
998 void nftnl_set_list_add_tail(
struct nftnl_set *s,
struct nftnl_set_list *list)
1000 list_add_tail(&s->head, &list->list);
1002 EXPORT_SYMBOL(nftnl_set_list_add_tail);
1004 void nftnl_set_list_del(
struct nftnl_set *s)
1008 EXPORT_SYMBOL(nftnl_set_list_del);
1011 int (*cb)(
struct nftnl_set *t,
void *data),
void *data)
1013 struct nftnl_set *cur, *tmp;
1016 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
1017 ret = cb(cur, data);
1023 EXPORT_SYMBOL(nftnl_set_list_foreach);
1027 struct nftnl_set *cur;
1040 if (nftnl_set_list_is_empty(l))
1043 iter->cur = list_entry(l->list.next,
struct nftnl_set, head);
1047 EXPORT_SYMBOL(nftnl_set_list_iter_create);
1054 EXPORT_SYMBOL(nftnl_set_list_iter_cur);
1058 struct nftnl_set *s = iter->cur;
1064 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set, head);
1065 if (&iter->cur->head == iter->list->list.next)
1070 EXPORT_SYMBOL(nftnl_set_list_iter_next);
1076 EXPORT_SYMBOL(nftnl_set_list_iter_destroy);
1078 static struct nftnl_set *nftnl_set_lookup(
const char *this_set_name,
1082 struct nftnl_set *s;
1083 const char *set_name;
1085 iter = nftnl_set_list_iter_create(set_list);
1089 s = nftnl_set_list_iter_cur(iter);
1091 set_name = nftnl_set_get_str(s, NFTNL_SET_NAME);
1092 if (strcmp(this_set_name, set_name) == 0)
1095 s = nftnl_set_list_iter_next(iter);
1097 nftnl_set_list_iter_destroy(iter);
1102 int nftnl_set_lookup_id(
struct nftnl_expr *e,
1105 const char *set_name;
1106 struct nftnl_set *s;
1108 set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
1109 if (set_name == NULL)
1112 s = nftnl_set_lookup(set_name, set_list);
1116 *set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);