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>
30 struct list_head head;
43 EXPORT_SYMBOL_ALIAS(nftnl_table_alloc, nft_table_alloc);
47 if (t->flags & (1 << NFTNL_TABLE_NAME))
52 EXPORT_SYMBOL_ALIAS(nftnl_table_free, nft_table_free);
54 bool nftnl_table_is_set(
const struct nftnl_table *t, uint16_t attr)
56 return t->flags & (1 << attr);
58 EXPORT_SYMBOL_ALIAS(nftnl_table_is_set, nft_table_attr_is_set);
60 void nftnl_table_unset(
struct nftnl_table *t, uint16_t attr)
62 if (!(t->flags & (1 << attr)))
66 case NFTNL_TABLE_NAME:
72 case NFTNL_TABLE_FLAGS:
73 case NFTNL_TABLE_FAMILY:
78 t->flags &= ~(1 << attr);
80 EXPORT_SYMBOL_ALIAS(nftnl_table_unset, nft_table_attr_unset);
82 static uint32_t nftnl_table_validate[NFTNL_TABLE_MAX + 1] = {
83 [NFTNL_TABLE_FLAGS] =
sizeof(uint32_t),
84 [NFTNL_TABLE_FAMILY] =
sizeof(uint32_t),
87 void nftnl_table_set_data(
struct nftnl_table *t, uint16_t attr,
88 const void *data, uint32_t data_len)
90 if (attr > NFTNL_TABLE_MAX)
93 nftnl_assert_validate(data, nftnl_table_validate, attr, data_len);
96 case NFTNL_TABLE_NAME:
100 t->name = strdup(data);
102 case NFTNL_TABLE_FLAGS:
103 t->table_flags = *((uint32_t *)data);
105 case NFTNL_TABLE_FAMILY:
106 t->family = *((uint32_t *)data);
108 case NFTNL_TABLE_USE:
109 t->use = *((uint32_t *)data);
112 t->flags |= (1 << attr);
114 EXPORT_SYMBOL_ALIAS(nftnl_table_set_data, nft_table_attr_set_data);
116 void nftnl_table_set(
struct nftnl_table *t, uint16_t attr,
const void *data)
118 nftnl_table_set_data(t, attr, data, nftnl_table_validate[attr]);
120 EXPORT_SYMBOL_ALIAS(nftnl_table_set, nft_table_attr_set);
122 void nftnl_table_set_u32(
struct nftnl_table *t, uint16_t attr, uint32_t val)
124 nftnl_table_set_data(t, attr, &val,
sizeof(uint32_t));
126 EXPORT_SYMBOL_ALIAS(nftnl_table_set_u32, nft_table_attr_set_u32);
128 void nftnl_table_set_u8(
struct nftnl_table *t, uint16_t attr, uint8_t val)
130 nftnl_table_set_data(t, attr, &val,
sizeof(uint8_t));
132 EXPORT_SYMBOL_ALIAS(nftnl_table_set_u8, nft_table_attr_set_u8);
134 void nftnl_table_set_str(
struct nftnl_table *t, uint16_t attr,
const char *str)
136 nftnl_table_set_data(t, attr, str, 0);
138 EXPORT_SYMBOL_ALIAS(nftnl_table_set_str, nft_table_attr_set_str);
140 const void *nftnl_table_get_data(
const struct nftnl_table *t, uint16_t attr,
143 if (!(t->flags & (1 << attr)))
147 case NFTNL_TABLE_NAME:
149 case NFTNL_TABLE_FLAGS:
150 *data_len =
sizeof(uint32_t);
151 return &t->table_flags;
152 case NFTNL_TABLE_FAMILY:
153 *data_len =
sizeof(uint32_t);
155 case NFTNL_TABLE_USE:
156 *data_len =
sizeof(uint32_t);
161 EXPORT_SYMBOL_ALIAS(nftnl_table_get_data, nft_table_attr_get_data);
163 const void *nftnl_table_get(
const struct nftnl_table *t, uint16_t attr)
166 return nftnl_table_get_data(t, attr, &data_len);
168 EXPORT_SYMBOL_ALIAS(nftnl_table_get, nft_table_attr_get);
170 uint32_t nftnl_table_get_u32(
const struct nftnl_table *t, uint16_t attr)
172 const void *ret = nftnl_table_get(t, attr);
173 return ret == NULL ? 0 : *((uint32_t *)ret);
175 EXPORT_SYMBOL_ALIAS(nftnl_table_get_u32, nft_table_attr_get_u32);
177 uint8_t nftnl_table_get_u8(
const struct nftnl_table *t, uint16_t attr)
179 const void *ret = nftnl_table_get(t, attr);
180 return ret == NULL ? 0 : *((uint8_t *)ret);
182 EXPORT_SYMBOL_ALIAS(nftnl_table_get_u8, nft_table_attr_get_u8);
184 const char *nftnl_table_get_str(
const struct nftnl_table *t, uint16_t attr)
186 return nftnl_table_get(t, attr);
188 EXPORT_SYMBOL_ALIAS(nftnl_table_get_str, nft_table_attr_get_str);
190 void nftnl_table_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nftnl_table *t)
192 if (t->flags & (1 << NFTNL_TABLE_NAME))
193 mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, t->name);
194 if (t->flags & (1 << NFTNL_TABLE_FLAGS))
195 mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
197 EXPORT_SYMBOL_ALIAS(nftnl_table_nlmsg_build_payload, nft_table_nlmsg_build_payload);
199 static int nftnl_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)
212 case NFTA_TABLE_FLAGS:
214 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
223 int nftnl_table_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_table *t)
225 struct nlattr *tb[NFTA_TABLE_MAX+1] = {};
226 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
228 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0)
231 if (tb[NFTA_TABLE_NAME]) {
233 t->name = strdup(mnl_attr_get_str(tb[NFTA_TABLE_NAME]));
234 t->flags |= (1 << NFTNL_TABLE_NAME);
236 if (tb[NFTA_TABLE_FLAGS]) {
237 t->table_flags = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_FLAGS]));
238 t->flags |= (1 << NFTNL_TABLE_FLAGS);
240 if (tb[NFTA_TABLE_USE]) {
241 t->use = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_USE]));
242 t->flags |= (1 << NFTNL_TABLE_USE);
245 t->family = nfg->nfgen_family;
246 t->flags |= (1 << NFTNL_TABLE_FAMILY);
250 EXPORT_SYMBOL_ALIAS(nftnl_table_nlmsg_parse, nft_table_nlmsg_parse);
253 int nftnl_mxml_table_parse(mxml_node_t *tree,
struct nftnl_table *t,
254 struct nftnl_parse_err *err)
260 name = nftnl_mxml_str_parse(tree,
"name", MXML_DESCEND_FIRST,
261 NFTNL_XML_MAND, err);
263 nftnl_table_set_str(t, NFTNL_TABLE_NAME, name);
265 family = nftnl_mxml_family_parse(tree,
"family", MXML_DESCEND_FIRST,
266 NFTNL_XML_MAND, err);
268 nftnl_table_set_u32(t, NFTNL_TABLE_FAMILY, family);
270 if (nftnl_mxml_num_parse(tree,
"flags", MXML_DESCEND, BASE_DEC,
271 &flags, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
272 nftnl_table_set_u32(t, NFTNL_TABLE_FLAGS, flags);
274 if (nftnl_mxml_num_parse(tree,
"use", MXML_DESCEND, BASE_DEC,
275 &use, NFTNL_TYPE_U32, NFTNL_XML_MAND, err) == 0)
276 nftnl_table_set_u32(t, NFTNL_TABLE_USE, use);
282 static int nftnl_table_xml_parse(
struct nftnl_table *t,
const void *data,
283 struct nftnl_parse_err *err,
284 enum nftnl_parse_input input)
288 mxml_node_t *tree = nftnl_mxml_build_tree(data,
"table", err, input);
292 ret = nftnl_mxml_table_parse(tree, t, err);
302 int nftnl_jansson_parse_table(
struct nftnl_table *t, json_t *tree,
303 struct nftnl_parse_err *err)
310 root = nftnl_jansson_get_node(tree,
"table", err);
314 str = nftnl_jansson_parse_str(root,
"name", err);
316 nftnl_table_set_str(t, NFTNL_TABLE_NAME, str);
318 if (nftnl_jansson_parse_family(root, &family, err) == 0)
319 nftnl_table_set_u32(t, NFTNL_TABLE_FAMILY, family);
321 if (nftnl_jansson_parse_val(root,
"flags", NFTNL_TYPE_U32, &flags,
323 nftnl_table_set_u32(t, NFTNL_TABLE_FLAGS, flags);
325 if (nftnl_jansson_parse_val(root,
"use", NFTNL_TYPE_U32, &use, err) == 0)
326 nftnl_table_set_u32(t, NFTNL_TABLE_USE, use);
332 static int nftnl_table_json_parse(
struct nftnl_table *t,
const void *json,
333 struct nftnl_parse_err *err,
334 enum nftnl_parse_input input)
341 tree = nftnl_jansson_create_root(json, &error, err, input);
345 ret = nftnl_jansson_parse_table(t, tree, err);
347 nftnl_jansson_free_root(tree);
356 static int nftnl_table_do_parse(
struct nftnl_table *t,
enum nftnl_parse_type type,
357 const void *data,
struct nftnl_parse_err *err,
358 enum nftnl_parse_input input)
361 struct nftnl_parse_err perr;
364 case NFTNL_PARSE_XML:
365 ret = nftnl_table_xml_parse(t, data, &perr, input);
367 case NFTNL_PARSE_JSON:
368 ret = nftnl_table_json_parse(t, data, &perr, input);
382 int nftnl_table_parse(
struct nftnl_table *t,
enum nftnl_parse_type type,
383 const char *data,
struct nftnl_parse_err *err)
385 return nftnl_table_do_parse(t, type, data, err, NFTNL_PARSE_BUFFER);
387 EXPORT_SYMBOL_ALIAS(nftnl_table_parse, nft_table_parse);
389 int nftnl_table_parse_file(
struct nftnl_table *t,
enum nftnl_parse_type type,
390 FILE *fp,
struct nftnl_parse_err *err)
392 return nftnl_table_do_parse(t, type, fp, err, NFTNL_PARSE_FILE);
394 EXPORT_SYMBOL_ALIAS(nftnl_table_parse_file, nft_table_parse_file);
396 static int nftnl_table_export(
char *buf,
size_t size,
399 NFTNL_BUF_INIT(b, buf, size);
401 nftnl_buf_open(&b, type, TABLE);
402 if (t->flags & (1 << NFTNL_TABLE_NAME))
403 nftnl_buf_str(&b, type, t->name, NAME);
404 if (t->flags & (1 << NFTNL_TABLE_FAMILY))
405 nftnl_buf_str(&b, type, nftnl_family2str(t->family), FAMILY);
406 if (t->flags & (1 << NFTNL_TABLE_FLAGS))
407 nftnl_buf_u32(&b, type, t->table_flags, FLAGS);
408 if (t->flags & (1 << NFTNL_TABLE_USE))
409 nftnl_buf_u32(&b, type, t->use, USE);
411 nftnl_buf_close(&b, type, TABLE);
413 return nftnl_buf_done(&b);
416 static int nftnl_table_snprintf_default(
char *buf,
size_t size,
419 return snprintf(buf, size,
"table %s %s flags %x use %d",
420 t->name, nftnl_family2str(t->family),
421 t->table_flags, t->use);
424 static int nftnl_table_cmd_snprintf(
char *buf,
size_t size,
426 uint32_t type, uint32_t flags)
428 int ret, len = size, offset = 0;
430 ret = nftnl_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
431 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
434 case NFTNL_OUTPUT_DEFAULT:
435 ret = nftnl_table_snprintf_default(buf+offset, len, t);
437 case NFTNL_OUTPUT_XML:
438 case NFTNL_OUTPUT_JSON:
439 ret = nftnl_table_export(buf+offset, len, t, type);
444 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
446 ret = nftnl_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
447 SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
452 int nftnl_table_snprintf(
char *buf,
size_t size,
const struct nftnl_table *t,
453 uint32_t type, uint32_t flags)
455 return nftnl_table_cmd_snprintf(buf, size, t, nftnl_flag2cmd(flags), type,
458 EXPORT_SYMBOL_ALIAS(nftnl_table_snprintf, nft_table_snprintf);
460 static int nftnl_table_do_snprintf(
char *buf,
size_t size,
const void *t,
461 uint32_t cmd, uint32_t type, uint32_t flags)
463 return nftnl_table_snprintf(buf, size, t, type, flags);
466 int nftnl_table_fprintf(FILE *fp,
const struct nftnl_table *t, uint32_t type,
469 return nftnl_fprintf(fp, t, NFTNL_CMD_UNSPEC, type, flags,
470 nftnl_table_do_snprintf);
472 EXPORT_SYMBOL_ALIAS(nftnl_table_fprintf, nft_table_fprintf);
475 struct list_head list;
486 INIT_LIST_HEAD(&list->list);
490 EXPORT_SYMBOL_ALIAS(nftnl_table_list_alloc, nft_table_list_alloc);
496 list_for_each_entry_safe(r, tmp, &list->list, head) {
502 EXPORT_SYMBOL_ALIAS(nftnl_table_list_free, nft_table_list_free);
506 return list_empty(&list->list);
508 EXPORT_SYMBOL_ALIAS(nftnl_table_list_is_empty, nft_table_list_is_empty);
512 list_add(&r->head, &list->list);
514 EXPORT_SYMBOL_ALIAS(nftnl_table_list_add, nft_table_list_add);
518 list_add_tail(&r->head, &list->list);
520 EXPORT_SYMBOL_ALIAS(nftnl_table_list_add_tail, nft_table_list_add_tail);
526 EXPORT_SYMBOL_ALIAS(nftnl_table_list_del, nft_table_list_del);
535 list_for_each_entry_safe(cur, tmp, &table_list->list, head) {
542 EXPORT_SYMBOL_ALIAS(nftnl_table_list_foreach, nft_table_list_foreach);
558 if (nftnl_table_list_is_empty(l))
561 iter->cur = list_entry(l->list.next,
struct nftnl_table, head);
565 EXPORT_SYMBOL_ALIAS(nftnl_table_list_iter_create, nft_table_list_iter_create);
575 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_table, head);
576 if (&iter->cur->head == iter->list->list.next)
581 EXPORT_SYMBOL_ALIAS(nftnl_table_list_iter_next, nft_table_list_iter_next);
587 EXPORT_SYMBOL_ALIAS(nftnl_table_list_iter_destroy, nft_table_list_iter_destroy);