15 #include <netinet/in.h>
20 #include <libmnl/libmnl.h>
21 #include <linux/netfilter/nfnetlink.h>
22 #include <linux/netfilter/nf_tables.h>
24 #include <libnftnl/rule.h>
25 #include <libnftnl/set.h>
26 #include <libnftnl/expr.h>
28 EXPORT_SYMBOL(nftnl_rule_alloc);
29 struct nftnl_rule *nftnl_rule_alloc(
void)
33 r = calloc(1,
sizeof(
struct nftnl_rule));
37 INIT_LIST_HEAD(&r->expr_list);
42 EXPORT_SYMBOL(nftnl_rule_free);
43 void nftnl_rule_free(
const struct nftnl_rule *r)
45 struct nftnl_expr *e, *tmp;
47 list_for_each_entry_safe(e, tmp, &r->expr_list, head)
50 if (r->flags & (1 << (NFTNL_RULE_TABLE)))
52 if (r->flags & (1 << (NFTNL_RULE_CHAIN)))
54 if (r->flags & (1 << (NFTNL_RULE_USERDATA)))
60 EXPORT_SYMBOL(nftnl_rule_is_set);
61 bool nftnl_rule_is_set(const struct nftnl_rule *r, uint16_t attr)
63 return r->flags & (1 << attr);
66 EXPORT_SYMBOL(nftnl_rule_unset);
67 void nftnl_rule_unset(
struct nftnl_rule *r, uint16_t attr)
69 if (!(r->flags & (1 << attr)))
73 case NFTNL_RULE_TABLE:
76 case NFTNL_RULE_CHAIN:
79 case NFTNL_RULE_HANDLE:
80 case NFTNL_RULE_COMPAT_PROTO:
81 case NFTNL_RULE_COMPAT_FLAGS:
82 case NFTNL_RULE_POSITION:
83 case NFTNL_RULE_FAMILY:
85 case NFTNL_RULE_POSITION_ID:
87 case NFTNL_RULE_USERDATA:
92 r->flags &= ~(1 << attr);
95 static uint32_t nftnl_rule_validate[NFTNL_RULE_MAX + 1] = {
96 [NFTNL_RULE_HANDLE] =
sizeof(uint64_t),
97 [NFTNL_RULE_COMPAT_PROTO] =
sizeof(uint32_t),
98 [NFTNL_RULE_COMPAT_FLAGS] =
sizeof(uint32_t),
99 [NFTNL_RULE_FAMILY] =
sizeof(uint32_t),
100 [NFTNL_RULE_POSITION] =
sizeof(uint64_t),
101 [NFTNL_RULE_ID] =
sizeof(uint32_t),
102 [NFTNL_RULE_POSITION_ID] =
sizeof(uint32_t),
105 EXPORT_SYMBOL(nftnl_rule_set_data);
106 int nftnl_rule_set_data(
struct nftnl_rule *r, uint16_t attr,
107 const void *data, uint32_t data_len)
109 nftnl_assert_attr_exists(attr, NFTNL_RULE_MAX);
110 nftnl_assert_validate(data, nftnl_rule_validate, attr, data_len);
113 case NFTNL_RULE_TABLE:
114 return nftnl_set_str_attr(&r->table, &r->flags,
115 attr, data, data_len);
116 case NFTNL_RULE_CHAIN:
117 return nftnl_set_str_attr(&r->chain, &r->flags,
118 attr, data, data_len);
119 case NFTNL_RULE_HANDLE:
120 memcpy(&r->handle, data,
sizeof(r->handle));
122 case NFTNL_RULE_COMPAT_PROTO:
123 memcpy(&r->compat.proto, data,
sizeof(r->compat.proto));
125 case NFTNL_RULE_COMPAT_FLAGS:
126 memcpy(&r->compat.flags, data,
sizeof(r->compat.flags));
128 case NFTNL_RULE_FAMILY:
129 memcpy(&r->family, data,
sizeof(r->family));
131 case NFTNL_RULE_POSITION:
132 memcpy(&r->position, data,
sizeof(r->position));
134 case NFTNL_RULE_USERDATA:
135 if (r->flags & (1 << NFTNL_RULE_USERDATA))
138 r->user.data = malloc(data_len);
142 memcpy(r->user.data, data, data_len);
143 r->user.len = data_len;
146 memcpy(&r->id, data,
sizeof(r->id));
148 case NFTNL_RULE_POSITION_ID:
149 memcpy(&r->position_id, data,
sizeof(r->position_id));
152 r->flags |= (1 << attr);
156 int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data) __visible;
157 int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data)
159 return nftnl_rule_set_data(r, attr, data, nftnl_rule_validate[attr]);
162 EXPORT_SYMBOL(nftnl_rule_set_u32);
163 void nftnl_rule_set_u32(
struct nftnl_rule *r, uint16_t attr, uint32_t val)
165 nftnl_rule_set_data(r, attr, &val,
sizeof(uint32_t));
168 EXPORT_SYMBOL(nftnl_rule_set_u64);
169 void nftnl_rule_set_u64(
struct nftnl_rule *r, uint16_t attr, uint64_t val)
171 nftnl_rule_set_data(r, attr, &val,
sizeof(uint64_t));
174 EXPORT_SYMBOL(nftnl_rule_set_str);
175 int nftnl_rule_set_str(
struct nftnl_rule *r, uint16_t attr,
const char *str)
177 return nftnl_rule_set_data(r, attr, str, strlen(str) + 1);
180 EXPORT_SYMBOL(nftnl_rule_get_data);
181 const void *nftnl_rule_get_data(
const struct nftnl_rule *r, uint16_t attr,
184 if (!(r->flags & (1 << attr)))
188 case NFTNL_RULE_FAMILY:
189 *data_len =
sizeof(uint32_t);
191 case NFTNL_RULE_TABLE:
192 *data_len = strlen(r->table) + 1;
194 case NFTNL_RULE_CHAIN:
195 *data_len = strlen(r->chain) + 1;
197 case NFTNL_RULE_HANDLE:
198 *data_len =
sizeof(uint64_t);
200 case NFTNL_RULE_COMPAT_PROTO:
201 *data_len =
sizeof(uint32_t);
202 return &r->compat.proto;
203 case NFTNL_RULE_COMPAT_FLAGS:
204 *data_len =
sizeof(uint32_t);
205 return &r->compat.flags;
206 case NFTNL_RULE_POSITION:
207 *data_len =
sizeof(uint64_t);
209 case NFTNL_RULE_USERDATA:
210 *data_len = r->user.len;
213 *data_len =
sizeof(uint32_t);
215 case NFTNL_RULE_POSITION_ID:
216 *data_len =
sizeof(uint32_t);
217 return &r->position_id;
222 EXPORT_SYMBOL(nftnl_rule_get);
223 const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
226 return nftnl_rule_get_data(r, attr, &data_len);
229 EXPORT_SYMBOL(nftnl_rule_get_str);
230 const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
232 return nftnl_rule_get(r, attr);
235 EXPORT_SYMBOL(nftnl_rule_get_u32);
236 uint32_t nftnl_rule_get_u32(
const struct nftnl_rule *r, uint16_t attr)
239 const uint32_t *val = nftnl_rule_get_data(r, attr, &data_len);
241 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
243 return val ? *val : 0;
246 EXPORT_SYMBOL(nftnl_rule_get_u64);
247 uint64_t nftnl_rule_get_u64(
const struct nftnl_rule *r, uint16_t attr)
250 const uint64_t *val = nftnl_rule_get_data(r, attr, &data_len);
252 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
254 return val ? *val : 0;
257 EXPORT_SYMBOL(nftnl_rule_get_u8);
258 uint8_t nftnl_rule_get_u8(
const struct nftnl_rule *r, uint16_t attr)
261 const uint8_t *val = nftnl_rule_get_data(r, attr, &data_len);
263 nftnl_assert(val, attr, data_len ==
sizeof(uint8_t));
265 return val ? *val : 0;
268 EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
269 void nftnl_rule_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_rule *r)
271 struct nftnl_expr *expr;
272 struct nlattr *nest, *nest2;
274 if (r->flags & (1 << NFTNL_RULE_TABLE))
275 mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
276 if (r->flags & (1 << NFTNL_RULE_CHAIN))
277 mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain);
278 if (r->flags & (1 << NFTNL_RULE_HANDLE))
279 mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
280 if (r->flags & (1 << NFTNL_RULE_POSITION))
281 mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
282 if (r->flags & (1 << NFTNL_RULE_USERDATA)) {
283 mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
287 if (!list_empty(&r->expr_list)) {
288 nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
289 list_for_each_entry(expr, &r->expr_list, head) {
290 nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
291 nftnl_expr_build_payload(nlh, expr);
292 mnl_attr_nest_end(nlh, nest2);
294 mnl_attr_nest_end(nlh, nest);
297 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO) &&
298 r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) {
300 nest = mnl_attr_nest_start(nlh, NFTA_RULE_COMPAT);
301 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_PROTO,
302 htonl(r->compat.proto));
303 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_FLAGS,
304 htonl(r->compat.flags));
305 mnl_attr_nest_end(nlh, nest);
307 if (r->flags & (1 << NFTNL_RULE_ID))
308 mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id));
309 if (r->flags & (1 << NFTNL_RULE_POSITION_ID))
310 mnl_attr_put_u32(nlh, NFTA_RULE_POSITION_ID, htonl(r->position_id));
313 EXPORT_SYMBOL(nftnl_rule_add_expr);
314 void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
316 list_add_tail(&expr->head, &r->expr_list);
319 EXPORT_SYMBOL(nftnl_rule_del_expr);
320 void nftnl_rule_del_expr(
struct nftnl_expr *expr)
322 list_del(&expr->head);
325 static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
327 const struct nlattr **tb = data;
328 int type = mnl_attr_get_type(attr);
330 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
334 case NFTA_RULE_TABLE:
335 case NFTA_RULE_CHAIN:
336 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
339 case NFTA_RULE_HANDLE:
340 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
343 case NFTA_RULE_COMPAT:
344 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
347 case NFTA_RULE_POSITION:
348 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
351 case NFTA_RULE_USERDATA:
352 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
356 case NFTA_RULE_POSITION_ID:
357 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
366 static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
368 struct nftnl_expr *expr;
371 mnl_attr_for_each_nested(attr, nest) {
372 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
375 expr = nftnl_expr_parse(attr);
379 list_add_tail(&expr->head, &r->expr_list);
384 static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
386 const struct nlattr **tb = data;
387 int type = mnl_attr_get_type(attr);
389 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
393 case NFTA_RULE_COMPAT_PROTO:
394 case NFTA_RULE_COMPAT_FLAGS:
395 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
404 static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
406 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
408 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
411 if (tb[NFTA_RULE_COMPAT_PROTO]) {
413 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
414 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
416 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
418 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
419 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
424 EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
425 int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
427 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
428 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
431 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
434 if (tb[NFTA_RULE_TABLE]) {
435 if (r->flags & (1 << NFTNL_RULE_TABLE))
437 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
440 r->flags |= (1 << NFTNL_RULE_TABLE);
442 if (tb[NFTA_RULE_CHAIN]) {
443 if (r->flags & (1 << NFTNL_RULE_CHAIN))
445 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
448 r->flags |= (1 << NFTNL_RULE_CHAIN);
450 if (tb[NFTA_RULE_HANDLE]) {
451 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
452 r->flags |= (1 << NFTNL_RULE_HANDLE);
454 if (tb[NFTA_RULE_EXPRESSIONS]) {
455 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
459 if (tb[NFTA_RULE_COMPAT]) {
460 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
464 if (tb[NFTA_RULE_POSITION]) {
465 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
466 r->flags |= (1 << NFTNL_RULE_POSITION);
468 if (tb[NFTA_RULE_USERDATA]) {
470 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
472 if (r->flags & (1 << NFTNL_RULE_USERDATA))
475 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
477 r->user.data = malloc(r->user.len);
478 if (r->user.data == NULL)
481 memcpy(r->user.data, udata, r->user.len);
482 r->flags |= (1 << NFTNL_RULE_USERDATA);
484 if (tb[NFTA_RULE_ID]) {
485 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
486 r->flags |= (1 << NFTNL_RULE_ID);
488 if (tb[NFTA_RULE_POSITION_ID]) {
489 r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID]));
490 r->flags |= (1 << NFTNL_RULE_POSITION_ID);
493 r->family = nfg->nfgen_family;
494 r->flags |= (1 << NFTNL_RULE_FAMILY);
499 EXPORT_SYMBOL(nftnl_rule_parse);
500 int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
501 const char *data,
struct nftnl_parse_err *err)
508 EXPORT_SYMBOL(nftnl_rule_parse_file);
509 int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
510 FILE *fp,
struct nftnl_parse_err *err)
517 static int nftnl_rule_snprintf_default(
char *buf,
size_t remain,
518 const struct nftnl_rule *r,
519 uint32_t type, uint32_t flags)
521 struct nftnl_expr *expr;
522 int ret, offset = 0, i;
523 const char *sep =
"";
525 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
526 ret = snprintf(buf + offset, remain,
"%s%s", sep,
527 nftnl_family2str(r->family));
528 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
532 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
533 ret = snprintf(buf + offset, remain,
"%s%s", sep,
535 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
539 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
540 ret = snprintf(buf + offset, remain,
"%s%s", sep,
542 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
545 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
546 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
548 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
552 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
553 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
555 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
559 if (r->flags & (1 << NFTNL_RULE_ID)) {
560 ret = snprintf(buf + offset, remain,
"%s%u", sep, r->id);
561 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
565 if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) {
566 ret = snprintf(buf + offset, remain,
"%s%u", sep,
568 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
572 list_for_each_entry(expr, &r->expr_list, head) {
573 ret = snprintf(buf + offset, remain,
574 "\n [ %s ", expr->ops->name);
575 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
577 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
579 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
581 ret = snprintf(buf + offset, remain,
"]");
582 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
586 ret = snprintf(buf + offset, remain,
"\n userdata = { ");
587 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
589 for (i = 0; i < r->user.len; i++) {
590 char *c = r->user.data;
592 ret = snprintf(buf + offset, remain,
593 isprint(c[i]) ?
"%c" :
"\\x%02hhx",
595 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
598 ret = snprintf(buf + offset, remain,
" }");
599 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
606 static int nftnl_rule_cmd_snprintf(
char *buf,
size_t remain,
607 const struct nftnl_rule *r, uint32_t cmd,
608 uint32_t type, uint32_t flags)
610 uint32_t inner_flags = flags;
613 inner_flags &= ~NFTNL_OF_EVENT_ANY;
615 if (type != NFTNL_OUTPUT_DEFAULT)
618 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
620 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
624 EXPORT_SYMBOL(nftnl_rule_snprintf);
625 int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
626 uint32_t type, uint32_t flags)
631 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
635 static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
636 uint32_t cmd, uint32_t type, uint32_t flags)
638 return nftnl_rule_snprintf(buf, size, r, type, flags);
641 EXPORT_SYMBOL(nftnl_rule_fprintf);
642 int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
645 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
646 nftnl_rule_do_snprintf);
649 EXPORT_SYMBOL(nftnl_expr_foreach);
650 int nftnl_expr_foreach(
struct nftnl_rule *r,
651 int (*cb)(
struct nftnl_expr *e,
void *data),
654 struct nftnl_expr *cur, *tmp;
657 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
666 const struct nftnl_rule *r;
667 struct nftnl_expr *cur;
670 static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
674 if (list_empty(&r->expr_list))
677 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
681 EXPORT_SYMBOL(nftnl_expr_iter_create);
682 struct nftnl_expr_iter *nftnl_expr_iter_create(
const struct nftnl_rule *r)
690 nftnl_expr_iter_init(r, iter);
695 EXPORT_SYMBOL(nftnl_expr_iter_next);
698 struct nftnl_expr *expr = iter->cur;
704 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
705 if (&iter->cur->head == iter->r->expr_list.next)
711 EXPORT_SYMBOL(nftnl_expr_iter_destroy);
718 struct list_head list;
721 EXPORT_SYMBOL(nftnl_rule_list_alloc);
730 INIT_LIST_HEAD(&list->list);
735 EXPORT_SYMBOL(nftnl_rule_list_free);
738 struct nftnl_rule *r, *tmp;
740 list_for_each_entry_safe(r, tmp, &list->list, head) {
747 EXPORT_SYMBOL(nftnl_rule_list_is_empty);
750 return list_empty(&list->list);
753 EXPORT_SYMBOL(nftnl_rule_list_add);
754 void nftnl_rule_list_add(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
756 list_add(&r->head, &list->list);
759 EXPORT_SYMBOL(nftnl_rule_list_insert_at);
760 void nftnl_rule_list_insert_at(
struct nftnl_rule *r,
struct nftnl_rule *pos)
762 list_add(&r->head, &pos->head);
765 EXPORT_SYMBOL(nftnl_rule_list_add_tail);
766 void nftnl_rule_list_add_tail(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
768 list_add_tail(&r->head, &list->list);
771 EXPORT_SYMBOL(nftnl_rule_list_del);
772 void nftnl_rule_list_del(
struct nftnl_rule *r)
777 EXPORT_SYMBOL(nftnl_rule_list_foreach);
779 int (*cb)(
struct nftnl_rule *r,
void *data),
782 struct nftnl_rule *cur, *tmp;
785 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
795 struct nftnl_rule *cur;
798 EXPORT_SYMBOL(nftnl_rule_list_iter_create);
809 if (nftnl_rule_list_is_empty(l))
812 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
817 EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
823 EXPORT_SYMBOL(nftnl_rule_list_iter_next);
826 struct nftnl_rule *r = iter->cur;
832 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
833 if (&iter->cur->head == iter->list->list.next)
839 EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);