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 EXPORT_SYMBOL(nftnl_set_alloc);
31 struct nftnl_set *nftnl_set_alloc(
void)
35 s = calloc(1,
sizeof(
struct nftnl_set));
39 INIT_LIST_HEAD(&s->element_list);
43 EXPORT_SYMBOL(nftnl_set_free);
44 void nftnl_set_free(
const struct nftnl_set *s)
46 struct nftnl_set_elem *elem, *tmp;
48 if (s->flags & (1 << NFTNL_SET_TABLE))
50 if (s->flags & (1 << NFTNL_SET_NAME))
52 if (s->flags & (1 << NFTNL_SET_USERDATA))
55 list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
56 list_del(&elem->head);
57 nftnl_set_elem_free(elem);
62 EXPORT_SYMBOL(nftnl_set_is_set);
63 bool nftnl_set_is_set(
const struct nftnl_set *s, uint16_t attr)
65 return s->flags & (1 << attr);
68 EXPORT_SYMBOL(nftnl_set_unset);
69 void nftnl_set_unset(
struct nftnl_set *s, uint16_t attr)
71 if (!(s->flags & (1 << attr)))
81 case NFTNL_SET_HANDLE:
83 case NFTNL_SET_KEY_TYPE:
84 case NFTNL_SET_KEY_LEN:
85 case NFTNL_SET_DATA_TYPE:
86 case NFTNL_SET_DATA_LEN:
87 case NFTNL_SET_OBJ_TYPE:
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:
95 case NFTNL_SET_USERDATA:
102 s->flags &= ~(1 << attr);
105 static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
106 [NFTNL_SET_HANDLE] =
sizeof(uint64_t),
107 [NFTNL_SET_FLAGS] =
sizeof(uint32_t),
108 [NFTNL_SET_KEY_TYPE] =
sizeof(uint32_t),
109 [NFTNL_SET_KEY_LEN] =
sizeof(uint32_t),
110 [NFTNL_SET_DATA_TYPE] =
sizeof(uint32_t),
111 [NFTNL_SET_DATA_LEN] =
sizeof(uint32_t),
112 [NFTNL_SET_OBJ_TYPE] =
sizeof(uint32_t),
113 [NFTNL_SET_FAMILY] =
sizeof(uint32_t),
114 [NFTNL_SET_POLICY] =
sizeof(uint32_t),
115 [NFTNL_SET_DESC_SIZE] =
sizeof(uint32_t),
116 [NFTNL_SET_TIMEOUT] =
sizeof(uint64_t),
117 [NFTNL_SET_GC_INTERVAL] =
sizeof(uint32_t),
120 EXPORT_SYMBOL(nftnl_set_set_data);
121 int nftnl_set_set_data(
struct nftnl_set *s, uint16_t attr,
const void *data,
124 nftnl_assert_attr_exists(attr, NFTNL_SET_MAX);
125 nftnl_assert_validate(data, nftnl_set_validate, attr, data_len);
128 case NFTNL_SET_TABLE:
129 if (s->flags & (1 << NFTNL_SET_TABLE))
132 s->table = strdup(data);
137 if (s->flags & (1 << NFTNL_SET_NAME))
140 s->name = strdup(data);
144 case NFTNL_SET_HANDLE:
145 memcpy(&s->handle, data,
sizeof(s->handle));
147 case NFTNL_SET_FLAGS:
148 memcpy(&s->set_flags, data,
sizeof(s->set_flags));
150 case NFTNL_SET_KEY_TYPE:
151 memcpy(&s->key_type, data,
sizeof(s->key_type));
153 case NFTNL_SET_KEY_LEN:
154 memcpy(&s->key_len, data,
sizeof(s->key_len));
156 case NFTNL_SET_DATA_TYPE:
157 memcpy(&s->data_type, data,
sizeof(s->data_type));
159 case NFTNL_SET_DATA_LEN:
160 memcpy(&s->data_len, data,
sizeof(s->data_len));
162 case NFTNL_SET_OBJ_TYPE:
163 memcpy(&s->obj_type, data,
sizeof(s->obj_type));
165 case NFTNL_SET_FAMILY:
166 memcpy(&s->family, data,
sizeof(s->family));
169 memcpy(&s->id, data,
sizeof(s->id));
171 case NFTNL_SET_POLICY:
172 memcpy(&s->policy, data,
sizeof(s->policy));
174 case NFTNL_SET_DESC_SIZE:
175 memcpy(&s->desc.size, data,
sizeof(s->desc.size));
177 case NFTNL_SET_TIMEOUT:
178 memcpy(&s->timeout, data,
sizeof(s->timeout));
180 case NFTNL_SET_GC_INTERVAL:
181 memcpy(&s->gc_interval, data,
sizeof(s->gc_interval));
183 case NFTNL_SET_USERDATA:
184 if (s->flags & (1 << NFTNL_SET_USERDATA))
187 s->user.data = malloc(data_len);
190 memcpy(s->user.data, data, data_len);
191 s->user.len = data_len;
194 s->flags |= (1 << attr);
198 EXPORT_SYMBOL(nftnl_set_set);
199 int nftnl_set_set(
struct nftnl_set *s, uint16_t attr,
const void *data)
201 return nftnl_set_set_data(s, attr, data, nftnl_set_validate[attr]);
204 EXPORT_SYMBOL(nftnl_set_set_u32);
205 void nftnl_set_set_u32(
struct nftnl_set *s, uint16_t attr, uint32_t val)
207 nftnl_set_set(s, attr, &val);
210 EXPORT_SYMBOL(nftnl_set_set_u64);
211 void nftnl_set_set_u64(
struct nftnl_set *s, uint16_t attr, uint64_t val)
213 nftnl_set_set(s, attr, &val);
216 EXPORT_SYMBOL(nftnl_set_set_str);
217 int nftnl_set_set_str(
struct nftnl_set *s, uint16_t attr,
const char *str)
219 return nftnl_set_set_data(s, attr, str, strlen(str) + 1);
222 EXPORT_SYMBOL(nftnl_set_get_data);
223 const void *nftnl_set_get_data(
const struct nftnl_set *s, uint16_t attr,
226 if (!(s->flags & (1 << attr)))
230 case NFTNL_SET_TABLE:
231 *data_len = strlen(s->table) + 1;
234 *data_len = strlen(s->name) + 1;
236 case NFTNL_SET_HANDLE:
237 *data_len =
sizeof(uint64_t);
239 case NFTNL_SET_FLAGS:
240 *data_len =
sizeof(uint32_t);
241 return &s->set_flags;
242 case NFTNL_SET_KEY_TYPE:
243 *data_len =
sizeof(uint32_t);
245 case NFTNL_SET_KEY_LEN:
246 *data_len =
sizeof(uint32_t);
248 case NFTNL_SET_DATA_TYPE:
249 *data_len =
sizeof(uint32_t);
250 return &s->data_type;
251 case NFTNL_SET_DATA_LEN:
252 *data_len =
sizeof(uint32_t);
254 case NFTNL_SET_OBJ_TYPE:
255 *data_len =
sizeof(uint32_t);
257 case NFTNL_SET_FAMILY:
258 *data_len =
sizeof(uint32_t);
261 *data_len =
sizeof(uint32_t);
263 case NFTNL_SET_POLICY:
264 *data_len =
sizeof(uint32_t);
266 case NFTNL_SET_DESC_SIZE:
267 *data_len =
sizeof(uint32_t);
268 return &s->desc.size;
269 case NFTNL_SET_TIMEOUT:
270 *data_len =
sizeof(uint64_t);
272 case NFTNL_SET_GC_INTERVAL:
273 *data_len =
sizeof(uint32_t);
274 return &s->gc_interval;
275 case NFTNL_SET_USERDATA:
276 *data_len = s->user.len;
282 EXPORT_SYMBOL(nftnl_set_get);
283 const void *nftnl_set_get(
const struct nftnl_set *s, uint16_t attr)
286 return nftnl_set_get_data(s, attr, &data_len);
289 EXPORT_SYMBOL(nftnl_set_get_str);
290 const char *nftnl_set_get_str(
const struct nftnl_set *s, uint16_t attr)
292 return nftnl_set_get(s, attr);
295 EXPORT_SYMBOL(nftnl_set_get_u32);
296 uint32_t nftnl_set_get_u32(
const struct nftnl_set *s, uint16_t attr)
299 const uint32_t *val = nftnl_set_get_data(s, attr, &data_len);
301 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
303 return val ? *val : 0;
306 EXPORT_SYMBOL(nftnl_set_get_u64);
307 uint64_t nftnl_set_get_u64(
const struct nftnl_set *s, uint16_t attr)
310 const uint64_t *val = nftnl_set_get_data(s, attr, &data_len);
312 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
314 return val ? *val : 0;
317 struct nftnl_set *nftnl_set_clone(
const struct nftnl_set *set)
319 struct nftnl_set *newset;
320 struct nftnl_set_elem *elem, *newelem;
322 newset = nftnl_set_alloc();
326 memcpy(newset, set,
sizeof(*set));
328 if (set->flags & (1 << NFTNL_SET_TABLE)) {
329 newset->table = strdup(set->table);
333 if (set->flags & (1 << NFTNL_SET_NAME)) {
334 newset->name = strdup(set->name);
339 INIT_LIST_HEAD(&newset->element_list);
340 list_for_each_entry(elem, &set->element_list, head) {
341 newelem = nftnl_set_elem_clone(elem);
345 list_add_tail(&newelem->head, &newset->element_list);
350 nftnl_set_free(newset);
355 nftnl_set_nlmsg_build_desc_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
359 nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC);
360 mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
361 mnl_attr_nest_end(nlh, nest);
364 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload);
365 void nftnl_set_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
367 if (s->flags & (1 << NFTNL_SET_TABLE))
368 mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
369 if (s->flags & (1 << NFTNL_SET_NAME))
370 mnl_attr_put_strz(nlh, NFTA_SET_NAME, s->name);
371 if (s->flags & (1 << NFTNL_SET_HANDLE))
372 mnl_attr_put_u64(nlh, NFTA_SET_HANDLE, htobe64(s->handle));
373 if (s->flags & (1 << NFTNL_SET_FLAGS))
374 mnl_attr_put_u32(nlh, NFTA_SET_FLAGS, htonl(s->set_flags));
375 if (s->flags & (1 << NFTNL_SET_KEY_TYPE))
376 mnl_attr_put_u32(nlh, NFTA_SET_KEY_TYPE, htonl(s->key_type));
377 if (s->flags & (1 << NFTNL_SET_KEY_LEN))
378 mnl_attr_put_u32(nlh, NFTA_SET_KEY_LEN, htonl(s->key_len));
380 if (s->flags & (1 << NFTNL_SET_DATA_TYPE))
381 mnl_attr_put_u32(nlh, NFTA_SET_DATA_TYPE, htonl(s->data_type));
382 if (s->flags & (1 << NFTNL_SET_DATA_LEN))
383 mnl_attr_put_u32(nlh, NFTA_SET_DATA_LEN, htonl(s->data_len));
384 if (s->flags & (1 << NFTNL_SET_OBJ_TYPE))
385 mnl_attr_put_u32(nlh, NFTA_SET_OBJ_TYPE, htonl(s->obj_type));
386 if (s->flags & (1 << NFTNL_SET_ID))
387 mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
388 if (s->flags & (1 << NFTNL_SET_POLICY))
389 mnl_attr_put_u32(nlh, NFTA_SET_POLICY, htonl(s->policy));
390 if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
391 nftnl_set_nlmsg_build_desc_payload(nlh, s);
392 if (s->flags & (1 << NFTNL_SET_TIMEOUT))
393 mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
394 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL))
395 mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
396 if (s->flags & (1 << NFTNL_SET_USERDATA))
397 mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
401 static int nftnl_set_parse_attr_cb(
const struct nlattr *attr,
void *data)
403 const struct nlattr **tb = data;
404 int type = mnl_attr_get_type(attr);
406 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
412 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
415 case NFTA_SET_HANDLE:
416 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
420 case NFTA_SET_KEY_TYPE:
421 case NFTA_SET_KEY_LEN:
422 case NFTA_SET_DATA_TYPE:
423 case NFTA_SET_DATA_LEN:
425 case NFTA_SET_POLICY:
426 case NFTA_SET_GC_INTERVAL:
427 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
430 case NFTA_SET_USERDATA:
431 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
434 case NFTA_SET_TIMEOUT:
435 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
439 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
448 static int nftnl_set_desc_parse_attr_cb(
const struct nlattr *attr,
void *data)
450 const struct nlattr **tb = data;
451 int type = mnl_attr_get_type(attr);
453 if (mnl_attr_type_valid(attr, NFTA_SET_DESC_MAX) < 0)
457 case NFTA_SET_DESC_SIZE:
458 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
467 static int nftnl_set_desc_parse(
struct nftnl_set *s,
468 const struct nlattr *attr)
470 struct nlattr *tb[NFTA_SET_DESC_MAX + 1] = {};
472 if (mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, tb) < 0)
475 if (tb[NFTA_SET_DESC_SIZE]) {
476 s->desc.size = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DESC_SIZE]));
477 s->flags |= (1 << NFTNL_SET_DESC_SIZE);
483 EXPORT_SYMBOL(nftnl_set_nlmsg_parse);
484 int nftnl_set_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
486 struct nlattr *tb[NFTA_SET_MAX+1] = {};
487 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
490 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
493 if (tb[NFTA_SET_TABLE]) {
494 if (s->flags & (1 << NFTNL_SET_TABLE))
496 s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
499 s->flags |= (1 << NFTNL_SET_TABLE);
501 if (tb[NFTA_SET_NAME]) {
502 if (s->flags & (1 << NFTNL_SET_NAME))
504 s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
507 s->flags |= (1 << NFTNL_SET_NAME);
509 if (tb[NFTA_SET_HANDLE]) {
510 s->handle = be64toh(mnl_attr_get_u64(tb[NFTA_SET_HANDLE]));
511 s->flags |= (1 << NFTNL_SET_HANDLE);
513 if (tb[NFTA_SET_FLAGS]) {
514 s->set_flags = ntohl(mnl_attr_get_u32(tb[NFTA_SET_FLAGS]));
515 s->flags |= (1 << NFTNL_SET_FLAGS);
517 if (tb[NFTA_SET_KEY_TYPE]) {
518 s->key_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_TYPE]));
519 s->flags |= (1 << NFTNL_SET_KEY_TYPE);
521 if (tb[NFTA_SET_KEY_LEN]) {
522 s->key_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_LEN]));
523 s->flags |= (1 << NFTNL_SET_KEY_LEN);
525 if (tb[NFTA_SET_DATA_TYPE]) {
526 s->data_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_TYPE]));
527 s->flags |= (1 << NFTNL_SET_DATA_TYPE);
529 if (tb[NFTA_SET_DATA_LEN]) {
530 s->data_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_LEN]));
531 s->flags |= (1 << NFTNL_SET_DATA_LEN);
533 if (tb[NFTA_SET_OBJ_TYPE]) {
534 s->obj_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_OBJ_TYPE]));
535 s->flags |= (1 << NFTNL_SET_OBJ_TYPE);
537 if (tb[NFTA_SET_ID]) {
538 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ID]));
539 s->flags |= (1 << NFTNL_SET_ID);
541 if (tb[NFTA_SET_POLICY]) {
542 s->policy = ntohl(mnl_attr_get_u32(tb[NFTA_SET_POLICY]));
543 s->flags |= (1 << NFTNL_SET_POLICY);
545 if (tb[NFTA_SET_TIMEOUT]) {
546 s->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_TIMEOUT]));
547 s->flags |= (1 << NFTNL_SET_TIMEOUT);
549 if (tb[NFTA_SET_GC_INTERVAL]) {
550 s->gc_interval = ntohl(mnl_attr_get_u32(tb[NFTA_SET_GC_INTERVAL]));
551 s->flags |= (1 << NFTNL_SET_GC_INTERVAL);
553 if (tb[NFTA_SET_USERDATA]) {
554 ret = nftnl_set_set_data(s, NFTNL_SET_USERDATA,
555 mnl_attr_get_payload(tb[NFTA_SET_USERDATA]),
556 mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]));
560 if (tb[NFTA_SET_DESC]) {
561 ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
566 s->family = nfg->nfgen_family;
567 s->flags |= (1 << NFTNL_SET_FAMILY);
572 static int nftnl_set_do_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
573 const void *data,
struct nftnl_parse_err *err,
574 enum nftnl_parse_input input)
577 struct nftnl_parse_err perr = {};
580 case NFTNL_PARSE_JSON:
581 case NFTNL_PARSE_XML:
594 EXPORT_SYMBOL(nftnl_set_parse);
595 int nftnl_set_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
596 const char *data,
struct nftnl_parse_err *err)
598 return nftnl_set_do_parse(s, type, data, err, NFTNL_PARSE_BUFFER);
601 EXPORT_SYMBOL(nftnl_set_parse_file);
602 int nftnl_set_parse_file(
struct nftnl_set *s,
enum nftnl_parse_type type,
603 FILE *fp,
struct nftnl_parse_err *err)
605 return nftnl_set_do_parse(s, type, fp, err, NFTNL_PARSE_FILE);
608 static int nftnl_set_snprintf_default(
char *buf,
size_t size,
609 const struct nftnl_set *s,
610 uint32_t type, uint32_t flags)
613 int remain = size, offset = 0;
614 struct nftnl_set_elem *elem;
616 ret = snprintf(buf, remain,
"%s %s %x",
617 s->name, s->table, s->set_flags);
618 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
620 if (s->flags & (1 << NFTNL_SET_TIMEOUT)) {
621 ret = snprintf(buf + offset, remain,
" timeout %"PRIu64
"ms",
623 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
626 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL)) {
627 ret = snprintf(buf + offset, remain,
" gc_interval %ums",
629 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
632 if (s->flags & (1 << NFTNL_SET_POLICY)) {
633 ret = snprintf(buf + offset, remain,
" policy %u", s->policy);
634 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
637 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
638 ret = snprintf(buf + offset, remain,
" size %u", s->desc.size);
639 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
643 if (list_empty(&s->element_list))
646 ret = snprintf(buf + offset, remain,
"\n");
647 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
649 list_for_each_entry(elem, &s->element_list, head) {
650 ret = snprintf(buf + offset, remain,
"\t");
651 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
653 ret = nftnl_set_elem_snprintf(buf + offset, remain, elem, type,
655 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
661 static int nftnl_set_cmd_snprintf(
char *buf,
size_t size,
662 const struct nftnl_set *s, uint32_t cmd,
663 uint32_t type, uint32_t flags)
665 int ret, remain = size, offset = 0;
666 uint32_t inner_flags = flags;
668 if (type == NFTNL_OUTPUT_XML)
672 inner_flags &= ~NFTNL_OF_EVENT_ANY;
675 case NFTNL_OUTPUT_DEFAULT:
676 ret = nftnl_set_snprintf_default(buf + offset, remain, s, type,
678 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
687 EXPORT_SYMBOL(nftnl_set_snprintf);
688 int nftnl_set_snprintf(
char *buf,
size_t size,
const struct nftnl_set *s,
689 uint32_t type, uint32_t flags)
694 return nftnl_set_cmd_snprintf(buf, size, s, nftnl_flag2cmd(flags), type,
698 static int nftnl_set_do_snprintf(
char *buf,
size_t size,
const void *s,
699 uint32_t cmd, uint32_t type, uint32_t flags)
701 return nftnl_set_snprintf(buf, size, s, type, flags);
704 EXPORT_SYMBOL(nftnl_set_fprintf);
705 int nftnl_set_fprintf(FILE *fp,
const struct nftnl_set *s, uint32_t type,
708 return nftnl_fprintf(fp, s, NFTNL_CMD_UNSPEC, type, flags,
709 nftnl_set_do_snprintf);
712 EXPORT_SYMBOL(nftnl_set_elem_add);
713 void nftnl_set_elem_add(
struct nftnl_set *s,
struct nftnl_set_elem *elem)
715 list_add_tail(&elem->head, &s->element_list);
719 struct list_head list;
722 EXPORT_SYMBOL(nftnl_set_list_alloc);
731 INIT_LIST_HEAD(&list->list);
736 EXPORT_SYMBOL(nftnl_set_list_free);
739 struct nftnl_set *s, *tmp;
741 list_for_each_entry_safe(s, tmp, &list->list, head) {
748 EXPORT_SYMBOL(nftnl_set_list_is_empty);
751 return list_empty(&list->list);
754 EXPORT_SYMBOL(nftnl_set_list_add);
755 void nftnl_set_list_add(
struct nftnl_set *s,
struct nftnl_set_list *list)
757 list_add(&s->head, &list->list);
760 EXPORT_SYMBOL(nftnl_set_list_add_tail);
761 void nftnl_set_list_add_tail(
struct nftnl_set *s,
struct nftnl_set_list *list)
763 list_add_tail(&s->head, &list->list);
766 EXPORT_SYMBOL(nftnl_set_list_del);
767 void nftnl_set_list_del(
struct nftnl_set *s)
772 EXPORT_SYMBOL(nftnl_set_list_foreach);
774 int (*cb)(
struct nftnl_set *t,
void *data),
void *data)
776 struct nftnl_set *cur, *tmp;
779 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
789 struct nftnl_set *cur;
792 EXPORT_SYMBOL(nftnl_set_list_iter_create);
803 if (nftnl_set_list_is_empty(l))
806 iter->cur = list_entry(l->list.next,
struct nftnl_set, head);
811 EXPORT_SYMBOL(nftnl_set_list_iter_cur);
818 EXPORT_SYMBOL(nftnl_set_list_iter_next);
821 struct nftnl_set *s = iter->cur;
827 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set, head);
828 if (&iter->cur->head == iter->list->list.next)
834 EXPORT_SYMBOL(nftnl_set_list_iter_destroy);
840 static struct nftnl_set *nftnl_set_lookup(
const char *this_set_name,
845 const char *set_name;
847 iter = nftnl_set_list_iter_create(set_list);
851 s = nftnl_set_list_iter_cur(iter);
853 set_name = nftnl_set_get_str(s, NFTNL_SET_NAME);
854 if (strcmp(this_set_name, set_name) == 0)
857 s = nftnl_set_list_iter_next(iter);
859 nftnl_set_list_iter_destroy(iter);
864 int nftnl_set_lookup_id(
struct nftnl_expr *e,
867 const char *set_name;
870 set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
871 if (set_name == NULL)
874 s = nftnl_set_lookup(set_name, set_list);
878 *set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);