18 #include <netinet/in.h>
22 #include <libmnl/libmnl.h>
23 #include <linux/netfilter/nfnetlink.h>
24 #include <linux/netfilter/nf_tables.h>
26 #include <libnftnl/set.h>
27 #include <libnftnl/rule.h>
28 #include <libnftnl/expr.h>
30 EXPORT_SYMBOL(nftnl_set_elem_alloc);
31 struct nftnl_set_elem *nftnl_set_elem_alloc(
void)
33 struct nftnl_set_elem *s;
35 s = calloc(1,
sizeof(
struct nftnl_set_elem));
42 EXPORT_SYMBOL(nftnl_set_elem_free);
43 void nftnl_set_elem_free(
struct nftnl_set_elem *s)
45 if (s->flags & (1 << NFTNL_SET_ELEM_CHAIN))
48 if (s->flags & (1 << NFTNL_SET_ELEM_EXPR))
49 nftnl_expr_free(s->expr);
51 if (s->flags & (1 << NFTNL_SET_ELEM_USERDATA))
54 if (s->flags & (1 << NFTNL_SET_ELEM_OBJREF))
60 EXPORT_SYMBOL(nftnl_set_elem_is_set);
61 bool nftnl_set_elem_is_set(
const struct nftnl_set_elem *s, uint16_t attr)
63 return s->flags & (1 << attr);
66 EXPORT_SYMBOL(nftnl_set_elem_unset);
67 void nftnl_set_elem_unset(
struct nftnl_set_elem *s, uint16_t attr)
69 if (!(s->flags & (1 << attr)))
73 case NFTNL_SET_ELEM_CHAIN:
76 case NFTNL_SET_ELEM_FLAGS:
77 case NFTNL_SET_ELEM_KEY:
78 case NFTNL_SET_ELEM_VERDICT:
79 case NFTNL_SET_ELEM_DATA:
80 case NFTNL_SET_ELEM_TIMEOUT:
81 case NFTNL_SET_ELEM_EXPIRATION:
83 case NFTNL_SET_ELEM_USERDATA:
86 case NFTNL_SET_ELEM_EXPR:
87 nftnl_expr_free(s->expr);
89 case NFTNL_SET_ELEM_OBJREF:
96 s->flags &= ~(1 << attr);
99 static uint32_t nftnl_set_elem_validate[NFTNL_SET_ELEM_MAX + 1] = {
100 [NFTNL_SET_ELEM_FLAGS] =
sizeof(uint32_t),
101 [NFTNL_SET_ELEM_VERDICT] =
sizeof(uint32_t),
102 [NFTNL_SET_ELEM_TIMEOUT] =
sizeof(uint64_t),
103 [NFTNL_SET_ELEM_EXPIRATION] =
sizeof(uint64_t),
106 EXPORT_SYMBOL(nftnl_set_elem_set);
107 int nftnl_set_elem_set(
struct nftnl_set_elem *s, uint16_t attr,
108 const void *data, uint32_t data_len)
110 nftnl_assert_attr_exists(attr, NFTNL_SET_ELEM_MAX);
111 nftnl_assert_validate(data, nftnl_set_elem_validate, attr, data_len);
114 case NFTNL_SET_ELEM_FLAGS:
115 memcpy(&s->set_elem_flags, data,
sizeof(s->set_elem_flags));
117 case NFTNL_SET_ELEM_KEY:
118 memcpy(&s->key.val, data, data_len);
119 s->key.len = data_len;
121 case NFTNL_SET_ELEM_VERDICT:
122 memcpy(&s->data.verdict, data,
sizeof(s->data.verdict));
124 case NFTNL_SET_ELEM_CHAIN:
125 if (s->flags & (1 << NFTNL_SET_ELEM_CHAIN))
126 xfree(s->data.chain);
128 s->data.chain = strdup(data);
132 case NFTNL_SET_ELEM_DATA:
133 memcpy(s->data.val, data, data_len);
134 s->data.len = data_len;
136 case NFTNL_SET_ELEM_TIMEOUT:
137 memcpy(&s->timeout, data,
sizeof(s->timeout));
139 case NFTNL_SET_ELEM_EXPIRATION:
140 memcpy(&s->expiration, data,
sizeof(s->expiration));
142 case NFTNL_SET_ELEM_USERDATA:
143 if (s->flags & (1 << NFTNL_SET_ELEM_USERDATA))
146 s->user.data = malloc(data_len);
149 memcpy(s->user.data, data, data_len);
150 s->user.len = data_len;
152 case NFTNL_SET_ELEM_OBJREF:
153 if (s->flags & (1 << NFTNL_SET_ELEM_OBJREF))
156 s->objref = strdup(data);
161 s->flags |= (1 << attr);
165 EXPORT_SYMBOL(nftnl_set_elem_set_u32);
166 void nftnl_set_elem_set_u32(
struct nftnl_set_elem *s, uint16_t attr, uint32_t val)
168 nftnl_set_elem_set(s, attr, &val,
sizeof(uint32_t));
171 EXPORT_SYMBOL(nftnl_set_elem_set_u64);
172 void nftnl_set_elem_set_u64(
struct nftnl_set_elem *s, uint16_t attr, uint64_t val)
174 nftnl_set_elem_set(s, attr, &val,
sizeof(uint64_t));
177 EXPORT_SYMBOL(nftnl_set_elem_set_str);
178 int nftnl_set_elem_set_str(
struct nftnl_set_elem *s, uint16_t attr,
const char *str)
180 return nftnl_set_elem_set(s, attr, str, strlen(str) + 1);
183 EXPORT_SYMBOL(nftnl_set_elem_get);
184 const void *nftnl_set_elem_get(
struct nftnl_set_elem *s, uint16_t attr, uint32_t *data_len)
186 if (!(s->flags & (1 << attr)))
190 case NFTNL_SET_ELEM_FLAGS:
191 *data_len =
sizeof(s->set_elem_flags);
192 return &s->set_elem_flags;
193 case NFTNL_SET_ELEM_KEY:
194 *data_len = s->key.len;
196 case NFTNL_SET_ELEM_VERDICT:
197 *data_len =
sizeof(s->data.verdict);
198 return &s->data.verdict;
199 case NFTNL_SET_ELEM_CHAIN:
200 *data_len = strlen(s->data.chain) + 1;
201 return s->data.chain;
202 case NFTNL_SET_ELEM_DATA:
203 *data_len = s->data.len;
205 case NFTNL_SET_ELEM_TIMEOUT:
206 *data_len =
sizeof(s->timeout);
208 case NFTNL_SET_ELEM_EXPIRATION:
209 *data_len =
sizeof(s->expiration);
210 return &s->expiration;
211 case NFTNL_SET_ELEM_USERDATA:
212 *data_len = s->user.len;
214 case NFTNL_SET_ELEM_EXPR:
216 case NFTNL_SET_ELEM_OBJREF:
217 *data_len = strlen(s->objref) + 1;
223 EXPORT_SYMBOL(nftnl_set_elem_get_str);
224 const char *nftnl_set_elem_get_str(
struct nftnl_set_elem *s, uint16_t attr)
228 return nftnl_set_elem_get(s, attr, &size);
231 EXPORT_SYMBOL(nftnl_set_elem_get_u32);
232 uint32_t nftnl_set_elem_get_u32(
struct nftnl_set_elem *s, uint16_t attr)
236 memcpy(&val, nftnl_set_elem_get(s, attr, &size),
sizeof(val));
241 EXPORT_SYMBOL(nftnl_set_elem_get_u64);
242 uint64_t nftnl_set_elem_get_u64(
struct nftnl_set_elem *s, uint16_t attr)
247 memcpy(&val, nftnl_set_elem_get(s, attr, &size),
sizeof(val));
252 struct nftnl_set_elem *nftnl_set_elem_clone(
struct nftnl_set_elem *elem)
254 struct nftnl_set_elem *newelem;
256 newelem = nftnl_set_elem_alloc();
260 memcpy(newelem, elem,
sizeof(*elem));
262 if (elem->flags & (1 << NFTNL_SET_ELEM_CHAIN)) {
263 newelem->data.chain = strdup(elem->data.chain);
264 if (!newelem->data.chain)
270 nftnl_set_elem_free(newelem);
274 void nftnl_set_elem_nlmsg_build_payload(
struct nlmsghdr *nlh,
275 struct nftnl_set_elem *e)
277 if (e->flags & (1 << NFTNL_SET_ELEM_FLAGS))
278 mnl_attr_put_u32(nlh, NFTA_SET_ELEM_FLAGS, htonl(e->set_elem_flags));
279 if (e->flags & (1 << NFTNL_SET_ELEM_TIMEOUT))
280 mnl_attr_put_u64(nlh, NFTA_SET_ELEM_TIMEOUT, htobe64(e->timeout));
281 if (e->flags & (1 << NFTNL_SET_ELEM_EXPIRATION))
282 mnl_attr_put_u64(nlh, NFTA_SET_ELEM_EXPIRATION, htobe64(e->expiration));
283 if (e->flags & (1 << NFTNL_SET_ELEM_KEY)) {
284 struct nlattr *nest1;
286 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_KEY);
287 mnl_attr_put(nlh, NFTA_DATA_VALUE, e->key.len, e->key.val);
288 mnl_attr_nest_end(nlh, nest1);
290 if (e->flags & (1 << NFTNL_SET_ELEM_VERDICT)) {
291 struct nlattr *nest1, *nest2;
293 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_DATA);
294 nest2 = mnl_attr_nest_start(nlh, NFTA_DATA_VERDICT);
295 mnl_attr_put_u32(nlh, NFTA_VERDICT_CODE, htonl(e->data.verdict));
296 if (e->flags & (1 << NFTNL_SET_ELEM_CHAIN))
297 mnl_attr_put_strz(nlh, NFTA_VERDICT_CHAIN, e->data.chain);
299 mnl_attr_nest_end(nlh, nest1);
300 mnl_attr_nest_end(nlh, nest2);
302 if (e->flags & (1 << NFTNL_SET_ELEM_DATA)) {
303 struct nlattr *nest1;
305 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_DATA);
306 mnl_attr_put(nlh, NFTA_DATA_VALUE, e->data.len, e->data.val);
307 mnl_attr_nest_end(nlh, nest1);
309 if (e->flags & (1 << NFTNL_SET_ELEM_USERDATA))
310 mnl_attr_put(nlh, NFTA_SET_ELEM_USERDATA, e->user.len, e->user.data);
311 if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF))
312 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_OBJREF, e->objref);
315 static void nftnl_set_elem_nlmsg_build_def(
struct nlmsghdr *nlh,
316 const struct nftnl_set *s)
318 if (s->flags & (1 << NFTNL_SET_NAME))
319 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_SET, s->name);
320 if (s->flags & (1 << NFTNL_SET_ID))
321 mnl_attr_put_u32(nlh, NFTA_SET_ELEM_LIST_SET_ID, htonl(s->id));
322 if (s->flags & (1 << NFTNL_SET_TABLE))
323 mnl_attr_put_strz(nlh, NFTA_SET_ELEM_LIST_TABLE, s->table);
326 static struct nlattr *nftnl_set_elem_build(
struct nlmsghdr *nlh,
327 struct nftnl_set_elem *elem,
int i)
329 struct nlattr *nest2;
331 nest2 = mnl_attr_nest_start(nlh, i);
332 nftnl_set_elem_nlmsg_build_payload(nlh, elem);
333 mnl_attr_nest_end(nlh, nest2);
338 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_build_payload);
339 void nftnl_set_elems_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
341 struct nftnl_set_elem *elem;
342 struct nlattr *nest1;
345 nftnl_set_elem_nlmsg_build_def(nlh, s);
347 if (list_empty(&s->element_list))
350 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
351 list_for_each_entry(elem, &s->element_list, head)
352 nftnl_set_elem_build(nlh, elem, ++i);
354 mnl_attr_nest_end(nlh, nest1);
357 static
int nftnl_set_elem_parse_attr_cb(const struct nlattr *attr,
void *data)
359 const struct nlattr **tb = data;
360 int type = mnl_attr_get_type(attr);
362 if (mnl_attr_type_valid(attr, NFTA_SET_MAX) < 0)
366 case NFTA_SET_ELEM_FLAGS:
367 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
370 case NFTA_SET_ELEM_TIMEOUT:
371 case NFTA_SET_ELEM_EXPIRATION:
372 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
375 case NFTA_SET_ELEM_KEY:
376 case NFTA_SET_ELEM_DATA:
377 case NFTA_SET_ELEM_EXPR:
378 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
381 case NFTA_SET_ELEM_USERDATA:
382 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
391 static int nftnl_set_elems_parse2(
struct nftnl_set *s,
const struct nlattr *nest)
393 struct nlattr *tb[NFTA_SET_ELEM_MAX+1] = {};
394 struct nftnl_set_elem *e;
397 e = nftnl_set_elem_alloc();
401 ret = mnl_attr_parse_nested(nest, nftnl_set_elem_parse_attr_cb, tb);
405 if (tb[NFTA_SET_ELEM_FLAGS]) {
407 ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_FLAGS]));
408 e->flags |= (1 << NFTNL_SET_ELEM_FLAGS);
410 if (tb[NFTA_SET_ELEM_TIMEOUT]) {
411 e->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_ELEM_TIMEOUT]));
412 e->flags |= (1 << NFTNL_SET_ELEM_TIMEOUT);
414 if (tb[NFTA_SET_ELEM_EXPIRATION]) {
415 e->expiration = be64toh(mnl_attr_get_u64(tb[NFTA_SET_ELEM_EXPIRATION]));
416 e->flags |= (1 << NFTNL_SET_ELEM_EXPIRATION);
418 if (tb[NFTA_SET_ELEM_KEY]) {
419 ret = nftnl_parse_data(&e->key, tb[NFTA_SET_ELEM_KEY], &type);
422 e->flags |= (1 << NFTNL_SET_ELEM_KEY);
424 if (tb[NFTA_SET_ELEM_DATA]) {
425 ret = nftnl_parse_data(&e->data, tb[NFTA_SET_ELEM_DATA], &type);
430 e->flags |= (1 << NFTNL_SET_ELEM_VERDICT);
433 e->flags |= (1 << NFTNL_SET_ELEM_VERDICT) |
434 (1 << NFTNL_SET_ELEM_CHAIN);
437 e->flags |= (1 << NFTNL_SET_ELEM_DATA);
441 if (tb[NFTA_SET_ELEM_EXPR]) {
442 e->expr = nftnl_expr_parse(tb[NFTA_SET_ELEM_EXPR]);
443 if (e->expr == NULL) {
447 e->flags |= (1 << NFTNL_SET_ELEM_EXPR);
449 if (tb[NFTA_SET_ELEM_USERDATA]) {
451 mnl_attr_get_payload(tb[NFTA_SET_ELEM_USERDATA]);
453 if (e->flags & (1 << NFTNL_RULE_USERDATA))
456 e->user.len = mnl_attr_get_payload_len(tb[NFTA_SET_ELEM_USERDATA]);
457 e->user.data = malloc(e->user.len);
458 if (e->user.data == NULL) {
462 memcpy(e->user.data, udata, e->user.len);
463 e->flags |= (1 << NFTNL_RULE_USERDATA);
465 if (tb[NFTA_SET_ELEM_OBJREF]) {
466 e->objref = strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_OBJREF]));
467 if (e->objref == NULL) {
471 e->flags |= (1 << NFTNL_SET_ELEM_OBJREF);
475 list_add_tail(&e->head, &s->element_list);
479 nftnl_expr_free(e->expr);
481 nftnl_set_elem_free(e);
486 nftnl_set_elem_list_parse_attr_cb(
const struct nlattr *attr,
void *data)
488 const struct nlattr **tb = data;
489 int type = mnl_attr_get_type(attr);
491 if (mnl_attr_type_valid(attr, NFTA_SET_ELEM_LIST_MAX) < 0)
495 case NFTA_SET_ELEM_LIST_TABLE:
496 case NFTA_SET_ELEM_LIST_SET:
497 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
500 case NFTA_SET_ELEM_LIST_ELEMENTS:
501 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
510 static int nftnl_set_elems_parse(
struct nftnl_set *s,
const struct nlattr *nest)
515 mnl_attr_for_each_nested(attr, nest) {
516 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
519 ret = nftnl_set_elems_parse2(s, attr);
526 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_parse);
527 int nftnl_set_elems_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
529 struct nlattr *tb[NFTA_SET_ELEM_LIST_MAX+1] = {};
530 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
533 if (mnl_attr_parse(nlh,
sizeof(*nfg),
534 nftnl_set_elem_list_parse_attr_cb, tb) < 0)
537 if (tb[NFTA_SET_ELEM_LIST_TABLE]) {
538 if (s->flags & (1 << NFTNL_SET_TABLE))
541 strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_TABLE]));
544 s->flags |= (1 << NFTNL_SET_TABLE);
546 if (tb[NFTA_SET_ELEM_LIST_SET]) {
547 if (s->flags & (1 << NFTNL_SET_NAME))
550 strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_SET]));
553 s->flags |= (1 << NFTNL_SET_NAME);
555 if (tb[NFTA_SET_ELEM_LIST_SET_ID]) {
556 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_LIST_SET_ID]));
557 s->flags |= (1 << NFTNL_SET_ID);
559 if (tb[NFTA_SET_ELEM_LIST_ELEMENTS]) {
560 ret = nftnl_set_elems_parse(s, tb[NFTA_SET_ELEM_LIST_ELEMENTS]);
565 s->family = nfg->nfgen_family;
566 s->flags |= (1 << NFTNL_SET_FAMILY);
571 EXPORT_SYMBOL(nftnl_set_elem_parse);
572 int nftnl_set_elem_parse(
struct nftnl_set_elem *e,
enum nftnl_parse_type type,
573 const char *data,
struct nftnl_parse_err *err)
579 EXPORT_SYMBOL(nftnl_set_elem_parse_file);
580 int nftnl_set_elem_parse_file(
struct nftnl_set_elem *e,
enum nftnl_parse_type type,
581 FILE *fp,
struct nftnl_parse_err *err)
587 static int nftnl_set_elem_snprintf_default(
char *buf,
size_t size,
588 const struct nftnl_set_elem *e)
590 int ret, remain = size, offset = 0, i;
592 ret = snprintf(buf, remain,
"element ");
593 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
595 for (i = 0; i < div_round_up(e->key.len,
sizeof(uint32_t)); i++) {
596 ret = snprintf(buf + offset, remain,
"%.8x ", e->key.val[i]);
597 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
600 ret = snprintf(buf + offset, remain,
" : ");
601 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
603 for (i = 0; i < div_round_up(e->data.len,
sizeof(uint32_t)); i++) {
604 ret = snprintf(buf + offset, remain,
"%.8x ", e->data.val[i]);
605 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
608 ret = snprintf(buf + offset, remain,
"%u [end]", e->set_elem_flags);
609 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
612 ret = snprintf(buf + offset, remain,
" userdata = {");
613 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
615 for (i = 0; i < e->user.len; i++) {
616 char *c = e->user.data;
618 ret = snprintf(buf + offset, remain,
"%c",
619 isalnum(c[i]) ? c[i] : 0);
620 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
623 ret = snprintf(buf + offset, remain,
" }\n");
624 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
630 static int nftnl_set_elem_cmd_snprintf(
char *buf,
size_t size,
631 const struct nftnl_set_elem *e,
632 uint32_t cmd, uint32_t type,
635 int ret, remain = size, offset = 0;
638 case NFTNL_OUTPUT_DEFAULT:
639 ret = nftnl_set_elem_snprintf_default(buf + offset, remain, e);
640 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
642 case NFTNL_OUTPUT_XML:
643 case NFTNL_OUTPUT_JSON:
652 EXPORT_SYMBOL(nftnl_set_elem_snprintf);
653 int nftnl_set_elem_snprintf(
char *buf,
size_t size,
654 const struct nftnl_set_elem *e,
655 uint32_t type, uint32_t flags)
660 return nftnl_set_elem_cmd_snprintf(buf, size, e, nftnl_flag2cmd(flags),
664 static int nftnl_set_elem_do_snprintf(
char *buf,
size_t size,
const void *e,
665 uint32_t cmd, uint32_t type,
668 return nftnl_set_elem_snprintf(buf, size, e, type, flags);
671 EXPORT_SYMBOL(nftnl_set_elem_fprintf);
672 int nftnl_set_elem_fprintf(FILE *fp,
struct nftnl_set_elem *se, uint32_t type,
675 return nftnl_fprintf(fp, se, NFTNL_CMD_UNSPEC, type, flags,
676 nftnl_set_elem_do_snprintf);
679 EXPORT_SYMBOL(nftnl_set_elem_foreach);
680 int nftnl_set_elem_foreach(
struct nftnl_set *s,
681 int (*cb)(
struct nftnl_set_elem *e,
void *data),
684 struct nftnl_set_elem *elem;
687 list_for_each_entry(elem, &s->element_list, head) {
688 ret = cb(elem, data);
696 const struct nftnl_set *
set;
697 const struct list_head *list;
698 struct nftnl_set_elem *cur;
701 EXPORT_SYMBOL(nftnl_set_elems_iter_create);
703 nftnl_set_elems_iter_create(
const struct nftnl_set *s)
712 iter->list = &s->element_list;
713 if (list_empty(&s->element_list))
716 iter->cur = list_entry(s->element_list.next,
717 struct nftnl_set_elem, head);
722 EXPORT_SYMBOL(nftnl_set_elems_iter_cur);
723 struct nftnl_set_elem *
729 EXPORT_SYMBOL(nftnl_set_elems_iter_next);
732 struct nftnl_set_elem *s = iter->cur;
737 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set_elem, head);
738 if (&iter->cur->head == iter->list->next)
744 EXPORT_SYMBOL(nftnl_set_elems_iter_destroy);
750 static bool nftnl_attr_nest_overflow(
struct nlmsghdr *nlh,
751 const struct nlattr *from,
752 const struct nlattr *to)
754 int len = (
void *)to + to->nla_len - (
void *)from;
760 if (len > UINT16_MAX) {
761 nlh->nlmsg_len -= to->nla_len;
767 EXPORT_SYMBOL(nftnl_set_elems_nlmsg_build_payload_iter);
768 int nftnl_set_elems_nlmsg_build_payload_iter(
struct nlmsghdr *nlh,
771 struct nftnl_set_elem *elem;
772 struct nlattr *nest1, *nest2;
775 nftnl_set_elem_nlmsg_build_def(nlh, iter->set);
778 if (list_empty(&iter->set->element_list))
781 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_LIST_ELEMENTS);
782 elem = nftnl_set_elems_iter_next(iter);
783 while (elem != NULL) {
784 nest2 = nftnl_set_elem_build(nlh, elem, ++i);
785 if (nftnl_attr_nest_overflow(nlh, nest1, nest2)) {
787 iter->cur = list_entry(iter->cur->head.prev,
788 struct nftnl_set_elem, head);
792 elem = nftnl_set_elems_iter_next(iter);
794 mnl_attr_nest_end(nlh, nest1);