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 mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, 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 c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
654 c->flags |= (1 << NFTNL_CHAIN_DEV);
656 if (tb[NFTA_HOOK_DEVS]) {
657 ret = nftnl_parse_devs(&c->dev_array, tb[NFTA_HOOK_DEVS]);
660 c->flags |= (1 << NFTNL_CHAIN_DEVICES);
666EXPORT_SYMBOL(nftnl_chain_nlmsg_parse);
667int nftnl_chain_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_chain *c)
669 struct nlattr *tb[NFTA_CHAIN_MAX+1] = {};
670 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
673 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0)
676 if (tb[NFTA_CHAIN_NAME]) {
677 if (c->flags & (1 << NFTNL_CHAIN_NAME))
679 c->name = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_NAME]));
682 c->flags |= (1 << NFTNL_CHAIN_NAME);
684 if (tb[NFTA_CHAIN_TABLE]) {
685 if (c->flags & (1 << NFTNL_CHAIN_TABLE))
687 c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE]));
690 c->flags |= (1 << NFTNL_CHAIN_TABLE);
692 if (tb[NFTA_CHAIN_HOOK]) {
693 ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
697 if (tb[NFTA_CHAIN_POLICY]) {
698 c->policy = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_POLICY]));
699 c->flags |= (1 << NFTNL_CHAIN_POLICY);
701 if (tb[NFTA_CHAIN_USE]) {
702 c->use = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_USE]));
703 c->flags |= (1 << NFTNL_CHAIN_USE);
705 if (tb[NFTA_CHAIN_COUNTERS]) {
706 ret = nftnl_chain_parse_counters(tb[NFTA_CHAIN_COUNTERS], c);
710 if (tb[NFTA_CHAIN_HANDLE]) {
711 c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
712 c->flags |= (1 << NFTNL_CHAIN_HANDLE);
714 if (tb[NFTA_CHAIN_TYPE]) {
715 if (c->flags & (1 << NFTNL_CHAIN_TYPE))
717 c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE]));
720 c->flags |= (1 << NFTNL_CHAIN_TYPE);
722 if (tb[NFTA_CHAIN_FLAGS]) {
723 c->chain_flags = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_FLAGS]));
724 c->flags |= (1 << NFTNL_CHAIN_FLAGS);
726 if (tb[NFTA_CHAIN_ID]) {
727 c->chain_id = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_ID]));
728 c->flags |= (1 << NFTNL_CHAIN_ID);
730 if (tb[NFTA_CHAIN_USERDATA]) {
731 nftnl_chain_set_data(c, NFTNL_CHAIN_USERDATA,
732 mnl_attr_get_payload(tb[NFTA_CHAIN_USERDATA]),
733 mnl_attr_get_payload_len(tb[NFTA_CHAIN_USERDATA]));
736 c->family = nfg->nfgen_family;
737 c->flags |= (1 << NFTNL_CHAIN_FAMILY);
742static int nftnl_chain_snprintf_default(
char *buf,
size_t remain,
745 int ret, offset = 0, i;
748 ret = snprintf(buf, remain,
"%s %s %s use %u",
749 nftnl_family2str(c->family), c->table, c->name, c->use);
750 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
752 if (c->flags & (1 << NFTNL_CHAIN_HOOKNUM)) {
753 ret = snprintf(buf + offset, remain,
" type %s hook %s prio %d",
754 c->type, nftnl_hooknum2str(c->family, c->hooknum),
756 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
758 if (c->flags & (1 << NFTNL_CHAIN_POLICY)) {
759 ret = snprintf(buf + offset, remain,
" policy %s",
760 nftnl_verdict2str(c->policy));
761 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
764 ret = snprintf(buf + offset, remain,
765 " packets %"PRIu64
" bytes %"PRIu64
"",
766 c->packets, c->bytes);
767 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
769 if (c->flags & (1 << NFTNL_CHAIN_DEV)) {
770 ret = snprintf(buf + offset, remain,
" dev %s ",
772 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
774 if (c->flags & (1 << NFTNL_CHAIN_DEVICES)) {
775 ret = snprintf(buf + offset, remain,
" dev { ");
776 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
778 nftnl_str_array_foreach(dev, &c->dev_array, i) {
779 ret = snprintf(buf + offset, remain,
" %s ",
781 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
783 ret = snprintf(buf + offset, remain,
" } ");
784 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
786 if (c->flags & (1 << NFTNL_CHAIN_FLAGS)) {
787 ret = snprintf(buf + offset, remain,
" flags %x",
789 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
791 if (c->flags & (1 << NFTNL_CHAIN_ID)) {
792 ret = snprintf(buf + offset, remain,
" id %x",
794 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
801static int nftnl_chain_cmd_snprintf(
char *buf,
size_t remain,
803 uint32_t type, uint32_t flags)
807 if (type != NFTNL_OUTPUT_DEFAULT)
810 ret = nftnl_chain_snprintf_default(buf + offset, remain, c);
811 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
815EXPORT_SYMBOL(nftnl_chain_snprintf);
816int nftnl_chain_snprintf(
char *buf,
size_t size,
const struct nftnl_chain *c,
817 uint32_t type, uint32_t flags)
822 return nftnl_chain_cmd_snprintf(buf, size, c, nftnl_flag2cmd(flags),
826static int nftnl_chain_do_snprintf(
char *buf,
size_t size,
const void *c,
827 uint32_t cmd, uint32_t type, uint32_t flags)
829 return nftnl_chain_snprintf(buf, size, c, type, flags);
832EXPORT_SYMBOL(nftnl_chain_fprintf);
833int nftnl_chain_fprintf(FILE *fp,
const struct nftnl_chain *c, uint32_t type,
836 return nftnl_fprintf(fp, c, NFTNL_CMD_UNSPEC, type, flags,
837 nftnl_chain_do_snprintf);
840EXPORT_SYMBOL(nftnl_rule_foreach);
842 int (*cb)(
struct nftnl_rule *r,
void *data),
845 struct nftnl_rule *cur, *tmp;
848 list_for_each_entry_safe(cur, tmp, &c->rule_list, head) {
856EXPORT_SYMBOL(nftnl_rule_lookup_byindex);
858nftnl_rule_lookup_byindex(
struct nftnl_chain *c, uint32_t index)
860 struct nftnl_rule *r;
862 list_for_each_entry(r, &c->rule_list, head) {
872 struct nftnl_rule *cur;
875static void nftnl_rule_iter_init(
const struct nftnl_chain *c,
879 if (list_empty(&c->rule_list))
882 iter->cur = list_entry(c->rule_list.next,
struct nftnl_rule,
886EXPORT_SYMBOL(nftnl_rule_iter_create);
895 nftnl_rule_iter_init(c, iter);
900EXPORT_SYMBOL(nftnl_rule_iter_next);
903 struct nftnl_rule *rule = iter->cur;
909 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_rule, head);
910 if (&iter->cur->head == iter->c->rule_list.next)
916EXPORT_SYMBOL(nftnl_rule_iter_destroy);
922#define CHAIN_NAME_HSIZE 512
926 struct list_head list;
927 struct hlist_head name_hash[CHAIN_NAME_HSIZE];
930EXPORT_SYMBOL(nftnl_chain_list_alloc);
940 INIT_LIST_HEAD(&list->list);
941 for (i = 0; i < CHAIN_NAME_HSIZE; i++)
942 INIT_HLIST_HEAD(&list->name_hash[i]);
947EXPORT_SYMBOL(nftnl_chain_list_free);
952 list_for_each_entry_safe(r, tmp, &list->list, head) {
954 hlist_del(&r->hnode);
960EXPORT_SYMBOL(nftnl_chain_list_is_empty);
963 return list_empty(&list->list);
966static uint32_t djb_hash(
const char *key)
968 uint32_t i, hash = 5381;
970 for (i = 0; i < strlen(key); i++)
971 hash = ((hash << 5) + hash) + key[i];
976EXPORT_SYMBOL(nftnl_chain_list_add);
979 int key = djb_hash(r->name) % CHAIN_NAME_HSIZE;
981 hlist_add_head(&r->hnode, &list->name_hash[key]);
982 list_add(&r->head, &list->list);
985EXPORT_SYMBOL(nftnl_chain_list_add_tail);
988 int key = djb_hash(r->name) % CHAIN_NAME_HSIZE;
990 hlist_add_head(&r->hnode, &list->name_hash[key]);
991 list_add_tail(&r->head, &list->list);
994EXPORT_SYMBOL(nftnl_chain_list_del);
998 hlist_del(&r->hnode);
1001EXPORT_SYMBOL(nftnl_chain_list_foreach);
1009 list_for_each_entry_safe(cur, tmp, &chain_list->list, head) {
1010 ret = cb(cur, data);
1017EXPORT_SYMBOL(nftnl_chain_list_lookup_byname);
1022 int key = djb_hash(chain) % CHAIN_NAME_HSIZE;
1024 struct hlist_node *n;
1026 hlist_for_each_entry(c, n, &chain_list->name_hash[key], hnode) {
1027 if (!strcmp(chain, c->name))
1038EXPORT_SYMBOL(nftnl_chain_list_iter_create);
1049 if (nftnl_chain_list_is_empty(l))
1052 iter->cur = list_entry(l->list.next,
struct nftnl_chain, head);
1057EXPORT_SYMBOL(nftnl_chain_list_iter_next);
1066 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_chain, head);
1067 if (&iter->cur->head == iter->list->list.next)
1073EXPORT_SYMBOL(nftnl_chain_list_iter_destroy);