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;
35 char name[NFT_CHAIN_MAXNAMELEN];
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, nft_chain_alloc);
107 EXPORT_SYMBOL(nftnl_chain_free, nft_chain_free);
109 bool nftnl_chain_is_set(
const struct nftnl_chain *c, uint16_t attr)
111 return c->flags & (1 << attr);
113 EXPORT_SYMBOL(nftnl_chain_is_set, nft_chain_attr_is_set);
115 void nftnl_chain_unset(
struct nftnl_chain *c, uint16_t attr)
117 if (!(c->flags & (1 << attr)))
121 case NFTNL_CHAIN_TABLE:
127 case NFTNL_CHAIN_USE:
129 case NFTNL_CHAIN_TYPE:
135 case NFTNL_CHAIN_NAME:
136 case NFTNL_CHAIN_HOOKNUM:
137 case NFTNL_CHAIN_PRIO:
138 case NFTNL_CHAIN_POLICY:
139 case NFTNL_CHAIN_BYTES:
140 case NFTNL_CHAIN_PACKETS:
141 case NFTNL_CHAIN_HANDLE:
142 case NFTNL_CHAIN_FAMILY:
144 case NFTNL_CHAIN_DEV:
154 c->flags &= ~(1 << attr);
156 EXPORT_SYMBOL(nftnl_chain_unset, nft_chain_attr_unset);
158 static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = {
159 [NFTNL_CHAIN_HOOKNUM] =
sizeof(uint32_t),
160 [NFTNL_CHAIN_PRIO] =
sizeof(int32_t),
161 [NFTNL_CHAIN_POLICY] =
sizeof(uint32_t),
162 [NFTNL_CHAIN_BYTES] =
sizeof(uint64_t),
163 [NFTNL_CHAIN_PACKETS] =
sizeof(uint64_t),
164 [NFTNL_CHAIN_HANDLE] =
sizeof(uint64_t),
165 [NFTNL_CHAIN_FAMILY] =
sizeof(uint32_t),
168 void nftnl_chain_set_data(
struct nftnl_chain *c, uint16_t attr,
169 const void *data, uint32_t data_len)
171 if (attr > NFTNL_CHAIN_MAX)
174 nftnl_assert_validate(data, nftnl_chain_validate, attr, data_len);
177 case NFTNL_CHAIN_NAME:
178 strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
180 case NFTNL_CHAIN_TABLE:
184 c->table = strdup(data);
186 case NFTNL_CHAIN_HOOKNUM:
187 memcpy(&c->hooknum, data,
sizeof(c->hooknum));
189 case NFTNL_CHAIN_PRIO:
190 memcpy(&c->prio, data,
sizeof(c->prio));
192 case NFTNL_CHAIN_POLICY:
193 c->policy = *((uint32_t *)data);
195 case NFTNL_CHAIN_USE:
196 c->use = *((uint32_t *)data);
198 case NFTNL_CHAIN_BYTES:
199 c->bytes = *((uint64_t *)data);
201 case NFTNL_CHAIN_PACKETS:
202 c->packets = *((uint64_t *)data);
204 case NFTNL_CHAIN_HANDLE:
205 c->handle = *((uint64_t *)data);
207 case NFTNL_CHAIN_FAMILY:
208 c->family = *((uint32_t *)data);
210 case NFTNL_CHAIN_TYPE:
214 c->type = strdup(data);
216 case NFTNL_CHAIN_DEV:
220 c->dev = strdup(data);
223 c->flags |= (1 << attr);
225 EXPORT_SYMBOL(nftnl_chain_set_data, nft_chain_attr_set_data);
227 void nftnl_chain_set(
struct nftnl_chain *c, uint16_t attr,
const void *data)
229 nftnl_chain_set_data(c, attr, data, nftnl_chain_validate[attr]);
231 EXPORT_SYMBOL(nftnl_chain_set, nft_chain_attr_set);
233 void nftnl_chain_set_u32(
struct nftnl_chain *c, uint16_t attr, uint32_t data)
235 nftnl_chain_set_data(c, attr, &data,
sizeof(uint32_t));
237 EXPORT_SYMBOL(nftnl_chain_set_u32, nft_chain_attr_set_u32);
239 void nftnl_chain_set_s32(
struct nftnl_chain *c, uint16_t attr, int32_t data)
241 nftnl_chain_set_data(c, attr, &data,
sizeof(int32_t));
243 EXPORT_SYMBOL(nftnl_chain_set_s32, nft_chain_attr_set_s32);
245 void nftnl_chain_set_u64(
struct nftnl_chain *c, uint16_t attr, uint64_t data)
247 nftnl_chain_set_data(c, attr, &data,
sizeof(uint64_t));
249 EXPORT_SYMBOL(nftnl_chain_set_u64, nft_chain_attr_set_u64);
251 void nftnl_chain_set_u8(
struct nftnl_chain *c, uint16_t attr, uint8_t data)
253 nftnl_chain_set_data(c, attr, &data,
sizeof(uint8_t));
255 EXPORT_SYMBOL(nftnl_chain_set_u8, nft_chain_attr_set_u8);
257 void nftnl_chain_set_str(
struct nftnl_chain *c, uint16_t attr,
const char *str)
259 nftnl_chain_set_data(c, attr, str, strlen(str));
261 EXPORT_SYMBOL(nftnl_chain_set_str, nft_chain_attr_set_str);
263 const void *nftnl_chain_get_data(
struct nftnl_chain *c, uint16_t attr,
266 if (!(c->flags & (1 << attr)))
270 case NFTNL_CHAIN_NAME:
272 case NFTNL_CHAIN_TABLE:
274 case NFTNL_CHAIN_HOOKNUM:
275 *data_len =
sizeof(uint32_t);
277 case NFTNL_CHAIN_PRIO:
278 *data_len =
sizeof(int32_t);
280 case NFTNL_CHAIN_POLICY:
281 *data_len =
sizeof(uint32_t);
283 case NFTNL_CHAIN_USE:
284 *data_len =
sizeof(uint32_t);
286 case NFTNL_CHAIN_BYTES:
287 *data_len =
sizeof(uint64_t);
289 case NFTNL_CHAIN_PACKETS:
290 *data_len =
sizeof(uint64_t);
292 case NFTNL_CHAIN_HANDLE:
293 *data_len =
sizeof(uint64_t);
295 case NFTNL_CHAIN_FAMILY:
296 *data_len =
sizeof(uint32_t);
298 case NFTNL_CHAIN_TYPE:
299 *data_len =
sizeof(uint32_t);
301 case NFTNL_CHAIN_DEV:
306 EXPORT_SYMBOL(nftnl_chain_get_data, nft_chain_attr_get_data);
308 const void *nftnl_chain_get(
struct nftnl_chain *c, uint16_t attr)
311 return nftnl_chain_get_data(c, attr, &data_len);
313 EXPORT_SYMBOL(nftnl_chain_get, nft_chain_attr_get);
315 const char *nftnl_chain_get_str(
struct nftnl_chain *c, uint16_t attr)
317 return nftnl_chain_get(c, attr);
319 EXPORT_SYMBOL(nftnl_chain_get_str, nft_chain_attr_get_str);
321 uint32_t nftnl_chain_get_u32(
struct nftnl_chain *c, uint16_t attr)
324 const uint32_t *val = nftnl_chain_get_data(c, attr, &data_len);
326 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
328 return val ? *val : 0;
330 EXPORT_SYMBOL(nftnl_chain_get_u32, nft_chain_attr_get_u32);
332 int32_t nftnl_chain_get_s32(
struct nftnl_chain *c, uint16_t attr)
335 const int32_t *val = nftnl_chain_get_data(c, attr, &data_len);
337 nftnl_assert(val, attr, data_len ==
sizeof(int32_t));
339 return val ? *val : 0;
341 EXPORT_SYMBOL(nftnl_chain_get_s32, nft_chain_attr_get_s32);
343 uint64_t nftnl_chain_get_u64(
struct nftnl_chain *c, uint16_t attr)
346 const uint64_t *val = nftnl_chain_get_data(c, attr, &data_len);
348 nftnl_assert(val, attr, data_len ==
sizeof(int64_t));
350 return val ? *val : 0;
352 EXPORT_SYMBOL(nftnl_chain_get_u64, nft_chain_attr_get_u64);
354 uint8_t nftnl_chain_get_u8(
struct nftnl_chain *c, uint16_t attr)
357 const uint8_t *val = nftnl_chain_get_data(c, attr, &data_len);
359 nftnl_assert(val, attr, data_len ==
sizeof(int8_t));
361 return val ? *val : 0;
363 EXPORT_SYMBOL(nftnl_chain_get_u8, nft_chain_attr_get_u8);
365 void nftnl_chain_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nftnl_chain *c)
367 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
368 mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, c->table);
369 if (c->flags & (1 << NFTNL_CHAIN_NAME))
370 mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, c->name);
371 if ((c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) &&
372 (c->flags & (1 << NFTNL_CHAIN_PRIO))) {
375 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
376 mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(c->hooknum));
377 mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
378 if (c->flags & (1 << NFTNL_CHAIN_DEV))
379 mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev);
380 mnl_attr_nest_end(nlh, nest);
382 if (c->flags & (1 << NFTNL_CHAIN_POLICY))
383 mnl_attr_put_u32(nlh, NFTA_CHAIN_POLICY, htonl(c->policy));
384 if (c->flags & (1 << NFTNL_CHAIN_USE))
385 mnl_attr_put_u32(nlh, NFTA_CHAIN_USE, htonl(c->use));
386 if ((c->flags & (1 << NFTNL_CHAIN_PACKETS)) &&
387 (c->flags & (1 << NFTNL_CHAIN_BYTES))) {
390 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_COUNTERS);
391 mnl_attr_put_u64(nlh, NFTA_COUNTER_PACKETS, be64toh(c->packets));
392 mnl_attr_put_u64(nlh, NFTA_COUNTER_BYTES, be64toh(c->bytes));
393 mnl_attr_nest_end(nlh, nest);
395 if (c->flags & (1 << NFTNL_CHAIN_HANDLE))
396 mnl_attr_put_u64(nlh, NFTA_CHAIN_HANDLE, be64toh(c->handle));
397 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
398 mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type);
400 EXPORT_SYMBOL(nftnl_chain_nlmsg_build_payload, nft_chain_nlmsg_build_payload);
402 static int nftnl_chain_parse_attr_cb(
const struct nlattr *attr,
void *data)
404 const struct nlattr **tb = data;
405 int type = mnl_attr_get_type(attr);
407 if (mnl_attr_type_valid(attr, NFTA_CHAIN_MAX) < 0)
411 case NFTA_CHAIN_NAME:
412 case NFTA_CHAIN_TABLE:
413 case NFTA_CHAIN_TYPE:
414 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
417 case NFTA_CHAIN_HOOK:
418 case NFTA_CHAIN_COUNTERS:
419 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
422 case NFTA_CHAIN_POLICY:
424 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
427 case NFTA_CHAIN_HANDLE:
428 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
437 static int nftnl_chain_parse_counters_cb(
const struct nlattr *attr,
void *data)
439 const struct nlattr **tb = data;
440 int type = mnl_attr_get_type(attr);
442 if (mnl_attr_type_valid(attr, NFTA_COUNTER_MAX) < 0)
446 case NFTA_COUNTER_BYTES:
447 case NFTA_COUNTER_PACKETS:
448 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
457 static int nftnl_chain_parse_counters(
struct nlattr *attr,
struct nftnl_chain *c)
459 struct nlattr *tb[NFTA_COUNTER_MAX+1] = {};
461 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_counters_cb, tb) < 0)
464 if (tb[NFTA_COUNTER_PACKETS]) {
465 c->packets = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_PACKETS]));
466 c->flags |= (1 << NFTNL_CHAIN_PACKETS);
468 if (tb[NFTA_COUNTER_BYTES]) {
469 c->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_BYTES]));
470 c->flags |= (1 << NFTNL_CHAIN_BYTES);
476 static int nftnl_chain_parse_hook_cb(
const struct nlattr *attr,
void *data)
478 const struct nlattr **tb = data;
479 int type = mnl_attr_get_type(attr);
481 if (mnl_attr_type_valid(attr, NFTA_HOOK_MAX) < 0)
485 case NFTA_HOOK_HOOKNUM:
486 case NFTA_HOOK_PRIORITY:
487 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
491 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
500 static int nftnl_chain_parse_hook(
struct nlattr *attr,
struct nftnl_chain *c)
502 struct nlattr *tb[NFTA_HOOK_MAX+1] = {};
504 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_hook_cb, tb) < 0)
507 if (tb[NFTA_HOOK_HOOKNUM]) {
508 c->hooknum = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_HOOKNUM]));
509 c->flags |= (1 << NFTNL_CHAIN_HOOKNUM);
511 if (tb[NFTA_HOOK_PRIORITY]) {
512 c->prio = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_PRIORITY]));
513 c->flags |= (1 << NFTNL_CHAIN_PRIO);
515 if (tb[NFTA_HOOK_DEV]) {
516 c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
517 c->flags |= (1 << NFTNL_CHAIN_DEV);
523 int nftnl_chain_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_chain *c)
525 struct nlattr *tb[NFTA_CHAIN_MAX+1] = {};
526 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
529 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0)
532 if (tb[NFTA_CHAIN_NAME]) {
533 strncpy(c->name, mnl_attr_get_str(tb[NFTA_CHAIN_NAME]),
534 NFT_CHAIN_MAXNAMELEN);
535 c->flags |= (1 << NFTNL_CHAIN_NAME);
537 if (tb[NFTA_CHAIN_TABLE]) {
539 c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE]));
540 c->flags |= (1 << NFTNL_CHAIN_TABLE);
542 if (tb[NFTA_CHAIN_HOOK]) {
543 ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
547 if (tb[NFTA_CHAIN_POLICY]) {
548 c->policy = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_POLICY]));
549 c->flags |= (1 << NFTNL_CHAIN_POLICY);
551 if (tb[NFTA_CHAIN_USE]) {
552 c->use = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_USE]));
553 c->flags |= (1 << NFTNL_CHAIN_USE);
555 if (tb[NFTA_CHAIN_COUNTERS]) {
556 ret = nftnl_chain_parse_counters(tb[NFTA_CHAIN_COUNTERS], c);
560 if (tb[NFTA_CHAIN_HANDLE]) {
561 c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
562 c->flags |= (1 << NFTNL_CHAIN_HANDLE);
564 if (tb[NFTA_CHAIN_TYPE]) {
566 c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE]));
567 c->flags |= (1 << NFTNL_CHAIN_TYPE);
570 c->family = nfg->nfgen_family;
571 c->flags |= (1 << NFTNL_CHAIN_FAMILY);
575 EXPORT_SYMBOL(nftnl_chain_nlmsg_parse, nft_chain_nlmsg_parse);
577 static inline int nftnl_str2hooknum(
int family,
const char *hook)
581 for (hooknum = 0; hooknum < NF_INET_NUMHOOKS; hooknum++) {
582 if (strcmp(hook, nftnl_hooknum2str(family, hooknum)) == 0)
589 int nftnl_jansson_parse_chain(
struct nftnl_chain *c, json_t *tree,
590 struct nftnl_parse_err *err)
593 uint64_t handle, bytes, packets;
595 int32_t family, prio, hooknum, use;
596 const char *name, *table, *type, *hooknum_str, *policy, *dev;
598 root = nftnl_jansson_get_node(tree,
"chain", err);
602 name = nftnl_jansson_parse_str(root,
"name", err);
604 nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, name);
606 if (nftnl_jansson_parse_val(root,
"handle", NFTNL_TYPE_U64, &handle,
608 nftnl_chain_set_u64(c,NFTNL_CHAIN_HANDLE, handle);
610 if (nftnl_jansson_parse_val(root,
"bytes", NFTNL_TYPE_U64, &bytes,
612 nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, bytes);
614 if (nftnl_jansson_parse_val(root,
"packets", NFTNL_TYPE_U64, &packets,
616 nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, packets);
618 if (nftnl_jansson_parse_family(root, &family, err) == 0)
619 nftnl_chain_set_u32(c, NFTNL_CHAIN_FAMILY, family);
621 table = nftnl_jansson_parse_str(root,
"table", err);
624 nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
626 if (nftnl_jansson_parse_val(root,
"use", NFTNL_TYPE_U32, &use, err) == 0)
627 nftnl_chain_set_u32(c, NFTNL_CHAIN_USE, use);
629 if (nftnl_jansson_node_exist(root,
"hooknum")) {
630 type = nftnl_jansson_parse_str(root,
"type", err);
633 nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, type);
635 if (nftnl_jansson_parse_val(root,
"prio", NFTNL_TYPE_S32,
637 nftnl_chain_set_s32(c, NFTNL_CHAIN_PRIO, prio);
639 hooknum_str = nftnl_jansson_parse_str(root,
"hooknum", err);
640 if (hooknum_str != NULL) {
641 hooknum = nftnl_str2hooknum(c->family, hooknum_str);
644 nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM,
648 policy = nftnl_jansson_parse_str(root,
"policy", err);
649 if (policy != NULL) {
650 if (nftnl_str2verdict(policy, &policy_num) != 0) {
652 err->node_name =
"policy";
653 err->error = NFTNL_PARSE_EBADTYPE;
656 nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY,
660 dev = nftnl_jansson_parse_str(root,
"device", err);
662 nftnl_chain_set_str(c, NFTNL_CHAIN_DEV, dev);
669 static int nftnl_chain_json_parse(
struct nftnl_chain *c,
const void *json,
670 struct nftnl_parse_err *err,
671 enum nftnl_parse_input input)
678 tree = nftnl_jansson_create_root(json, &error, err, input);
682 ret = nftnl_jansson_parse_chain(c, tree, err);
684 nftnl_jansson_free_root(tree);
694 int nftnl_mxml_chain_parse(mxml_node_t *tree,
struct nftnl_chain *c,
695 struct nftnl_parse_err *err)
697 const char *table, *name, *hooknum_str, *policy_str, *type, *dev;
698 int family, hooknum, policy;
699 uint64_t handle, bytes, packets, prio, use;
701 name = nftnl_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
702 NFTNL_XML_MAND, err);
704 nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, name);
706 if (nftnl_mxml_num_parse(tree,
"handle", MXML_DESCEND_FIRST, BASE_DEC,
707 &handle, NFTNL_TYPE_U64, NFTNL_XML_MAND, err) == 0)
708 nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle);
710 if (nftnl_mxml_num_parse(tree,
"bytes", MXML_DESCEND_FIRST, BASE_DEC,
711 &bytes, NFTNL_TYPE_U64, NFTNL_XML_MAND, err) == 0)
712 nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, bytes);
715 if (nftnl_mxml_num_parse(tree,
"packets", MXML_DESCEND_FIRST, BASE_DEC,
716 &packets, NFTNL_TYPE_U64, NFTNL_XML_MAND, err) == 0)
717 nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, packets);
719 table = nftnl_mxml_str_parse(tree,
"table", MXML_DESCEND_FIRST,
720 NFTNL_XML_MAND, err);
723 nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
725 if (nftnl_mxml_num_parse(tree,
"use", MXML_DESCEND_FIRST, BASE_DEC,
726 &use, NFTNL_TYPE_U64, NFTNL_XML_MAND, err) == 0)
727 nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, use);
729 family = nftnl_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
730 NFTNL_XML_MAND, err);
732 nftnl_chain_set_u32(c, NFTNL_CHAIN_FAMILY, family);
734 hooknum_str = nftnl_mxml_str_parse(tree,
"hooknum", MXML_DESCEND_FIRST,
736 if (hooknum_str != NULL) {
737 hooknum = nftnl_str2hooknum(c->family, hooknum_str);
740 nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, hooknum);
742 type = nftnl_mxml_str_parse(tree,
"type", MXML_DESCEND_FIRST,
743 NFTNL_XML_MAND, err);
746 nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, type);
748 if (nftnl_mxml_num_parse(tree,
"prio", MXML_DESCEND, BASE_DEC,
749 &prio, NFTNL_TYPE_S32, NFTNL_XML_MAND,
751 nftnl_chain_set_s32(c, NFTNL_CHAIN_PRIO, prio);
753 policy_str = nftnl_mxml_str_parse(tree,
"policy",
755 NFTNL_XML_MAND, err);
756 if (policy_str != NULL) {
757 if (nftnl_str2verdict(policy_str, &policy) != 0) {
759 err->node_name =
"policy";
760 err->error = NFTNL_PARSE_EBADTYPE;
763 nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY,
766 dev = nftnl_mxml_str_parse(tree,
"device", MXML_DESCEND_FIRST,
767 NFTNL_XML_MAND, err);
770 nftnl_chain_set_str(c, NFTNL_CHAIN_DEV, dev);
777 static int nftnl_chain_xml_parse(
struct nftnl_chain *c,
const void *xml,
778 struct nftnl_parse_err *err,
779 enum nftnl_parse_input input)
783 mxml_node_t *tree = nftnl_mxml_build_tree(xml,
"chain", err, input);
787 ret = nftnl_mxml_chain_parse(tree, c, err);
796 static int nftnl_chain_do_parse(
struct nftnl_chain *c,
enum nftnl_parse_type type,
797 const void *data,
struct nftnl_parse_err *err,
798 enum nftnl_parse_input input)
801 struct nftnl_parse_err perr;
804 case NFTNL_PARSE_XML:
805 ret = nftnl_chain_xml_parse(c, data, &perr, input);
807 case NFTNL_PARSE_JSON:
808 ret = nftnl_chain_json_parse(c, data, &perr, input);
822 int nftnl_chain_parse(
struct nftnl_chain *c,
enum nftnl_parse_type type,
823 const char *data,
struct nftnl_parse_err *err)
825 return nftnl_chain_do_parse(c, type, data, err, NFTNL_PARSE_BUFFER);
827 EXPORT_SYMBOL(nftnl_chain_parse, nft_chain_parse);
829 int nftnl_chain_parse_file(
struct nftnl_chain *c,
enum nftnl_parse_type type,
830 FILE *fp,
struct nftnl_parse_err *err)
832 return nftnl_chain_do_parse(c, type, fp, err, NFTNL_PARSE_FILE);
834 EXPORT_SYMBOL(nftnl_chain_parse_file, nft_chain_parse_file);
836 static int nftnl_chain_export(
char *buf,
size_t size,
struct nftnl_chain *c,
839 NFTNL_BUF_INIT(b, buf, size);
841 nftnl_buf_open(&b, type, CHAIN);
842 if (c->flags & (1 << NFTNL_CHAIN_NAME))
843 nftnl_buf_str(&b, type, c->name, NAME);
844 if (c->flags & (1 << NFTNL_CHAIN_HANDLE))
845 nftnl_buf_u64(&b, type, c->handle, HANDLE);
846 if (c->flags & (1 << NFTNL_CHAIN_BYTES))
847 nftnl_buf_u64(&b, type, c->bytes, BYTES);
848 if (c->flags & (1 << NFTNL_CHAIN_PACKETS))
849 nftnl_buf_u64(&b, type, c->packets, PACKETS);
850 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
851 nftnl_buf_str(&b, type, c->table, TABLE);
852 if (c->flags & (1 << NFTNL_CHAIN_FAMILY))
853 nftnl_buf_str(&b, type, nftnl_family2str(c->family), FAMILY);
854 if (c->flags & (1 << NFTNL_CHAIN_USE))
855 nftnl_buf_u32(&b, type, c->use, USE);
856 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
857 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
858 nftnl_buf_str(&b, type, c->type, TYPE);
859 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM))
860 nftnl_buf_str(&b, type, nftnl_hooknum2str(c->family,
861 c->hooknum), HOOKNUM);
862 if (c->flags & (1 << NFTNL_CHAIN_PRIO))
863 nftnl_buf_s32(&b, type, c->prio, PRIO);
864 if (c->flags & (1 << NFTNL_CHAIN_POLICY))
865 nftnl_buf_str(&b, type, nftnl_verdict2str(c->policy), POLICY);
866 if (c->flags & (1 << NFTNL_CHAIN_DEV))
867 nftnl_buf_str(&b, type, c->dev, DEVICE);
870 nftnl_buf_close(&b, type, CHAIN);
872 return nftnl_buf_done(&b);
875 static int nftnl_chain_snprintf_default(
char *buf,
size_t size,
878 int ret, len = size, offset = 0;
880 ret = snprintf(buf, len,
"%s %s %s use %u",
881 nftnl_family2str(c->family), c->table, c->name, c->use);
882 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
884 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
885 ret = snprintf(buf+offset, len,
886 " type %s hook %s prio %d policy %s "
887 "packets %"PRIu64
" bytes %"PRIu64
"",
888 c->type, nftnl_hooknum2str(c->family, c->hooknum),
889 c->prio, nftnl_verdict2str(c->policy),
890 c->packets, c->bytes);
891 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
893 if (c->flags & (1 << NFTNL_CHAIN_DEV)) {
894 ret = snprintf(buf+offset, len,
" dev %s ", c->dev);
895 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
902 static int nftnl_chain_cmd_snprintf(
char *buf,
size_t size,
struct nftnl_chain *c,
903 uint32_t cmd, uint32_t type, uint32_t flags)
905 int ret, len = size, offset = 0;
907 ret = nftnl_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
908 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
911 case NFTNL_OUTPUT_DEFAULT:
912 ret = nftnl_chain_snprintf_default(buf+offset, len, c);
914 case NFTNL_OUTPUT_XML:
915 case NFTNL_OUTPUT_JSON:
916 ret = nftnl_chain_export(buf+offset, len, c, type);
922 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
924 ret = nftnl_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
925 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
930 int nftnl_chain_snprintf(
char *buf,
size_t size,
struct nftnl_chain *c,
931 uint32_t type, uint32_t flags)
933 return nftnl_chain_cmd_snprintf(buf, size, c, nftnl_flag2cmd(flags), type,
936 EXPORT_SYMBOL(nftnl_chain_snprintf, nft_chain_snprintf);
938 static inline int nftnl_chain_do_snprintf(
char *buf,
size_t size,
void *c,
939 uint32_t cmd, uint32_t type,
942 return nftnl_chain_snprintf(buf, size, c, type, flags);
945 int nftnl_chain_fprintf(FILE *fp,
struct nftnl_chain *c, uint32_t type,
948 return nftnl_fprintf(fp, c, NFTNL_CMD_UNSPEC, type, flags,
949 nftnl_chain_do_snprintf);
951 EXPORT_SYMBOL(nftnl_chain_fprintf, nft_chain_fprintf);
954 struct list_head list;
965 INIT_LIST_HEAD(&list->list);
969 EXPORT_SYMBOL(nftnl_chain_list_alloc, nft_chain_list_alloc);
975 list_for_each_entry_safe(r, tmp, &list->list, head) {
981 EXPORT_SYMBOL(nftnl_chain_list_free, nft_chain_list_free);
985 return list_empty(&list->list);
987 EXPORT_SYMBOL(nftnl_chain_list_is_empty, nft_chain_list_is_empty);
991 list_add(&r->head, &list->list);
993 EXPORT_SYMBOL(nftnl_chain_list_add, nft_chain_list_add);
997 list_add_tail(&r->head, &list->list);
999 EXPORT_SYMBOL(nftnl_chain_list_add_tail, nft_chain_list_add_tail);
1005 EXPORT_SYMBOL(nftnl_chain_list_del, nft_chain_list_del);
1014 list_for_each_entry_safe(cur, tmp, &chain_list->list, head) {
1015 ret = cb(cur, data);
1021 EXPORT_SYMBOL(nftnl_chain_list_foreach, nft_chain_list_foreach);
1037 if (nftnl_chain_list_is_empty(l))
1040 iter->cur = list_entry(l->list.next,
struct nftnl_chain, head);
1044 EXPORT_SYMBOL(nftnl_chain_list_iter_create, nft_chain_list_iter_create);
1054 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_chain, head);
1055 if (&iter->cur->head == iter->list->list.next)
1060 EXPORT_SYMBOL(nftnl_chain_list_iter_next, nft_chain_list_iter_next);
1066 EXPORT_SYMBOL(nftnl_chain_list_iter_destroy, nft_chain_list_iter_destroy);