19 #include <netinet/in.h>
23 #include <libmnl/libmnl.h>
24 #include <linux/netfilter/nfnetlink.h>
25 #include <linux/netfilter/nf_tables.h>
26 #include <linux/netfilter.h>
27 #include <linux/netfilter_arp.h>
29 #include <libnftnl/chain.h>
33 struct list_head head;
50 static const char *nftnl_hooknum2str(
int family,
int hooknum)
58 case NF_INET_PRE_ROUTING:
60 case NF_INET_LOCAL_IN:
64 case NF_INET_LOCAL_OUT:
66 case NF_INET_POST_ROUTING:
82 case NF_NETDEV_INGRESS:
94 EXPORT_SYMBOL(nftnl_chain_alloc);
98 if (c->flags & (1 << NFTNL_CHAIN_NAME))
100 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
102 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
104 if (c->flags & (1 << NFTNL_CHAIN_DEV))
108 EXPORT_SYMBOL(nftnl_chain_free);
110 bool nftnl_chain_is_set(
const struct nftnl_chain *c, uint16_t attr)
112 return c->flags & (1 << attr);
114 EXPORT_SYMBOL(nftnl_chain_is_set);
116 void nftnl_chain_unset(
struct nftnl_chain *c, uint16_t attr)
118 if (!(c->flags & (1 << attr)))
122 case NFTNL_CHAIN_NAME:
125 case NFTNL_CHAIN_TABLE:
128 case NFTNL_CHAIN_USE:
130 case NFTNL_CHAIN_TYPE:
133 case NFTNL_CHAIN_HOOKNUM:
134 case NFTNL_CHAIN_PRIO:
135 case NFTNL_CHAIN_POLICY:
136 case NFTNL_CHAIN_BYTES:
137 case NFTNL_CHAIN_PACKETS:
138 case NFTNL_CHAIN_HANDLE:
139 case NFTNL_CHAIN_FAMILY:
141 case NFTNL_CHAIN_DEV:
148 c->flags &= ~(1 << attr);
150 EXPORT_SYMBOL(nftnl_chain_unset);
152 static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = {
153 [NFTNL_CHAIN_HOOKNUM] =
sizeof(uint32_t),
154 [NFTNL_CHAIN_PRIO] =
sizeof(int32_t),
155 [NFTNL_CHAIN_POLICY] =
sizeof(uint32_t),
156 [NFTNL_CHAIN_BYTES] =
sizeof(uint64_t),
157 [NFTNL_CHAIN_PACKETS] =
sizeof(uint64_t),
158 [NFTNL_CHAIN_HANDLE] =
sizeof(uint64_t),
159 [NFTNL_CHAIN_FAMILY] =
sizeof(uint32_t),
162 int nftnl_chain_set_data(
struct nftnl_chain *c, uint16_t attr,
163 const void *data, uint32_t data_len)
165 nftnl_assert_attr_exists(attr, NFTNL_CHAIN_MAX);
166 nftnl_assert_validate(data, nftnl_chain_validate, attr, data_len);
169 case NFTNL_CHAIN_NAME:
170 if (c->flags & (1 << NFTNL_CHAIN_NAME))
173 c->name = strdup(data);
177 case NFTNL_CHAIN_TABLE:
178 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
181 c->table = strdup(data);
185 case NFTNL_CHAIN_HOOKNUM:
186 memcpy(&c->hooknum, data,
sizeof(c->hooknum));
188 case NFTNL_CHAIN_PRIO:
189 memcpy(&c->prio, data,
sizeof(c->prio));
191 case NFTNL_CHAIN_POLICY:
192 c->policy = *((uint32_t *)data);
194 case NFTNL_CHAIN_USE:
195 c->use = *((uint32_t *)data);
197 case NFTNL_CHAIN_BYTES:
198 c->bytes = *((uint64_t *)data);
200 case NFTNL_CHAIN_PACKETS:
201 c->packets = *((uint64_t *)data);
203 case NFTNL_CHAIN_HANDLE:
204 c->handle = *((uint64_t *)data);
206 case NFTNL_CHAIN_FAMILY:
207 c->family = *((uint32_t *)data);
209 case NFTNL_CHAIN_TYPE:
210 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
213 c->type = strdup(data);
217 case NFTNL_CHAIN_DEV:
218 if (c->flags & (1 << NFTNL_CHAIN_DEV))
221 c->dev = strdup(data);
226 c->flags |= (1 << attr);
229 EXPORT_SYMBOL(nftnl_chain_set_data);
231 void nftnl_chain_set(
struct nftnl_chain *c, uint16_t attr,
const void *data)
233 nftnl_chain_set_data(c, attr, data, nftnl_chain_validate[attr]);
235 EXPORT_SYMBOL(nftnl_chain_set);
237 void nftnl_chain_set_u32(
struct nftnl_chain *c, uint16_t attr, uint32_t data)
239 nftnl_chain_set_data(c, attr, &data,
sizeof(uint32_t));
241 EXPORT_SYMBOL(nftnl_chain_set_u32);
243 void nftnl_chain_set_s32(
struct nftnl_chain *c, uint16_t attr, int32_t data)
245 nftnl_chain_set_data(c, attr, &data,
sizeof(int32_t));
247 EXPORT_SYMBOL(nftnl_chain_set_s32);
249 void nftnl_chain_set_u64(
struct nftnl_chain *c, uint16_t attr, uint64_t data)
251 nftnl_chain_set_data(c, attr, &data,
sizeof(uint64_t));
253 EXPORT_SYMBOL(nftnl_chain_set_u64);
255 void nftnl_chain_set_u8(
struct nftnl_chain *c, uint16_t attr, uint8_t data)
257 nftnl_chain_set_data(c, attr, &data,
sizeof(uint8_t));
259 EXPORT_SYMBOL(nftnl_chain_set_u8);
261 int nftnl_chain_set_str(
struct nftnl_chain *c, uint16_t attr,
const char *str)
263 return nftnl_chain_set_data(c, attr, str, strlen(str) + 1);
265 EXPORT_SYMBOL(nftnl_chain_set_str);
267 const void *nftnl_chain_get_data(
const struct nftnl_chain *c, uint16_t attr,
270 if (!(c->flags & (1 << attr)))
274 case NFTNL_CHAIN_NAME:
275 *data_len = strlen(c->name) + 1;
277 case NFTNL_CHAIN_TABLE:
278 *data_len = strlen(c->table) + 1;
280 case NFTNL_CHAIN_HOOKNUM:
281 *data_len =
sizeof(uint32_t);
283 case NFTNL_CHAIN_PRIO:
284 *data_len =
sizeof(int32_t);
286 case NFTNL_CHAIN_POLICY:
287 *data_len =
sizeof(uint32_t);
289 case NFTNL_CHAIN_USE:
290 *data_len =
sizeof(uint32_t);
292 case NFTNL_CHAIN_BYTES:
293 *data_len =
sizeof(uint64_t);
295 case NFTNL_CHAIN_PACKETS:
296 *data_len =
sizeof(uint64_t);
298 case NFTNL_CHAIN_HANDLE:
299 *data_len =
sizeof(uint64_t);
301 case NFTNL_CHAIN_FAMILY:
302 *data_len =
sizeof(uint32_t);
304 case NFTNL_CHAIN_TYPE:
305 *data_len =
sizeof(uint32_t);
307 case NFTNL_CHAIN_DEV:
308 *data_len = strlen(c->dev) + 1;
313 EXPORT_SYMBOL(nftnl_chain_get_data);
315 const void *nftnl_chain_get(
const struct nftnl_chain *c, uint16_t attr)
318 return nftnl_chain_get_data(c, attr, &data_len);
320 EXPORT_SYMBOL(nftnl_chain_get);
322 const char *nftnl_chain_get_str(
const struct nftnl_chain *c, uint16_t attr)
324 return nftnl_chain_get(c, attr);
326 EXPORT_SYMBOL(nftnl_chain_get_str);
328 uint32_t nftnl_chain_get_u32(
const struct nftnl_chain *c, uint16_t attr)
331 const uint32_t *val = nftnl_chain_get_data(c, attr, &data_len);
333 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
335 return val ? *val : 0;
337 EXPORT_SYMBOL(nftnl_chain_get_u32);
339 int32_t nftnl_chain_get_s32(
const struct nftnl_chain *c, uint16_t attr)
342 const int32_t *val = nftnl_chain_get_data(c, attr, &data_len);
344 nftnl_assert(val, attr, data_len ==
sizeof(int32_t));
346 return val ? *val : 0;
348 EXPORT_SYMBOL(nftnl_chain_get_s32);
350 uint64_t nftnl_chain_get_u64(
const struct nftnl_chain *c, uint16_t attr)
353 const uint64_t *val = nftnl_chain_get_data(c, attr, &data_len);
355 nftnl_assert(val, attr, data_len ==
sizeof(int64_t));
357 return val ? *val : 0;
359 EXPORT_SYMBOL(nftnl_chain_get_u64);
361 uint8_t nftnl_chain_get_u8(
const struct nftnl_chain *c, uint16_t attr)
364 const uint8_t *val = nftnl_chain_get_data(c, attr, &data_len);
366 nftnl_assert(val, attr, data_len ==
sizeof(int8_t));
368 return val ? *val : 0;
370 EXPORT_SYMBOL(nftnl_chain_get_u8);
372 void nftnl_chain_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nftnl_chain *c)
374 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
375 mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, c->table);
376 if (c->flags & (1 << NFTNL_CHAIN_NAME))
377 mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, c->name);
378 if ((c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) &&
379 (c->flags & (1 << NFTNL_CHAIN_PRIO))) {
382 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
383 mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(c->hooknum));
384 mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
385 if (c->flags & (1 << NFTNL_CHAIN_DEV))
386 mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev);
387 mnl_attr_nest_end(nlh, nest);
389 if (c->flags & (1 << NFTNL_CHAIN_POLICY))
390 mnl_attr_put_u32(nlh, NFTA_CHAIN_POLICY, htonl(c->policy));
391 if (c->flags & (1 << NFTNL_CHAIN_USE))
392 mnl_attr_put_u32(nlh, NFTA_CHAIN_USE, htonl(c->use));
393 if ((c->flags & (1 << NFTNL_CHAIN_PACKETS)) &&
394 (c->flags & (1 << NFTNL_CHAIN_BYTES))) {
397 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_COUNTERS);
398 mnl_attr_put_u64(nlh, NFTA_COUNTER_PACKETS, be64toh(c->packets));
399 mnl_attr_put_u64(nlh, NFTA_COUNTER_BYTES, be64toh(c->bytes));
400 mnl_attr_nest_end(nlh, nest);
402 if (c->flags & (1 << NFTNL_CHAIN_HANDLE))
403 mnl_attr_put_u64(nlh, NFTA_CHAIN_HANDLE, be64toh(c->handle));
404 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
405 mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type);
407 EXPORT_SYMBOL(nftnl_chain_nlmsg_build_payload);
409 static int nftnl_chain_parse_attr_cb(
const struct nlattr *attr,
void *data)
411 const struct nlattr **tb = data;
412 int type = mnl_attr_get_type(attr);
414 if (mnl_attr_type_valid(attr, NFTA_CHAIN_MAX) < 0)
418 case NFTA_CHAIN_NAME:
419 case NFTA_CHAIN_TABLE:
420 case NFTA_CHAIN_TYPE:
421 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
424 case NFTA_CHAIN_HOOK:
425 case NFTA_CHAIN_COUNTERS:
426 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
429 case NFTA_CHAIN_POLICY:
431 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
434 case NFTA_CHAIN_HANDLE:
435 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
444 static int nftnl_chain_parse_counters_cb(
const struct nlattr *attr,
void *data)
446 const struct nlattr **tb = data;
447 int type = mnl_attr_get_type(attr);
449 if (mnl_attr_type_valid(attr, NFTA_COUNTER_MAX) < 0)
453 case NFTA_COUNTER_BYTES:
454 case NFTA_COUNTER_PACKETS:
455 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
464 static int nftnl_chain_parse_counters(
struct nlattr *attr,
struct nftnl_chain *c)
466 struct nlattr *tb[NFTA_COUNTER_MAX+1] = {};
468 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_counters_cb, tb) < 0)
471 if (tb[NFTA_COUNTER_PACKETS]) {
472 c->packets = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_PACKETS]));
473 c->flags |= (1 << NFTNL_CHAIN_PACKETS);
475 if (tb[NFTA_COUNTER_BYTES]) {
476 c->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_BYTES]));
477 c->flags |= (1 << NFTNL_CHAIN_BYTES);
483 static int nftnl_chain_parse_hook_cb(
const struct nlattr *attr,
void *data)
485 const struct nlattr **tb = data;
486 int type = mnl_attr_get_type(attr);
488 if (mnl_attr_type_valid(attr, NFTA_HOOK_MAX) < 0)
492 case NFTA_HOOK_HOOKNUM:
493 case NFTA_HOOK_PRIORITY:
494 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
498 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
507 static int nftnl_chain_parse_hook(
struct nlattr *attr,
struct nftnl_chain *c)
509 struct nlattr *tb[NFTA_HOOK_MAX+1] = {};
511 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_hook_cb, tb) < 0)
514 if (tb[NFTA_HOOK_HOOKNUM]) {
515 c->hooknum = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_HOOKNUM]));
516 c->flags |= (1 << NFTNL_CHAIN_HOOKNUM);
518 if (tb[NFTA_HOOK_PRIORITY]) {
519 c->prio = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_PRIORITY]));
520 c->flags |= (1 << NFTNL_CHAIN_PRIO);
522 if (tb[NFTA_HOOK_DEV]) {
523 c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
526 c->flags |= (1 << NFTNL_CHAIN_DEV);
532 int nftnl_chain_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_chain *c)
534 struct nlattr *tb[NFTA_CHAIN_MAX+1] = {};
535 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
538 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0)
541 if (tb[NFTA_CHAIN_NAME]) {
542 if (c->flags & (1 << NFTNL_CHAIN_NAME))
544 c->name = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_NAME]));
547 c->flags |= (1 << NFTNL_CHAIN_NAME);
549 if (tb[NFTA_CHAIN_TABLE]) {
550 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
552 c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE]));
555 c->flags |= (1 << NFTNL_CHAIN_TABLE);
557 if (tb[NFTA_CHAIN_HOOK]) {
558 ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
562 if (tb[NFTA_CHAIN_POLICY]) {
563 c->policy = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_POLICY]));
564 c->flags |= (1 << NFTNL_CHAIN_POLICY);
566 if (tb[NFTA_CHAIN_USE]) {
567 c->use = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_USE]));
568 c->flags |= (1 << NFTNL_CHAIN_USE);
570 if (tb[NFTA_CHAIN_COUNTERS]) {
571 ret = nftnl_chain_parse_counters(tb[NFTA_CHAIN_COUNTERS], c);
575 if (tb[NFTA_CHAIN_HANDLE]) {
576 c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
577 c->flags |= (1 << NFTNL_CHAIN_HANDLE);
579 if (tb[NFTA_CHAIN_TYPE]) {
580 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
582 c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE]));
585 c->flags |= (1 << NFTNL_CHAIN_TYPE);
588 c->family = nfg->nfgen_family;
589 c->flags |= (1 << NFTNL_CHAIN_FAMILY);
593 EXPORT_SYMBOL(nftnl_chain_nlmsg_parse);
595 static inline int nftnl_str2hooknum(
int family,
const char *hook)
599 for (hooknum = 0; hooknum < NF_INET_NUMHOOKS; hooknum++) {
600 if (strcmp(hook, nftnl_hooknum2str(family, hooknum)) == 0)
607 int nftnl_jansson_parse_chain(
struct nftnl_chain *c, json_t *tree,
608 struct nftnl_parse_err *err)
611 uint64_t handle, bytes, packets;
613 int32_t family, prio, hooknum, use;
614 const char *name, *table, *type, *hooknum_str, *policy, *dev;
616 root = nftnl_jansson_get_node(tree,
"chain", err);
620 name = nftnl_jansson_parse_str(root,
"name", err);
622 nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, name);
624 if (nftnl_jansson_parse_val(root,
"handle", NFTNL_TYPE_U64, &handle,
626 nftnl_chain_set_u64(c,NFTNL_CHAIN_HANDLE, handle);
628 if (nftnl_jansson_parse_val(root,
"bytes", NFTNL_TYPE_U64, &bytes,
630 nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, bytes);
632 if (nftnl_jansson_parse_val(root,
"packets", NFTNL_TYPE_U64, &packets,
634 nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, packets);
636 if (nftnl_jansson_parse_family(root, &family, err) == 0)
637 nftnl_chain_set_u32(c, NFTNL_CHAIN_FAMILY, family);
639 table = nftnl_jansson_parse_str(root,
"table", err);
642 nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
644 if (nftnl_jansson_parse_val(root,
"use", NFTNL_TYPE_U32, &use, err) == 0)
645 nftnl_chain_set_u32(c, NFTNL_CHAIN_USE, use);
647 if (nftnl_jansson_node_exist(root,
"hooknum")) {
648 type = nftnl_jansson_parse_str(root,
"type", err);
651 nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, type);
653 if (nftnl_jansson_parse_val(root,
"prio", NFTNL_TYPE_S32,
655 nftnl_chain_set_s32(c, NFTNL_CHAIN_PRIO, prio);
657 hooknum_str = nftnl_jansson_parse_str(root,
"hooknum", err);
658 if (hooknum_str != NULL) {
659 hooknum = nftnl_str2hooknum(c->family, hooknum_str);
662 nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM,
666 policy = nftnl_jansson_parse_str(root,
"policy", err);
667 if (policy != NULL) {
668 if (nftnl_str2verdict(policy, &policy_num) != 0) {
670 err->node_name =
"policy";
671 err->error = NFTNL_PARSE_EBADTYPE;
674 nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY,
678 dev = nftnl_jansson_parse_str(root,
"device", err);
680 nftnl_chain_set_str(c, NFTNL_CHAIN_DEV, dev);
687 static int nftnl_chain_json_parse(
struct nftnl_chain *c,
const void *json,
688 struct nftnl_parse_err *err,
689 enum nftnl_parse_input input)
696 tree = nftnl_jansson_create_root(json, &error, err, input);
700 ret = nftnl_jansson_parse_chain(c, tree, err);
702 nftnl_jansson_free_root(tree);
711 static int nftnl_chain_do_parse(
struct nftnl_chain *c,
enum nftnl_parse_type type,
712 const void *data,
struct nftnl_parse_err *err,
713 enum nftnl_parse_input input)
716 struct nftnl_parse_err perr = {};
719 case NFTNL_PARSE_JSON:
720 ret = nftnl_chain_json_parse(c, data, &perr, input);
722 case NFTNL_PARSE_XML:
735 int nftnl_chain_parse(
struct nftnl_chain *c,
enum nftnl_parse_type type,
736 const char *data,
struct nftnl_parse_err *err)
738 return nftnl_chain_do_parse(c, type, data, err, NFTNL_PARSE_BUFFER);
740 EXPORT_SYMBOL(nftnl_chain_parse);
742 int nftnl_chain_parse_file(
struct nftnl_chain *c,
enum nftnl_parse_type type,
743 FILE *fp,
struct nftnl_parse_err *err)
745 return nftnl_chain_do_parse(c, type, fp, err, NFTNL_PARSE_FILE);
747 EXPORT_SYMBOL(nftnl_chain_parse_file);
749 static int nftnl_chain_export(
char *buf,
size_t size,
752 NFTNL_BUF_INIT(b, buf, size);
754 nftnl_buf_open(&b, type, CHAIN);
755 if (c->flags & (1 << NFTNL_CHAIN_NAME))
756 nftnl_buf_str(&b, type, c->name, NAME);
757 if (c->flags & (1 << NFTNL_CHAIN_HANDLE))
758 nftnl_buf_u64(&b, type, c->handle, HANDLE);
759 if (c->flags & (1 << NFTNL_CHAIN_BYTES))
760 nftnl_buf_u64(&b, type, c->bytes, BYTES);
761 if (c->flags & (1 << NFTNL_CHAIN_PACKETS))
762 nftnl_buf_u64(&b, type, c->packets, PACKETS);
763 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
764 nftnl_buf_str(&b, type, c->table, TABLE);
765 if (c->flags & (1 << NFTNL_CHAIN_FAMILY))
766 nftnl_buf_str(&b, type, nftnl_family2str(c->family), FAMILY);
767 if (c->flags & (1 << NFTNL_CHAIN_USE))
768 nftnl_buf_u32(&b, type, c->use, USE);
769 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
770 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
771 nftnl_buf_str(&b, type, c->type, TYPE);
772 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM))
773 nftnl_buf_str(&b, type, nftnl_hooknum2str(c->family,
774 c->hooknum), HOOKNUM);
775 if (c->flags & (1 << NFTNL_CHAIN_PRIO))
776 nftnl_buf_s32(&b, type, c->prio, PRIO);
777 if (c->flags & (1 << NFTNL_CHAIN_POLICY))
778 nftnl_buf_str(&b, type, nftnl_verdict2str(c->policy), POLICY);
779 if (c->flags & (1 << NFTNL_CHAIN_DEV))
780 nftnl_buf_str(&b, type, c->dev, DEVICE);
783 nftnl_buf_close(&b, type, CHAIN);
785 return nftnl_buf_done(&b);
788 static int nftnl_chain_snprintf_default(
char *buf,
size_t size,
791 int ret, remain = size, offset = 0;
793 ret = snprintf(buf, remain,
"%s %s %s use %u",
794 nftnl_family2str(c->family), c->table, c->name, c->use);
795 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
797 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
798 ret = snprintf(buf + offset, remain,
" type %s hook %s prio %d",
799 c->type, nftnl_hooknum2str(c->family, c->hooknum),
801 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
803 if (c->flags & (1 << NFTNL_CHAIN_POLICY)) {
804 ret = snprintf(buf + offset, remain,
" policy %s",
805 nftnl_verdict2str(c->policy));
806 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
809 ret = snprintf(buf + offset, remain,
810 " packets %"PRIu64
" bytes %"PRIu64
"",
811 c->packets, c->bytes);
812 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
814 if (c->flags & (1 << NFTNL_CHAIN_DEV)) {
815 ret = snprintf(buf + offset, remain,
" dev %s ",
817 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
824 static int nftnl_chain_cmd_snprintf(
char *buf,
size_t size,
826 uint32_t type, uint32_t flags)
828 int ret, remain = size, offset = 0;
830 ret = nftnl_cmd_header_snprintf(buf + offset, remain, cmd, type, flags);
831 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
834 case NFTNL_OUTPUT_DEFAULT:
835 ret = nftnl_chain_snprintf_default(buf + offset, remain, c);
837 case NFTNL_OUTPUT_XML:
838 case NFTNL_OUTPUT_JSON:
839 ret = nftnl_chain_export(buf + offset, remain, c, type);
845 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
847 ret = nftnl_cmd_footer_snprintf(buf + offset, remain, cmd, type, flags);
848 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
853 int nftnl_chain_snprintf(
char *buf,
size_t size,
const struct nftnl_chain *c,
854 uint32_t type, uint32_t flags)
859 return nftnl_chain_cmd_snprintf(buf, size, c, nftnl_flag2cmd(flags),
862 EXPORT_SYMBOL(nftnl_chain_snprintf);
864 static int nftnl_chain_do_snprintf(
char *buf,
size_t size,
const void *c,
865 uint32_t cmd, uint32_t type, uint32_t flags)
867 return nftnl_chain_snprintf(buf, size, c, type, flags);
870 int nftnl_chain_fprintf(FILE *fp,
const struct nftnl_chain *c, uint32_t type,
873 return nftnl_fprintf(fp, c, NFTNL_CMD_UNSPEC, type, flags,
874 nftnl_chain_do_snprintf);
876 EXPORT_SYMBOL(nftnl_chain_fprintf);
879 struct list_head list;
890 INIT_LIST_HEAD(&list->list);
894 EXPORT_SYMBOL(nftnl_chain_list_alloc);
900 list_for_each_entry_safe(r, tmp, &list->list, head) {
906 EXPORT_SYMBOL(nftnl_chain_list_free);
910 return list_empty(&list->list);
912 EXPORT_SYMBOL(nftnl_chain_list_is_empty);
916 list_add(&r->head, &list->list);
918 EXPORT_SYMBOL(nftnl_chain_list_add);
922 list_add_tail(&r->head, &list->list);
924 EXPORT_SYMBOL(nftnl_chain_list_add_tail);
930 EXPORT_SYMBOL(nftnl_chain_list_del);
939 list_for_each_entry_safe(cur, tmp, &chain_list->list, head) {
946 EXPORT_SYMBOL(nftnl_chain_list_foreach);
963 if (nftnl_chain_list_is_empty(l))
966 iter->cur = list_entry(l->list.next,
struct nftnl_chain, head);
970 EXPORT_SYMBOL(nftnl_chain_list_iter_create);
980 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_chain, head);
981 if (&iter->cur->head == iter->list->list.next)
986 EXPORT_SYMBOL(nftnl_chain_list_iter_next);
992 EXPORT_SYMBOL(nftnl_chain_list_iter_destroy);