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>
34 struct list_head head;
52 struct list_head expr_list;
63 INIT_LIST_HEAD(&r->expr_list);
67 EXPORT_SYMBOL(nftnl_rule_alloc);
69 void nftnl_rule_free(
const struct nftnl_rule *r)
71 struct nftnl_expr *e, *tmp;
73 list_for_each_entry_safe(e, tmp, &r->expr_list, head)
76 if (r->flags & (1 << (NFTNL_RULE_TABLE)))
78 if (r->flags & (1 << (NFTNL_RULE_CHAIN)))
80 if (r->flags & (1 << (NFTNL_RULE_USERDATA)))
85 EXPORT_SYMBOL(nftnl_rule_free);
87 bool nftnl_rule_is_set(const struct
nftnl_rule *r, uint16_t attr)
89 return r->flags & (1 << attr);
91 EXPORT_SYMBOL(nftnl_rule_is_set);
93 void nftnl_rule_unset(
struct nftnl_rule *r, uint16_t attr)
95 if (!(r->flags & (1 << attr)))
99 case NFTNL_RULE_TABLE:
102 case NFTNL_RULE_CHAIN:
105 case NFTNL_RULE_HANDLE:
106 case NFTNL_RULE_COMPAT_PROTO:
107 case NFTNL_RULE_COMPAT_FLAGS:
108 case NFTNL_RULE_POSITION:
109 case NFTNL_RULE_FAMILY:
112 case NFTNL_RULE_USERDATA:
117 r->flags &= ~(1 << attr);
119 EXPORT_SYMBOL(nftnl_rule_unset);
121 static uint32_t nftnl_rule_validate[NFTNL_RULE_MAX + 1] = {
122 [NFTNL_RULE_HANDLE] =
sizeof(uint64_t),
123 [NFTNL_RULE_COMPAT_PROTO] =
sizeof(uint32_t),
124 [NFTNL_RULE_COMPAT_FLAGS] =
sizeof(uint32_t),
125 [NFTNL_RULE_FAMILY] =
sizeof(uint32_t),
126 [NFTNL_RULE_POSITION] =
sizeof(uint64_t),
127 [NFTNL_RULE_ID] =
sizeof(uint32_t),
130 int nftnl_rule_set_data(
struct nftnl_rule *r, uint16_t attr,
131 const void *data, uint32_t data_len)
133 nftnl_assert_attr_exists(attr, NFTNL_RULE_MAX);
134 nftnl_assert_validate(data, nftnl_rule_validate, attr, data_len);
137 case NFTNL_RULE_TABLE:
138 if (r->flags & (1 << NFTNL_RULE_TABLE))
141 r->table = strdup(data);
145 case NFTNL_RULE_CHAIN:
146 if (r->flags & (1 << NFTNL_RULE_CHAIN))
149 r->chain = strdup(data);
153 case NFTNL_RULE_HANDLE:
154 r->handle = *((uint64_t *)data);
156 case NFTNL_RULE_COMPAT_PROTO:
157 r->compat.proto = *((uint32_t *)data);
159 case NFTNL_RULE_COMPAT_FLAGS:
160 r->compat.flags = *((uint32_t *)data);
162 case NFTNL_RULE_FAMILY:
163 r->family = *((uint32_t *)data);
165 case NFTNL_RULE_POSITION:
166 r->position = *((uint64_t *)data);
168 case NFTNL_RULE_USERDATA:
169 if (r->flags & (1 << NFTNL_RULE_USERDATA))
172 r->user.data = malloc(data_len);
176 memcpy(r->user.data, data, data_len);
177 r->user.len = data_len;
180 r->id = *((uint32_t *)data);
183 r->flags |= (1 << attr);
186 EXPORT_SYMBOL(nftnl_rule_set_data);
188 int nftnl_rule_set(
struct nftnl_rule *r, uint16_t attr,
const void *data)
190 return nftnl_rule_set_data(r, attr, data, nftnl_rule_validate[attr]);
192 EXPORT_SYMBOL(nftnl_rule_set);
194 void nftnl_rule_set_u32(
struct nftnl_rule *r, uint16_t attr, uint32_t val)
196 nftnl_rule_set_data(r, attr, &val,
sizeof(uint32_t));
198 EXPORT_SYMBOL(nftnl_rule_set_u32);
200 void nftnl_rule_set_u64(
struct nftnl_rule *r, uint16_t attr, uint64_t val)
202 nftnl_rule_set_data(r, attr, &val,
sizeof(uint64_t));
204 EXPORT_SYMBOL(nftnl_rule_set_u64);
206 int nftnl_rule_set_str(
struct nftnl_rule *r, uint16_t attr,
const char *str)
208 return nftnl_rule_set_data(r, attr, str, strlen(str) + 1);
210 EXPORT_SYMBOL(nftnl_rule_set_str);
212 const void *nftnl_rule_get_data(
const struct nftnl_rule *r, uint16_t attr,
215 if (!(r->flags & (1 << attr)))
219 case NFTNL_RULE_FAMILY:
220 *data_len =
sizeof(uint32_t);
222 case NFTNL_RULE_TABLE:
223 *data_len = strlen(r->table) + 1;
225 case NFTNL_RULE_CHAIN:
226 *data_len = strlen(r->chain) + 1;
228 case NFTNL_RULE_HANDLE:
229 *data_len =
sizeof(uint64_t);
231 case NFTNL_RULE_COMPAT_PROTO:
232 *data_len =
sizeof(uint32_t);
233 return &r->compat.proto;
234 case NFTNL_RULE_COMPAT_FLAGS:
235 *data_len =
sizeof(uint32_t);
236 return &r->compat.flags;
237 case NFTNL_RULE_POSITION:
238 *data_len =
sizeof(uint64_t);
240 case NFTNL_RULE_USERDATA:
241 *data_len = r->user.len;
244 *data_len =
sizeof(uint32_t);
249 EXPORT_SYMBOL(nftnl_rule_get_data);
251 const void *nftnl_rule_get(
const struct nftnl_rule *r, uint16_t attr)
254 return nftnl_rule_get_data(r, attr, &data_len);
256 EXPORT_SYMBOL(nftnl_rule_get);
258 const char *nftnl_rule_get_str(
const struct nftnl_rule *r, uint16_t attr)
260 return nftnl_rule_get(r, attr);
262 EXPORT_SYMBOL(nftnl_rule_get_str);
264 uint32_t nftnl_rule_get_u32(
const struct nftnl_rule *r, uint16_t attr)
267 const uint32_t *val = nftnl_rule_get_data(r, attr, &data_len);
269 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
271 return val ? *val : 0;
273 EXPORT_SYMBOL(nftnl_rule_get_u32);
275 uint64_t nftnl_rule_get_u64(
const struct nftnl_rule *r, uint16_t attr)
278 const uint64_t *val = nftnl_rule_get_data(r, attr, &data_len);
280 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
282 return val ? *val : 0;
284 EXPORT_SYMBOL(nftnl_rule_get_u64);
286 uint8_t nftnl_rule_get_u8(
const struct nftnl_rule *r, uint16_t attr)
289 const uint8_t *val = nftnl_rule_get_data(r, attr, &data_len);
291 nftnl_assert(val, attr, data_len ==
sizeof(uint8_t));
293 return val ? *val : 0;
295 EXPORT_SYMBOL(nftnl_rule_get_u8);
297 void nftnl_rule_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_rule *r)
299 struct nftnl_expr *expr;
300 struct nlattr *nest, *nest2;
302 if (r->flags & (1 << NFTNL_RULE_TABLE))
303 mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
304 if (r->flags & (1 << NFTNL_RULE_CHAIN))
305 mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain);
306 if (r->flags & (1 << NFTNL_RULE_HANDLE))
307 mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
308 if (r->flags & (1 << NFTNL_RULE_POSITION))
309 mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
310 if (r->flags & (1 << NFTNL_RULE_USERDATA)) {
311 mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
315 if (!list_empty(&r->expr_list)) {
316 nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
317 list_for_each_entry(expr, &r->expr_list, head) {
318 nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
319 nftnl_expr_build_payload(nlh, expr);
320 mnl_attr_nest_end(nlh, nest2);
322 mnl_attr_nest_end(nlh, nest);
325 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO) &&
326 r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) {
328 nest = mnl_attr_nest_start(nlh, NFTA_RULE_COMPAT);
329 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_PROTO,
330 htonl(r->compat.proto));
331 mnl_attr_put_u32(nlh, NFTA_RULE_COMPAT_FLAGS,
332 htonl(r->compat.flags));
333 mnl_attr_nest_end(nlh, nest);
335 if (r->flags & (1 << NFTNL_RULE_ID))
336 mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id));
338 EXPORT_SYMBOL(nftnl_rule_nlmsg_build_payload);
340 void nftnl_rule_add_expr(
struct nftnl_rule *r,
struct nftnl_expr *expr)
342 list_add_tail(&expr->head, &r->expr_list);
344 EXPORT_SYMBOL(nftnl_rule_add_expr);
346 static int nftnl_rule_parse_attr_cb(
const struct nlattr *attr,
void *data)
348 const struct nlattr **tb = data;
349 int type = mnl_attr_get_type(attr);
351 if (mnl_attr_type_valid(attr, NFTA_RULE_MAX) < 0)
355 case NFTA_RULE_TABLE:
356 case NFTA_RULE_CHAIN:
357 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
360 case NFTA_RULE_HANDLE:
361 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
364 case NFTA_RULE_COMPAT:
365 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
368 case NFTA_RULE_POSITION:
369 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
372 case NFTA_RULE_USERDATA:
373 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
377 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
386 static int nftnl_rule_parse_expr(
struct nlattr *nest,
struct nftnl_rule *r)
388 struct nftnl_expr *expr;
391 mnl_attr_for_each_nested(attr, nest) {
392 if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
395 expr = nftnl_expr_parse(attr);
399 list_add_tail(&expr->head, &r->expr_list);
404 static int nftnl_rule_parse_compat_cb(
const struct nlattr *attr,
void *data)
406 const struct nlattr **tb = data;
407 int type = mnl_attr_get_type(attr);
409 if (mnl_attr_type_valid(attr, NFTA_RULE_COMPAT_MAX) < 0)
413 case NFTA_RULE_COMPAT_PROTO:
414 case NFTA_RULE_COMPAT_FLAGS:
415 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
424 static int nftnl_rule_parse_compat(
struct nlattr *nest,
struct nftnl_rule *r)
426 struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1] = {};
428 if (mnl_attr_parse_nested(nest, nftnl_rule_parse_compat_cb, tb) < 0)
431 if (tb[NFTA_RULE_COMPAT_PROTO]) {
433 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_PROTO]));
434 r->flags |= (1 << NFTNL_RULE_COMPAT_PROTO);
436 if (tb[NFTA_RULE_COMPAT_FLAGS]) {
438 ntohl(mnl_attr_get_u32(tb[NFTA_RULE_COMPAT_FLAGS]));
439 r->flags |= (1 << NFTNL_RULE_COMPAT_FLAGS);
444 int nftnl_rule_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_rule *r)
446 struct nlattr *tb[NFTA_RULE_MAX+1] = {};
447 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
450 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
453 if (tb[NFTA_RULE_TABLE]) {
454 if (r->flags & (1 << NFTNL_RULE_TABLE))
456 r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
459 r->flags |= (1 << NFTNL_RULE_TABLE);
461 if (tb[NFTA_RULE_CHAIN]) {
462 if (r->flags & (1 << NFTNL_RULE_CHAIN))
464 r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
467 r->flags |= (1 << NFTNL_RULE_CHAIN);
469 if (tb[NFTA_RULE_HANDLE]) {
470 r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
471 r->flags |= (1 << NFTNL_RULE_HANDLE);
473 if (tb[NFTA_RULE_EXPRESSIONS]) {
474 ret = nftnl_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r);
478 if (tb[NFTA_RULE_COMPAT]) {
479 ret = nftnl_rule_parse_compat(tb[NFTA_RULE_COMPAT], r);
483 if (tb[NFTA_RULE_POSITION]) {
484 r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
485 r->flags |= (1 << NFTNL_RULE_POSITION);
487 if (tb[NFTA_RULE_USERDATA]) {
489 mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
491 if (r->flags & (1 << NFTNL_RULE_USERDATA))
494 r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
496 r->user.data = malloc(r->user.len);
497 if (r->user.data == NULL)
500 memcpy(r->user.data, udata, r->user.len);
501 r->flags |= (1 << NFTNL_RULE_USERDATA);
503 if (tb[NFTA_RULE_ID]) {
504 r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID]));
505 r->flags |= (1 << NFTNL_RULE_ID);
508 r->family = nfg->nfgen_family;
509 r->flags |= (1 << NFTNL_RULE_FAMILY);
513 EXPORT_SYMBOL(nftnl_rule_nlmsg_parse);
516 int nftnl_jansson_parse_rule(
struct nftnl_rule *r, json_t *tree,
517 struct nftnl_parse_err *err,
520 json_t *root, *array;
521 struct nftnl_expr *e;
522 const char *str = NULL;
527 root = nftnl_jansson_get_node(tree,
"rule", err);
531 if (nftnl_jansson_node_exist(root,
"family")) {
532 if (nftnl_jansson_parse_family(root, &family, err) != 0)
535 nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
538 if (nftnl_jansson_node_exist(root,
"table")) {
539 str = nftnl_jansson_parse_str(root,
"table", err);
543 nftnl_rule_set_str(r, NFTNL_RULE_TABLE, str);
546 if (nftnl_jansson_node_exist(root,
"chain")) {
547 str = nftnl_jansson_parse_str(root,
"chain", err);
551 nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, str);
554 if (nftnl_jansson_node_exist(root,
"handle")) {
555 if (nftnl_jansson_parse_val(root,
"handle", NFTNL_TYPE_U64, &uval64,
559 nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, uval64);
562 if (nftnl_jansson_node_exist(root,
"compat_proto") ||
563 nftnl_jansson_node_exist(root,
"compat_flags")) {
564 if (nftnl_jansson_parse_val(root,
"compat_proto", NFTNL_TYPE_U32,
568 nftnl_rule_set_u32(r, NFTNL_RULE_COMPAT_PROTO, uval32);
570 if (nftnl_jansson_parse_val(root,
"compat_flags", NFTNL_TYPE_U32,
574 nftnl_rule_set_u32(r, NFTNL_RULE_COMPAT_FLAGS, uval32);
577 if (nftnl_jansson_node_exist(root,
"position")) {
578 if (nftnl_jansson_parse_val(root,
"position", NFTNL_TYPE_U64,
582 nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, uval64);
585 if (nftnl_jansson_node_exist(root,
"id")) {
586 if (nftnl_jansson_parse_val(root,
"id", NFTNL_TYPE_U32,
589 nftnl_rule_set_u32(r, NFTNL_RULE_COMPAT_PROTO, uval32);
592 array = json_object_get(root,
"expr");
594 err->error = NFTNL_PARSE_EMISSINGNODE;
595 err->node_name =
"expr";
599 for (i = 0; i < json_array_size(array); ++i) {
601 e = nftnl_jansson_expr_parse(json_array_get(array, i), err,
606 nftnl_rule_add_expr(r, e);
615 static int nftnl_rule_json_parse(
struct nftnl_rule *r,
const void *json,
616 struct nftnl_parse_err *err,
617 enum nftnl_parse_input input,
625 tree = nftnl_jansson_create_root(json, &error, err, input);
629 ret = nftnl_jansson_parse_rule(r, tree, err, set_list);
631 nftnl_jansson_free_root(tree);
639 static int nftnl_rule_do_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
640 const void *data,
struct nftnl_parse_err *err,
641 enum nftnl_parse_input input)
644 struct nftnl_parse_err perr = {};
647 case NFTNL_PARSE_JSON:
648 ret = nftnl_rule_json_parse(r, data, &perr, input, NULL);
650 case NFTNL_PARSE_XML:
661 int nftnl_rule_parse(
struct nftnl_rule *r,
enum nftnl_parse_type type,
662 const char *data,
struct nftnl_parse_err *err)
664 return nftnl_rule_do_parse(r, type, data, err, NFTNL_PARSE_BUFFER);
666 EXPORT_SYMBOL(nftnl_rule_parse);
668 int nftnl_rule_parse_file(
struct nftnl_rule *r,
enum nftnl_parse_type type,
669 FILE *fp,
struct nftnl_parse_err *err)
671 return nftnl_rule_do_parse(r, type, fp, err, NFTNL_PARSE_FILE);
673 EXPORT_SYMBOL(nftnl_rule_parse_file);
675 static int nftnl_rule_export(
char *buf,
size_t size,
677 uint32_t type, uint32_t flags)
679 struct nftnl_expr *expr;
681 NFTNL_BUF_INIT(b, buf, size);
683 nftnl_buf_open(&b, type, RULE);
685 if (r->flags & (1 << NFTNL_RULE_FAMILY))
686 nftnl_buf_str(&b, type, nftnl_family2str(r->family), FAMILY);
687 if (r->flags & (1 << NFTNL_RULE_TABLE))
688 nftnl_buf_str(&b, type, r->table, TABLE);
689 if (r->flags & (1 << NFTNL_RULE_CHAIN))
690 nftnl_buf_str(&b, type, r->chain, CHAIN);
691 if (r->flags & (1 << NFTNL_RULE_HANDLE))
692 nftnl_buf_u64(&b, type, r->handle, HANDLE);
693 if (r->flags & (1 << NFTNL_RULE_COMPAT_PROTO))
694 nftnl_buf_u32(&b, type, r->compat.proto, COMPAT_PROTO);
695 if (r->flags & (1 << NFTNL_RULE_COMPAT_FLAGS))
696 nftnl_buf_u32(&b, type, r->compat.flags, COMPAT_FLAGS);
697 if (r->flags & (1 << NFTNL_RULE_POSITION))
698 nftnl_buf_u64(&b, type, r->position, POSITION);
699 if (r->flags & (1 << NFTNL_RULE_ID))
700 nftnl_buf_u32(&b, type, r->id, ID);
702 nftnl_buf_expr_open(&b, type);
703 list_for_each_entry(expr, &r->expr_list, head)
704 nftnl_buf_expr(&b, type, flags, expr);
705 nftnl_buf_expr_close(&b, type);
707 nftnl_buf_close(&b, type, RULE);
709 return nftnl_buf_done(&b);
712 static
int nftnl_rule_snprintf_default(
char *buf,
size_t size,
714 uint32_t type, uint32_t flags)
716 struct nftnl_expr *expr;
717 int ret, remain = size, offset = 0, i;
719 if (r->flags & (1 << NFTNL_RULE_FAMILY)) {
720 ret = snprintf(buf + offset, remain,
"%s ",
721 nftnl_family2str(r->family));
722 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
725 if (r->flags & (1 << NFTNL_RULE_TABLE)) {
726 ret = snprintf(buf + offset, remain,
"%s ",
728 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
731 if (r->flags & (1 << NFTNL_RULE_CHAIN)) {
732 ret = snprintf(buf + offset, remain,
"%s ",
734 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
736 if (r->flags & (1 << NFTNL_RULE_HANDLE)) {
737 ret = snprintf(buf + offset, remain,
"%llu ",
738 (
unsigned long long)r->handle);
739 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
742 if (r->flags & (1 << NFTNL_RULE_POSITION)) {
743 ret = snprintf(buf + offset, remain,
"%llu ",
744 (
unsigned long long)r->position);
745 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
748 if (r->flags & (1 << NFTNL_RULE_ID)) {
749 ret = snprintf(buf + offset, remain,
"%u ", r->id);
750 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
753 ret = snprintf(buf + offset, remain,
"\n");
754 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
756 list_for_each_entry(expr, &r->expr_list, head) {
757 ret = snprintf(buf + offset, remain,
" [ %s ", expr->ops->name);
758 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
760 ret = nftnl_expr_snprintf(buf + offset, remain, expr,
762 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
764 ret = snprintf(buf + offset, remain,
"]\n");
765 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
769 ret = snprintf(buf + offset, remain,
" userdata = { ");
770 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
772 for (i = 0; i < r->user.len; i++) {
773 char *c = r->user.data;
775 ret = snprintf(buf + offset, remain,
"%c",
776 isalnum(c[i]) ? c[i] : 0);
777 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
780 ret = snprintf(buf + offset, remain,
" }\n");
781 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
788 static int nftnl_rule_cmd_snprintf(
char *buf,
size_t size,
790 uint32_t type, uint32_t flags)
792 int ret, remain = size, offset = 0;
793 uint32_t inner_flags = flags;
795 inner_flags &= ~NFTNL_OF_EVENT_ANY;
797 ret = nftnl_cmd_header_snprintf(buf + offset, remain, cmd, type, flags);
798 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
801 case NFTNL_OUTPUT_DEFAULT:
802 ret = nftnl_rule_snprintf_default(buf + offset, remain, r, type,
805 case NFTNL_OUTPUT_JSON:
806 ret = nftnl_rule_export(buf + offset, remain, r, type,
809 case NFTNL_OUTPUT_XML:
814 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
816 ret = nftnl_cmd_footer_snprintf(buf + offset, remain, cmd, type, flags);
817 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
822 int nftnl_rule_snprintf(
char *buf,
size_t size,
const struct nftnl_rule *r,
823 uint32_t type, uint32_t flags)
828 return nftnl_rule_cmd_snprintf(buf, size, r, nftnl_flag2cmd(flags), type,
831 EXPORT_SYMBOL(nftnl_rule_snprintf);
833 static int nftnl_rule_do_snprintf(
char *buf,
size_t size,
const void *r,
834 uint32_t cmd, uint32_t type, uint32_t flags)
836 return nftnl_rule_snprintf(buf, size, r, type, flags);
839 int nftnl_rule_fprintf(FILE *fp,
const struct nftnl_rule *r, uint32_t type,
842 return nftnl_fprintf(fp, r, NFTNL_CMD_UNSPEC, type, flags,
843 nftnl_rule_do_snprintf);
845 EXPORT_SYMBOL(nftnl_rule_fprintf);
848 int (*cb)(
struct nftnl_expr *e,
void *data),
851 struct nftnl_expr *cur, *tmp;
854 list_for_each_entry_safe(cur, tmp, &r->expr_list, head) {
861 EXPORT_SYMBOL(nftnl_expr_foreach);
865 struct nftnl_expr *cur;
868 static void nftnl_expr_iter_init(
const struct nftnl_rule *r,
872 if (list_empty(&r->expr_list))
875 iter->cur = list_entry(r->expr_list.next,
struct nftnl_expr,
887 nftnl_expr_iter_init(r, iter);
891 EXPORT_SYMBOL(nftnl_expr_iter_create);
895 struct nftnl_expr *expr = iter->cur;
901 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_expr, head);
902 if (&iter->cur->head == iter->r->expr_list.next)
907 EXPORT_SYMBOL(nftnl_expr_iter_next);
913 EXPORT_SYMBOL(nftnl_expr_iter_destroy);
918 struct nftnl_expr *e1, *e2;
921 if (r1->flags & r1->flags & (1 << NFTNL_RULE_TABLE))
922 eq &= !strcmp(r1->table, r2->table);
923 if (r1->flags & r1->flags & (1 << NFTNL_RULE_CHAIN))
924 eq &= !strcmp(r1->chain, r2->chain);
925 if (r1->flags & r1->flags & (1 << NFTNL_RULE_COMPAT_FLAGS))
926 eq &= (r1->compat.flags == r2->compat.flags);
927 if (r1->flags & r1->flags & (1 << NFTNL_RULE_COMPAT_PROTO))
928 eq &= (r1->compat.proto == r2->compat.proto);
930 nftnl_expr_iter_init(r1, &it1);
931 nftnl_expr_iter_init(r2, &it2);
932 e1 = nftnl_expr_iter_next(&it1);
933 e2 = nftnl_expr_iter_next(&it2);
934 while (eq && e1 && e2) {
937 e1 = nftnl_expr_iter_next(&it1);
938 e2 = nftnl_expr_iter_next(&it2);
944 EXPORT_SYMBOL(nftnl_rule_cmp);
947 struct list_head list;
958 INIT_LIST_HEAD(&list->list);
962 EXPORT_SYMBOL(nftnl_rule_list_alloc);
968 list_for_each_entry_safe(r, tmp, &list->list, head) {
974 EXPORT_SYMBOL(nftnl_rule_list_free);
978 return list_empty(&list->list);
980 EXPORT_SYMBOL(nftnl_rule_list_is_empty);
984 list_add(&r->head, &list->list);
986 EXPORT_SYMBOL(nftnl_rule_list_add);
990 list_add_tail(&r->head, &list->list);
992 EXPORT_SYMBOL(nftnl_rule_list_add_tail);
994 void nftnl_rule_list_del(
struct nftnl_rule *r)
998 EXPORT_SYMBOL(nftnl_rule_list_del);
1007 list_for_each_entry_safe(cur, tmp, &rule_list->list, head) {
1008 ret = cb(cur, data);
1014 EXPORT_SYMBOL(nftnl_rule_list_foreach);
1031 if (nftnl_rule_list_is_empty(l))
1034 iter->cur = list_entry(l->list.next,
struct nftnl_rule, head);
1038 EXPORT_SYMBOL(nftnl_rule_list_iter_create);
1044 EXPORT_SYMBOL(nftnl_rule_list_iter_cur);
1054 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
1055 if (&iter->cur->head == iter->list->list.next)
1060 EXPORT_SYMBOL(nftnl_rule_list_iter_next);
1066 EXPORT_SYMBOL(nftnl_rule_list_iter_destroy);