49 #include <libmnl/libmnl.h> 52 #include <nftables_common.h> 54 #include <nftables/nftables.h> 60 unsigned int max_errors = 1;
62 unsigned int debug_level;
65 const char *include_paths[INCLUDE_PATHS_MAX] = { DEFAULT_INCLUDE_PATH };
76 realm_table_rt_init();
77 devgroup_table_init();
78 realm_table_meta_init();
79 ct_label_table_init();
81 #ifdef HAVE_LIBXTABLES 93 iface_cache_release();
94 ct_label_table_exit();
95 realm_table_rt_exit();
96 devgroup_table_exit();
97 realm_table_meta_exit();
113 return NFT_EXIT_SUCCESS;
116 __attribute__((format(printf, 2, 0)))
117 static int nft_print(
void *ctx,
const char *fmt, ...)
121 vfprintf(stdout, fmt, arg);
134 struct nft_ctx *ctx = NULL;
135 ctx = calloc(1,
sizeof(
struct nft_ctx));
139 memset(ctx, 0,
sizeof(*ctx));
140 ctx->nf_sock = netlink_open_sock();
142 init_list_head(&ctx->cache.list);
143 init_list_head(&ctx->output.msgs);
145 ctx->output.ctx = ctx;
146 ctx->output.print = nft_print;
161 int (*print)(
void *ctx,
const char *fmt, ...),
165 nft->output.print = print;
166 nft->output.ctx = ctx;
179 netlink_close_sock(nft->nf_sock);
180 cache_release(&nft->cache);
181 erec_free_list(&nft->output.msgs);
185 static const struct input_descriptor indesc_cmdline = {
186 .type = INDESC_BUFFER,
197 FILE *errfile = fmemopen(err_buf, err_buf_len,
"w");
199 erec_print_list(errfile, &nft->output.msgs);
201 if (!strlen(err_buf))
202 return NFT_EXIT_FAILURE;
203 return NFT_EXIT_SUCCESS;
238 char *buf,
size_t buflen)
240 int rc = NFT_EXIT_SUCCESS;
241 struct parser_state state;
244 parser_init(nft->nf_sock, &nft->cache, &state, &nft->output.msgs);
245 scanner = scanner_init(&state);
246 scanner_push_buffer(scanner, &indesc_cmdline, buf);
248 if (nft_run(nft, nft->nf_sock, &nft->cache, scanner,
249 &state, &nft->output.msgs) != 0)
250 rc = NFT_EXIT_FAILURE;
252 scanner_destroy(scanner);
278 int rc = NFT_EXIT_SUCCESS;
279 struct parser_state state;
283 rc = cache_update(nft->nf_sock, &nft->cache, CMD_INVALID, &msgs);
286 parser_init(nft->nf_sock, &nft->cache, &state, &nft->output.msgs);
287 scanner = scanner_init(&state);
288 if (scanner_read_file(scanner, filename, &internal_location) < 0)
289 return NFT_EXIT_FAILURE;
290 if (nft_run(nft, nft->nf_sock, &nft->cache, scanner,
291 &state, &nft->output.msgs) != 0)
292 rc = NFT_EXIT_FAILURE;
294 scanner_destroy(scanner);
358 bool batch_supported = netlink_batch_supported(nft->nf_sock, &seqnum);
359 struct nft_batch *batch = NULL;
361 if (!batch_supported)
364 batch = calloc(1,
sizeof(*batch));
368 batch->batch = mnl_batch_init();
369 mnl_batch_begin(batch->batch, mnl_seqnum_alloc(&nft->cache.seqnum));
371 batch->nl_ctx.msgs = &nft->output.msgs;
372 batch->nl_ctx.batch = batch->batch;
373 batch->nl_ctx.batch_supported = batch_supported;
374 batch->nl_ctx.octx = &nft->output;
375 batch->nl_ctx.nf_sock = nft->nf_sock;
376 batch->nl_ctx.cache = &nft->cache;
377 init_list_head(&batch->nl_ctx.list);
391 const char * buf,
size_t buflen)
393 int rc = NFT_EXIT_SUCCESS;
395 struct parser_state state;
397 struct cmd *cmd, *next;
398 struct netlink_ctx *ctx = &batch->nl_ctx;
401 parser_init(nft->nf_sock, &nft->cache, &state, &nft->output.msgs);
402 scanner = scanner_init(&state);
403 scanner_push_buffer(scanner, &indesc_cmdline, buf);
405 ret = nft_parse(scanner, &state);
406 if (ret != 0 || state.nerrs > 0) {
407 rc = NFT_EXIT_FAILURE;
411 list_for_each_entry(cmd, &state.cmds, list) {
413 ctx->seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum);
414 ret = do_command(ctx, cmd);
416 return NFT_EXIT_FAILURE;
419 list_for_each_entry_safe(cmd, next, &state.cmds, list) {
420 list_del(&cmd->list);
424 scanner_destroy(scanner);
440 mnl_batch_end(batch->batch, mnl_seqnum_alloc(&nft->cache.seqnum));
442 if (!mnl_batch_ready(batch->batch)) {
447 ret = netlink_batch_send(&batch->nl_ctx, &err_list);
449 struct mnl_err *err, *tmp;
450 list_for_each_entry_safe(err, tmp, &err_list, head) {
451 netlink_io_error(&batch->nl_ctx, NULL,
452 "Could not process rule: %s",
456 mnl_err_list_free(err);
472 mnl_batch_reset(batch->batch);
int nft_global_set_max_errors(unsigned int errors)
void nft_context_free(struct nft_ctx *nft)
int nft_run_command_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
int nft_batch_commit(struct nft_ctx *nft, struct nft_batch *batch)
void nft_context_set_print_func(struct nft_ctx *nft, int(*print)(void *ctx, const char *fmt,...), void *ctx)
void nft_global_deinit(void)
int nft_get_error(struct nft_ctx *nft, char *err_buf, size_t err_buf_len)
struct nft_batch * nft_batch_start(struct nft_ctx *nft)
int nft_batch_add(struct nft_ctx *nft, struct nft_batch *batch, const char *buf, size_t buflen)
int nft_run_command_from_filename(struct nft_ctx *nft, const char *filename)
void nft_global_init(void)
struct nft_ctx * nft_context_new(void)
void nft_batch_free(struct nft_batch *batch)