19 #include <netinet/in.h>
22 #include <libmnl/libmnl.h>
23 #include <linux/netfilter/nfnetlink.h>
24 #include <linux/netfilter/nf_tables.h>
26 #include <libnftnl/table.h>
29 struct list_head head;
38 struct nft_table *nft_table_alloc(
void)
40 return calloc(1,
sizeof(
struct nft_table));
42 EXPORT_SYMBOL(nft_table_alloc);
44 void nft_table_free(
struct nft_table *t)
46 if (t->flags & (1 << NFT_TABLE_ATTR_NAME))
51 EXPORT_SYMBOL(nft_table_free);
53 bool nft_table_attr_is_set(
const struct nft_table *t, uint16_t attr)
55 return t->flags & (1 << attr);
57 EXPORT_SYMBOL(nft_table_attr_is_set);
59 void nft_table_attr_unset(
struct nft_table *t, uint16_t attr)
61 if (!(t->flags & (1 << attr)))
65 case NFT_TABLE_ATTR_NAME:
71 case NFT_TABLE_ATTR_FLAGS:
72 case NFT_TABLE_ATTR_FAMILY:
74 case NFT_TABLE_ATTR_USE:
78 t->flags &= ~(1 << attr);
80 EXPORT_SYMBOL(nft_table_attr_unset);
82 static uint32_t nft_table_attr_validate[NFT_TABLE_ATTR_MAX + 1] = {
83 [NFT_TABLE_ATTR_FLAGS] =
sizeof(uint32_t),
84 [NFT_TABLE_ATTR_FAMILY] =
sizeof(uint32_t),
87 void nft_table_attr_set_data(
struct nft_table *t, uint16_t attr,
88 const void *data, uint32_t data_len)
90 if (attr > NFT_TABLE_ATTR_MAX)
93 nft_assert_validate(data, nft_table_attr_validate, attr, data_len);
96 case NFT_TABLE_ATTR_NAME:
100 t->name = strdup(data);
102 case NFT_TABLE_ATTR_FLAGS:
103 t->table_flags = *((uint32_t *)data);
105 case NFT_TABLE_ATTR_FAMILY:
106 t->family = *((uint32_t *)data);
108 case NFT_TABLE_ATTR_USE:
112 t->flags |= (1 << attr);
114 EXPORT_SYMBOL(nft_table_attr_set_data);
116 void nft_table_attr_set(
struct nft_table *t, uint16_t attr,
const void *data)
118 nft_table_attr_set_data(t, attr, data, nft_table_attr_validate[attr]);
120 EXPORT_SYMBOL(nft_table_attr_set);
122 void nft_table_attr_set_u32(
struct nft_table *t, uint16_t attr, uint32_t val)
124 nft_table_attr_set_data(t, attr, &val,
sizeof(uint32_t));
126 EXPORT_SYMBOL(nft_table_attr_set_u32);
128 void nft_table_attr_set_u8(
struct nft_table *t, uint16_t attr, uint8_t val)
130 nft_table_attr_set_data(t, attr, &val,
sizeof(uint8_t));
132 EXPORT_SYMBOL(nft_table_attr_set_u8);
134 void nft_table_attr_set_str(
struct nft_table *t, uint16_t attr,
const char *str)
136 nft_table_attr_set_data(t, attr, str, 0);
138 EXPORT_SYMBOL(nft_table_attr_set_str);
140 const void *nft_table_attr_get_data(
struct nft_table *t, uint16_t attr,
143 if (!(t->flags & (1 << attr)))
147 case NFT_TABLE_ATTR_NAME:
149 case NFT_TABLE_ATTR_FLAGS:
150 *data_len =
sizeof(uint32_t);
151 return &t->table_flags;
152 case NFT_TABLE_ATTR_FAMILY:
153 *data_len =
sizeof(uint32_t);
155 case NFT_TABLE_ATTR_USE:
156 *data_len =
sizeof(uint32_t);
161 EXPORT_SYMBOL(nft_table_attr_get_data);
163 const void *nft_table_attr_get(
struct nft_table *t, uint16_t attr)
166 return nft_table_attr_get_data(t, attr, &data_len);
168 EXPORT_SYMBOL(nft_table_attr_get);
170 uint32_t nft_table_attr_get_u32(
struct nft_table *t, uint16_t attr)
172 const void *ret = nft_table_attr_get(t, attr);
173 return ret == NULL ? 0 : *((uint32_t *)ret);
175 EXPORT_SYMBOL(nft_table_attr_get_u32);
177 uint8_t nft_table_attr_get_u8(
struct nft_table *t, uint16_t attr)
179 const void *ret = nft_table_attr_get(t, attr);
180 return ret == NULL ? 0 : *((uint8_t *)ret);
182 EXPORT_SYMBOL(nft_table_attr_get_u8);
184 const char *nft_table_attr_get_str(
struct nft_table *t, uint16_t attr)
186 return nft_table_attr_get(t, attr);
188 EXPORT_SYMBOL(nft_table_attr_get_str);
190 void nft_table_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nft_table *t)
192 if (t->flags & (1 << NFT_TABLE_ATTR_NAME))
193 mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, t->name);
194 if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS))
195 mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
197 EXPORT_SYMBOL(nft_table_nlmsg_build_payload);
199 static int nft_table_parse_attr_cb(
const struct nlattr *attr,
void *data)
201 const struct nlattr **tb = data;
202 int type = mnl_attr_get_type(attr);
204 if (mnl_attr_type_valid(attr, NFTA_TABLE_MAX) < 0)
208 case NFTA_TABLE_NAME:
209 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
210 perror(
"mnl_attr_validate");
214 case NFTA_TABLE_FLAGS:
215 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
216 perror(
"mnl_attr_validate");
221 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
222 perror(
"mnl_attr_validate");
232 int nft_table_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nft_table *t)
234 struct nlattr *tb[NFTA_TABLE_MAX+1] = {};
235 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
237 if (mnl_attr_parse(nlh,
sizeof(*nfg), nft_table_parse_attr_cb, tb) < 0)
240 if (tb[NFTA_TABLE_NAME]) {
241 t->name = strdup(mnl_attr_get_str(tb[NFTA_TABLE_NAME]));
242 t->flags |= (1 << NFT_TABLE_ATTR_NAME);
244 if (tb[NFTA_TABLE_FLAGS]) {
245 t->table_flags = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_FLAGS]));
246 t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
248 if (tb[NFTA_TABLE_USE]) {
249 t->use = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_USE]));
250 t->flags |= (1 << NFT_TABLE_ATTR_USE);
253 t->family = nfg->nfgen_family;
254 t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
258 EXPORT_SYMBOL(nft_table_nlmsg_parse);
261 int nft_mxml_table_parse(mxml_node_t *tree,
struct nft_table *t,
262 struct nft_parse_err *err)
267 name = nft_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
275 t->name = strdup(name);
276 t->flags |= (1 << NFT_TABLE_ATTR_NAME);
278 family = nft_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
284 t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
286 if (nft_mxml_num_parse(tree,
"flags", MXML_DESCEND, BASE_DEC,
287 &t->table_flags, NFT_TYPE_U32,
288 NFT_XML_MAND, err) != 0)
291 t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
297 static int nft_table_xml_parse(
struct nft_table *t,
const void *data,
298 struct nft_parse_err *err,
299 enum nft_parse_input input)
303 mxml_node_t *tree = nft_mxml_build_tree(data,
"table", err, input);
307 ret = nft_mxml_table_parse(tree, t, err);
317 int nft_jansson_parse_table(
struct nft_table *t, json_t *tree,
318 struct nft_parse_err *err)
325 root = nft_jansson_get_node(tree,
"table", err);
329 str = nft_jansson_parse_str(root,
"name", err);
333 nft_table_attr_set_str(t, NFT_TABLE_ATTR_NAME, str);
335 if (nft_jansson_parse_family(root, &family, err) != 0)
338 nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FAMILY, family);
340 if (nft_jansson_parse_val(root,
"flags", NFT_TYPE_U32, &flags, err) < 0)
343 nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
345 nft_jansson_free_root(tree);
348 nft_jansson_free_root(tree);
353 static int nft_table_json_parse(
struct nft_table *t,
const void *json,
354 struct nft_parse_err *err,
355 enum nft_parse_input input)
361 tree = nft_jansson_create_root(json, &error, err, input);
365 return nft_jansson_parse_table(t, tree, err);
372 static int nft_table_do_parse(
struct nft_table *t,
enum nft_parse_type type,
373 const void *data,
struct nft_parse_err *err,
374 enum nft_parse_input input)
377 struct nft_parse_err perr;
381 ret = nft_table_xml_parse(t, data, &perr, input);
384 ret = nft_table_json_parse(t, data, &perr, input);
398 int nft_table_parse(
struct nft_table *t,
enum nft_parse_type type,
399 const char *data,
struct nft_parse_err *err)
401 return nft_table_do_parse(t, type, data, err, NFT_PARSE_BUFFER);
403 EXPORT_SYMBOL(nft_table_parse);
405 int nft_table_parse_file(
struct nft_table *t,
enum nft_parse_type type,
406 FILE *fp,
struct nft_parse_err *err)
408 return nft_table_do_parse(t, type, fp, err, NFT_PARSE_FILE);
410 EXPORT_SYMBOL(nft_table_parse_file);
412 static int nft_table_snprintf_json(
char *buf,
size_t size,
struct nft_table *t)
414 return snprintf(buf, size,
422 t->name, nft_family2str(t->family),
423 t->table_flags, t->use);
426 static int nft_table_snprintf_xml(
char *buf,
size_t size,
struct nft_table *t)
428 return snprintf(buf, size,
"<table><name>%s</name><family>%s</family>"
429 "<flags>%d</flags><use>%d</use></table>",
430 t->name, nft_family2str(t->family),
431 t->table_flags, t->use);
434 static int nft_table_snprintf_default(
char *buf,
size_t size,
struct nft_table *t)
436 return snprintf(buf, size,
"table %s %s flags %x use %d",
437 t->name, nft_family2str(t->family),
438 t->table_flags, t->use);
441 int nft_table_snprintf(
char *buf,
size_t size,
struct nft_table *t,
442 uint32_t type, uint32_t flags)
444 int ret, len = size, offset = 0;
446 ret = nft_event_header_snprintf(buf+offset, len, type, flags);
447 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
450 case NFT_OUTPUT_DEFAULT:
451 ret = nft_table_snprintf_default(buf+offset, len, t);
454 ret = nft_table_snprintf_xml(buf+offset, len, t);
456 case NFT_OUTPUT_JSON:
457 ret = nft_table_snprintf_json(buf+offset, len, t);
462 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
464 ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
465 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
469 EXPORT_SYMBOL(nft_table_snprintf);
471 static inline int nft_table_do_snprintf(
char *buf,
size_t size,
void *t,
472 uint32_t type, uint32_t flags)
474 return nft_table_snprintf(buf, size, t, type, flags);
477 int nft_table_fprintf(FILE *fp,
struct nft_table *t, uint32_t type,
480 return nft_fprintf(fp, t, type, flags, nft_table_do_snprintf);
482 EXPORT_SYMBOL(nft_table_fprintf);
485 struct list_head list;
496 INIT_LIST_HEAD(&list->list);
500 EXPORT_SYMBOL(nft_table_list_alloc);
504 struct nft_table *r, *tmp;
506 list_for_each_entry_safe(r, tmp, &list->list, head) {
512 EXPORT_SYMBOL(nft_table_list_free);
516 return list_empty(&list->list);
518 EXPORT_SYMBOL(nft_table_list_is_empty);
520 void nft_table_list_add(
struct nft_table *r,
struct nft_table_list *list)
522 list_add(&r->head, &list->list);
524 EXPORT_SYMBOL(nft_table_list_add);
526 void nft_table_list_add_tail(
struct nft_table *r,
struct nft_table_list *list)
528 list_add_tail(&r->head, &list->list);
530 EXPORT_SYMBOL(nft_table_list_add_tail);
532 void nft_table_list_del(
struct nft_table *t)
536 EXPORT_SYMBOL(nft_table_list_del);
539 int (*cb)(
struct nft_table *t,
void *data),
542 struct nft_table *cur, *tmp;
545 list_for_each_entry_safe(cur, tmp, &table_list->list, head) {
552 EXPORT_SYMBOL(nft_table_list_foreach);
556 struct nft_table *cur;
568 iter->cur = list_entry(l->list.next,
struct nft_table, head);
572 EXPORT_SYMBOL(nft_table_list_iter_create);
576 struct nft_table *r = iter->cur;
579 iter->cur = list_entry(iter->cur->head.next,
struct nft_table, head);
580 if (&iter->cur->head == iter->list->list.next)
585 EXPORT_SYMBOL(nft_table_list_iter_next);
591 EXPORT_SYMBOL(nft_table_list_iter_destroy);