15#include <netinet/in.h>
19#include <libmnl/libmnl.h>
20#include <linux/netfilter/nfnetlink.h>
21#include <linux/netfilter/nf_tables.h>
22#include <linux/netfilter.h>
23#include <linux/netfilter_arp.h>
25#include <libnftnl/chain.h>
26#include <libnftnl/rule.h>
29 struct list_head head;
30 struct hlist_node hnode;
36 struct nftnl_str_array dev_array;
54 struct list_head rule_list;
57static const char *nftnl_hooknum2str(
int family,
int hooknum)
65 case NF_INET_PRE_ROUTING:
67 case NF_INET_LOCAL_IN:
71 case NF_INET_LOCAL_OUT:
73 case NF_INET_POST_ROUTING:
89 case NF_NETDEV_INGRESS:
97EXPORT_SYMBOL(nftnl_chain_alloc);
106 INIT_LIST_HEAD(&c->rule_list);
111EXPORT_SYMBOL(nftnl_chain_free);
114 struct nftnl_rule *r, *tmp;
116 list_for_each_entry_safe(r, tmp, &c->rule_list, head)
119 if (c->flags & (1 << NFTNL_CHAIN_NAME))
121 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
123 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
125 if (c->flags & (1 << NFTNL_CHAIN_DEV))
127 if (c->flags & (1 << NFTNL_CHAIN_USERDATA))
129 if (c->flags & (1 << NFTNL_CHAIN_DEVICES))
130 nftnl_str_array_clear((
struct nftnl_str_array *)&c->dev_array);
134EXPORT_SYMBOL(nftnl_chain_is_set);
135bool nftnl_chain_is_set(
const struct nftnl_chain *c, uint16_t attr)
137 return c->flags & (1 << attr);
140EXPORT_SYMBOL(nftnl_chain_unset);
141void nftnl_chain_unset(
struct nftnl_chain *c, uint16_t attr)
143 if (!(c->flags & (1 << attr)))
147 case NFTNL_CHAIN_NAME:
150 case NFTNL_CHAIN_TABLE:
153 case NFTNL_CHAIN_USE:
155 case NFTNL_CHAIN_TYPE:
158 case NFTNL_CHAIN_HOOKNUM:
159 case NFTNL_CHAIN_PRIO:
160 case NFTNL_CHAIN_POLICY:
161 case NFTNL_CHAIN_BYTES:
162 case NFTNL_CHAIN_PACKETS:
163 case NFTNL_CHAIN_HANDLE:
164 case NFTNL_CHAIN_FAMILY:
165 case NFTNL_CHAIN_FLAGS:
168 case NFTNL_CHAIN_DEV:
171 case NFTNL_CHAIN_DEVICES:
172 nftnl_str_array_clear(&c->dev_array);
174 case NFTNL_CHAIN_USERDATA:
181 c->flags &= ~(1 << attr);
184static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = {
185 [NFTNL_CHAIN_HOOKNUM] =
sizeof(uint32_t),
186 [NFTNL_CHAIN_PRIO] =
sizeof(int32_t),
187 [NFTNL_CHAIN_POLICY] =
sizeof(uint32_t),
188 [NFTNL_CHAIN_USE] =
sizeof(uint32_t),
189 [NFTNL_CHAIN_BYTES] =
sizeof(uint64_t),
190 [NFTNL_CHAIN_PACKETS] =
sizeof(uint64_t),
191 [NFTNL_CHAIN_HANDLE] =
sizeof(uint64_t),
192 [NFTNL_CHAIN_FAMILY] =
sizeof(uint32_t),
193 [NFTNL_CHAIN_FLAGS] =
sizeof(uint32_t),
194 [NFTNL_CHAIN_ID] =
sizeof(uint32_t),
197EXPORT_SYMBOL(nftnl_chain_set_data);
198int nftnl_chain_set_data(
struct nftnl_chain *c, uint16_t attr,
199 const void *data, uint32_t data_len)
201 nftnl_assert_attr_exists(attr, NFTNL_CHAIN_MAX);
202 nftnl_assert_validate(data, nftnl_chain_validate, attr, data_len);
205 case NFTNL_CHAIN_NAME:
206 return nftnl_set_str_attr(&c->name, &c->flags,
207 attr, data, data_len);
208 case NFTNL_CHAIN_TABLE:
209 return nftnl_set_str_attr(&c->table, &c->flags,
210 attr, data, data_len);
211 case NFTNL_CHAIN_HOOKNUM:
212 memcpy(&c->hooknum, data,
sizeof(c->hooknum));
214 case NFTNL_CHAIN_PRIO:
215 memcpy(&c->prio, data,
sizeof(c->prio));
217 case NFTNL_CHAIN_POLICY:
218 memcpy(&c->policy, data,
sizeof(c->policy));
220 case NFTNL_CHAIN_USE:
221 memcpy(&c->use, data,
sizeof(c->use));
223 case NFTNL_CHAIN_BYTES:
224 memcpy(&c->bytes, data,
sizeof(c->bytes));
226 case NFTNL_CHAIN_PACKETS:
227 memcpy(&c->packets, data,
sizeof(c->packets));
229 case NFTNL_CHAIN_HANDLE:
230 memcpy(&c->handle, data,
sizeof(c->handle));
232 case NFTNL_CHAIN_FAMILY:
233 memcpy(&c->family, data,
sizeof(c->family));
235 case NFTNL_CHAIN_TYPE:
236 return nftnl_set_str_attr(&c->type, &c->flags,
237 attr, data, data_len);
238 case NFTNL_CHAIN_DEV:
239 return nftnl_set_str_attr(&c->dev, &c->flags,
240 attr, data, data_len);
241 case NFTNL_CHAIN_DEVICES:
242 if (nftnl_str_array_set(&c->dev_array, data) < 0)
245 case NFTNL_CHAIN_FLAGS:
246 memcpy(&c->chain_flags, data,
sizeof(c->chain_flags));
249 memcpy(&c->chain_id, data,
sizeof(c->chain_id));
251 case NFTNL_CHAIN_USERDATA:
252 if (c->flags & (1 << NFTNL_CHAIN_USERDATA))
255 c->user.data = malloc(data_len);
258 memcpy(c->user.data, data, data_len);
259 c->user.len = data_len;
262 c->flags |= (1 << attr);
266void nftnl_chain_set(
struct nftnl_chain *c, uint16_t attr,
const void *data) __visible;
267void nftnl_chain_set(
struct nftnl_chain *c, uint16_t attr,
const void *data)
269 nftnl_chain_set_data(c, attr, data, nftnl_chain_validate[attr]);
272EXPORT_SYMBOL(nftnl_chain_set_u32);
273void nftnl_chain_set_u32(
struct nftnl_chain *c, uint16_t attr, uint32_t data)
275 nftnl_chain_set_data(c, attr, &data,
sizeof(uint32_t));
278EXPORT_SYMBOL(nftnl_chain_set_s32);
279void nftnl_chain_set_s32(
struct nftnl_chain *c, uint16_t attr, int32_t data)
281 nftnl_chain_set_data(c, attr, &data,
sizeof(int32_t));
284EXPORT_SYMBOL(nftnl_chain_set_u64);
285void nftnl_chain_set_u64(
struct nftnl_chain *c, uint16_t attr, uint64_t data)
287 nftnl_chain_set_data(c, attr, &data,
sizeof(uint64_t));
290EXPORT_SYMBOL(nftnl_chain_set_u8);
291void nftnl_chain_set_u8(
struct nftnl_chain *c, uint16_t attr, uint8_t data)
293 nftnl_chain_set_data(c, attr, &data,
sizeof(uint8_t));
296EXPORT_SYMBOL(nftnl_chain_set_str);
297int nftnl_chain_set_str(
struct nftnl_chain *c, uint16_t attr,
const char *str)
299 return nftnl_chain_set_data(c, attr, str, strlen(str) + 1);
302EXPORT_SYMBOL(nftnl_chain_set_array);
303int nftnl_chain_set_array(
struct nftnl_chain *c, uint16_t attr,
306 return nftnl_chain_set_data(c, attr, data, 0);
309EXPORT_SYMBOL(nftnl_chain_get_data);
310const void *nftnl_chain_get_data(
const struct nftnl_chain *c, uint16_t attr,
313 if (!(c->flags & (1 << attr)))
317 case NFTNL_CHAIN_NAME:
318 *data_len = strlen(c->name) + 1;
320 case NFTNL_CHAIN_TABLE:
321 *data_len = strlen(c->table) + 1;
323 case NFTNL_CHAIN_HOOKNUM:
324 *data_len =
sizeof(uint32_t);
326 case NFTNL_CHAIN_PRIO:
327 *data_len =
sizeof(int32_t);
329 case NFTNL_CHAIN_POLICY:
330 *data_len =
sizeof(uint32_t);
332 case NFTNL_CHAIN_USE:
333 *data_len =
sizeof(uint32_t);
335 case NFTNL_CHAIN_BYTES:
336 *data_len =
sizeof(uint64_t);
338 case NFTNL_CHAIN_PACKETS:
339 *data_len =
sizeof(uint64_t);
341 case NFTNL_CHAIN_HANDLE:
342 *data_len =
sizeof(uint64_t);
344 case NFTNL_CHAIN_FAMILY:
345 *data_len =
sizeof(uint32_t);
347 case NFTNL_CHAIN_TYPE:
348 *data_len =
sizeof(uint32_t);
350 case NFTNL_CHAIN_DEV:
351 *data_len = strlen(c->dev) + 1;
353 case NFTNL_CHAIN_DEVICES:
355 return c->dev_array.array;
356 case NFTNL_CHAIN_FLAGS:
357 *data_len =
sizeof(uint32_t);
358 return &c->chain_flags;
360 *data_len =
sizeof(uint32_t);
362 case NFTNL_CHAIN_USERDATA:
363 *data_len = c->user.len;
369EXPORT_SYMBOL(nftnl_chain_get);
370const void *nftnl_chain_get(
const struct nftnl_chain *c, uint16_t attr)
373 return nftnl_chain_get_data(c, attr, &data_len);
376EXPORT_SYMBOL(nftnl_chain_get_str);
377const char *nftnl_chain_get_str(
const struct nftnl_chain *c, uint16_t attr)
379 return nftnl_chain_get(c, attr);
382EXPORT_SYMBOL(nftnl_chain_get_u32);
383uint32_t nftnl_chain_get_u32(
const struct nftnl_chain *c, uint16_t attr)
386 const uint32_t *val = nftnl_chain_get_data(c, attr, &data_len);
388 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
390 return val ? *val : 0;
393EXPORT_SYMBOL(nftnl_chain_get_s32);
394int32_t nftnl_chain_get_s32(
const struct nftnl_chain *c, uint16_t attr)
397 const int32_t *val = nftnl_chain_get_data(c, attr, &data_len);
399 nftnl_assert(val, attr, data_len ==
sizeof(int32_t));
401 return val ? *val : 0;
404EXPORT_SYMBOL(nftnl_chain_get_u64);
405uint64_t nftnl_chain_get_u64(
const struct nftnl_chain *c, uint16_t attr)
408 const uint64_t *val = nftnl_chain_get_data(c, attr, &data_len);
410 nftnl_assert(val, attr, data_len ==
sizeof(int64_t));
412 return val ? *val : 0;
415EXPORT_SYMBOL(nftnl_chain_get_u8);
416uint8_t nftnl_chain_get_u8(
const struct nftnl_chain *c, uint16_t attr)
419 const uint8_t *val = nftnl_chain_get_data(c, attr, &data_len);
421 nftnl_assert(val, attr, data_len ==
sizeof(int8_t));
423 return val ? *val : 0;
426EXPORT_SYMBOL(nftnl_chain_get_array);
427const char *
const *nftnl_chain_get_array(
const struct nftnl_chain *c, uint16_t attr)
430 const char *
const *val = nftnl_chain_get_data(c, attr, &data_len);
432 nftnl_assert(val, attr, attr == NFTNL_CHAIN_DEVICES);
437EXPORT_SYMBOL(nftnl_chain_nlmsg_build_payload);
438void nftnl_chain_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nftnl_chain *c)
440 struct nlattr *nest = NULL;
443 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
444 mnl_attr_put_strz(nlh, NFTA_CHAIN_TABLE, c->table);
445 if (c->flags & (1 << NFTNL_CHAIN_NAME))
446 mnl_attr_put_strz(nlh, NFTA_CHAIN_NAME, c->name);
448 if ((c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) ||
449 (c->flags & (1 << NFTNL_CHAIN_PRIO)) ||
450 (c->flags & (1 << NFTNL_CHAIN_DEV)) ||
451 (c->flags & (1 << NFTNL_CHAIN_DEVICES)))
452 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_HOOK);
454 if ((c->flags & (1 << NFTNL_CHAIN_HOOKNUM)))
455 mnl_attr_put_u32(nlh, NFTA_HOOK_HOOKNUM, htonl(c->hooknum));
456 if ((c->flags & (1 << NFTNL_CHAIN_PRIO)))
457 mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
459 if (c->flags & (1 << NFTNL_CHAIN_DEV))
460 mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev);
461 else if (c->flags & (1 << NFTNL_CHAIN_DEVICES)) {
462 struct nlattr *nest_dev;
465 nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
466 nftnl_str_array_foreach(dev, &c->dev_array, i)
467 nftnl_attr_put_ifname(nlh, dev);
468 mnl_attr_nest_end(nlh, nest_dev);
471 if ((c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) ||
472 (c->flags & (1 << NFTNL_CHAIN_PRIO)) ||
473 (c->flags & (1 << NFTNL_CHAIN_DEV)) ||
474 (c->flags & (1 << NFTNL_CHAIN_DEVICES)))
475 mnl_attr_nest_end(nlh, nest);
477 if (c->flags & (1 << NFTNL_CHAIN_POLICY))
478 mnl_attr_put_u32(nlh, NFTA_CHAIN_POLICY, htonl(c->policy));
479 if (c->flags & (1 << NFTNL_CHAIN_USE))
480 mnl_attr_put_u32(nlh, NFTA_CHAIN_USE, htonl(c->use));
481 if ((c->flags & (1 << NFTNL_CHAIN_PACKETS)) &&
482 (c->flags & (1 << NFTNL_CHAIN_BYTES))) {
483 nest = mnl_attr_nest_start(nlh, NFTA_CHAIN_COUNTERS);
484 mnl_attr_put_u64(nlh, NFTA_COUNTER_PACKETS, be64toh(c->packets));
485 mnl_attr_put_u64(nlh, NFTA_COUNTER_BYTES, be64toh(c->bytes));
486 mnl_attr_nest_end(nlh, nest);
488 if (c->flags & (1 << NFTNL_CHAIN_HANDLE))
489 mnl_attr_put_u64(nlh, NFTA_CHAIN_HANDLE, be64toh(c->handle));
490 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
491 mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type);
492 if (c->flags & (1 << NFTNL_CHAIN_FLAGS))
493 mnl_attr_put_u32(nlh, NFTA_CHAIN_FLAGS, htonl(c->chain_flags));
494 if (c->flags & (1 << NFTNL_CHAIN_ID))
495 mnl_attr_put_u32(nlh, NFTA_CHAIN_ID, htonl(c->chain_id));
496 if (c->flags & (1 << NFTNL_CHAIN_USERDATA))
497 mnl_attr_put(nlh, NFTA_CHAIN_USERDATA, c->user.len, c->user.data);
500EXPORT_SYMBOL(nftnl_chain_rule_add);
501void nftnl_chain_rule_add(
struct nftnl_rule *rule,
struct nftnl_chain *c)
503 list_add(&rule->head, &c->rule_list);
506EXPORT_SYMBOL(nftnl_chain_rule_del);
507void nftnl_chain_rule_del(
struct nftnl_rule *r)
512EXPORT_SYMBOL(nftnl_chain_rule_add_tail);
513void nftnl_chain_rule_add_tail(
struct nftnl_rule *rule,
struct nftnl_chain *c)
515 list_add_tail(&rule->head, &c->rule_list);
518EXPORT_SYMBOL(nftnl_chain_rule_insert_at);
519void nftnl_chain_rule_insert_at(
struct nftnl_rule *rule,
struct nftnl_rule *pos)
521 list_add_tail(&rule->head, &pos->head);
524EXPORT_SYMBOL(nftnl_chain_rule_append_at);
525void nftnl_chain_rule_append_at(
struct nftnl_rule *rule,
struct nftnl_rule *pos)
527 list_add(&rule->head, &pos->head);
530static int nftnl_chain_parse_attr_cb(
const struct nlattr *attr,
void *data)
532 const struct nlattr **tb = data;
533 int type = mnl_attr_get_type(attr);
535 if (mnl_attr_type_valid(attr, NFTA_CHAIN_MAX) < 0)
539 case NFTA_CHAIN_NAME:
540 case NFTA_CHAIN_TABLE:
541 case NFTA_CHAIN_TYPE:
542 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
545 case NFTA_CHAIN_HOOK:
546 case NFTA_CHAIN_COUNTERS:
547 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
550 case NFTA_CHAIN_POLICY:
552 case NFTA_CHAIN_FLAGS:
554 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
557 case NFTA_CHAIN_HANDLE:
558 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
561 case NFTA_CHAIN_USERDATA:
562 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
571static int nftnl_chain_parse_counters_cb(
const struct nlattr *attr,
void *data)
573 const struct nlattr **tb = data;
574 int type = mnl_attr_get_type(attr);
576 if (mnl_attr_type_valid(attr, NFTA_COUNTER_MAX) < 0)
580 case NFTA_COUNTER_BYTES:
581 case NFTA_COUNTER_PACKETS:
582 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
591static int nftnl_chain_parse_counters(
struct nlattr *attr,
struct nftnl_chain *c)
593 struct nlattr *tb[NFTA_COUNTER_MAX+1] = {};
595 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_counters_cb, tb) < 0)
598 if (tb[NFTA_COUNTER_PACKETS]) {
599 c->packets = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_PACKETS]));
600 c->flags |= (1 << NFTNL_CHAIN_PACKETS);
602 if (tb[NFTA_COUNTER_BYTES]) {
603 c->bytes = be64toh(mnl_attr_get_u64(tb[NFTA_COUNTER_BYTES]));
604 c->flags |= (1 << NFTNL_CHAIN_BYTES);
610static int nftnl_chain_parse_hook_cb(
const struct nlattr *attr,
void *data)
612 const struct nlattr **tb = data;
613 int type = mnl_attr_get_type(attr);
615 if (mnl_attr_type_valid(attr, NFTA_HOOK_MAX) < 0)
619 case NFTA_HOOK_HOOKNUM:
620 case NFTA_HOOK_PRIORITY:
621 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
625 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
634static int nftnl_chain_parse_hook(
struct nlattr *attr,
struct nftnl_chain *c)
636 struct nlattr *tb[NFTA_HOOK_MAX+1] = {};
639 if (mnl_attr_parse_nested(attr, nftnl_chain_parse_hook_cb, tb) < 0)
642 if (tb[NFTA_HOOK_HOOKNUM]) {
643 c->hooknum = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_HOOKNUM]));
644 c->flags |= (1 << NFTNL_CHAIN_HOOKNUM);
646 if (tb[NFTA_HOOK_PRIORITY]) {
647 c->prio = ntohl(mnl_attr_get_u32(tb[NFTA_HOOK_PRIORITY]));
648 c->flags |= (1 << NFTNL_CHAIN_PRIO);
650 if (tb[NFTA_HOOK_DEV]) {
651 if (c->flags & (1 << NFTNL_CHAIN_DEV))
653 c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
656 c->flags |= (1 << NFTNL_CHAIN_DEV);
658 if (tb[NFTA_HOOK_DEVS]) {
659 ret = nftnl_parse_devs(&c->dev_array, tb[NFTA_HOOK_DEVS]);
662 c->flags |= (1 << NFTNL_CHAIN_DEVICES);
668EXPORT_SYMBOL(nftnl_chain_nlmsg_parse);
669int nftnl_chain_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_chain *c)
671 struct nlattr *tb[NFTA_CHAIN_MAX+1] = {};
672 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
675 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0)
678 if (nftnl_parse_str_attr(tb[NFTA_CHAIN_NAME], NFTNL_CHAIN_NAME,
679 &c->name, &c->flags) < 0)
681 if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TABLE], NFTNL_CHAIN_TABLE,
682 &c->table, &c->flags) < 0)
684 if (tb[NFTA_CHAIN_HOOK]) {
685 ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
689 if (tb[NFTA_CHAIN_POLICY]) {
690 c->policy = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_POLICY]));
691 c->flags |= (1 << NFTNL_CHAIN_POLICY);
693 if (tb[NFTA_CHAIN_USE]) {
694 c->use = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_USE]));
695 c->flags |= (1 << NFTNL_CHAIN_USE);
697 if (tb[NFTA_CHAIN_COUNTERS]) {
698 ret = nftnl_chain_parse_counters(tb[NFTA_CHAIN_COUNTERS], c);
702 if (tb[NFTA_CHAIN_HANDLE]) {
703 c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
704 c->flags |= (1 << NFTNL_CHAIN_HANDLE);
706 if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TYPE], NFTNL_CHAIN_TYPE,
707 &c->type, &c->flags) < 0)
709 if (tb[NFTA_CHAIN_FLAGS]) {
710 c->chain_flags = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_FLAGS]));
711 c->flags |= (1 << NFTNL_CHAIN_FLAGS);
713 if (tb[NFTA_CHAIN_ID]) {
714 c->chain_id = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_ID]));
715 c->flags |= (1 << NFTNL_CHAIN_ID);
717 if (tb[NFTA_CHAIN_USERDATA]) {
718 nftnl_chain_set_data(c, NFTNL_CHAIN_USERDATA,
719 mnl_attr_get_payload(tb[NFTA_CHAIN_USERDATA]),
720 mnl_attr_get_payload_len(tb[NFTA_CHAIN_USERDATA]));
723 c->family = nfg->nfgen_family;
724 c->flags |= (1 << NFTNL_CHAIN_FAMILY);
729static int nftnl_chain_snprintf_default(
char *buf,
size_t remain,
732 int ret, offset = 0, i;
735 ret = snprintf(buf, remain,
"%s %s %s use %u",
736 nftnl_family2str(c->family), c->table, c->name, c->use);
737 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
739 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
740 ret = snprintf(buf + offset, remain,
" type %s hook %s prio %d",
741 c->type, nftnl_hooknum2str(c->family, c->hooknum),
743 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
745 if (c->flags & (1 << NFTNL_CHAIN_POLICY)) {
746 ret = snprintf(buf + offset, remain,
" policy %s",
747 nftnl_verdict2str(c->policy));
748 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
751 ret = snprintf(buf + offset, remain,
752 " packets %"PRIu64
" bytes %"PRIu64
"",
753 c->packets, c->bytes);
754 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
756 if (c->flags & (1 << NFTNL_CHAIN_DEV)) {
757 ret = snprintf(buf + offset, remain,
" dev %s ",
759 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
761 if (c->flags & (1 << NFTNL_CHAIN_DEVICES)) {
762 ret = snprintf(buf + offset, remain,
" dev { ");
763 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
765 nftnl_str_array_foreach(dev, &c->dev_array, i) {
766 ret = snprintf(buf + offset, remain,
" %s ",
768 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
770 ret = snprintf(buf + offset, remain,
" } ");
771 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
773 if (c->flags & (1 << NFTNL_CHAIN_FLAGS)) {
774 ret = snprintf(buf + offset, remain,
" flags %x",
776 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
778 if (c->flags & (1 << NFTNL_CHAIN_ID)) {
779 ret = snprintf(buf + offset, remain,
" id %x",
781 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
788static int nftnl_chain_cmd_snprintf(
char *buf,
size_t remain,
790 uint32_t type, uint32_t flags)
794 if (type != NFTNL_OUTPUT_DEFAULT)
797 ret = nftnl_chain_snprintf_default(buf + offset, remain, c);
798 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
802EXPORT_SYMBOL(nftnl_chain_snprintf);
803int nftnl_chain_snprintf(
char *buf,
size_t size,
const struct nftnl_chain *c,
804 uint32_t type, uint32_t flags)
809 return nftnl_chain_cmd_snprintf(buf, size, c, nftnl_flag2cmd(flags),
813static int nftnl_chain_do_snprintf(
char *buf,
size_t size,
const void *c,
814 uint32_t cmd, uint32_t type, uint32_t flags)
816 return nftnl_chain_snprintf(buf, size, c, type, flags);
819EXPORT_SYMBOL(nftnl_chain_fprintf);
820int nftnl_chain_fprintf(FILE *fp,
const struct nftnl_chain *c, uint32_t type,
823 return nftnl_fprintf(fp, c, NFTNL_CMD_UNSPEC, type, flags,
824 nftnl_chain_do_snprintf);
827EXPORT_SYMBOL(nftnl_rule_foreach);
829 int (*cb)(
struct nftnl_rule *r,
void *data),
832 struct nftnl_rule *cur, *tmp;
835 list_for_each_entry_safe(cur, tmp, &c->rule_list, head) {
843EXPORT_SYMBOL(nftnl_rule_lookup_byindex);
845nftnl_rule_lookup_byindex(
struct nftnl_chain *c, uint32_t index)
847 struct nftnl_rule *r;
849 list_for_each_entry(r, &c->rule_list, head) {
859 struct nftnl_rule *cur;
862static void nftnl_rule_iter_init(
const struct nftnl_chain *c,
866 if (list_empty(&c->rule_list))
869 iter->cur = list_entry(c->rule_list.next,
struct nftnl_rule,
873EXPORT_SYMBOL(nftnl_rule_iter_create);
882 nftnl_rule_iter_init(c, iter);
887EXPORT_SYMBOL(nftnl_rule_iter_next);
890 struct nftnl_rule *rule = iter->cur;
896 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
897 if (&iter->cur->head == iter->c->rule_list.next)
903EXPORT_SYMBOL(nftnl_rule_iter_destroy);
909#define CHAIN_NAME_HSIZE 512
913 struct list_head list;
914 struct hlist_head name_hash[CHAIN_NAME_HSIZE];
917EXPORT_SYMBOL(nftnl_chain_list_alloc);
927 INIT_LIST_HEAD(&list->list);
928 for (i = 0; i < CHAIN_NAME_HSIZE; i++)
929 INIT_HLIST_HEAD(&list->name_hash[i]);
934EXPORT_SYMBOL(nftnl_chain_list_free);
939 list_for_each_entry_safe(r, tmp, &list->list, head) {
941 hlist_del(&r->hnode);
947EXPORT_SYMBOL(nftnl_chain_list_is_empty);
950 return list_empty(&list->list);
953static uint32_t djb_hash(
const char *key)
955 uint32_t i, hash = 5381;
957 for (i = 0; i < strlen(key); i++)
958 hash = ((hash << 5) + hash) + key[i];
963EXPORT_SYMBOL(nftnl_chain_list_add);
966 int key = djb_hash(r->name) % CHAIN_NAME_HSIZE;
968 hlist_add_head(&r->hnode, &list->name_hash[key]);
969 list_add(&r->head, &list->list);
972EXPORT_SYMBOL(nftnl_chain_list_add_tail);
975 int key = djb_hash(r->name) % CHAIN_NAME_HSIZE;
977 hlist_add_head(&r->hnode, &list->name_hash[key]);
978 list_add_tail(&r->head, &list->list);
981EXPORT_SYMBOL(nftnl_chain_list_del);
985 hlist_del(&r->hnode);
988EXPORT_SYMBOL(nftnl_chain_list_foreach);
996 list_for_each_entry_safe(cur, tmp, &chain_list->list, head) {
1004EXPORT_SYMBOL(nftnl_chain_list_lookup_byname);
1009 int key = djb_hash(chain) % CHAIN_NAME_HSIZE;
1011 struct hlist_node *n;
1013 hlist_for_each_entry(c, n, &chain_list->name_hash[key], hnode) {
1014 if (!strcmp(chain, c->name))
1025EXPORT_SYMBOL(nftnl_chain_list_iter_create);
1036 if (nftnl_chain_list_is_empty(l))
1039 iter->cur = list_entry(l->list.next,
struct nftnl_chain, head);
1044EXPORT_SYMBOL(nftnl_chain_list_iter_next);
1053 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_chain, head);
1054 if (&iter->cur->head == iter->list->list.next)
1060EXPORT_SYMBOL(nftnl_chain_list_iter_destroy);