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>
32 struct list_head head;
34 char name[NFT_CHAIN_MAXNAMELEN];
48 static const char *nft_hooknum2str(
int family,
int hooknum)
56 case NF_INET_PRE_ROUTING:
58 case NF_INET_LOCAL_IN:
62 case NF_INET_LOCAL_OUT:
64 case NF_INET_POST_ROUTING:
84 return calloc(1,
sizeof(
struct nft_chain));
86 EXPORT_SYMBOL(nft_chain_alloc);
97 EXPORT_SYMBOL(nft_chain_free);
99 bool nft_chain_attr_is_set(
const struct nft_chain *c, uint16_t attr)
101 return c->flags & (1 << attr);
103 EXPORT_SYMBOL(nft_chain_attr_is_set);
105 void nft_chain_attr_unset(
struct nft_chain *c, uint16_t attr)
107 if (!(c->flags & (1 << attr)))
111 case NFT_CHAIN_ATTR_TABLE:
117 case NFT_CHAIN_ATTR_USE:
120 case NFT_CHAIN_ATTR_TYPE:
126 case NFT_CHAIN_ATTR_NAME:
127 case NFT_CHAIN_ATTR_HOOKNUM:
128 case NFT_CHAIN_ATTR_PRIO:
129 case NFT_CHAIN_ATTR_POLICY:
130 case NFT_CHAIN_ATTR_BYTES:
131 case NFT_CHAIN_ATTR_PACKETS:
132 case NFT_CHAIN_ATTR_HANDLE:
133 case NFT_CHAIN_ATTR_FAMILY:
139 c->flags &= ~(1 << attr);
141 EXPORT_SYMBOL(nft_chain_attr_unset);
143 static uint32_t nft_chain_attr_validate[NFT_CHAIN_ATTR_MAX + 1] = {
144 [NFT_CHAIN_ATTR_HOOKNUM] =
sizeof(uint32_t),
145 [NFT_CHAIN_ATTR_PRIO] =
sizeof(int32_t),
146 [NFT_CHAIN_ATTR_POLICY] =
sizeof(uint32_t),
147 [NFT_CHAIN_ATTR_BYTES] =
sizeof(uint64_t),
148 [NFT_CHAIN_ATTR_PACKETS] =
sizeof(uint64_t),
149 [NFT_CHAIN_ATTR_HANDLE] =
sizeof(uint64_t),
150 [NFT_CHAIN_ATTR_FAMILY] =
sizeof(uint32_t),
153 void nft_chain_attr_set_data(
struct nft_chain *c, uint16_t attr,
154 const void *data, uint32_t data_len)
156 if (attr > NFT_CHAIN_ATTR_MAX)
159 nft_assert_validate(data, nft_chain_attr_validate, attr, data_len);
162 case NFT_CHAIN_ATTR_NAME:
163 strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
165 case NFT_CHAIN_ATTR_TABLE:
169 c->table = strdup(data);
171 case NFT_CHAIN_ATTR_HOOKNUM:
172 memcpy(&c->hooknum, data,
sizeof(c->hooknum));
174 case NFT_CHAIN_ATTR_PRIO:
175 memcpy(&c->prio, data,
sizeof(c->prio));
177 case NFT_CHAIN_ATTR_POLICY:
178 c->policy = *((uint32_t *)data);
180 case NFT_CHAIN_ATTR_USE:
183 case NFT_CHAIN_ATTR_BYTES:
184 c->bytes = *((uint64_t *)data);
186 case NFT_CHAIN_ATTR_PACKETS:
187 c->packets = *((uint64_t *)data);
189 case NFT_CHAIN_ATTR_HANDLE:
190 c->handle = *((uint64_t *)data);
192 case NFT_CHAIN_ATTR_FAMILY:
193 c->family = *((uint32_t *)data);
195 case NFT_CHAIN_ATTR_TYPE:
199 c->type = strdup(data);
202 c->flags |= (1 << attr);
204 EXPORT_SYMBOL(nft_chain_attr_set_data);
206 void nft_chain_attr_set(
struct nft_chain *c, uint16_t attr,
const void *data)
208 nft_chain_attr_set_data(c, attr, data, nft_chain_attr_validate[attr]);
210 EXPORT_SYMBOL(nft_chain_attr_set);
212 void nft_chain_attr_set_u32(
struct nft_chain *c, uint16_t attr, uint32_t data)
214 nft_chain_attr_set_data(c, attr, &data,
sizeof(uint32_t));
216 EXPORT_SYMBOL(nft_chain_attr_set_u32);
218 void nft_chain_attr_set_s32(
struct nft_chain *c, uint16_t attr, int32_t data)
220 nft_chain_attr_set_data(c, attr, &data,
sizeof(int32_t));
222 EXPORT_SYMBOL(nft_chain_attr_set_s32);
224 void nft_chain_attr_set_u64(
struct nft_chain *c, uint16_t attr, uint64_t data)
226 nft_chain_attr_set_data(c, attr, &data,
sizeof(uint64_t));
228 EXPORT_SYMBOL(nft_chain_attr_set_u64);
230 void nft_chain_attr_set_u8(
struct nft_chain *c, uint16_t attr, uint8_t data)
232 nft_chain_attr_set_data(c, attr, &data,
sizeof(uint8_t));
234 EXPORT_SYMBOL(nft_chain_attr_set_u8);
236 void nft_chain_attr_set_str(
struct nft_chain *c, uint16_t attr,
const char *str)
238 nft_chain_attr_set_data(c, attr, str, strlen(str));
240 EXPORT_SYMBOL(nft_chain_attr_set_str);
242 const void *nft_chain_attr_get_data(
struct nft_chain *c, uint16_t attr,
245 if (!(c->flags & (1 << attr)))
249 case NFT_CHAIN_ATTR_NAME:
251 case NFT_CHAIN_ATTR_TABLE:
253 case NFT_CHAIN_ATTR_HOOKNUM:
254 *data_len =
sizeof(uint32_t);
256 case NFT_CHAIN_ATTR_PRIO:
257 *data_len =
sizeof(int32_t);
259 case NFT_CHAIN_ATTR_POLICY:
260 *data_len =
sizeof(uint32_t);
262 case NFT_CHAIN_ATTR_USE:
263 *data_len =
sizeof(uint32_t);
265 case NFT_CHAIN_ATTR_BYTES:
266 *data_len =
sizeof(uint64_t);
268 case NFT_CHAIN_ATTR_PACKETS:
269 *data_len =
sizeof(uint64_t);
271 case NFT_CHAIN_ATTR_HANDLE:
272 *data_len =
sizeof(uint64_t);
274 case NFT_CHAIN_ATTR_FAMILY:
275 *data_len =
sizeof(uint32_t);
277 case NFT_CHAIN_ATTR_TYPE:
278 *data_len =
sizeof(uint32_t);
283 EXPORT_SYMBOL(nft_chain_attr_get_data);
285 const void *nft_chain_attr_get(
struct nft_chain *c, uint16_t attr)
288 return nft_chain_attr_get_data(c, attr, &data_len);
290 EXPORT_SYMBOL(nft_chain_attr_get);
292 const char *nft_chain_attr_get_str(
struct nft_chain *c, uint16_t attr)
294 return nft_chain_attr_get(c, attr);
296 EXPORT_SYMBOL(nft_chain_attr_get_str);
298 uint32_t nft_chain_attr_get_u32(
struct nft_chain *c, uint16_t attr)
301 const uint32_t *val = nft_chain_attr_get_data(c, attr, &data_len);
303 nft_assert(val, attr, data_len ==
sizeof(uint32_t));
305 return val ? *val : 0;
307 EXPORT_SYMBOL(nft_chain_attr_get_u32);
309 int32_t nft_chain_attr_get_s32(
struct nft_chain *c, uint16_t attr)
312 const int32_t *val = nft_chain_attr_get_data(c, attr, &data_len);
314 nft_assert(val, attr, data_len ==
sizeof(int32_t));
316 return val ? *val : 0;
318 EXPORT_SYMBOL(nft_chain_attr_get_s32);
320 uint64_t nft_chain_attr_get_u64(
struct nft_chain *c, uint16_t attr)
323 const uint64_t *val = nft_chain_attr_get_data(c, attr, &data_len);
325 nft_assert(val, attr, data_len ==
sizeof(int64_t));
327 return val ? *val : 0;
329 EXPORT_SYMBOL(nft_chain_attr_get_u64);
331 uint8_t nft_chain_attr_get_u8(
struct nft_chain *c, uint16_t attr)
334 const uint8_t *val = nft_chain_attr_get_data(c, attr, &data_len);
336 nft_assert(val, attr, data_len ==
sizeof(int8_t));
338 return val ? *val : 0;
340 EXPORT_SYMBOL(nft_chain_attr_get_u8);
342 void nft_chain_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nft_chain *c)
344 if (c->flags & (1 << NFT_CHAIN_ATTR_TABLE))
345 mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, c->table);
346 if (c->flags & (1 << NFT_CHAIN_ATTR_NAME))
347 mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, c->name);
348 if ((c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) &&
349 (c->flags & (1 << NFT_CHAIN_ATTR_PRIO))) {
352 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
353 mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(c->hooknum));
354 mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
355 mnl_attr_nest_end(nlh, nest);
357 if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY))
358 mnl_attr_put_u32(nlh, NFTA_CHAIN_POLICY, htonl(c->policy));
359 if ((c->flags & (1 << NFT_CHAIN_ATTR_PACKETS)) &&
360 (c->flags & (1 << NFT_CHAIN_ATTR_BYTES))) {
363 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_COUNTERS);
364 mnl_attr_put_u64(nlh, NFTA_COUNTER_PACKETS, be64toh(c->packets));
365 mnl_attr_put_u64(nlh, NFTA_COUNTER_BYTES, be64toh(c->bytes));
366 mnl_attr_nest_end(nlh, nest);
368 if (c->flags & (1 << NFT_CHAIN_ATTR_HANDLE))
369 mnl_attr_put_u64(nlh, NFTA_CHAIN_HANDLE, be64toh(c->handle));
370 if (c->flags & (1 << NFT_CHAIN_ATTR_TYPE))
371 mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type);
373 EXPORT_SYMBOL(nft_chain_nlmsg_build_payload);
375 static int nft_chain_parse_attr_cb(
const struct nlattr *attr,
void *data)
377 const struct nlattr **tb = data;
378 int type = mnl_attr_get_type(attr);
380 if (mnl_attr_type_valid(attr, NFTA_CHAIN_MAX) < 0)
384 case NFTA_CHAIN_NAME:
385 case NFTA_CHAIN_TABLE:
386 case NFTA_CHAIN_TYPE:
387 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
388 perror(
"mnl_attr_validate");
392 case NFTA_CHAIN_HOOK:
393 case NFTA_CHAIN_COUNTERS:
394 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
395 perror(
"mnl_attr_validate");
399 case NFTA_CHAIN_POLICY:
401 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
402 perror(
"mnl_attr_validate");
406 case NFTA_CHAIN_HANDLE:
407 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
408 perror(
"mnl_attr_validate");
418 static int nft_chain_parse_counters_cb(
const struct nlattr *attr,
void *data)
420 const struct nlattr **tb = data;
421 int type = mnl_attr_get_type(attr);
423 if (mnl_attr_type_valid(attr, NFTA_COUNTER_MAX) < 0)
427 case NFTA_COUNTER_BYTES:
428 case NFTA_COUNTER_PACKETS:
429 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
430 perror(
"mnl_attr_validate");
440 static int nft_chain_parse_counters(
struct nlattr *attr,
struct nft_chain *c)
442 struct nlattr *tb[NFTA_COUNTER_MAX+1] = {};
444 if (mnl_attr_parse_nested(attr, nft_chain_parse_counters_cb, tb) < 0)
447 if (tb[NFTA_COUNTER_PACKETS]) {
448 c->packets = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_PACKETS]));
449 c->flags |= (1 << NFT_CHAIN_ATTR_PACKETS);
451 if (tb[NFTA_COUNTER_BYTES]) {
452 c->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_BYTES]));
453 c->flags |= (1 << NFT_CHAIN_ATTR_BYTES);
458 static int nft_chain_parse_hook_cb(
const struct nlattr *attr,
void *data)
460 const struct nlattr **tb = data;
461 int type = mnl_attr_get_type(attr);
463 if (mnl_attr_type_valid(attr, NFTA_HOOK_MAX) < 0)
467 case NFTA_HOOK_HOOKNUM:
468 case NFTA_HOOK_PRIORITY:
469 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
470 perror(
"mnl_attr_validate");
480 static int nft_chain_parse_hook(
struct nlattr *attr,
struct nft_chain *c)
482 struct nlattr *tb[NFTA_HOOK_MAX+1] = {};
484 if (mnl_attr_parse_nested(attr, nft_chain_parse_hook_cb, tb) < 0)
487 if (tb[NFTA_HOOK_HOOKNUM]) {
488 c->hooknum = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_HOOKNUM]));
489 c->flags |= (1 << NFT_CHAIN_ATTR_HOOKNUM);
491 if (tb[NFTA_HOOK_PRIORITY]) {
492 c->prio = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_PRIORITY]));
493 c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
499 int nft_chain_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nft_chain *c)
501 struct nlattr *tb[NFTA_CHAIN_MAX+1] = {};
502 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
505 if (mnl_attr_parse(nlh,
sizeof(*nfg), nft_chain_parse_attr_cb, tb) < 0)
508 if (tb[NFTA_CHAIN_NAME]) {
509 strncpy(c->name, mnl_attr_get_str(tb[NFTA_CHAIN_NAME]),
510 NFT_CHAIN_MAXNAMELEN);
511 c->flags |= (1 << NFT_CHAIN_ATTR_NAME);
513 if (tb[NFTA_CHAIN_TABLE]) {
514 c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE]));
515 c->flags |= (1 << NFT_CHAIN_ATTR_TABLE);
517 if (tb[NFTA_CHAIN_HOOK]) {
518 ret = nft_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
522 if (tb[NFTA_CHAIN_POLICY]) {
523 c->policy = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_POLICY]));
524 c->flags |= (1 << NFT_CHAIN_ATTR_POLICY);
526 if (tb[NFTA_CHAIN_USE]) {
527 c->use = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_USE]));
528 c->flags |= (1 << NFT_CHAIN_ATTR_USE);
530 if (tb[NFTA_CHAIN_COUNTERS]) {
531 ret = nft_chain_parse_counters(tb[NFTA_CHAIN_COUNTERS], c);
535 if (tb[NFTA_CHAIN_HANDLE]) {
536 c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
537 c->flags |= (1 << NFT_CHAIN_ATTR_HANDLE);
539 if (tb[NFTA_CHAIN_TYPE]) {
540 c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE]));
541 c->flags |= (1 << NFT_CHAIN_ATTR_TYPE);
544 c->family = nfg->nfgen_family;
545 c->flags |= (1 << NFT_CHAIN_ATTR_FAMILY);
549 EXPORT_SYMBOL(nft_chain_nlmsg_parse);
551 static inline int nft_str2hooknum(
int family,
const char *hook)
555 for (hooknum = 0; hooknum < NF_INET_NUMHOOKS; hooknum++) {
556 if (strcmp(hook, nft_hooknum2str(family, hooknum)) == 0)
563 int nft_jansson_parse_chain(
struct nft_chain *c, json_t *tree,
564 struct nft_parse_err *err)
572 root = nft_jansson_get_node(tree,
"chain", err);
576 valstr = nft_jansson_parse_str(root,
"name", err);
580 nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_NAME, valstr);
582 if (nft_jansson_parse_val(root,
"handle", NFT_TYPE_U64, &uval64,
586 nft_chain_attr_set_u64(c,NFT_CHAIN_ATTR_HANDLE, uval64);
588 if (nft_jansson_parse_val(root,
"bytes", NFT_TYPE_U64, &uval64,
592 nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, uval64);
594 if (nft_jansson_parse_val(root,
"packets", NFT_TYPE_U64, &uval64,
598 nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, uval64);
600 if (nft_jansson_parse_family(root, &val32, err) != 0)
603 nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_FAMILY, val32);
605 valstr = nft_jansson_parse_str(root,
"table", err);
610 nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TABLE, valstr);
612 if (nft_jansson_node_exist(root,
"hooknum")) {
613 valstr = nft_jansson_parse_str(root,
"type", err);
618 nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TYPE, valstr);
620 if (nft_jansson_parse_val(root,
"prio", NFT_TYPE_S32,
624 nft_chain_attr_set_s32(c, NFT_CHAIN_ATTR_PRIO, val32);
626 valstr = nft_jansson_parse_str(root,
"hooknum", err);
630 val32 = nft_str2hooknum(c->family, valstr);
634 nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, val32);
636 valstr = nft_jansson_parse_str(root,
"policy", err);
640 if (nft_str2verdict(valstr, &policy) != 0) {
642 err->node_name =
"policy";
643 err->error = NFT_PARSE_EBADTYPE;
647 nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy);
650 nft_jansson_free_root(tree);
654 nft_jansson_free_root(tree);
659 static int nft_chain_json_parse(
struct nft_chain *c,
const void *json,
660 struct nft_parse_err *err,
661 enum nft_parse_input input)
667 tree = nft_jansson_create_root(json, &error, err, input);
671 return nft_jansson_parse_chain(c, tree, err);
679 int nft_mxml_chain_parse(mxml_node_t *tree,
struct nft_chain *c,
680 struct nft_parse_err *err)
682 const char *table, *name, *hooknum_str, *policy_str, *type;
683 int family, hooknum, policy;
685 name = nft_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
690 strncpy(c->name, name, NFT_CHAIN_MAXNAMELEN);
691 c->flags |= (1 << NFT_CHAIN_ATTR_NAME);
693 if (nft_mxml_num_parse(tree,
"handle", MXML_DESCEND_FIRST, BASE_DEC,
694 &c->handle, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
697 c->flags |= (1 << NFT_CHAIN_ATTR_HANDLE);
699 if (nft_mxml_num_parse(tree,
"bytes", MXML_DESCEND_FIRST, BASE_DEC,
700 &c->bytes, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
703 c->flags |= (1 << NFT_CHAIN_ATTR_BYTES);
705 if (nft_mxml_num_parse(tree,
"packets", MXML_DESCEND_FIRST, BASE_DEC,
706 &c->packets, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
709 c->flags |= (1 << NFT_CHAIN_ATTR_PACKETS);
711 table = nft_mxml_str_parse(tree,
"table", MXML_DESCEND_FIRST,
719 c->table = strdup(table);
720 c->flags |= (1 << NFT_CHAIN_ATTR_TABLE);
722 family = nft_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
728 c->flags |= (1 << NFT_CHAIN_ATTR_FAMILY);
730 hooknum_str = nft_mxml_str_parse(tree,
"hooknum", MXML_DESCEND_FIRST,
732 if (hooknum_str != NULL) {
733 hooknum = nft_str2hooknum(c->family, hooknum_str);
737 c->hooknum = hooknum;
738 c->flags |= (1 << NFT_CHAIN_ATTR_HOOKNUM);
740 type = nft_mxml_str_parse(tree,
"type", MXML_DESCEND_FIRST,
748 c->type = strdup(type);
749 c->flags |= (1 << NFT_CHAIN_ATTR_TYPE);
752 if (nft_mxml_num_parse(tree,
"prio", MXML_DESCEND, BASE_DEC,
753 &c->prio, NFT_TYPE_S32,
754 NFT_XML_MAND, err) != 0)
757 c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
759 policy_str = nft_mxml_str_parse(tree,
"policy",
762 if (policy_str == NULL)
765 if (nft_str2verdict(policy_str, &policy) != 0) {
767 err->node_name =
"policy";
768 err->error = NFT_PARSE_EBADTYPE;
773 c->flags |= (1 << NFT_CHAIN_ATTR_POLICY);
780 static int nft_chain_xml_parse(
struct nft_chain *c,
const void *xml,
781 struct nft_parse_err *err,
782 enum nft_parse_input input)
786 mxml_node_t *tree = nft_mxml_build_tree(xml,
"chain", err, input);
790 ret = nft_mxml_chain_parse(tree, c, err);
799 static int nft_chain_do_parse(
struct nft_chain *c,
enum nft_parse_type type,
800 const void *data,
struct nft_parse_err *err,
801 enum nft_parse_input input)
804 struct nft_parse_err perr;
808 ret = nft_chain_xml_parse(c, data, &perr, input);
811 ret = nft_chain_json_parse(c, data, &perr, input);
825 int nft_chain_parse(
struct nft_chain *c,
enum nft_parse_type type,
826 const char *data,
struct nft_parse_err *err)
828 return nft_chain_do_parse(c, type, data, err, NFT_PARSE_BUFFER);
830 EXPORT_SYMBOL(nft_chain_parse);
832 int nft_chain_parse_file(
struct nft_chain *c,
enum nft_parse_type type,
833 FILE *fp,
struct nft_parse_err *err)
835 return nft_chain_do_parse(c, type, fp, err, NFT_PARSE_FILE);
837 EXPORT_SYMBOL(nft_chain_parse_file);
839 static int nft_chain_snprintf_json(
char *buf,
size_t size,
struct nft_chain *c)
841 int ret, len = size, offset = 0;
843 ret = snprintf(buf, len,
846 "\"handle\":%"PRIu64
","
847 "\"bytes\":%"PRIu64
","
848 "\"packets\":%"PRIu64
","
852 c->name, c->handle, c->bytes, c->packets,
853 nft_family2str(c->family),
855 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
857 if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) {
858 ret = snprintf(buf+offset, len,
860 "\"hooknum\":\"%s\","
863 c->type, nft_hooknum2str(c->family, c->hooknum),
864 c->prio, nft_verdict2str(c->policy));
865 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
868 ret = snprintf(buf+offset, len,
"}}");
869 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
874 static int nft_chain_snprintf_xml(
char *buf,
size_t size,
struct nft_chain *c)
876 int ret, len = size, offset = 0;
878 ret = snprintf(buf, len,
"<chain><name>%s</name>"
879 "<handle>%"PRIu64
"</handle><bytes>%"PRIu64
"</bytes>"
880 "<packets>%"PRIu64
"</packets><table>%s</table>",
881 c->name, c->handle, c->bytes, c->packets, c->table);
882 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
884 if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) {
885 ret = snprintf(buf+offset, len,
887 "<hooknum>%s</hooknum>"
889 "<policy>%s</policy>",
890 c->type, nft_hooknum2str(c->family, c->hooknum),
891 c->prio, nft_verdict2str(c->policy));
892 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
895 ret = snprintf(buf+offset, len,
"<family>%s</family></chain>",
896 nft_family2str(c->family));
897 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
902 static int nft_chain_snprintf_default(
char *buf,
size_t size,
905 int ret, len = size, offset = 0;
907 ret = snprintf(buf, len,
"%s %s %s use %u",
908 nft_family2str(c->family), c->table, c->name, c->use);
909 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
911 if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) {
912 ret = snprintf(buf+offset, len,
913 " type %s hook %s prio %d policy %s "
914 "packets %"PRIu64
" bytes %"PRIu64
"",
915 c->type, nft_hooknum2str(c->family, c->hooknum),
916 c->prio, nft_verdict2str(c->policy),
917 c->packets, c->bytes);
918 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
924 int nft_chain_snprintf(
char *buf,
size_t size,
struct nft_chain *c,
925 uint32_t type, uint32_t flags)
927 int ret, len = size, offset = 0;
929 ret = nft_event_header_snprintf(buf+offset, len, type, flags);
930 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
933 case NFT_OUTPUT_DEFAULT:
934 ret = nft_chain_snprintf_default(buf+offset, len, c);
937 ret = nft_chain_snprintf_xml(buf+offset, len, c);
939 case NFT_OUTPUT_JSON:
940 ret = nft_chain_snprintf_json(buf+offset, len, c);
946 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
948 ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
949 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
953 EXPORT_SYMBOL(nft_chain_snprintf);
955 static inline int nft_chain_do_snprintf(
char *buf,
size_t size,
void *c,
956 uint32_t type, uint32_t flags)
958 return nft_chain_snprintf(buf, size, c, type, flags);
961 int nft_chain_fprintf(FILE *fp,
struct nft_chain *c, uint32_t type,
964 return nft_fprintf(fp, c, type, flags, nft_chain_do_snprintf);
966 EXPORT_SYMBOL(nft_chain_fprintf);
969 struct list_head list;
980 INIT_LIST_HEAD(&list->list);
984 EXPORT_SYMBOL(nft_chain_list_alloc);
990 list_for_each_entry_safe(r, tmp, &list->list, head) {
996 EXPORT_SYMBOL(nft_chain_list_free);
1000 return list_empty(&list->list);
1002 EXPORT_SYMBOL(nft_chain_list_is_empty);
1006 list_add(&r->head, &list->list);
1008 EXPORT_SYMBOL(nft_chain_list_add);
1012 list_add_tail(&r->head, &list->list);
1014 EXPORT_SYMBOL(nft_chain_list_add_tail);
1016 void nft_chain_list_del(
struct nft_chain *r)
1020 EXPORT_SYMBOL(nft_chain_list_del);
1023 int (*cb)(
struct nft_chain *r,
void *data),
1029 list_for_each_entry_safe(cur, tmp, &chain_list->list, head) {
1030 ret = cb(cur, data);
1036 EXPORT_SYMBOL(nft_chain_list_foreach);
1052 iter->cur = list_entry(l->list.next,
struct nft_chain, head);
1056 EXPORT_SYMBOL(nft_chain_list_iter_create);
1063 iter->cur = list_entry(iter->cur->head.next,
struct nft_chain, head);
1064 if (&iter->cur->head == iter->list->list.next)
1069 EXPORT_SYMBOL(nft_chain_list_iter_next);
1075 EXPORT_SYMBOL(nft_chain_list_iter_destroy);