19 #include <netinet/in.h>
25 #include <libmnl/libmnl.h>
26 #include <linux/netfilter/nfnetlink.h>
27 #include <linux/netfilter/nf_tables.h>
29 #include <libnftnl/rule.h>
30 #include <libnftnl/set.h>
31 #include <libnftnl/expr.h>
33 EXPORT_SYMBOL(nftnl_rule_alloc);
34 struct nftnl_rule *nftnl_rule_alloc(
void)
38 r = calloc(1,
sizeof(
struct nftnl_rule));
42 INIT_LIST_HEAD(&r->expr_list);
47 EXPORT_SYMBOL(nftnl_rule_free);
48 void nftnl_rule_free(
const struct nftnl_rule *r)
50 struct nftnl_expr *e, *tmp;
52 list_for_each_entry_safe(e, tmp, &r->expr_list, head)
55 if (r->flags & (1 << (NFTNL_RULE_TABLE)))
57 if (r->flags & (1 << (NFTNL_RULE_CHAIN)))
59 if (r->flags & (1 << (NFTNL_RULE_USERDATA)))
65 EXPORT_SYMBOL(nftnl_rule_is_set);
66 bool nftnl_rule_is_set(const struct nftnl_rule *r, uint16_t attr)
68 return r->flags & (1 << attr);
71 EXPORT_SYMBOL(nftnl_rule_unset);
72 void nftnl_rule_unset(
struct nftnl_rule *r, uint16_t attr)
74 if (!(r->flags & (1 << attr)))
78 case NFTNL_RULE_TABLE:
81 case NFTNL_RULE_CHAIN:
84 case NFTNL_RULE_HANDLE:
85 case NFTNL_RULE_COMPAT_PROTO:
86 case NFTNL_RULE_COMPAT_FLAGS:
87 case NFTNL_RULE_POSITION:
88 case NFTNL_RULE_FAMILY:
90 case NFTNL_RULE_POSITION_ID:
92 case NFTNL_RULE_USERDATA:
97 r->flags &= ~(1 << attr);
100 static uint32_t nftnl_rule_validate[NFTNL_RULE_MAX + 1] = {
101 [NFTNL_RULE_HANDLE] =
sizeof(uint64_t),
102 [NFTNL_RULE_COMPAT_PROTO] =
sizeof(uint32_t),
103 [NFTNL_RULE_COMPAT_FLAGS] =
sizeof(uint32_t),
104 [NFTNL_RULE_FAMILY] =
sizeof(uint32_t),
105 [NFTNL_RULE_POSITION] =
sizeof(uint64_t),
106 [NFTNL_RULE_ID] =
sizeof(uint32_t),
107 [NFTNL_RULE_POSITION_ID] =
sizeof(uint32_t),
110 EXPORT_SYMBOL(nftnl_rule_set_data);
111 int nftnl_rule_set_data(
struct nftnl_rule *r, uint16_t attr,
112 const void *data, uint32_t data_len)
114 nftnl_assert_attr_exists(attr, NFTNL_RULE_MAX);
115 nftnl_assert_validate(data, nftnl_rule_validate, attr, data_len);
118 case NFTNL_RULE_TABLE:
119 if (r->flags & (1 << NFTNL_RULE_TABLE))
122 r->table = strdup(data);
126 case NFTNL_RULE_CHAIN:
127 if (r->flags & (1 << NFTNL_RULE_CHAIN))
130 r->chain = strdup(data);
134 case NFTNL_RULE_HANDLE:
135 memcpy(&r->handle, data,
sizeof(r->handle));
137 case NFTNL_RULE_COMPAT_PROTO:
138 memcpy(&r->compat.proto, data,
sizeof(r->compat.proto));
140 case NFTNL_RULE_COMPAT_FLAGS:
141 memcpy(&r->compat.flags, data,
sizeof(r->compat.flags));
143 case NFTNL_RULE_FAMILY:
144 memcpy(&r->family, data,
sizeof(r->family));
146 case NFTNL_RULE_POSITION:
147 memcpy(&r->position, data,
sizeof(r->position));
149 case NFTNL_RULE_USERDATA:
150 if (r->flags & (1 << NFTNL_RULE_USERDATA))
153 r->user.data = malloc(data_len);
157 memcpy(r->user.data, data, data_len);
158 r->user.len = data_len;
161 memcpy(&r->id, data,
sizeof(r->id));
163 case NFTNL_RULE_POSITION_ID:
164 memcpy(&r->position_id, data,
sizeof(r->position_id));
167 r->flags |= (1 << attr);
171 EXPORT_SYMBOL(nftnl_rule_set);
172 int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data)
174 return nftnl_rule_set_data(r, attr, data, nftnl_rule_validate[attr]);
177 EXPORT_SYMBOL(nftnl_rule_set_u32);
178 void nftnl_rule_set_u32(
struct nftnl_rule *r, uint16_t attr, uint32_t val)
180 nftnl_rule_set_data(r, attr, &val,
sizeof(uint32_t));
183 EXPORT_SYMBOL(nftnl_rule_set_u64);
184 void nftnl_rule_set_u64(
struct nftnl_rule *r, uint16_t attr, uint64_t val)
186 nftnl_rule_set_data(r, attr, &val,
sizeof(uint64_t));
189 EXPORT_SYMBOL(nftnl_rule_set_str);
190 int nftnl_rule_set_str(
struct nftnl_rule *r, uint16_t attr,
const char *str)
192 return nftnl_rule_set_data(r, attr, str, strlen(str) + 1);
195 EXPORT_SYMBOL(nftnl_rule_get_data);
196 const void *nftnl_rule_get_data(
const struct nftnl_rule *r, uint16_t attr,
199 if (!(r->flags & (1 << attr)))
203 case NFTNL_RULE_FAMILY:
204 *data_len =
sizeof(uint32_t);
206 case NFTNL_RULE_TABLE:
207 *data_len = strlen(r->table) + 1;
209 case NFTNL_RULE_CHAIN:
210 *data_len = strlen(r->chain) + 1;
212 case NFTNL_RULE_HANDLE:
213 *data_len =
sizeof(uint64_t);
215 case NFTNL_RULE_COMPAT_PROTO:
216 *data_len =
sizeof(uint32_t);
217 return &r->compat.proto;
218 case NFTNL_RULE_COMPAT_FLAGS:
219 *data_len =
sizeof(uint32_t);
220 return &r->compat.flags;
221 case NFTNL_RULE_POSITION:
222 *data_len =
sizeof(uint64_t);
224 case NFTNL_RULE_USERDATA:
225 *data_len = r->user.len;
228 *data_len =
sizeof(uint32_t);
230 case NFTNL_RULE_POSITION_ID:
231 *data_len =
sizeof(uint32_t);
232 return &r->position_id;
237 EXPORT_SYMBOL(nftnl_rule_get);
238 const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
241 return nftnl_rule_get_data(r, attr, &data_len);
244 EXPORT_SYMBOL(nftnl_rule_get_str);
245 const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
247 return nftnl_rule_get(r, attr);
250 EXPORT_SYMBOL(nftnl_rule_get_u32);
251 uint32_t nftnl_rule_get_u32(
const struct nftnl_rule *r, uint16_t attr)
254 const uint32_t *val = nftnl_rule_get_data(r, attr, &data_len);
256 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
258 return val ? *val : 0;
261 EXPORT_SYMBOL(nftnl_rule_get_u64);
262 uint64_t nftnl_rule_get_u64(
const struct nftnl_rule *r, uint16_t attr)
265 const uint64_t *val = nftnl_rule_get_data(r, attr, &data_len);
267 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
269 return val ? *val : 0;
272 EXPORT_SYMBOL(nftnl_rule_get_u8);
273 uint8_t nftnl_rule_get_u8(
const struct nftnl_rule *r, uint16_t attr)
276 const uint8_t *val = nftnl_rule_get_data(r, attr, &data_len);
278 nftnl_assert(val, attr, data_len ==
sizeof(uint8_t));
280 return val ? *val : 0;
283 EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
284 void nftnl_rule_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_rule *r)
286 struct nftnl_expr *expr;
287 struct nlattr *nest, *nest2;
289 if (r->flags & (1 << NFTNL_RULE_TABLE))
290 mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
291 if (r->flags & (1 << NFTNL_RULE_CHAIN))
292 mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain);
293 if (r->flags & (1 << NFTNL_RULE_HANDLE))
294 mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
295 if (r->flags & (1 << NFTNL_RULE_POSITION))
296 mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
297 if (r->flags & (1 << NFTNL_RULE_USERDATA)) {
298 mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
302 if (!list_empty(&r->expr_list)) {
303 nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
304 list_for_each_entry(expr, &r->expr_list, head) {
305 nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
306 nftnl_expr_build_payload(nlh, expr);
307 mnl_attr_nest_end(nlh, nest2);
309 mnl_attr_nest_end(nlh, nest);
312 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO) &&
313 r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) {
315 nest = mnl_attr_nest_start(nlh, NFTA_RULE_COMPAT);
316 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_PROTO,
317 htonl(r->compat.proto));
318 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_FLAGS,
319 htonl(r->compat.flags));
320 mnl_attr_nest_end(nlh, nest);
322 if (r->flags & (1 << NFTNL_RULE_ID))
323 mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id));
324 if (r->flags & (1 << NFTNL_RULE_POSITION_ID))
325 mnl_attr_put_u32(nlh, NFTA_RULE_POSITION_ID, htonl(r->position_id));
328 EXPORT_SYMBOL(nftnl_rule_add_expr);
329 void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
331 list_add_tail(&expr->head, &r->expr_list);
334 static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
336 const struct nlattr **tb = data;
337 int type = mnl_attr_get_type(attr);
339 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
343 case NFTA_RULE_TABLE:
344 case NFTA_RULE_CHAIN:
345 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
348 case NFTA_RULE_HANDLE:
349 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
352 case NFTA_RULE_COMPAT:
353 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
356 case NFTA_RULE_POSITION:
357 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
360 case NFTA_RULE_USERDATA:
361 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
365 case NFTA_RULE_POSITION_ID:
366 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
375 static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
377 struct nftnl_expr *expr;
380 mnl_attr_for_each_nested(attr, nest) {
381 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
384 expr = nftnl_expr_parse(attr);
388 list_add_tail(&expr->head, &r->expr_list);
393 static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
395 const struct nlattr **tb = data;
396 int type = mnl_attr_get_type(attr);
398 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
402 case NFTA_RULE_COMPAT_PROTO:
403 case NFTA_RULE_COMPAT_FLAGS:
404 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
413 static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
415 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
417 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
420 if (tb[NFTA_RULE_COMPAT_PROTO]) {
422 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
423 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
425 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
427 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
428 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
433 EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
434 int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
436 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
437 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
440 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
443 if (tb[NFTA_RULE_TABLE]) {
444 if (r->flags & (1 << NFTNL_RULE_TABLE))
446 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
449 r->flags |= (1 << NFTNL_RULE_TABLE);
451 if (tb[NFTA_RULE_CHAIN]) {
452 if (r->flags & (1 << NFTNL_RULE_CHAIN))
454 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
457 r->flags |= (1 << NFTNL_RULE_CHAIN);
459 if (tb[NFTA_RULE_HANDLE]) {
460 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
461 r->flags |= (1 << NFTNL_RULE_HANDLE);
463 if (tb[NFTA_RULE_EXPRESSIONS]) {
464 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
468 if (tb[NFTA_RULE_COMPAT]) {
469 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
473 if (tb[NFTA_RULE_POSITION]) {
474 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
475 r->flags |= (1 << NFTNL_RULE_POSITION);
477 if (tb[NFTA_RULE_USERDATA]) {
479 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
481 if (r->flags & (1 << NFTNL_RULE_USERDATA))
484 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
486 r->user.data = malloc(r->user.len);
487 if (r->user.data == NULL)
490 memcpy(r->user.data, udata, r->user.len);
491 r->flags |= (1 << NFTNL_RULE_USERDATA);
493 if (tb[NFTA_RULE_ID]) {
494 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
495 r->flags |= (1 << NFTNL_RULE_ID);
497 if (tb[NFTA_RULE_POSITION_ID]) {
498 r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID]));
499 r->flags |= (1 << NFTNL_RULE_POSITION_ID);
502 r->family = nfg->nfgen_family;
503 r->flags |= (1 << NFTNL_RULE_FAMILY);
508 static int nftnl_rule_do_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
509 const void *data,
struct nftnl_parse_err *err,
510 enum nftnl_parse_input input)
513 struct nftnl_parse_err perr = {};
516 case NFTNL_PARSE_JSON:
517 case NFTNL_PARSE_XML:
529 EXPORT_SYMBOL(nftnl_rule_parse);
530 int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
531 const char *data,
struct nftnl_parse_err *err)
533 return nftnl_rule_do_parse(r, type, data, err, NFTNL_PARSE_BUFFER);
536 EXPORT_SYMBOL(nftnl_rule_parse_file);
537 int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
538 FILE *fp,
struct nftnl_parse_err *err)
540 return nftnl_rule_do_parse(r, type, fp, err, NFTNL_PARSE_FILE);
543 static int nftnl_rule_snprintf_default(
char *buf,
size_t size,
544 const struct nftnl_rule *r,
545 uint32_t type, uint32_t flags)
547 struct nftnl_expr *expr;
548 int ret, remain = size, offset = 0, i;
550 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
551 ret = snprintf(buf + offset, remain,
"%s ",
552 nftnl_family2str(r->family));
553 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
556 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
557 ret = snprintf(buf + offset, remain,
"%s ",
559 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
562 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
563 ret = snprintf(buf + offset, remain,
"%s ",
565 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
567 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
568 ret = snprintf(buf + offset, remain,
"%llu ",
569 (
unsigned long long)r->handle);
570 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
573 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
574 ret = snprintf(buf + offset, remain,
"%llu ",
575 (
unsigned long long)r->position);
576 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
579 if (r->flags & (1 << NFTNL_RULE_ID)) {
580 ret = snprintf(buf + offset, remain,
"%u ", r->id);
581 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
584 if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) {
585 ret = snprintf(buf + offset, remain,
"%u ", r->position_id);
586 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
589 ret = snprintf(buf + offset, remain,
"\n");
590 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
592 list_for_each_entry(expr, &r->expr_list, head) {
593 ret = snprintf(buf + offset, remain,
" [ %s ", expr->ops->name);
594 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
596 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
598 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
600 ret = snprintf(buf + offset, remain,
"]\n");
601 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
605 ret = snprintf(buf + offset, remain,
" userdata = { ");
606 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
608 for (i = 0; i < r->user.len; i++) {
609 char *c = r->user.data;
611 ret = snprintf(buf + offset, remain,
"%c",
612 isalnum(c[i]) ? c[i] : 0);
613 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
616 ret = snprintf(buf + offset, remain,
" }\n");
617 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
624 static int nftnl_rule_cmd_snprintf(
char *buf,
size_t size,
625 const struct nftnl_rule *r, uint32_t cmd,
626 uint32_t type, uint32_t flags)
628 int ret, remain = size, offset = 0;
629 uint32_t inner_flags = flags;
631 inner_flags &= ~NFTNL_OF_EVENT_ANY;
634 case NFTNL_OUTPUT_DEFAULT:
635 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
637 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
639 case NFTNL_OUTPUT_JSON:
640 case NFTNL_OUTPUT_XML:
648 EXPORT_SYMBOL(nftnl_rule_snprintf);
649 int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
650 uint32_t type, uint32_t flags)
655 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
659 static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
660 uint32_t cmd, uint32_t type, uint32_t flags)
662 return nftnl_rule_snprintf(buf, size, r, type, flags);
665 EXPORT_SYMBOL(nftnl_rule_fprintf);
666 int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
669 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
670 nftnl_rule_do_snprintf);
673 EXPORT_SYMBOL(nftnl_expr_foreach);
674 int nftnl_expr_foreach(
struct nftnl_rule *r,
675 int (*cb)(
struct nftnl_expr *e,
void *data),
678 struct nftnl_expr *cur, *tmp;
681 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
690 const struct nftnl_rule *r;
691 struct nftnl_expr *cur;
694 static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
698 if (list_empty(&r->expr_list))
701 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
705 EXPORT_SYMBOL(nftnl_expr_iter_create);
706 struct nftnl_expr_iter *nftnl_expr_iter_create(
const struct nftnl_rule *r)
714 nftnl_expr_iter_init(r, iter);
719 EXPORT_SYMBOL(nftnl_expr_iter_next);
722 struct nftnl_expr *expr = iter->cur;
728 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
729 if (&iter->cur->head == iter->r->expr_list.next)
735 EXPORT_SYMBOL(nftnl_expr_iter_destroy);
742 struct list_head list;
745 EXPORT_SYMBOL(nftnl_rule_list_alloc);
754 INIT_LIST_HEAD(&list->list);
759 EXPORT_SYMBOL(nftnl_rule_list_free);
762 struct nftnl_rule *r, *tmp;
764 list_for_each_entry_safe(r, tmp, &list->list, head) {
771 EXPORT_SYMBOL(nftnl_rule_list_is_empty);
774 return list_empty(&list->list);
777 EXPORT_SYMBOL(nftnl_rule_list_add);
778 void nftnl_rule_list_add(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
780 list_add(&r->head, &list->list);
783 EXPORT_SYMBOL(nftnl_rule_list_insert_at);
784 void nftnl_rule_list_insert_at(
struct nftnl_rule *r,
struct nftnl_rule *pos)
786 list_add(&r->head, &pos->head);
789 EXPORT_SYMBOL(nftnl_rule_list_add_tail);
790 void nftnl_rule_list_add_tail(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
792 list_add_tail(&r->head, &list->list);
795 EXPORT_SYMBOL(nftnl_rule_list_del);
796 void nftnl_rule_list_del(
struct nftnl_rule *r)
801 EXPORT_SYMBOL(nftnl_rule_list_foreach);
803 int (*cb)(
struct nftnl_rule *r,
void *data),
806 struct nftnl_rule *cur, *tmp;
809 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
819 struct nftnl_rule *cur;
822 EXPORT_SYMBOL(nftnl_rule_list_iter_create);
833 if (nftnl_rule_list_is_empty(l))
836 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
841 EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
847 EXPORT_SYMBOL(nftnl_rule_list_iter_next);
850 struct nftnl_rule *r = iter->cur;
856 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
857 if (&iter->cur->head == iter->list->list.next)
863 EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);