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>
32 EXPORT_SYMBOL(nftnl_rule_alloc);
33 struct nftnl_rule *nftnl_rule_alloc(
void)
37 r = calloc(1,
sizeof(
struct nftnl_rule));
41 INIT_LIST_HEAD(&r->expr_list);
46 EXPORT_SYMBOL(nftnl_rule_free);
47 void 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)))
64 EXPORT_SYMBOL(nftnl_rule_is_set);
65 bool nftnl_rule_is_set(const struct nftnl_rule *r, uint16_t attr)
67 return r->flags & (1 << attr);
70 EXPORT_SYMBOL(nftnl_rule_unset);
71 void 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);
99 static 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),
109 EXPORT_SYMBOL(nftnl_rule_set_data);
110 int 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);
170 int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data) __visible;
171 int 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]);
176 EXPORT_SYMBOL(nftnl_rule_set_u32);
177 void 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));
182 EXPORT_SYMBOL(nftnl_rule_set_u64);
183 void 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));
188 EXPORT_SYMBOL(nftnl_rule_set_str);
189 int 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);
194 EXPORT_SYMBOL(nftnl_rule_get_data);
195 const 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;
236 EXPORT_SYMBOL(nftnl_rule_get);
237 const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
240 return nftnl_rule_get_data(r, attr, &data_len);
243 EXPORT_SYMBOL(nftnl_rule_get_str);
244 const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
246 return nftnl_rule_get(r, attr);
249 EXPORT_SYMBOL(nftnl_rule_get_u32);
250 uint32_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;
260 EXPORT_SYMBOL(nftnl_rule_get_u64);
261 uint64_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;
271 EXPORT_SYMBOL(nftnl_rule_get_u8);
272 uint8_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;
282 EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
283 void 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));
327 EXPORT_SYMBOL(nftnl_rule_add_expr);
328 void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
330 list_add_tail(&expr->head, &r->expr_list);
333 static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
335 const struct nlattr **tb = data;
336 int type = mnl_attr_get_type(attr);
338 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
342 case NFTA_RULE_TABLE:
343 case NFTA_RULE_CHAIN:
344 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
347 case NFTA_RULE_HANDLE:
348 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
351 case NFTA_RULE_COMPAT:
352 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
355 case NFTA_RULE_POSITION:
356 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
359 case NFTA_RULE_USERDATA:
360 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
364 case NFTA_RULE_POSITION_ID:
365 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
374 static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
376 struct nftnl_expr *expr;
379 mnl_attr_for_each_nested(attr, nest) {
380 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
383 expr = nftnl_expr_parse(attr);
387 list_add_tail(&expr->head, &r->expr_list);
392 static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
394 const struct nlattr **tb = data;
395 int type = mnl_attr_get_type(attr);
397 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
401 case NFTA_RULE_COMPAT_PROTO:
402 case NFTA_RULE_COMPAT_FLAGS:
403 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
412 static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
414 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
416 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
419 if (tb[NFTA_RULE_COMPAT_PROTO]) {
421 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
422 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
424 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
426 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
427 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
432 EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
433 int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
435 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
436 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
439 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
442 if (tb[NFTA_RULE_TABLE]) {
443 if (r->flags & (1 << NFTNL_RULE_TABLE))
445 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
448 r->flags |= (1 << NFTNL_RULE_TABLE);
450 if (tb[NFTA_RULE_CHAIN]) {
451 if (r->flags & (1 << NFTNL_RULE_CHAIN))
453 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
456 r->flags |= (1 << NFTNL_RULE_CHAIN);
458 if (tb[NFTA_RULE_HANDLE]) {
459 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
460 r->flags |= (1 << NFTNL_RULE_HANDLE);
462 if (tb[NFTA_RULE_EXPRESSIONS]) {
463 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
467 if (tb[NFTA_RULE_COMPAT]) {
468 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
472 if (tb[NFTA_RULE_POSITION]) {
473 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
474 r->flags |= (1 << NFTNL_RULE_POSITION);
476 if (tb[NFTA_RULE_USERDATA]) {
478 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
480 if (r->flags & (1 << NFTNL_RULE_USERDATA))
483 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
485 r->user.data = malloc(r->user.len);
486 if (r->user.data == NULL)
489 memcpy(r->user.data, udata, r->user.len);
490 r->flags |= (1 << NFTNL_RULE_USERDATA);
492 if (tb[NFTA_RULE_ID]) {
493 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
494 r->flags |= (1 << NFTNL_RULE_ID);
496 if (tb[NFTA_RULE_POSITION_ID]) {
497 r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID]));
498 r->flags |= (1 << NFTNL_RULE_POSITION_ID);
501 r->family = nfg->nfgen_family;
502 r->flags |= (1 << NFTNL_RULE_FAMILY);
507 static int nftnl_rule_do_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
508 const void *data,
struct nftnl_parse_err *err,
509 enum nftnl_parse_input input)
512 struct nftnl_parse_err perr = {};
515 case NFTNL_PARSE_JSON:
516 case NFTNL_PARSE_XML:
528 EXPORT_SYMBOL(nftnl_rule_parse);
529 int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
530 const char *data,
struct nftnl_parse_err *err)
532 return nftnl_rule_do_parse(r, type, data, err, NFTNL_PARSE_BUFFER);
535 EXPORT_SYMBOL(nftnl_rule_parse_file);
536 int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
537 FILE *fp,
struct nftnl_parse_err *err)
539 return nftnl_rule_do_parse(r, type, fp, err, NFTNL_PARSE_FILE);
542 static int nftnl_rule_snprintf_default(
char *buf,
size_t size,
543 const struct nftnl_rule *r,
544 uint32_t type, uint32_t flags)
546 struct nftnl_expr *expr;
547 int ret, remain = size, offset = 0, i;
549 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
550 ret = snprintf(buf + offset, remain,
"%s ",
551 nftnl_family2str(r->family));
552 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
555 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
556 ret = snprintf(buf + offset, remain,
"%s ",
558 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
561 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
562 ret = snprintf(buf + offset, remain,
"%s ",
564 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
566 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
567 ret = snprintf(buf + offset, remain,
"%llu ",
568 (
unsigned long long)r->handle);
569 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
572 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
573 ret = snprintf(buf + offset, remain,
"%llu ",
574 (
unsigned long long)r->position);
575 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
578 if (r->flags & (1 << NFTNL_RULE_ID)) {
579 ret = snprintf(buf + offset, remain,
"%u ", r->id);
580 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
583 if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) {
584 ret = snprintf(buf + offset, remain,
"%u ", r->position_id);
585 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
588 ret = snprintf(buf + offset, remain,
"\n");
589 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
591 list_for_each_entry(expr, &r->expr_list, head) {
592 ret = snprintf(buf + offset, remain,
" [ %s ", expr->ops->name);
593 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
595 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
597 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
599 ret = snprintf(buf + offset, remain,
"]\n");
600 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
604 ret = snprintf(buf + offset, remain,
" userdata = { ");
605 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
607 for (i = 0; i < r->user.len; i++) {
608 char *c = r->user.data;
610 ret = snprintf(buf + offset, remain,
"%c",
611 isalnum(c[i]) ? c[i] : 0);
612 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
615 ret = snprintf(buf + offset, remain,
" }\n");
616 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
623 static int nftnl_rule_cmd_snprintf(
char *buf,
size_t size,
624 const struct nftnl_rule *r, uint32_t cmd,
625 uint32_t type, uint32_t flags)
627 int ret, remain = size, offset = 0;
628 uint32_t inner_flags = flags;
630 inner_flags &= ~NFTNL_OF_EVENT_ANY;
633 case NFTNL_OUTPUT_DEFAULT:
634 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
636 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
638 case NFTNL_OUTPUT_JSON:
639 case NFTNL_OUTPUT_XML:
647 EXPORT_SYMBOL(nftnl_rule_snprintf);
648 int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
649 uint32_t type, uint32_t flags)
654 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
658 static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
659 uint32_t cmd, uint32_t type, uint32_t flags)
661 return nftnl_rule_snprintf(buf, size, r, type, flags);
664 EXPORT_SYMBOL(nftnl_rule_fprintf);
665 int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
668 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
669 nftnl_rule_do_snprintf);
672 EXPORT_SYMBOL(nftnl_expr_foreach);
673 int nftnl_expr_foreach(
struct nftnl_rule *r,
674 int (*cb)(
struct nftnl_expr *e,
void *data),
677 struct nftnl_expr *cur, *tmp;
680 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
689 const struct nftnl_rule *r;
690 struct nftnl_expr *cur;
693 static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
697 if (list_empty(&r->expr_list))
700 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
704 EXPORT_SYMBOL(nftnl_expr_iter_create);
705 struct nftnl_expr_iter *nftnl_expr_iter_create(
const struct nftnl_rule *r)
713 nftnl_expr_iter_init(r, iter);
718 EXPORT_SYMBOL(nftnl_expr_iter_next);
721 struct nftnl_expr *expr = iter->cur;
727 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
728 if (&iter->cur->head == iter->r->expr_list.next)
734 EXPORT_SYMBOL(nftnl_expr_iter_destroy);
741 struct list_head list;
744 EXPORT_SYMBOL(nftnl_rule_list_alloc);
753 INIT_LIST_HEAD(&list->list);
758 EXPORT_SYMBOL(nftnl_rule_list_free);
761 struct nftnl_rule *r, *tmp;
763 list_for_each_entry_safe(r, tmp, &list->list, head) {
770 EXPORT_SYMBOL(nftnl_rule_list_is_empty);
773 return list_empty(&list->list);
776 EXPORT_SYMBOL(nftnl_rule_list_add);
777 void nftnl_rule_list_add(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
779 list_add(&r->head, &list->list);
782 EXPORT_SYMBOL(nftnl_rule_list_insert_at);
783 void nftnl_rule_list_insert_at(
struct nftnl_rule *r,
struct nftnl_rule *pos)
785 list_add(&r->head, &pos->head);
788 EXPORT_SYMBOL(nftnl_rule_list_add_tail);
789 void nftnl_rule_list_add_tail(
struct nftnl_rule *r,
struct nftnl_rule_list *list)
791 list_add_tail(&r->head, &list->list);
794 EXPORT_SYMBOL(nftnl_rule_list_del);
795 void nftnl_rule_list_del(
struct nftnl_rule *r)
800 EXPORT_SYMBOL(nftnl_rule_list_foreach);
802 int (*cb)(
struct nftnl_rule *r,
void *data),
805 struct nftnl_rule *cur, *tmp;
808 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
818 struct nftnl_rule *cur;
821 EXPORT_SYMBOL(nftnl_rule_list_iter_create);
832 if (nftnl_rule_list_is_empty(l))
835 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
840 EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
846 EXPORT_SYMBOL(nftnl_rule_list_iter_next);
849 struct nftnl_rule *r = iter->cur;
855 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
856 if (&iter->cur->head == iter->list->list.next)
862 EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);