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 if (r->flags & (1 << NFTNL_RULE_TABLE))
121 r->table = strdup(data);
125 case NFTNL_RULE_CHAIN:
126 if (r->flags & (1 << NFTNL_RULE_CHAIN))
129 r->chain = strdup(data);
133 case NFTNL_RULE_HANDLE:
134 memcpy(&r->handle, data,
sizeof(r->handle));
136 case NFTNL_RULE_COMPAT_PROTO:
137 memcpy(&r->compat.proto, data,
sizeof(r->compat.proto));
139 case NFTNL_RULE_COMPAT_FLAGS:
140 memcpy(&r->compat.flags, data,
sizeof(r->compat.flags));
142 case NFTNL_RULE_FAMILY:
143 memcpy(&r->family, data,
sizeof(r->family));
145 case NFTNL_RULE_POSITION:
146 memcpy(&r->position, data,
sizeof(r->position));
148 case NFTNL_RULE_USERDATA:
149 if (r->flags & (1 << NFTNL_RULE_USERDATA))
152 r->user.data = malloc(data_len);
156 memcpy(r->user.data, data, data_len);
157 r->user.len = data_len;
160 memcpy(&r->id, data,
sizeof(r->id));
162 case NFTNL_RULE_POSITION_ID:
163 memcpy(&r->position_id, data,
sizeof(r->position_id));
166 r->flags |= (1 << attr);
170int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data) __visible;
171int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data)
173 return nftnl_rule_set_data(r, attr, data, nftnl_rule_validate[attr]);
176EXPORT_SYMBOL(nftnl_rule_set_u32);
177void nftnl_rule_set_u32(
struct nftnl_rule *r, uint16_t attr, uint32_t val)
179 nftnl_rule_set_data(r, attr, &val,
sizeof(uint32_t));
182EXPORT_SYMBOL(nftnl_rule_set_u64);
183void nftnl_rule_set_u64(
struct nftnl_rule *r, uint16_t attr, uint64_t val)
185 nftnl_rule_set_data(r, attr, &val,
sizeof(uint64_t));
188EXPORT_SYMBOL(nftnl_rule_set_str);
189int nftnl_rule_set_str(
struct nftnl_rule *r, uint16_t attr,
const char *str)
191 return nftnl_rule_set_data(r, attr, str, strlen(str) + 1);
194EXPORT_SYMBOL(nftnl_rule_get_data);
195const void *nftnl_rule_get_data(
const struct nftnl_rule *r, uint16_t attr,
198 if (!(r->flags & (1 << attr)))
202 case NFTNL_RULE_FAMILY:
203 *data_len =
sizeof(uint32_t);
205 case NFTNL_RULE_TABLE:
206 *data_len = strlen(r->table) + 1;
208 case NFTNL_RULE_CHAIN:
209 *data_len = strlen(r->chain) + 1;
211 case NFTNL_RULE_HANDLE:
212 *data_len =
sizeof(uint64_t);
214 case NFTNL_RULE_COMPAT_PROTO:
215 *data_len =
sizeof(uint32_t);
216 return &r->compat.proto;
217 case NFTNL_RULE_COMPAT_FLAGS:
218 *data_len =
sizeof(uint32_t);
219 return &r->compat.flags;
220 case NFTNL_RULE_POSITION:
221 *data_len =
sizeof(uint64_t);
223 case NFTNL_RULE_USERDATA:
224 *data_len = r->user.len;
227 *data_len =
sizeof(uint32_t);
229 case NFTNL_RULE_POSITION_ID:
230 *data_len =
sizeof(uint32_t);
231 return &r->position_id;
236EXPORT_SYMBOL(nftnl_rule_get);
237const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
240 return nftnl_rule_get_data(r, attr, &data_len);
243EXPORT_SYMBOL(nftnl_rule_get_str);
244const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
246 return nftnl_rule_get(r, attr);
249EXPORT_SYMBOL(nftnl_rule_get_u32);
250uint32_t nftnl_rule_get_u32(
const struct nftnl_rule *r, uint16_t attr)
253 const uint32_t *val = nftnl_rule_get_data(r, attr, &data_len);
255 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
257 return val ? *val : 0;
260EXPORT_SYMBOL(nftnl_rule_get_u64);
261uint64_t nftnl_rule_get_u64(
const struct nftnl_rule *r, uint16_t attr)
264 const uint64_t *val = nftnl_rule_get_data(r, attr, &data_len);
266 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
268 return val ? *val : 0;
271EXPORT_SYMBOL(nftnl_rule_get_u8);
272uint8_t nftnl_rule_get_u8(
const struct nftnl_rule *r, uint16_t attr)
275 const uint8_t *val = nftnl_rule_get_data(r, attr, &data_len);
277 nftnl_assert(val, attr, data_len ==
sizeof(uint8_t));
279 return val ? *val : 0;
282EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
283void nftnl_rule_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_rule *r)
285 struct nftnl_expr *expr;
286 struct nlattr *nest, *nest2;
288 if (r->flags & (1 << NFTNL_RULE_TABLE))
289 mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
290 if (r->flags & (1 << NFTNL_RULE_CHAIN))
291 mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain);
292 if (r->flags & (1 << NFTNL_RULE_HANDLE))
293 mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
294 if (r->flags & (1 << NFTNL_RULE_POSITION))
295 mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
296 if (r->flags & (1 << NFTNL_RULE_USERDATA)) {
297 mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
301 if (!list_empty(&r->expr_list)) {
302 nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
303 list_for_each_entry(expr, &r->expr_list, head) {
304 nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
305 nftnl_expr_build_payload(nlh, expr);
306 mnl_attr_nest_end(nlh, nest2);
308 mnl_attr_nest_end(nlh, nest);
311 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO) &&
312 r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) {
314 nest = mnl_attr_nest_start(nlh, NFTA_RULE_COMPAT);
315 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_PROTO,
316 htonl(r->compat.proto));
317 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_FLAGS,
318 htonl(r->compat.flags));
319 mnl_attr_nest_end(nlh, nest);
321 if (r->flags & (1 << NFTNL_RULE_ID))
322 mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id));
323 if (r->flags & (1 << NFTNL_RULE_POSITION_ID))
324 mnl_attr_put_u32(nlh, NFTA_RULE_POSITION_ID, htonl(r->position_id));
327EXPORT_SYMBOL(nftnl_rule_add_expr);
328void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
330 list_add_tail(&expr->head, &r->expr_list);
333EXPORT_SYMBOL(nftnl_rule_del_expr);
334void nftnl_rule_del_expr(
struct nftnl_expr *expr)
336 list_del(&expr->head);
339static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
341 const struct nlattr **tb = data;
342 int type = mnl_attr_get_type(attr);
344 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
348 case NFTA_RULE_TABLE:
349 case NFTA_RULE_CHAIN:
350 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
353 case NFTA_RULE_HANDLE:
354 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
357 case NFTA_RULE_COMPAT:
358 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
361 case NFTA_RULE_POSITION:
362 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
365 case NFTA_RULE_USERDATA:
366 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
370 case NFTA_RULE_POSITION_ID:
371 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
380static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
382 struct nftnl_expr *expr;
385 mnl_attr_for_each_nested(attr, nest) {
386 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
389 expr = nftnl_expr_parse(attr);
393 list_add_tail(&expr->head, &r->expr_list);
398static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
400 const struct nlattr **tb = data;
401 int type = mnl_attr_get_type(attr);
403 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
407 case NFTA_RULE_COMPAT_PROTO:
408 case NFTA_RULE_COMPAT_FLAGS:
409 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
418static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
420 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
422 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
425 if (tb[NFTA_RULE_COMPAT_PROTO]) {
427 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
428 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
430 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
432 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
433 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
438EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
439int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
441 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
442 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
445 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
448 if (tb[NFTA_RULE_TABLE]) {
449 if (r->flags & (1 << NFTNL_RULE_TABLE))
451 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
454 r->flags |= (1 << NFTNL_RULE_TABLE);
456 if (tb[NFTA_RULE_CHAIN]) {
457 if (r->flags & (1 << NFTNL_RULE_CHAIN))
459 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
462 r->flags |= (1 << NFTNL_RULE_CHAIN);
464 if (tb[NFTA_RULE_HANDLE]) {
465 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
466 r->flags |= (1 << NFTNL_RULE_HANDLE);
468 if (tb[NFTA_RULE_EXPRESSIONS]) {
469 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
473 if (tb[NFTA_RULE_COMPAT]) {
474 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
478 if (tb[NFTA_RULE_POSITION]) {
479 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
480 r->flags |= (1 << NFTNL_RULE_POSITION);
482 if (tb[NFTA_RULE_USERDATA]) {
484 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
486 if (r->flags & (1 << NFTNL_RULE_USERDATA))
489 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
491 r->user.data = malloc(r->user.len);
492 if (r->user.data == NULL)
495 memcpy(r->user.data, udata, r->user.len);
496 r->flags |= (1 << NFTNL_RULE_USERDATA);
498 if (tb[NFTA_RULE_ID]) {
499 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
500 r->flags |= (1 << NFTNL_RULE_ID);
502 if (tb[NFTA_RULE_POSITION_ID]) {
503 r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID]));
504 r->flags |= (1 << NFTNL_RULE_POSITION_ID);
507 r->family = nfg->nfgen_family;
508 r->flags |= (1 << NFTNL_RULE_FAMILY);
513static int nftnl_rule_do_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
514 const void *data,
struct nftnl_parse_err *err,
515 enum nftnl_parse_input input)
518 struct nftnl_parse_err perr = {};
521 case NFTNL_PARSE_JSON:
522 case NFTNL_PARSE_XML:
534EXPORT_SYMBOL(nftnl_rule_parse);
535int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
536 const char *data,
struct nftnl_parse_err *err)
538 return nftnl_rule_do_parse(r, type, data, err, NFTNL_PARSE_BUFFER);
541EXPORT_SYMBOL(nftnl_rule_parse_file);
542int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
543 FILE *fp,
struct nftnl_parse_err *err)
545 return nftnl_rule_do_parse(r, type, fp, err, NFTNL_PARSE_FILE);
548static int nftnl_rule_snprintf_default(
char *buf,
size_t remain,
549 const struct nftnl_rule *r,
550 uint32_t type, uint32_t flags)
552 struct nftnl_expr *expr;
553 int ret, offset = 0, i;
554 const char *sep =
"";
556 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
557 ret = snprintf(buf + offset, remain,
"%s%s", sep,
558 nftnl_family2str(r->family));
559 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
563 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
564 ret = snprintf(buf + offset, remain,
"%s%s", sep,
566 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
570 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
571 ret = snprintf(buf + offset, remain,
"%s%s", sep,
573 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
576 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
577 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
579 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
583 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
584 ret = snprintf(buf + offset, remain,
"%s%" PRIu64, sep,
586 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
590 if (r->flags & (1 << NFTNL_RULE_ID)) {
591 ret = snprintf(buf + offset, remain,
"%s%u", sep, r->id);
592 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
596 if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) {
597 ret = snprintf(buf + offset, remain,
"%s%u", sep,
599 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
603 ret = snprintf(buf + offset, remain,
"\n");
604 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
606 list_for_each_entry(expr, &r->expr_list, head) {
607 ret = snprintf(buf + offset, remain,
" [ %s ", expr->ops->name);
608 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
610 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
612 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
614 ret = snprintf(buf + offset, remain,
"]\n");
615 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
619 ret = snprintf(buf + offset, remain,
" userdata = { ");
620 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
622 for (i = 0; i < r->user.len; i++) {
623 char *c = r->user.data;
625 ret = snprintf(buf + offset, remain,
626 isprint(c[i]) ?
"%c" :
"\\x%02hhx",
628 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
631 ret = snprintf(buf + offset, remain,
" }");
632 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
639static int nftnl_rule_cmd_snprintf(
char *buf,
size_t remain,
640 const struct nftnl_rule *r, uint32_t cmd,
641 uint32_t type, uint32_t flags)
643 uint32_t inner_flags = flags;
646 inner_flags &= ~NFTNL_OF_EVENT_ANY;
648 if (type != NFTNL_OUTPUT_DEFAULT)
651 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
653 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
657EXPORT_SYMBOL(nftnl_rule_snprintf);
658int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
659 uint32_t type, uint32_t flags)
664 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
668static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
669 uint32_t cmd, uint32_t type, uint32_t flags)
671 return nftnl_rule_snprintf(buf, size, r, type, flags);
674EXPORT_SYMBOL(nftnl_rule_fprintf);
675int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
678 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
679 nftnl_rule_do_snprintf);
682EXPORT_SYMBOL(nftnl_expr_foreach);
683int nftnl_expr_foreach(
struct nftnl_rule *r,
684 int (*cb)(
struct nftnl_expr *e,
void *data),
687 struct nftnl_expr *cur, *tmp;
690 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
699 const struct nftnl_rule *r;
700 struct nftnl_expr *cur;
703static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
707 if (list_empty(&r->expr_list))
710 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
714EXPORT_SYMBOL(nftnl_expr_iter_create);
715struct nftnl_expr_iter *nftnl_expr_iter_create(
const struct nftnl_rule *r)
723 nftnl_expr_iter_init(r, iter);
728EXPORT_SYMBOL(nftnl_expr_iter_next);
731 struct nftnl_expr *expr = iter->cur;
737 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
738 if (&iter->cur->head == iter->r->expr_list.next)
744EXPORT_SYMBOL(nftnl_expr_iter_destroy);
751 struct list_head list;
754EXPORT_SYMBOL(nftnl_rule_list_alloc);
763 INIT_LIST_HEAD(&list->list);
768EXPORT_SYMBOL(nftnl_rule_list_free);
771 struct nftnl_rule *r, *tmp;
773 list_for_each_entry_safe(r, tmp, &list->list, head) {
780EXPORT_SYMBOL(nftnl_rule_list_is_empty);
783 return list_empty(&list->list);
786EXPORT_SYMBOL(nftnl_rule_list_add);
787void nftnl_rule_list_add(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
789 list_add(&r->head, &list->list);
792EXPORT_SYMBOL(nftnl_rule_list_insert_at);
793void nftnl_rule_list_insert_at(
struct nftnl_rule *r,
struct nftnl_rule *pos)
795 list_add(&r->head, &pos->head);
798EXPORT_SYMBOL(nftnl_rule_list_add_tail);
799void nftnl_rule_list_add_tail(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
801 list_add_tail(&r->head, &list->list);
804EXPORT_SYMBOL(nftnl_rule_list_del);
805void nftnl_rule_list_del(
struct nftnl_rule *r)
810EXPORT_SYMBOL(nftnl_rule_list_foreach);
812 int (*cb)(
struct nftnl_rule *r,
void *data),
815 struct nftnl_rule *cur, *tmp;
818 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
828 struct nftnl_rule *cur;
831EXPORT_SYMBOL(nftnl_rule_list_iter_create);
842 if (nftnl_rule_list_is_empty(l))
845 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
850EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
856EXPORT_SYMBOL(nftnl_rule_list_iter_next);
859 struct nftnl_rule *r = iter->cur;
865 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
866 if (&iter->cur->head == iter->list->list.next)
872EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);