19#include <netinet/in.h>
24#include <libmnl/libmnl.h>
25#include <linux/netfilter/nfnetlink.h>
26#include <linux/netfilter/nf_tables.h>
28#include <libnftnl/rule.h>
29#include <libnftnl/set.h>
30#include <libnftnl/expr.h>
32EXPORT_SYMBOL(nftnl_rule_alloc);
33struct nftnl_rule *nftnl_rule_alloc(
void)
37 r = calloc(1,
sizeof(
struct nftnl_rule));
41 INIT_LIST_HEAD(&r->expr_list);
46EXPORT_SYMBOL(nftnl_rule_free);
47void nftnl_rule_free(
const struct nftnl_rule *r)
49 struct nftnl_expr *e, *tmp;
51 list_for_each_entry_safe(e, tmp, &r->expr_list, head)
54 if (r->flags & (1 << (NFTNL_RULE_TABLE)))
56 if (r->flags & (1 << (NFTNL_RULE_CHAIN)))
58 if (r->flags & (1 << (NFTNL_RULE_USERDATA)))
64EXPORT_SYMBOL(nftnl_rule_is_set);
65bool nftnl_rule_is_set(
const struct nftnl_rule *r, uint16_t attr)
67 return r->flags & (1 << attr);
70EXPORT_SYMBOL(nftnl_rule_unset);
71void nftnl_rule_unset(
struct nftnl_rule *r, uint16_t attr)
73 if (!(r->flags & (1 << attr)))
77 case NFTNL_RULE_TABLE:
80 case NFTNL_RULE_CHAIN:
83 case NFTNL_RULE_HANDLE:
84 case NFTNL_RULE_COMPAT_PROTO:
85 case NFTNL_RULE_COMPAT_FLAGS:
86 case NFTNL_RULE_POSITION:
87 case NFTNL_RULE_FAMILY:
89 case NFTNL_RULE_POSITION_ID:
91 case NFTNL_RULE_USERDATA:
96 r->flags &= ~(1 << attr);
99static uint32_t nftnl_rule_validate[NFTNL_RULE_MAX + 1] = {
100 [NFTNL_RULE_HANDLE] =
sizeof(uint64_t),
101 [NFTNL_RULE_COMPAT_PROTO] =
sizeof(uint32_t),
102 [NFTNL_RULE_COMPAT_FLAGS] =
sizeof(uint32_t),
103 [NFTNL_RULE_FAMILY] =
sizeof(uint32_t),
104 [NFTNL_RULE_POSITION] =
sizeof(uint64_t),
105 [NFTNL_RULE_ID] =
sizeof(uint32_t),
106 [NFTNL_RULE_POSITION_ID] =
sizeof(uint32_t),
109EXPORT_SYMBOL(nftnl_rule_set_data);
110int nftnl_rule_set_data(
struct nftnl_rule *r, uint16_t attr,
111 const void *data, uint32_t data_len)
113 nftnl_assert_attr_exists(attr, NFTNL_RULE_MAX);
114 nftnl_assert_validate(data, nftnl_rule_validate, attr, data_len);
117 case NFTNL_RULE_TABLE:
118 return nftnl_set_str_attr(&r->table, &r->flags,
119 attr, data, data_len);
120 case NFTNL_RULE_CHAIN:
121 return nftnl_set_str_attr(&r->chain, &r->flags,
122 attr, data, data_len);
123 case NFTNL_RULE_HANDLE:
124 memcpy(&r->handle, data,
sizeof(r->handle));
126 case NFTNL_RULE_COMPAT_PROTO:
127 memcpy(&r->compat.proto, data,
sizeof(r->compat.proto));
129 case NFTNL_RULE_COMPAT_FLAGS:
130 memcpy(&r->compat.flags, data,
sizeof(r->compat.flags));
132 case NFTNL_RULE_FAMILY:
133 memcpy(&r->family, data,
sizeof(r->family));
135 case NFTNL_RULE_POSITION:
136 memcpy(&r->position, data,
sizeof(r->position));
138 case NFTNL_RULE_USERDATA:
139 if (r->flags & (1 << NFTNL_RULE_USERDATA))
142 r->user.data = malloc(data_len);
146 memcpy(r->user.data, data, data_len);
147 r->user.len = data_len;
150 memcpy(&r->id, data,
sizeof(r->id));
152 case NFTNL_RULE_POSITION_ID:
153 memcpy(&r->position_id, data,
sizeof(r->position_id));
156 r->flags |= (1 << attr);
160int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data) __visible;
161int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data)
163 return nftnl_rule_set_data(r, attr, data, nftnl_rule_validate[attr]);
166EXPORT_SYMBOL(nftnl_rule_set_u32);
167void nftnl_rule_set_u32(
struct nftnl_rule *r, uint16_t attr, uint32_t val)
169 nftnl_rule_set_data(r, attr, &val,
sizeof(uint32_t));
172EXPORT_SYMBOL(nftnl_rule_set_u64);
173void nftnl_rule_set_u64(
struct nftnl_rule *r, uint16_t attr, uint64_t val)
175 nftnl_rule_set_data(r, attr, &val,
sizeof(uint64_t));
178EXPORT_SYMBOL(nftnl_rule_set_str);
179int nftnl_rule_set_str(
struct nftnl_rule *r, uint16_t attr,
const char *str)
181 return nftnl_rule_set_data(r, attr, str, strlen(str) + 1);
184EXPORT_SYMBOL(nftnl_rule_get_data);
185const void *nftnl_rule_get_data(
const struct nftnl_rule *r, uint16_t attr,
188 if (!(r->flags & (1 << attr)))
192 case NFTNL_RULE_FAMILY:
193 *data_len =
sizeof(uint32_t);
195 case NFTNL_RULE_TABLE:
196 *data_len = strlen(r->table) + 1;
198 case NFTNL_RULE_CHAIN:
199 *data_len = strlen(r->chain) + 1;
201 case NFTNL_RULE_HANDLE:
202 *data_len =
sizeof(uint64_t);
204 case NFTNL_RULE_COMPAT_PROTO:
205 *data_len =
sizeof(uint32_t);
206 return &r->compat.proto;
207 case NFTNL_RULE_COMPAT_FLAGS:
208 *data_len =
sizeof(uint32_t);
209 return &r->compat.flags;
210 case NFTNL_RULE_POSITION:
211 *data_len =
sizeof(uint64_t);
213 case NFTNL_RULE_USERDATA:
214 *data_len = r->user.len;
217 *data_len =
sizeof(uint32_t);
219 case NFTNL_RULE_POSITION_ID:
220 *data_len =
sizeof(uint32_t);
221 return &r->position_id;
226EXPORT_SYMBOL(nftnl_rule_get);
227const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
230 return nftnl_rule_get_data(r, attr, &data_len);
233EXPORT_SYMBOL(nftnl_rule_get_str);
234const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
236 return nftnl_rule_get(r, attr);
239EXPORT_SYMBOL(nftnl_rule_get_u32);
240uint32_t nftnl_rule_get_u32(
const struct nftnl_rule *r, uint16_t attr)
243 const uint32_t *val = nftnl_rule_get_data(r, attr, &data_len);
245 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
247 return val ? *val : 0;
250EXPORT_SYMBOL(nftnl_rule_get_u64);
251uint64_t nftnl_rule_get_u64(
const struct nftnl_rule *r, uint16_t attr)
254 const uint64_t *val = nftnl_rule_get_data(r, attr, &data_len);
256 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
258 return val ? *val : 0;
261EXPORT_SYMBOL(nftnl_rule_get_u8);
262uint8_t nftnl_rule_get_u8(
const struct nftnl_rule *r, uint16_t attr)
265 const uint8_t *val = nftnl_rule_get_data(r, attr, &data_len);
267 nftnl_assert(val, attr, data_len ==
sizeof(uint8_t));
269 return val ? *val : 0;
272EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
273void nftnl_rule_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_rule *r)
275 struct nftnl_expr *expr;
276 struct nlattr *nest, *nest2;
278 if (r->flags & (1 << NFTNL_RULE_TABLE))
279 mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
280 if (r->flags & (1 << NFTNL_RULE_CHAIN))
281 mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain);
282 if (r->flags & (1 << NFTNL_RULE_HANDLE))
283 mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
284 if (r->flags & (1 << NFTNL_RULE_POSITION))
285 mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
286 if (r->flags & (1 << NFTNL_RULE_USERDATA)) {
287 mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
291 if (!list_empty(&r->expr_list)) {
292 nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
293 list_for_each_entry(expr, &r->expr_list, head) {
294 nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
295 nftnl_expr_build_payload(nlh, expr);
296 mnl_attr_nest_end(nlh, nest2);
298 mnl_attr_nest_end(nlh, nest);
301 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO) &&
302 r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) {
304 nest = mnl_attr_nest_start(nlh, NFTA_RULE_COMPAT);
305 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_PROTO,
306 htonl(r->compat.proto));
307 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_FLAGS,
308 htonl(r->compat.flags));
309 mnl_attr_nest_end(nlh, nest);
311 if (r->flags & (1 << NFTNL_RULE_ID))
312 mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id));
313 if (r->flags & (1 << NFTNL_RULE_POSITION_ID))
314 mnl_attr_put_u32(nlh, NFTA_RULE_POSITION_ID, htonl(r->position_id));
317EXPORT_SYMBOL(nftnl_rule_add_expr);
318void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
320 list_add_tail(&expr->head, &r->expr_list);
323EXPORT_SYMBOL(nftnl_rule_del_expr);
324void nftnl_rule_del_expr(
struct nftnl_expr *expr)
326 list_del(&expr->head);
329static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
331 const struct nlattr **tb = data;
332 int type = mnl_attr_get_type(attr);
334 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
338 case NFTA_RULE_TABLE:
339 case NFTA_RULE_CHAIN:
340 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
343 case NFTA_RULE_HANDLE:
344 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
347 case NFTA_RULE_COMPAT:
348 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
351 case NFTA_RULE_POSITION:
352 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
355 case NFTA_RULE_USERDATA:
356 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
360 case NFTA_RULE_POSITION_ID:
361 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
370static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
372 struct nftnl_expr *expr;
375 mnl_attr_for_each_nested(attr, nest) {
376 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
379 expr = nftnl_expr_parse(attr);
383 list_add_tail(&expr->head, &r->expr_list);
388static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
390 const struct nlattr **tb = data;
391 int type = mnl_attr_get_type(attr);
393 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
397 case NFTA_RULE_COMPAT_PROTO:
398 case NFTA_RULE_COMPAT_FLAGS:
399 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
408static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
410 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
412 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
415 if (tb[NFTA_RULE_COMPAT_PROTO]) {
417 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
418 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
420 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
422 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
423 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
428EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
429int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
431 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
432 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
435 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
438 if (tb[NFTA_RULE_TABLE]) {
439 if (r->flags & (1 << NFTNL_RULE_TABLE))
441 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
444 r->flags |= (1 << NFTNL_RULE_TABLE);
446 if (tb[NFTA_RULE_CHAIN]) {
447 if (r->flags & (1 << NFTNL_RULE_CHAIN))
449 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
452 r->flags |= (1 << NFTNL_RULE_CHAIN);
454 if (tb[NFTA_RULE_HANDLE]) {
455 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
456 r->flags |= (1 << NFTNL_RULE_HANDLE);
458 if (tb[NFTA_RULE_EXPRESSIONS]) {
459 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
463 if (tb[NFTA_RULE_COMPAT]) {
464 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
468 if (tb[NFTA_RULE_POSITION]) {
469 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
470 r->flags |= (1 << NFTNL_RULE_POSITION);
472 if (tb[NFTA_RULE_USERDATA]) {
474 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
476 if (r->flags & (1 << NFTNL_RULE_USERDATA))
479 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
481 r->user.data = malloc(r->user.len);
482 if (r->user.data == NULL)
485 memcpy(r->user.data, udata, r->user.len);
486 r->flags |= (1 << NFTNL_RULE_USERDATA);
488 if (tb[NFTA_RULE_ID]) {
489 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
490 r->flags |= (1 << NFTNL_RULE_ID);
492 if (tb[NFTA_RULE_POSITION_ID]) {
493 r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID]));
494 r->flags |= (1 << NFTNL_RULE_POSITION_ID);
497 r->family = nfg->nfgen_family;
498 r->flags |= (1 << NFTNL_RULE_FAMILY);
503EXPORT_SYMBOL(nftnl_rule_parse);
504int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
505 const char *data,
struct nftnl_parse_err *err)
512EXPORT_SYMBOL(nftnl_rule_parse_file);
513int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
514 FILE *fp,
struct nftnl_parse_err *err)
521static int nftnl_rule_snprintf_default(
char *buf,
size_t remain,
522 const struct nftnl_rule *r,
523 uint32_t type, uint32_t flags)
525 struct nftnl_expr *expr;
526 int ret, offset = 0, i;
527 const char *sep =
"";
529 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
530 ret = snprintf(buf + offset, remain,
"%s%s", sep,
531 nftnl_family2str(r->family));
532 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
536 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
537 ret = snprintf(buf + offset, remain,
"%s%s", sep,
539 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
543 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
544 ret = snprintf(buf + offset, remain,
"%s%s", sep,
546 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
549 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
550 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
552 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
556 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
557 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
559 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
563 if (r->flags & (1 << NFTNL_RULE_ID)) {
564 ret = snprintf(buf + offset, remain,
"%s%u", sep, r->id);
565 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
569 if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) {
570 ret = snprintf(buf + offset, remain,
"%s%u", sep,
572 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
576 list_for_each_entry(expr, &r->expr_list, head) {
577 ret = snprintf(buf + offset, remain,
578 "\n [ %s ", expr->ops->name);
579 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
581 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
583 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
585 ret = snprintf(buf + offset, remain,
"]");
586 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
590 ret = snprintf(buf + offset, remain,
"\n userdata = { ");
591 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
593 for (i = 0; i < r->user.len; i++) {
594 char *c = r->user.data;
596 ret = snprintf(buf + offset, remain,
597 isprint(c[i]) ?
"%c" :
"\\x%02hhx",
599 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
602 ret = snprintf(buf + offset, remain,
" }");
603 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
610static int nftnl_rule_cmd_snprintf(
char *buf,
size_t remain,
611 const struct nftnl_rule *r, uint32_t cmd,
612 uint32_t type, uint32_t flags)
614 uint32_t inner_flags = flags;
617 inner_flags &= ~NFTNL_OF_EVENT_ANY;
619 if (type != NFTNL_OUTPUT_DEFAULT)
622 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
624 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
628EXPORT_SYMBOL(nftnl_rule_snprintf);
629int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
630 uint32_t type, uint32_t flags)
635 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
639static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
640 uint32_t cmd, uint32_t type, uint32_t flags)
642 return nftnl_rule_snprintf(buf, size, r, type, flags);
645EXPORT_SYMBOL(nftnl_rule_fprintf);
646int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
649 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
650 nftnl_rule_do_snprintf);
653EXPORT_SYMBOL(nftnl_expr_foreach);
654int nftnl_expr_foreach(
struct nftnl_rule *r,
655 int (*cb)(
struct nftnl_expr *e,
void *data),
658 struct nftnl_expr *cur, *tmp;
661 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
670 const struct nftnl_rule *r;
671 struct nftnl_expr *cur;
674static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
678 if (list_empty(&r->expr_list))
681 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
685EXPORT_SYMBOL(nftnl_expr_iter_create);
686struct nftnl_expr_iter *nftnl_expr_iter_create(
const struct nftnl_rule *r)
694 nftnl_expr_iter_init(r, iter);
699EXPORT_SYMBOL(nftnl_expr_iter_next);
702 struct nftnl_expr *expr = iter->cur;
708 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
709 if (&iter->cur->head == iter->r->expr_list.next)
715EXPORT_SYMBOL(nftnl_expr_iter_destroy);
722 struct list_head list;
725EXPORT_SYMBOL(nftnl_rule_list_alloc);
734 INIT_LIST_HEAD(&list->list);
739EXPORT_SYMBOL(nftnl_rule_list_free);
742 struct nftnl_rule *r, *tmp;
744 list_for_each_entry_safe(r, tmp, &list->list, head) {
751EXPORT_SYMBOL(nftnl_rule_list_is_empty);
754 return list_empty(&list->list);
757EXPORT_SYMBOL(nftnl_rule_list_add);
758void nftnl_rule_list_add(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
760 list_add(&r->head, &list->list);
763EXPORT_SYMBOL(nftnl_rule_list_insert_at);
764void nftnl_rule_list_insert_at(
struct nftnl_rule *r,
struct nftnl_rule *pos)
766 list_add(&r->head, &pos->head);
769EXPORT_SYMBOL(nftnl_rule_list_add_tail);
770void nftnl_rule_list_add_tail(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
772 list_add_tail(&r->head, &list->list);
775EXPORT_SYMBOL(nftnl_rule_list_del);
776void nftnl_rule_list_del(
struct nftnl_rule *r)
781EXPORT_SYMBOL(nftnl_rule_list_foreach);
783 int (*cb)(
struct nftnl_rule *r,
void *data),
786 struct nftnl_rule *cur, *tmp;
789 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
799 struct nftnl_rule *cur;
802EXPORT_SYMBOL(nftnl_rule_list_iter_create);
813 if (nftnl_rule_list_is_empty(l))
816 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
821EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
827EXPORT_SYMBOL(nftnl_rule_list_iter_next);
830 struct nftnl_rule *r = iter->cur;
836 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
837 if (&iter->cur->head == iter->list->list.next)
843EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);