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(nftnl_table_alloc);
47 if (t->flags & (1 << NFTNL_TABLE_NAME))
52 EXPORT_SYMBOL(nftnl_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(nftnl_table_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:
69 case NFTNL_TABLE_FLAGS:
70 case NFTNL_TABLE_FAMILY:
75 t->flags &= ~(1 << attr);
77 EXPORT_SYMBOL(nftnl_table_unset);
79 static uint32_t nftnl_table_validate[NFTNL_TABLE_MAX + 1] = {
80 [NFTNL_TABLE_FLAGS] =
sizeof(uint32_t),
81 [NFTNL_TABLE_FAMILY] =
sizeof(uint32_t),
84 int nftnl_table_set_data(
struct nftnl_table *t, uint16_t attr,
85 const void *data, uint32_t data_len)
87 nftnl_assert_attr_exists(attr, NFTNL_TABLE_MAX);
88 nftnl_assert_validate(data, nftnl_table_validate, attr, data_len);
91 case NFTNL_TABLE_NAME:
92 if (t->flags & (1 << NFTNL_TABLE_NAME))
95 t->name = strdup(data);
99 case NFTNL_TABLE_FLAGS:
100 t->table_flags = *((uint32_t *)data);
102 case NFTNL_TABLE_FAMILY:
103 t->family = *((uint32_t *)data);
105 case NFTNL_TABLE_USE:
106 t->use = *((uint32_t *)data);
109 t->flags |= (1 << attr);
112 EXPORT_SYMBOL(nftnl_table_set_data);
114 void nftnl_table_set(
struct nftnl_table *t, uint16_t attr,
const void *data)
116 nftnl_table_set_data(t, attr, data, nftnl_table_validate[attr]);
118 EXPORT_SYMBOL(nftnl_table_set);
120 void nftnl_table_set_u32(
struct nftnl_table *t, uint16_t attr, uint32_t val)
122 nftnl_table_set_data(t, attr, &val,
sizeof(uint32_t));
124 EXPORT_SYMBOL(nftnl_table_set_u32);
126 void nftnl_table_set_u8(
struct nftnl_table *t, uint16_t attr, uint8_t val)
128 nftnl_table_set_data(t, attr, &val,
sizeof(uint8_t));
130 EXPORT_SYMBOL(nftnl_table_set_u8);
132 int nftnl_table_set_str(
struct nftnl_table *t, uint16_t attr,
const char *str)
134 return nftnl_table_set_data(t, attr, str, strlen(str) + 1);
136 EXPORT_SYMBOL(nftnl_table_set_str);
138 const void *nftnl_table_get_data(
const struct nftnl_table *t, uint16_t attr,
141 if (!(t->flags & (1 << attr)))
145 case NFTNL_TABLE_NAME:
146 *data_len = strlen(t->name) + 1;
148 case NFTNL_TABLE_FLAGS:
149 *data_len =
sizeof(uint32_t);
150 return &t->table_flags;
151 case NFTNL_TABLE_FAMILY:
152 *data_len =
sizeof(uint32_t);
154 case NFTNL_TABLE_USE:
155 *data_len =
sizeof(uint32_t);
160 EXPORT_SYMBOL(nftnl_table_get_data);
162 const void *nftnl_table_get(
const struct nftnl_table *t, uint16_t attr)
165 return nftnl_table_get_data(t, attr, &data_len);
167 EXPORT_SYMBOL(nftnl_table_get);
169 uint32_t nftnl_table_get_u32(
const struct nftnl_table *t, uint16_t attr)
171 const void *ret = nftnl_table_get(t, attr);
172 return ret == NULL ? 0 : *((uint32_t *)ret);
174 EXPORT_SYMBOL(nftnl_table_get_u32);
176 uint8_t nftnl_table_get_u8(
const struct nftnl_table *t, uint16_t attr)
178 const void *ret = nftnl_table_get(t, attr);
179 return ret == NULL ? 0 : *((uint8_t *)ret);
181 EXPORT_SYMBOL(nftnl_table_get_u8);
183 const char *nftnl_table_get_str(
const struct nftnl_table *t, uint16_t attr)
185 return nftnl_table_get(t, attr);
187 EXPORT_SYMBOL(nftnl_table_get_str);
189 void nftnl_table_nlmsg_build_payload(
struct nlmsghdr *nlh,
const struct nftnl_table *t)
191 if (t->flags & (1 << NFTNL_TABLE_NAME))
192 mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, t->name);
193 if (t->flags & (1 << NFTNL_TABLE_FLAGS))
194 mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
196 EXPORT_SYMBOL(nftnl_table_nlmsg_build_payload);
198 static int nftnl_table_parse_attr_cb(
const struct nlattr *attr,
void *data)
200 const struct nlattr **tb = data;
201 int type = mnl_attr_get_type(attr);
203 if (mnl_attr_type_valid(attr, NFTA_TABLE_MAX) < 0)
207 case NFTA_TABLE_NAME:
208 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
211 case NFTA_TABLE_FLAGS:
213 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
222 int nftnl_table_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nftnl_table *t)
224 struct nlattr *tb[NFTA_TABLE_MAX+1] = {};
225 struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
227 if (mnl_attr_parse(nlh,
sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0)
230 if (tb[NFTA_TABLE_NAME]) {
231 if (t->flags & (1 << NFTNL_TABLE_NAME))
233 t->name = strdup(mnl_attr_get_str(tb[NFTA_TABLE_NAME]));
236 t->flags |= (1 << NFTNL_TABLE_NAME);
238 if (tb[NFTA_TABLE_FLAGS]) {
239 t->table_flags = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_FLAGS]));
240 t->flags |= (1 << NFTNL_TABLE_FLAGS);
242 if (tb[NFTA_TABLE_USE]) {
243 t->use = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_USE]));
244 t->flags |= (1 << NFTNL_TABLE_USE);
247 t->family = nfg->nfgen_family;
248 t->flags |= (1 << NFTNL_TABLE_FAMILY);
252 EXPORT_SYMBOL(nftnl_table_nlmsg_parse);
255 int nftnl_jansson_parse_table(
struct nftnl_table *t, json_t *tree,
256 struct nftnl_parse_err *err)
263 root = nftnl_jansson_get_node(tree,
"table", err);
267 str = nftnl_jansson_parse_str(root,
"name", err);
269 nftnl_table_set_str(t, NFTNL_TABLE_NAME, str);
271 if (nftnl_jansson_parse_family(root, &family, err) == 0)
272 nftnl_table_set_u32(t, NFTNL_TABLE_FAMILY, family);
274 if (nftnl_jansson_parse_val(root,
"flags", NFTNL_TYPE_U32, &flags,
276 nftnl_table_set_u32(t, NFTNL_TABLE_FLAGS, flags);
278 if (nftnl_jansson_parse_val(root,
"use", NFTNL_TYPE_U32, &use, err) == 0)
279 nftnl_table_set_u32(t, NFTNL_TABLE_USE, use);
285 static int nftnl_table_json_parse(
struct nftnl_table *t,
const void *json,
286 struct nftnl_parse_err *err,
287 enum nftnl_parse_input input)
294 tree = nftnl_jansson_create_root(json, &error, err, input);
298 ret = nftnl_jansson_parse_table(t, tree, err);
300 nftnl_jansson_free_root(tree);
309 static int nftnl_table_do_parse(
struct nftnl_table *t,
enum nftnl_parse_type type,
310 const void *data,
struct nftnl_parse_err *err,
311 enum nftnl_parse_input input)
314 struct nftnl_parse_err perr = {};
317 case NFTNL_PARSE_JSON:
318 ret = nftnl_table_json_parse(t, data, &perr, input);
320 case NFTNL_PARSE_XML:
333 int nftnl_table_parse(
struct nftnl_table *t,
enum nftnl_parse_type type,
334 const char *data,
struct nftnl_parse_err *err)
336 return nftnl_table_do_parse(t, type, data, err, NFTNL_PARSE_BUFFER);
338 EXPORT_SYMBOL(nftnl_table_parse);
340 int nftnl_table_parse_file(
struct nftnl_table *t,
enum nftnl_parse_type type,
341 FILE *fp,
struct nftnl_parse_err *err)
343 return nftnl_table_do_parse(t, type, fp, err, NFTNL_PARSE_FILE);
345 EXPORT_SYMBOL(nftnl_table_parse_file);
347 static int nftnl_table_export(
char *buf,
size_t size,
350 NFTNL_BUF_INIT(b, buf, size);
352 nftnl_buf_open(&b, type, TABLE);
353 if (t->flags & (1 << NFTNL_TABLE_NAME))
354 nftnl_buf_str(&b, type, t->name, NAME);
355 if (t->flags & (1 << NFTNL_TABLE_FAMILY))
356 nftnl_buf_str(&b, type, nftnl_family2str(t->family), FAMILY);
357 if (t->flags & (1 << NFTNL_TABLE_FLAGS))
358 nftnl_buf_u32(&b, type, t->table_flags, FLAGS);
359 if (t->flags & (1 << NFTNL_TABLE_USE))
360 nftnl_buf_u32(&b, type, t->use, USE);
362 nftnl_buf_close(&b, type, TABLE);
364 return nftnl_buf_done(&b);
367 static int nftnl_table_snprintf_default(
char *buf,
size_t size,
370 return snprintf(buf, size,
"table %s %s flags %x use %d",
371 t->name, nftnl_family2str(t->family),
372 t->table_flags, t->use);
375 static int nftnl_table_cmd_snprintf(
char *buf,
size_t size,
377 uint32_t type, uint32_t flags)
379 int ret, remain = size, offset = 0;
381 ret = nftnl_cmd_header_snprintf(buf + offset, remain, cmd, type, flags);
382 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
385 case NFTNL_OUTPUT_DEFAULT:
386 ret = nftnl_table_snprintf_default(buf + offset, remain, t);
388 case NFTNL_OUTPUT_XML:
389 case NFTNL_OUTPUT_JSON:
390 ret = nftnl_table_export(buf + offset, remain, t, type);
395 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
397 ret = nftnl_cmd_footer_snprintf(buf + offset, remain, cmd, type, flags);
398 SNPRINTF_BUFFER_SIZE(ret, remain, offset);
403 int nftnl_table_snprintf(
char *buf,
size_t size,
const struct nftnl_table *t,
404 uint32_t type, uint32_t flags)
409 return nftnl_table_cmd_snprintf(buf, size, t, nftnl_flag2cmd(flags), type,
412 EXPORT_SYMBOL(nftnl_table_snprintf);
414 static int nftnl_table_do_snprintf(
char *buf,
size_t size,
const void *t,
415 uint32_t cmd, uint32_t type, uint32_t flags)
417 return nftnl_table_snprintf(buf, size, t, type, flags);
420 int nftnl_table_fprintf(FILE *fp,
const struct nftnl_table *t, uint32_t type,
423 return nftnl_fprintf(fp, t, NFTNL_CMD_UNSPEC, type, flags,
424 nftnl_table_do_snprintf);
426 EXPORT_SYMBOL(nftnl_table_fprintf);
429 struct list_head list;
440 INIT_LIST_HEAD(&list->list);
444 EXPORT_SYMBOL(nftnl_table_list_alloc);
450 list_for_each_entry_safe(r, tmp, &list->list, head) {
456 EXPORT_SYMBOL(nftnl_table_list_free);
460 return list_empty(&list->list);
462 EXPORT_SYMBOL(nftnl_table_list_is_empty);
466 list_add(&r->head, &list->list);
468 EXPORT_SYMBOL(nftnl_table_list_add);
472 list_add_tail(&r->head, &list->list);
474 EXPORT_SYMBOL(nftnl_table_list_add_tail);
480 EXPORT_SYMBOL(nftnl_table_list_del);
489 list_for_each_entry_safe(cur, tmp, &table_list->list, head) {
496 EXPORT_SYMBOL(nftnl_table_list_foreach);
513 if (nftnl_table_list_is_empty(l))
516 iter->cur = list_entry(l->list.next,
struct nftnl_table, head);
520 EXPORT_SYMBOL(nftnl_table_list_iter_create);
530 iter->cur = list_entry(iter->cur->head.next,
struct nftnl_table, head);
531 if (&iter->cur->head == iter->list->list.next)
536 EXPORT_SYMBOL(nftnl_table_list_iter_next);
542 EXPORT_SYMBOL(nftnl_table_list_iter_destroy);