19 #include <netinet/in.h>
23 #include <libmnl/libmnl.h>
24 #include <linux/netfilter/nfnetlink.h>
25 #include <linux/netfilter/nf_tables.h>
27 #include <libnftnl/set.h>
28 #include <libnftnl/expr.h>
30 EXPORT_SYMBOL(nftnl_set_alloc);
31 struct nftnl_set *nftnl_set_alloc(
void)
35 s = calloc(1,
sizeof(
struct nftnl_set));
39 INIT_LIST_HEAD(&s->element_list);
43 EXPORT_SYMBOL(nftnl_set_free);
44 void nftnl_set_free(
const struct nftnl_set *s)
46 struct nftnl_set_elem *elem, *tmp;
48 if (s->flags & (1 << NFTNL_SET_TABLE))
50 if (s->flags & (1 << NFTNL_SET_NAME))
52 if (s->flags & (1 << NFTNL_SET_USERDATA))
54 if (s->flags & (1 << NFTNL_SET_EXPR))
55 nftnl_expr_free(s->expr);
57 list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
58 list_del(&elem->head);
59 nftnl_set_elem_free(elem);
64 EXPORT_SYMBOL(nftnl_set_is_set);
65 bool nftnl_set_is_set(
const struct nftnl_set *s, uint16_t attr)
67 return s->flags & (1 << attr);
70 EXPORT_SYMBOL(nftnl_set_unset);
71 void nftnl_set_unset(
struct nftnl_set *s, uint16_t attr)
73 if (!(s->flags & (1 << attr)))
83 case NFTNL_SET_HANDLE:
85 case NFTNL_SET_KEY_TYPE:
86 case NFTNL_SET_KEY_LEN:
87 case NFTNL_SET_DATA_TYPE:
88 case NFTNL_SET_DATA_LEN:
89 case NFTNL_SET_OBJ_TYPE:
90 case NFTNL_SET_FAMILY:
92 case NFTNL_SET_POLICY:
93 case NFTNL_SET_DESC_SIZE:
94 case NFTNL_SET_DESC_CONCAT:
95 case NFTNL_SET_TIMEOUT:
96 case NFTNL_SET_GC_INTERVAL:
98 case NFTNL_SET_USERDATA:
102 nftnl_expr_free(s->expr);
108 s->flags &= ~(1 << attr);
111 static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
112 [NFTNL_SET_HANDLE] =
sizeof(uint64_t),
113 [NFTNL_SET_FLAGS] =
sizeof(uint32_t),
114 [NFTNL_SET_KEY_TYPE] =
sizeof(uint32_t),
115 [NFTNL_SET_KEY_LEN] =
sizeof(uint32_t),
116 [NFTNL_SET_DATA_TYPE] =
sizeof(uint32_t),
117 [NFTNL_SET_DATA_LEN] =
sizeof(uint32_t),
118 [NFTNL_SET_OBJ_TYPE] =
sizeof(uint32_t),
119 [NFTNL_SET_FAMILY] =
sizeof(uint32_t),
120 [NFTNL_SET_POLICY] =
sizeof(uint32_t),
121 [NFTNL_SET_DESC_SIZE] =
sizeof(uint32_t),
122 [NFTNL_SET_TIMEOUT] =
sizeof(uint64_t),
123 [NFTNL_SET_GC_INTERVAL] =
sizeof(uint32_t),
126 EXPORT_SYMBOL(nftnl_set_set_data);
127 int nftnl_set_set_data(
struct nftnl_set *s, uint16_t attr,
const void *data,
130 nftnl_assert_attr_exists(attr, NFTNL_SET_MAX);
131 nftnl_assert_validate(data, nftnl_set_validate, attr, data_len);
134 case NFTNL_SET_TABLE:
135 if (s->flags & (1 << NFTNL_SET_TABLE))
138 s->table = strdup(data);
143 if (s->flags & (1 << NFTNL_SET_NAME))
146 s->name = strdup(data);
150 case NFTNL_SET_HANDLE:
151 memcpy(&s->handle, data,
sizeof(s->handle));
153 case NFTNL_SET_FLAGS:
154 memcpy(&s->set_flags, data,
sizeof(s->set_flags));
156 case NFTNL_SET_KEY_TYPE:
157 memcpy(&s->key_type, data,
sizeof(s->key_type));
159 case NFTNL_SET_KEY_LEN:
160 memcpy(&s->key_len, data,
sizeof(s->key_len));
162 case NFTNL_SET_DATA_TYPE:
163 memcpy(&s->data_type, data,
sizeof(s->data_type));
165 case NFTNL_SET_DATA_LEN:
166 memcpy(&s->data_len, data,
sizeof(s->data_len));
168 case NFTNL_SET_OBJ_TYPE:
169 memcpy(&s->obj_type, data,
sizeof(s->obj_type));
171 case NFTNL_SET_FAMILY:
172 memcpy(&s->family, data,
sizeof(s->family));
175 memcpy(&s->id, data,
sizeof(s->id));
177 case NFTNL_SET_POLICY:
178 memcpy(&s->policy, data,
sizeof(s->policy));
180 case NFTNL_SET_DESC_SIZE:
181 memcpy(&s->desc.size, data,
sizeof(s->desc.size));
183 case NFTNL_SET_DESC_CONCAT:
184 memcpy(&s->desc.field_len, data, data_len);
185 while (s->desc.field_len[++s->desc.field_count]);
187 case NFTNL_SET_TIMEOUT:
188 memcpy(&s->timeout, data,
sizeof(s->timeout));
190 case NFTNL_SET_GC_INTERVAL:
191 memcpy(&s->gc_interval, data,
sizeof(s->gc_interval));
193 case NFTNL_SET_USERDATA:
194 if (s->flags & (1 << NFTNL_SET_USERDATA))
197 s->user.data = malloc(data_len);
200 memcpy(s->user.data, data, data_len);
201 s->user.len = data_len;
204 if (s->flags & (1 << NFTNL_SET_EXPR))
205 nftnl_expr_free(s->expr);
207 s->expr = (
void *)data;
210 s->flags |= (1 << attr);
214 int nftnl_set_set(
struct nftnl_set *s, uint16_t attr,
const void *data) __visible;
215 int nftnl_set_set(
struct nftnl_set *s, uint16_t attr,
const void *data)
217 return nftnl_set_set_data(s, attr, data, nftnl_set_validate[attr]);
220 EXPORT_SYMBOL(nftnl_set_set_u32);
221 void nftnl_set_set_u32(
struct nftnl_set *s, uint16_t attr, uint32_t val)
223 nftnl_set_set_data(s, attr, &val,
sizeof(uint32_t));
226 EXPORT_SYMBOL(nftnl_set_set_u64);
227 void nftnl_set_set_u64(
struct nftnl_set *s, uint16_t attr, uint64_t val)
229 nftnl_set_set_data(s, attr, &val,
sizeof(uint64_t));
232 EXPORT_SYMBOL(nftnl_set_set_str);
233 int nftnl_set_set_str(
struct nftnl_set *s, uint16_t attr,
const char *str)
235 return nftnl_set_set_data(s, attr, str, strlen(str) + 1);
238 EXPORT_SYMBOL(nftnl_set_get_data);
239 const void *nftnl_set_get_data(
const struct nftnl_set *s, uint16_t attr,
242 if (!(s->flags & (1 << attr)))
246 case NFTNL_SET_TABLE:
247 *data_len = strlen(s->table) + 1;
250 *data_len = strlen(s->name) + 1;
252 case NFTNL_SET_HANDLE:
253 *data_len =
sizeof(uint64_t);
255 case NFTNL_SET_FLAGS:
256 *data_len =
sizeof(uint32_t);
257 return &s->set_flags;
258 case NFTNL_SET_KEY_TYPE:
259 *data_len =
sizeof(uint32_t);
261 case NFTNL_SET_KEY_LEN:
262 *data_len =
sizeof(uint32_t);
264 case NFTNL_SET_DATA_TYPE:
265 *data_len =
sizeof(uint32_t);
266 return &s->data_type;
267 case NFTNL_SET_DATA_LEN:
268 *data_len =
sizeof(uint32_t);
270 case NFTNL_SET_OBJ_TYPE:
271 *data_len =
sizeof(uint32_t);
273 case NFTNL_SET_FAMILY:
274 *data_len =
sizeof(uint32_t);
277 *data_len =
sizeof(uint32_t);
279 case NFTNL_SET_POLICY:
280 *data_len =
sizeof(uint32_t);
282 case NFTNL_SET_DESC_SIZE:
283 *data_len =
sizeof(uint32_t);
284 return &s->desc.size;
285 case NFTNL_SET_DESC_CONCAT:
286 *data_len = s->desc.field_count;
287 return s->desc.field_len;
288 case NFTNL_SET_TIMEOUT:
289 *data_len =
sizeof(uint64_t);
291 case NFTNL_SET_GC_INTERVAL:
292 *data_len =
sizeof(uint32_t);
293 return &s->gc_interval;
294 case NFTNL_SET_USERDATA:
295 *data_len = s->user.len;
303 EXPORT_SYMBOL(nftnl_set_get);
304 const void *nftnl_set_get(
const struct nftnl_set *s, uint16_t attr)
307 return nftnl_set_get_data(s, attr, &data_len);
310 EXPORT_SYMBOL(nftnl_set_get_str);
311 const char *nftnl_set_get_str(
const struct nftnl_set *s, uint16_t attr)
313 return nftnl_set_get(s, attr);
316 EXPORT_SYMBOL(nftnl_set_get_u32);
317 uint32_t nftnl_set_get_u32(
const struct nftnl_set *s, uint16_t attr)
320 const uint32_t *val = nftnl_set_get_data(s, attr, &data_len);
322 nftnl_assert(val, attr, data_len ==
sizeof(uint32_t));
324 return val ? *val : 0;
327 EXPORT_SYMBOL(nftnl_set_get_u64);
328 uint64_t nftnl_set_get_u64(
const struct nftnl_set *s, uint16_t attr)
331 const uint64_t *val = nftnl_set_get_data(s, attr, &data_len);
333 nftnl_assert(val, attr, data_len ==
sizeof(uint64_t));
335 return val ? *val : 0;
338 struct nftnl_set *nftnl_set_clone(
const struct nftnl_set *set)
340 struct nftnl_set *newset;
341 struct nftnl_set_elem *elem, *newelem;
343 newset = nftnl_set_alloc();
347 memcpy(newset, set,
sizeof(*set));
349 if (set->flags & (1 << NFTNL_SET_TABLE)) {
350 newset->table = strdup(set->table);
354 if (set->flags & (1 << NFTNL_SET_NAME)) {
355 newset->name = strdup(set->name);
360 INIT_LIST_HEAD(&newset->element_list);
361 list_for_each_entry(elem, &set->element_list, head) {
362 newelem = nftnl_set_elem_clone(elem);
366 list_add_tail(&newelem->head, &newset->element_list);
371 nftnl_set_free(newset);
375 static void nftnl_set_nlmsg_build_desc_size_payload(
struct nlmsghdr *nlh,
378 mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
381 static void nftnl_set_nlmsg_build_desc_concat_payload(
struct nlmsghdr *nlh,
387 nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC_CONCAT);
388 for (i = 0; i < NFT_REG32_COUNT && i < s->desc.field_count; i++) {
389 struct nlattr *nest_elem;
391 nest_elem = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
392 mnl_attr_put_u32(nlh, NFTA_SET_FIELD_LEN,
393 htonl(s->desc.field_len[i]));
394 mnl_attr_nest_end(nlh, nest_elem);
396 mnl_attr_nest_end(nlh, nest);
400 nftnl_set_nlmsg_build_desc_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
404 nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC);
406 if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
407 nftnl_set_nlmsg_build_desc_size_payload(nlh, s);
408 if (s->flags & (1 << NFTNL_SET_DESC_CONCAT))
409 nftnl_set_nlmsg_build_desc_concat_payload(nlh, s);
411 mnl_attr_nest_end(nlh, nest);
414 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload);
415 void nftnl_set_nlmsg_build_payload(
struct nlmsghdr *nlh,
struct nftnl_set *s)
417 if (s->flags & (1 << NFTNL_SET_TABLE))
418 mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
419 if (s->flags & (1 << NFTNL_SET_NAME))
420 mnl_attr_put_strz(nlh, NFTA_SET_NAME, s->name);
421 if (s->flags & (1 << NFTNL_SET_HANDLE))
422 mnl_attr_put_u64(nlh, NFTA_SET_HANDLE, htobe64(s->handle));
423 if (s->flags & (1 << NFTNL_SET_FLAGS))
424 mnl_attr_put_u32(nlh, NFTA_SET_FLAGS, htonl(s->set_flags));
425 if (s->flags & (1 << NFTNL_SET_KEY_TYPE))
426 mnl_attr_put_u32(nlh, NFTA_SET_KEY_TYPE, htonl(s->key_type));
427 if (s->flags & (1 << NFTNL_SET_KEY_LEN))
428 mnl_attr_put_u32(nlh, NFTA_SET_KEY_LEN, htonl(s->key_len));
430 if (s->flags & (1 << NFTNL_SET_DATA_TYPE))
431 mnl_attr_put_u32(nlh, NFTA_SET_DATA_TYPE, htonl(s->data_type));
432 if (s->flags & (1 << NFTNL_SET_DATA_LEN))
433 mnl_attr_put_u32(nlh, NFTA_SET_DATA_LEN, htonl(s->data_len));
434 if (s->flags & (1 << NFTNL_SET_OBJ_TYPE))
435 mnl_attr_put_u32(nlh, NFTA_SET_OBJ_TYPE, htonl(s->obj_type));
436 if (s->flags & (1 << NFTNL_SET_ID))
437 mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
438 if (s->flags & (1 << NFTNL_SET_POLICY))
439 mnl_attr_put_u32(nlh, NFTA_SET_POLICY, htonl(s->policy));
440 if (s->flags & (1 << NFTNL_SET_DESC_SIZE | 1 << NFTNL_SET_DESC_CONCAT))
441 nftnl_set_nlmsg_build_desc_payload(nlh, s);
442 if (s->flags & (1 << NFTNL_SET_TIMEOUT))
443 mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
444 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL))
445 mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
446 if (s->flags & (1 << NFTNL_SET_USERDATA))
447 mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
448 if (s->flags & (1 << NFTNL_SET_EXPR)) {
449 struct nlattr *nest1;
451 nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPR);
452 nftnl_expr_build_payload(nlh, s->expr);
453 mnl_attr_nest_end(nlh, nest1);
458 static int nftnl_set_parse_attr_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_SET_MAX) < 0)
469 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
472 case NFTA_SET_HANDLE:
473 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
477 case NFTA_SET_KEY_TYPE:
478 case NFTA_SET_KEY_LEN:
479 case NFTA_SET_DATA_TYPE:
480 case NFTA_SET_DATA_LEN:
482 case NFTA_SET_POLICY:
483 case NFTA_SET_GC_INTERVAL:
484 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
487 case NFTA_SET_USERDATA:
488 if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
491 case NFTA_SET_TIMEOUT:
492 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
496 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
506 nftnl_set_desc_concat_field_parse_attr_cb(
const struct nlattr *attr,
void *data)
508 int type = mnl_attr_get_type(attr);
509 struct nftnl_set *s = data;
511 if (type != NFTA_SET_FIELD_LEN)
514 if (mnl_attr_validate(attr, MNL_TYPE_U32))
517 s->desc.field_len[s->desc.field_count] = ntohl(mnl_attr_get_u32(attr));
518 s->desc.field_count++;
524 nftnl_set_desc_concat_parse_attr_cb(
const struct nlattr *attr,
void *data)
526 int type = mnl_attr_get_type(attr);
527 struct nftnl_set *s = data;
529 if (type != NFTA_LIST_ELEM)
532 return mnl_attr_parse_nested(attr,
533 nftnl_set_desc_concat_field_parse_attr_cb,
537 static int nftnl_set_desc_parse_attr_cb(
const struct nlattr *attr,
void *data)
539 int type = mnl_attr_get_type(attr), err;
540 struct nftnl_set *s = data;
542 if (mnl_attr_type_valid(attr, NFTA_SET_DESC_MAX) < 0)
546 case NFTA_SET_DESC_SIZE:
547 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
552 s->desc.size = ntohl(mnl_attr_get_u32(attr));
553 s->flags |= (1 << NFTNL_SET_DESC_SIZE);
555 case NFTA_SET_DESC_CONCAT:
556 err = mnl_attr_parse_nested(attr,
557 nftnl_set_desc_concat_parse_attr_cb,
559 if (err != MNL_CB_OK)
562 s->flags |= (1 << NFTNL_SET_DESC_CONCAT);
571 static int nftnl_set_desc_parse(
struct nftnl_set *s,
const struct nlattr *attr)
573 return mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, s);
576 EXPORT_SYMBOL(nftnl_set_nlmsg_parse);
577 int nftnl_set_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_set *s)
579 struct nlattr *tb[NFTA_SET_MAX+1] = {};
580 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
583 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
586 if (tb[NFTA_SET_TABLE]) {
587 if (s->flags & (1 << NFTNL_SET_TABLE))
589 s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
592 s->flags |= (1 << NFTNL_SET_TABLE);
594 if (tb[NFTA_SET_NAME]) {
595 if (s->flags & (1 << NFTNL_SET_NAME))
597 s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
600 s->flags |= (1 << NFTNL_SET_NAME);
602 if (tb[NFTA_SET_HANDLE]) {
603 s->handle = be64toh(mnl_attr_get_u64(tb[NFTA_SET_HANDLE]));
604 s->flags |= (1 << NFTNL_SET_HANDLE);
606 if (tb[NFTA_SET_FLAGS]) {
607 s->set_flags = ntohl(mnl_attr_get_u32(tb[NFTA_SET_FLAGS]));
608 s->flags |= (1 << NFTNL_SET_FLAGS);
610 if (tb[NFTA_SET_KEY_TYPE]) {
611 s->key_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_TYPE]));
612 s->flags |= (1 << NFTNL_SET_KEY_TYPE);
614 if (tb[NFTA_SET_KEY_LEN]) {
615 s->key_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_KEY_LEN]));
616 s->flags |= (1 << NFTNL_SET_KEY_LEN);
618 if (tb[NFTA_SET_DATA_TYPE]) {
619 s->data_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_TYPE]));
620 s->flags |= (1 << NFTNL_SET_DATA_TYPE);
622 if (tb[NFTA_SET_DATA_LEN]) {
623 s->data_len = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DATA_LEN]));
624 s->flags |= (1 << NFTNL_SET_DATA_LEN);
626 if (tb[NFTA_SET_OBJ_TYPE]) {
627 s->obj_type = ntohl(mnl_attr_get_u32(tb[NFTA_SET_OBJ_TYPE]));
628 s->flags |= (1 << NFTNL_SET_OBJ_TYPE);
630 if (tb[NFTA_SET_ID]) {
631 s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ID]));
632 s->flags |= (1 << NFTNL_SET_ID);
634 if (tb[NFTA_SET_POLICY]) {
635 s->policy = ntohl(mnl_attr_get_u32(tb[NFTA_SET_POLICY]));
636 s->flags |= (1 << NFTNL_SET_POLICY);
638 if (tb[NFTA_SET_TIMEOUT]) {
639 s->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_SET_TIMEOUT]));
640 s->flags |= (1 << NFTNL_SET_TIMEOUT);
642 if (tb[NFTA_SET_GC_INTERVAL]) {
643 s->gc_interval = ntohl(mnl_attr_get_u32(tb[NFTA_SET_GC_INTERVAL]));
644 s->flags |= (1 << NFTNL_SET_GC_INTERVAL);
646 if (tb[NFTA_SET_USERDATA]) {
647 ret = nftnl_set_set_data(s, NFTNL_SET_USERDATA,
648 mnl_attr_get_payload(tb[NFTA_SET_USERDATA]),
649 mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]));
653 if (tb[NFTA_SET_DESC]) {
654 ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
658 if (tb[NFTA_SET_EXPR]) {
659 s->expr = nftnl_expr_parse(tb[NFTA_SET_EXPR]);
663 s->flags |= (1 << NFTNL_SET_EXPR);
666 s->family = nfg->nfgen_family;
667 s->flags |= (1 << NFTNL_SET_FAMILY);
672 static int nftnl_set_do_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
673 const void *data,
struct nftnl_parse_err *err,
674 enum nftnl_parse_input input)
677 struct nftnl_parse_err perr = {};
680 case NFTNL_PARSE_JSON:
681 case NFTNL_PARSE_XML:
694 EXPORT_SYMBOL(nftnl_set_parse);
695 int nftnl_set_parse(
struct nftnl_set *s,
enum nftnl_parse_type type,
696 const char *data,
struct nftnl_parse_err *err)
698 return nftnl_set_do_parse(s, type, data, err, NFTNL_PARSE_BUFFER);
701 EXPORT_SYMBOL(nftnl_set_parse_file);
702 int nftnl_set_parse_file(
struct nftnl_set *s,
enum nftnl_parse_type type,
703 FILE *fp,
struct nftnl_parse_err *err)
705 return nftnl_set_do_parse(s, type, fp, err, NFTNL_PARSE_FILE);
708 static int nftnl_set_snprintf_default(
char *buf,
size_t size,
709 const struct nftnl_set *s,
710 uint32_t type, uint32_t flags)
713 int remain = size, offset = 0;
714 struct nftnl_set_elem *elem;
716 ret = snprintf(buf, remain,
"%s %s %x",
717 s->name, s->table, s->set_flags);
718 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
720 if (s->flags & (1 << NFTNL_SET_TIMEOUT)) {
721 ret = snprintf(buf + offset, remain,
" timeout %"PRIu64
"ms",
723 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
726 if (s->flags & (1 << NFTNL_SET_GC_INTERVAL)) {
727 ret = snprintf(buf + offset, remain,
" gc_interval %ums",
729 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
732 if (s->flags & (1 << NFTNL_SET_POLICY)) {
733 ret = snprintf(buf + offset, remain,
" policy %u", s->policy);
734 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
737 if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
738 ret = snprintf(buf + offset, remain,
" size %u", s->desc.size);
739 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
743 if (list_empty(&s->element_list))
746 ret = snprintf(buf + offset, remain,
"\n");
747 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
749 list_for_each_entry(elem, &s->element_list, head) {
750 ret = snprintf(buf + offset, remain,
"\t");
751 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
753 ret = nftnl_set_elem_snprintf(buf + offset, remain, elem, type,
755 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
761 static int nftnl_set_cmd_snprintf(
char *buf,
size_t size,
762 const struct nftnl_set *s, uint32_t cmd,
763 uint32_t type, uint32_t flags)
765 int ret, remain = size, offset = 0;
766 uint32_t inner_flags = flags;
768 if (type == NFTNL_OUTPUT_XML)
772 inner_flags &= ~NFTNL_OF_EVENT_ANY;
775 case NFTNL_OUTPUT_DEFAULT:
776 ret = nftnl_set_snprintf_default(buf + offset, remain, s, type,
778 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
787 EXPORT_SYMBOL(nftnl_set_snprintf);
788 int nftnl_set_snprintf(
char *buf,
size_t size,
const struct nftnl_set *s,
789 uint32_t type, uint32_t flags)
794 return nftnl_set_cmd_snprintf(buf, size, s, nftnl_flag2cmd(flags), type,
798 static int nftnl_set_do_snprintf(
char *buf,
size_t size,
const void *s,
799 uint32_t cmd, uint32_t type, uint32_t flags)
801 return nftnl_set_snprintf(buf, size, s, type, flags);
804 EXPORT_SYMBOL(nftnl_set_fprintf);
805 int nftnl_set_fprintf(FILE *fp,
const struct nftnl_set *s, uint32_t type,
808 return nftnl_fprintf(fp, s, NFTNL_CMD_UNSPEC, type, flags,
809 nftnl_set_do_snprintf);
812 EXPORT_SYMBOL(nftnl_set_elem_add);
813 void nftnl_set_elem_add(
struct nftnl_set *s,
struct nftnl_set_elem *elem)
815 list_add_tail(&elem->head, &s->element_list);
818 #define SET_NAME_HSIZE 512
821 struct list_head list;
822 struct hlist_head name_hash[SET_NAME_HSIZE];
825 EXPORT_SYMBOL(nftnl_set_list_alloc);
835 INIT_LIST_HEAD(&list->list);
836 for (i = 0; i < SET_NAME_HSIZE; i++)
837 INIT_HLIST_HEAD(&list->name_hash[i]);
842 EXPORT_SYMBOL(nftnl_set_list_free);
845 struct nftnl_set *s, *tmp;
847 list_for_each_entry_safe(s, tmp, &list->list, head) {
849 hlist_del(&s->hnode);
855 EXPORT_SYMBOL(nftnl_set_list_is_empty);
858 return list_empty(&list->list);
861 static uint32_t djb_hash(
const char *key)
863 uint32_t i, hash = 5381;
865 for (i = 0; i < strlen(key); i++)
866 hash = ((hash << 5) + hash) + key[i];
871 EXPORT_SYMBOL(nftnl_set_list_add);
872 void nftnl_set_list_add(
struct nftnl_set *s,
struct nftnl_set_list *list)
874 int key = djb_hash(s->name) % SET_NAME_HSIZE;
876 hlist_add_head(&s->hnode, &list->name_hash[key]);
877 list_add(&s->head, &list->list);
880 EXPORT_SYMBOL(nftnl_set_list_add_tail);
881 void nftnl_set_list_add_tail(
struct nftnl_set *s,
struct nftnl_set_list *list)
883 int key = djb_hash(s->name) % SET_NAME_HSIZE;
885 hlist_add_head(&s->hnode, &list->name_hash[key]);
886 list_add_tail(&s->head, &list->list);
889 EXPORT_SYMBOL(nftnl_set_list_del);
890 void nftnl_set_list_del(
struct nftnl_set *s)
893 hlist_del(&s->hnode);
896 EXPORT_SYMBOL(nftnl_set_list_foreach);
898 int (*cb)(
struct nftnl_set *t,
void *data),
void *data)
900 struct nftnl_set *cur, *tmp;
903 list_for_each_entry_safe(cur, tmp, &set_list->list, head) {
913 struct nftnl_set *cur;
916 EXPORT_SYMBOL(nftnl_set_list_iter_create);
927 if (nftnl_set_list_is_empty(l))
930 iter->cur = list_entry(l->list.next,
struct nftnl_set, head);
935 EXPORT_SYMBOL(nftnl_set_list_iter_cur);
942 EXPORT_SYMBOL(nftnl_set_list_iter_next);
945 struct nftnl_set *s = iter->cur;
951 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_set, head);
952 if (&iter->cur->head == iter->list->list.next)
958 EXPORT_SYMBOL(nftnl_set_list_iter_destroy);
964 EXPORT_SYMBOL(nftnl_set_list_lookup_byname);
966 nftnl_set_list_lookup_byname(
struct nftnl_set_list *set_list,
const char *set)
968 int key = djb_hash(set) % SET_NAME_HSIZE;
969 struct hlist_node *n;
972 hlist_for_each_entry(s, n, &set_list->name_hash[key], hnode) {
973 if (!strcmp(set, s->name))
979 int nftnl_set_lookup_id(
struct nftnl_expr *e,
982 const char *set_name;
985 set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
986 if (set_name == NULL)
989 s = nftnl_set_list_lookup_byname(set_list, set_name);
993 *set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);