From patchwork Thu Oct 19 08:18:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827971 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhft0g5Fz9t3n for ; Thu, 19 Oct 2017 19:19:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752273AbdJSITd (ORCPT ); Thu, 19 Oct 2017 04:19:33 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49454 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752301AbdJSITd (ORCPT ); Thu, 19 Oct 2017 04:19:33 -0400 Received: from localhost ([::1]:43994 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e5639-0003q2-Uq; Thu, 19 Oct 2017 10:19:31 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 1/7] nft_ctx_free: Fix for wrong argument passed to cache_release Date: Thu, 19 Oct 2017 10:18:41 +0200 Message-Id: <20171019081847.16171-2-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org nft_ctx_free() should not refer to the global 'nft' variable, this will break as soon as the function is moved away from main.c. In order to use the cache reference from passed argument, the latter must not be const. Signed-off-by: Phil Sutter --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index b59c932ad4299..1b26838058a4a 100644 --- a/src/main.c +++ b/src/main.c @@ -305,13 +305,13 @@ static struct nft_ctx *nft_ctx_new(uint32_t flags) return ctx; } -static void nft_ctx_free(const struct nft_ctx *ctx) +static void nft_ctx_free(struct nft_ctx *ctx) { if (ctx->nf_sock) netlink_close_sock(ctx->nf_sock); iface_cache_release(); - cache_release(&nft->cache); + cache_release(&ctx->cache); xfree(ctx); nft_exit(); } From patchwork Thu Oct 19 08:18:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827970 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhfp22cFz9t3n for ; Thu, 19 Oct 2017 19:19:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752303AbdJSIT3 (ORCPT ); Thu, 19 Oct 2017 04:19:29 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49444 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752295AbdJSIT1 (ORCPT ); Thu, 19 Oct 2017 04:19:27 -0400 Received: from localhost ([::1]:43984 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e5633-0003pN-W9; Thu, 19 Oct 2017 10:19:26 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 2/7] libnftables: Move library stuff out of main.c Date: Thu, 19 Oct 2017 10:18:42 +0200 Message-Id: <20171019081847.16171-3-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Phil Sutter --- include/Makefile.am | 3 +- include/nftables.h | 65 +---------- include/nftables/Makefile.am | 1 + include/nftables/nftables.h | 88 +++++++++++++++ src/Makefile.am | 3 +- src/libnftables.c | 261 +++++++++++++++++++++++++++++++++++++++++++ src/main.c | 253 +---------------------------------------- 7 files changed, 356 insertions(+), 318 deletions(-) create mode 100644 include/nftables/Makefile.am create mode 100644 include/nftables/nftables.h create mode 100644 src/libnftables.c diff --git a/include/Makefile.am b/include/Makefile.am index 5dd73d81f427e..a74ffbfa8de0a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1,5 @@ -SUBDIRS = linux +SUBDIRS = linux \ + nftables noinst_HEADERS = cli.h \ datatype.h \ diff --git a/include/nftables.h b/include/nftables.h index 01d72a87212ea..a633e1a2cc2e2 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -4,63 +4,7 @@ #include #include #include - -enum numeric_level { - NUMERIC_NONE, - NUMERIC_ADDR, - NUMERIC_PORT, - NUMERIC_ALL, -}; - -enum debug_level { - DEBUG_SCANNER = 0x1, - DEBUG_PARSER = 0x2, - DEBUG_EVALUATION = 0x4, - DEBUG_NETLINK = 0x8, - DEBUG_MNL = 0x10, - DEBUG_PROTO_CTX = 0x20, - DEBUG_SEGTREE = 0x40, -}; - -#define INCLUDE_PATHS_MAX 16 - -struct output_ctx { - unsigned int numeric; - unsigned int stateless; - unsigned int ip2name; - unsigned int handle; - unsigned int echo; - FILE *output_fp; -}; - -struct nft_cache { - bool initialized; - struct list_head list; - uint32_t seqnum; -}; - -struct mnl_socket; - -struct nft_ctx { - struct mnl_socket *nf_sock; - const char *include_paths[INCLUDE_PATHS_MAX]; - unsigned int num_include_paths; - unsigned int parser_max_errors; - unsigned int debug_mask; - struct output_ctx output; - bool check; - struct nft_cache cache; - uint32_t flags; -}; - -#define NFT_CTX_DEFAULT 0 - -enum nftables_exit_codes { - NFT_EXIT_SUCCESS = 0, - NFT_EXIT_FAILURE = 1, - NFT_EXIT_NOMEM = 2, - NFT_EXIT_NONL = 3, -}; +#include struct input_descriptor; struct location { @@ -128,13 +72,6 @@ struct input_descriptor { off_t line_offset; }; -struct parser_state; -struct mnl_socket; - -int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, - void *scanner, struct parser_state *state, - struct list_head *msgs); - void ct_label_table_init(void); void mark_table_init(void); void gmp_init(void); diff --git a/include/nftables/Makefile.am b/include/nftables/Makefile.am new file mode 100644 index 0000000000000..9e31d519599c1 --- /dev/null +++ b/include/nftables/Makefile.am @@ -0,0 +1 @@ +noinst_HEADERS = nftables.h diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h new file mode 100644 index 0000000000000..052a77bfb5371 --- /dev/null +++ b/include/nftables/nftables.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 Eric Leblond + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef LIB_NFTABLES_H +#define LIB_NFTABLES_H + +struct parser_state; +struct mnl_socket; + +struct nft_cache { + bool initialized; + struct list_head list; + uint32_t seqnum; +}; + +#define INCLUDE_PATHS_MAX 16 + +struct output_ctx { + unsigned int numeric; + unsigned int stateless; + unsigned int ip2name; + unsigned int handle; + unsigned int echo; + FILE *output_fp; +}; + +struct nft_ctx { + struct mnl_socket *nf_sock; + const char *include_paths[INCLUDE_PATHS_MAX]; + unsigned int num_include_paths; + unsigned int parser_max_errors; + unsigned int debug_mask; + struct output_ctx output; + bool check; + struct nft_cache cache; + uint32_t flags; +}; + +enum debug_level { + DEBUG_SCANNER = 0x1, + DEBUG_PARSER = 0x2, + DEBUG_EVALUATION = 0x4, + DEBUG_NETLINK = 0x8, + DEBUG_MNL = 0x10, + DEBUG_PROTO_CTX = 0x20, + DEBUG_SEGTREE = 0x40, +}; + +enum numeric_level { + NUMERIC_NONE, + NUMERIC_ADDR, + NUMERIC_PORT, + NUMERIC_ALL, +}; + +/** + * Possible flags to pass to nft_ctx_new() + */ +#define NFT_CTX_DEFAULT 0 + +/** + * Exit codes returned by nft_run_cmd_from_*() + */ +enum nftables_exit_codes { + NFT_EXIT_SUCCESS = 0, + NFT_EXIT_FAILURE = 1, + NFT_EXIT_NOMEM = 2, + NFT_EXIT_NONL = 3, +}; + + +struct nft_ctx *nft_ctx_new(uint32_t flags); +void nft_ctx_free(struct nft_ctx *ctx); +FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); + +int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, + void *scanner, struct parser_state *state, + struct list_head *msgs); + +int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen); +int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename); + +#endif /* LIB_NFTABLES_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 99eef7bb849b6..4d613a731dfb9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,7 +56,8 @@ nft_SOURCES = main.c \ mergesort.c \ scanner.l \ tcpopt.c \ - parser_bison.y + parser_bison.y \ + libnftables.c if BUILD_CLI nft_SOURCES += cli.c diff --git a/src/libnftables.c b/src/libnftables.c new file mode 100644 index 0000000000000..187747c66af21 --- /dev/null +++ b/src/libnftables.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2017 Eric Leblond + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static int nft_netlink(struct nft_ctx *nft, + struct parser_state *state, struct list_head *msgs, + struct mnl_socket *nf_sock) +{ + uint32_t batch_seqnum, seqnum = 0; + struct nftnl_batch *batch; + struct netlink_ctx ctx; + struct cmd *cmd; + struct mnl_err *err, *tmp; + LIST_HEAD(err_list); + bool batch_supported = netlink_batch_supported(nf_sock, &seqnum); + int ret = 0; + + batch = mnl_batch_init(); + + batch_seqnum = mnl_batch_begin(batch, mnl_seqnum_alloc(&seqnum)); + list_for_each_entry(cmd, &state->cmds, list) { + memset(&ctx, 0, sizeof(ctx)); + ctx.msgs = msgs; + ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum); + ctx.batch = batch; + ctx.batch_supported = batch_supported; + ctx.octx = &nft->output; + ctx.nf_sock = nf_sock; + ctx.cache = &nft->cache; + ctx.debug_mask = nft->debug_mask; + init_list_head(&ctx.list); + ret = do_command(&ctx, cmd); + if (ret < 0) + goto out; + } + if (!nft->check) + mnl_batch_end(batch, mnl_seqnum_alloc(&seqnum)); + + if (!mnl_batch_ready(batch)) + goto out; + + ret = netlink_batch_send(&ctx, &err_list); + + list_for_each_entry_safe(err, tmp, &err_list, head) { + list_for_each_entry(cmd, &state->cmds, list) { + if (err->seqnum == cmd->seqnum || + err->seqnum == batch_seqnum) { + netlink_io_error(&ctx, &cmd->location, + "Could not process rule: %s", + strerror(err->err)); + errno = err->err; + if (err->seqnum == cmd->seqnum) { + mnl_err_list_free(err); + break; + } + } + } + } +out: + mnl_batch_reset(batch); + return ret; +} + +int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, + void *scanner, struct parser_state *state, + struct list_head *msgs) +{ + struct cmd *cmd, *next; + int ret; + + ret = nft_parse(nft, scanner, state); + if (ret != 0 || state->nerrs > 0) { + ret = -1; + goto err1; + } + + list_for_each_entry(cmd, &state->cmds, list) + nft_cmd_expand(cmd); + + ret = nft_netlink(nft, state, msgs, nf_sock); +err1: + list_for_each_entry_safe(cmd, next, &state->cmds, list) { + list_del(&cmd->list); + cmd_free(cmd); + } + + return ret; +} + +static void nft_init(void) +{ + mark_table_init(); + realm_table_rt_init(); + devgroup_table_init(); + realm_table_meta_init(); + ct_label_table_init(); + gmp_init(); +#ifdef HAVE_LIBXTABLES + xt_init(); +#endif +} + +static void nft_exit(void) +{ + ct_label_table_exit(); + realm_table_rt_exit(); + devgroup_table_exit(); + realm_table_meta_exit(); + mark_table_exit(); +} + +static void nft_ctx_netlink_init(struct nft_ctx *ctx) +{ + ctx->nf_sock = netlink_open_sock(); +} + +struct nft_ctx *nft_ctx_new(uint32_t flags) +{ + struct nft_ctx *ctx; + + nft_init(); + ctx = xzalloc(sizeof(struct nft_ctx)); + + ctx->include_paths[0] = DEFAULT_INCLUDE_PATH; + ctx->num_include_paths = 1; + ctx->parser_max_errors = 10; + init_list_head(&ctx->cache.list); + ctx->flags = flags; + + if (flags == NFT_CTX_DEFAULT) + nft_ctx_netlink_init(ctx); + + return ctx; +} + +void nft_ctx_free(struct nft_ctx *ctx) +{ + if (ctx->nf_sock) + netlink_close_sock(ctx->nf_sock); + + iface_cache_release(); + cache_release(&ctx->cache); + xfree(ctx); + nft_exit(); +} + +FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp) +{ + FILE *old = ctx->output.output_fp; + + ctx->output.output_fp = fp; + + return old; +} + +static const struct input_descriptor indesc_cmdline = { + .type = INDESC_BUFFER, + .name = "", +}; + +int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen) +{ + int rc = NFT_EXIT_SUCCESS; + struct parser_state state; + LIST_HEAD(msgs); + void *scanner; + FILE *fp; + + parser_init(nft->nf_sock, &nft->cache, &state, + &msgs, nft->debug_mask, &nft->output); + scanner = scanner_init(&state); + scanner_push_buffer(scanner, &indesc_cmdline, buf); + + if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0) + rc = NFT_EXIT_FAILURE; + + fp = nft_ctx_set_output(nft, stderr); + erec_print_list(&nft->output, &msgs, nft->debug_mask); + nft_ctx_set_output(nft, fp); + scanner_destroy(scanner); + + return rc; +} + +int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename) +{ + struct parser_state state; + LIST_HEAD(msgs); + void *scanner; + int rc; + FILE *fp; + + rc = cache_update(nft->nf_sock, &nft->cache, CMD_INVALID, &msgs, + nft->debug_mask, &nft->output); + if (rc < 0) + return NFT_EXIT_FAILURE; + + parser_init(nft->nf_sock, &nft->cache, &state, + &msgs, nft->debug_mask, &nft->output); + scanner = scanner_init(&state); + if (scanner_read_file(scanner, filename, &internal_location) < 0) { + rc = NFT_EXIT_FAILURE; + goto err; + } + + if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0) + rc = NFT_EXIT_FAILURE; +err: + fp = nft_ctx_set_output(nft, stderr); + erec_print_list(&nft->output, &msgs, nft->debug_mask); + nft_ctx_set_output(nft, fp); + scanner_destroy(scanner); + + return rc; +} + +int nft_print(struct output_ctx *octx, const char *fmt, ...) +{ + int ret; + va_list arg; + + if (!octx->output_fp) + return -1; + + va_start(arg, fmt); + ret = vfprintf(octx->output_fp, fmt, arg); + va_end(arg); + fflush(octx->output_fp); + + return ret; +} + +int nft_gmp_print(struct output_ctx *octx, const char *fmt, ...) +{ + int ret; + va_list arg; + + if (!octx->output_fp) + return -1; + + va_start(arg, fmt); + ret = gmp_vfprintf(octx->output_fp, fmt, arg); + va_end(arg); + fflush(octx->output_fp); + + return ret; +} + diff --git a/src/main.c b/src/main.c index 1b26838058a4a..a7da460f28ca5 100644 --- a/src/main.c +++ b/src/main.c @@ -18,15 +18,9 @@ #include #include -#include -#include #include -#include -#include -#include -#include -#include #include +#include static struct nft_ctx *nft; @@ -169,251 +163,6 @@ static const struct { }, }; -static const struct input_descriptor indesc_cmdline = { - .type = INDESC_BUFFER, - .name = "", -}; - -static int nft_netlink(struct nft_ctx *nft, - struct parser_state *state, struct list_head *msgs, - struct mnl_socket *nf_sock) -{ - uint32_t batch_seqnum, seqnum = 0; - struct nftnl_batch *batch; - struct netlink_ctx ctx; - struct cmd *cmd; - struct mnl_err *err, *tmp; - LIST_HEAD(err_list); - bool batch_supported = netlink_batch_supported(nf_sock, &seqnum); - int ret = 0; - - batch = mnl_batch_init(); - - batch_seqnum = mnl_batch_begin(batch, mnl_seqnum_alloc(&seqnum)); - list_for_each_entry(cmd, &state->cmds, list) { - memset(&ctx, 0, sizeof(ctx)); - ctx.msgs = msgs; - ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum); - ctx.batch = batch; - ctx.batch_supported = batch_supported; - ctx.octx = &nft->output; - ctx.nf_sock = nf_sock; - ctx.cache = &nft->cache; - ctx.debug_mask = nft->debug_mask; - init_list_head(&ctx.list); - ret = do_command(&ctx, cmd); - if (ret < 0) - goto out; - } - if (!nft->check) - mnl_batch_end(batch, mnl_seqnum_alloc(&seqnum)); - - if (!mnl_batch_ready(batch)) - goto out; - - ret = netlink_batch_send(&ctx, &err_list); - - list_for_each_entry_safe(err, tmp, &err_list, head) { - list_for_each_entry(cmd, &state->cmds, list) { - if (err->seqnum == cmd->seqnum || - err->seqnum == batch_seqnum) { - netlink_io_error(&ctx, &cmd->location, - "Could not process rule: %s", - strerror(err->err)); - errno = err->err; - if (err->seqnum == cmd->seqnum) { - mnl_err_list_free(err); - break; - } - } - } - } -out: - mnl_batch_reset(batch); - return ret; -} - -int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, - void *scanner, struct parser_state *state, - struct list_head *msgs) -{ - struct cmd *cmd, *next; - int ret; - - ret = nft_parse(nft, scanner, state); - if (ret != 0 || state->nerrs > 0) { - ret = -1; - goto err1; - } - - list_for_each_entry(cmd, &state->cmds, list) - nft_cmd_expand(cmd); - - ret = nft_netlink(nft, state, msgs, nf_sock); -err1: - list_for_each_entry_safe(cmd, next, &state->cmds, list) { - list_del(&cmd->list); - cmd_free(cmd); - } - - return ret; -} - -static void nft_init(void) -{ - mark_table_init(); - realm_table_rt_init(); - devgroup_table_init(); - realm_table_meta_init(); - ct_label_table_init(); - gmp_init(); -#ifdef HAVE_LIBXTABLES - xt_init(); -#endif -} - -static void nft_exit(void) -{ - ct_label_table_exit(); - realm_table_rt_exit(); - devgroup_table_exit(); - realm_table_meta_exit(); - mark_table_exit(); -} - -static void nft_ctx_netlink_init(struct nft_ctx *ctx) -{ - ctx->nf_sock = netlink_open_sock(); -} - -static struct nft_ctx *nft_ctx_new(uint32_t flags) -{ - struct nft_ctx *ctx; - - nft_init(); - ctx = xzalloc(sizeof(struct nft_ctx)); - - ctx->include_paths[0] = DEFAULT_INCLUDE_PATH; - ctx->num_include_paths = 1; - ctx->parser_max_errors = 10; - init_list_head(&ctx->cache.list); - ctx->flags = flags; - - if (flags == NFT_CTX_DEFAULT) - nft_ctx_netlink_init(ctx); - - return ctx; -} - -static void nft_ctx_free(struct nft_ctx *ctx) -{ - if (ctx->nf_sock) - netlink_close_sock(ctx->nf_sock); - - iface_cache_release(); - cache_release(&ctx->cache); - xfree(ctx); - nft_exit(); -} - -static FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp) -{ - FILE *old = ctx->output.output_fp; - - ctx->output.output_fp = fp; - - return old; -} - -static int nft_run_cmd_from_buffer(struct nft_ctx *nft, - char *buf, size_t buflen) -{ - int rc = NFT_EXIT_SUCCESS; - struct parser_state state; - LIST_HEAD(msgs); - void *scanner; - FILE *fp; - - parser_init(nft->nf_sock, &nft->cache, &state, - &msgs, nft->debug_mask, &nft->output); - scanner = scanner_init(&state); - scanner_push_buffer(scanner, &indesc_cmdline, buf); - - if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0) - rc = NFT_EXIT_FAILURE; - - fp = nft_ctx_set_output(nft, stderr); - erec_print_list(&nft->output, &msgs, nft->debug_mask); - nft_ctx_set_output(nft, fp); - scanner_destroy(scanner); - - return rc; -} - -static int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename) -{ - struct parser_state state; - LIST_HEAD(msgs); - void *scanner; - int rc; - FILE *fp; - - rc = cache_update(nft->nf_sock, &nft->cache, CMD_INVALID, &msgs, - nft->debug_mask, &nft->output); - if (rc < 0) - return NFT_EXIT_FAILURE; - - parser_init(nft->nf_sock, &nft->cache, &state, - &msgs, nft->debug_mask, &nft->output); - scanner = scanner_init(&state); - if (scanner_read_file(scanner, filename, &internal_location) < 0) { - rc = NFT_EXIT_FAILURE; - goto err; - } - - if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0) - rc = NFT_EXIT_FAILURE; -err: - fp = nft_ctx_set_output(nft, stderr); - erec_print_list(&nft->output, &msgs, nft->debug_mask); - nft_ctx_set_output(nft, fp); - scanner_destroy(scanner); - - return rc; -} - -int nft_print(struct output_ctx *octx, const char *fmt, ...) -{ - int ret; - va_list arg; - - if (!octx->output_fp) - return -1; - - va_start(arg, fmt); - ret = vfprintf(octx->output_fp, fmt, arg); - va_end(arg); - fflush(octx->output_fp); - - return ret; -} - -int nft_gmp_print(struct output_ctx *octx, const char *fmt, ...) -{ - int ret; - va_list arg; - - if (!octx->output_fp) - return -1; - - va_start(arg, fmt); - ret = gmp_vfprintf(octx->output_fp, fmt, arg); - va_end(arg); - fflush(octx->output_fp); - - return ret; -} - int main(int argc, char * const *argv) { char *buf = NULL, *filename = NULL; From patchwork Thu Oct 19 08:18:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827968 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhff6bR0z9t3n for ; Thu, 19 Oct 2017 19:19:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752255AbdJSITH (ORCPT ); Thu, 19 Oct 2017 04:19:07 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49404 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751908AbdJSITF (ORCPT ); Thu, 19 Oct 2017 04:19:05 -0400 Received: from localhost ([::1]:43944 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e562h-0003nf-SM; Thu, 19 Oct 2017 10:19:03 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 3/7] libnftables: Introduce nft_ctx_flush_cache() Date: Thu, 19 Oct 2017 10:18:43 +0200 Message-Id: <20171019081847.16171-4-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This allows an application to explicitly flush caches associated with a given nft context. Note that this is a bit inconsistent in that it releases the global interface cache, but nft_ctx_free() does the same so at least it's not a regression. Signed-off-by: Phil Sutter --- include/nftables/nftables.h | 1 + src/libnftables.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h index 052a77bfb5371..fbc6fd4252a97 100644 --- a/include/nftables/nftables.h +++ b/include/nftables/nftables.h @@ -77,6 +77,7 @@ enum nftables_exit_codes { struct nft_ctx *nft_ctx_new(uint32_t flags); void nft_ctx_free(struct nft_ctx *ctx); FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); +void nft_ctx_flush_cache(struct nft_ctx *ctx); int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, void *scanner, struct parser_state *state, diff --git a/src/libnftables.c b/src/libnftables.c index 187747c66af21..0de50c854d572 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -146,13 +146,18 @@ struct nft_ctx *nft_ctx_new(uint32_t flags) return ctx; } +void nft_ctx_flush_cache(struct nft_ctx *ctx) +{ + iface_cache_release(); + cache_release(&ctx->cache); +} + void nft_ctx_free(struct nft_ctx *ctx) { if (ctx->nf_sock) netlink_close_sock(ctx->nf_sock); - iface_cache_release(); - cache_release(&ctx->cache); + nft_ctx_flush_cache(ctx); xfree(ctx); nft_exit(); } From patchwork Thu Oct 19 08:18:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827966 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhfb3Wnqz9t3n for ; Thu, 19 Oct 2017 19:19:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752273AbdJSITN (ORCPT ); Thu, 19 Oct 2017 04:19:13 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49414 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751937AbdJSITK (ORCPT ); Thu, 19 Oct 2017 04:19:10 -0400 Received: from localhost ([::1]:43954 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e562n-0003o6-Ep; Thu, 19 Oct 2017 10:19:09 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 4/7] cli: Use nft_run_cmd_from_buffer() Date: Thu, 19 Oct 2017 10:18:44 +0200 Message-Id: <20171019081847.16171-5-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This simplifies CLI code and allows to reduce libnftables API by not exporting nft_run(). Since nft_run_cmd_from_buffer() takes care of scanner initialization and libmnl socket passed to cli_init() is present as nft_ctx field as well, signature of cli_init() can be reduced to just take nft_ctx pointer as single argument. Note that this change introduces two (possibly unwanted) side-effects: * Input descriptor passed to scanner_push_buffer() is changed from the CLI-specific one to the one used by nft_run_cmd_from_buffer(). In practice though, this doesn't make a difference: input descriptor types INDESC_CLI and INDESC_BUFFER are treated equally by erec_print(). Also, scanner_push_buffer() NULLs input descriptor name, so that is not used at all in latter code. * Error messages are printed to stderr instead of cli_nft->output. This could be fixed by introducing an 'error_output' field in nft_ctx for nft_run_cmd_from_buffer() to use when printing error messages. Signed-off-by: Phil Sutter --- include/cli.h | 6 ++---- include/nftables/nftables.h | 5 ----- src/cli.c | 24 +++--------------------- src/libnftables.c | 6 +++--- src/main.c | 3 +-- 5 files changed, 9 insertions(+), 35 deletions(-) diff --git a/include/cli.h b/include/cli.h index 3ae1c459bce2d..3780e0917969d 100644 --- a/include/cli.h +++ b/include/cli.h @@ -5,11 +5,9 @@ struct parser_state; #ifdef HAVE_LIBREADLINE -extern int cli_init(struct nft_ctx *nft, struct mnl_socket *nf_sock, - struct parser_state *state); +extern int cli_init(struct nft_ctx *nft); #else -static inline int cli_init(struct nft_ctx *nft, struct mnl_socket *nf_sock, - struct parser_state *state) +static inline int cli_init(struct nft_ctx *nft) { return -1; } diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h index fbc6fd4252a97..b91219d423df9 100644 --- a/include/nftables/nftables.h +++ b/include/nftables/nftables.h @@ -9,7 +9,6 @@ #ifndef LIB_NFTABLES_H #define LIB_NFTABLES_H -struct parser_state; struct mnl_socket; struct nft_cache { @@ -79,10 +78,6 @@ void nft_ctx_free(struct nft_ctx *ctx); FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); void nft_ctx_flush_cache(struct nft_ctx *ctx); -int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, - void *scanner, struct parser_state *state, - struct list_head *msgs); - int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen); int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename); diff --git a/src/cli.c b/src/cli.c index cadc3af6e8034..37351f2f8b04f 100644 --- a/src/cli.c +++ b/src/cli.c @@ -35,15 +35,7 @@ #define CMDLINE_HISTFILE ".nft.history" -static const struct input_descriptor indesc_cli = { - .type = INDESC_CLI, - .name = "", -}; - -static struct parser_state *state; static struct nft_ctx *cli_nft; -static struct mnl_socket *cli_nf_sock; -static void *scanner; static char histfile[PATH_MAX]; static char *multiline; static bool eof; @@ -134,14 +126,9 @@ static void cli_complete(char *line) xfree(line); line = s; - parser_init(cli_nf_sock, &cli_nft->cache, state, &msgs, - cli_nft->debug_mask, &cli_nft->output); - scanner_push_buffer(scanner, &indesc_cli, line); - nft_run(cli_nft, cli_nf_sock, scanner, state, &msgs); - erec_print_list(&cli_nft->output, &msgs, cli_nft->debug_mask); + nft_run_cmd_from_buffer(cli_nft, line, len + 2); xfree(line); - cache_release(&cli_nft->cache); - iface_cache_release(); + nft_ctx_flush_cache(cli_nft); } static char **cli_completion(const char *text, int start, int end) @@ -149,12 +136,10 @@ static char **cli_completion(const char *text, int start, int end) return NULL; } -int cli_init(struct nft_ctx *nft, struct mnl_socket *nf_sock, - struct parser_state *_state) +int cli_init(struct nft_ctx *nft) { const char *home; - cli_nf_sock = nf_sock; cli_nft = nft; rl_readline_name = "nft"; rl_instream = stdin; @@ -171,9 +156,6 @@ int cli_init(struct nft_ctx *nft, struct mnl_socket *nf_sock, read_history(histfile); history_set_pos(history_length); - state = _state; - scanner = scanner_init(state); - while (!eof) rl_callback_read_char(); return 0; diff --git a/src/libnftables.c b/src/libnftables.c index 0de50c854d572..d88c299c3647e 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -74,9 +74,9 @@ out: return ret; } -int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, - void *scanner, struct parser_state *state, - struct list_head *msgs) +static int nft_run(struct nft_ctx *nft, struct mnl_socket *nf_sock, + void *scanner, struct parser_state *state, + struct list_head *msgs) { struct cmd *cmd, *next; int ret; diff --git a/src/main.c b/src/main.c index a7da460f28ca5..3c107181305c7 100644 --- a/src/main.c +++ b/src/main.c @@ -168,7 +168,6 @@ int main(int argc, char * const *argv) char *buf = NULL, *filename = NULL; unsigned int len; bool interactive = false; - struct parser_state state; int i, val, rc; nft = nft_ctx_new(NFT_CTX_DEFAULT); @@ -272,7 +271,7 @@ int main(int argc, char * const *argv) } else if (filename != NULL) { rc = nft_run_cmd_from_filename(nft, filename); } else if (interactive) { - if (cli_init(nft, nft->nf_sock, &state) < 0) { + if (cli_init(nft) < 0) { fprintf(stderr, "%s: interactive CLI not supported in this build\n", argv[0]); exit(NFT_EXIT_FAILURE); From patchwork Thu Oct 19 08:18:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827969 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhfj36M3z9t3n for ; Thu, 19 Oct 2017 19:19:25 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752290AbdJSITW (ORCPT ); Thu, 19 Oct 2017 04:19:22 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49434 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752181AbdJSITV (ORCPT ); Thu, 19 Oct 2017 04:19:21 -0400 Received: from localhost ([::1]:43974 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e562y-0003of-If; Thu, 19 Oct 2017 10:19:20 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 5/7] libnftables: Introduce nft_ctx_set_dry_run() Date: Thu, 19 Oct 2017 10:18:45 +0200 Message-Id: <20171019081847.16171-6-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Provide a convenient interface to configure dry run mode. Signed-off-by: Phil Sutter --- include/nftables/nftables.h | 3 +++ src/libnftables.c | 5 +++++ src/main.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h index b91219d423df9..f0c9bbf3ba3fe 100644 --- a/include/nftables/nftables.h +++ b/include/nftables/nftables.h @@ -75,7 +75,10 @@ enum nftables_exit_codes { struct nft_ctx *nft_ctx_new(uint32_t flags); void nft_ctx_free(struct nft_ctx *ctx); + FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); +void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry); + void nft_ctx_flush_cache(struct nft_ctx *ctx); int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen); diff --git a/src/libnftables.c b/src/libnftables.c index d88c299c3647e..817f537e32618 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -171,6 +171,11 @@ FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp) return old; } +void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry) +{ + ctx->check = dry; +} + static const struct input_descriptor indesc_cmdline = { .type = INDESC_BUFFER, .name = "", diff --git a/src/main.c b/src/main.c index 3c107181305c7..8359367b78654 100644 --- a/src/main.c +++ b/src/main.c @@ -187,7 +187,7 @@ int main(int argc, char * const *argv) PACKAGE_NAME, PACKAGE_VERSION, RELEASE_NAME); exit(NFT_EXIT_SUCCESS); case OPT_CHECK: - nft->check = true; + nft_ctx_set_dry_run(nft, true); break; case OPT_FILE: filename = optarg; From patchwork Thu Oct 19 08:18:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827967 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhfc39bcz9t44 for ; Thu, 19 Oct 2017 19:19:20 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752285AbdJSITS (ORCPT ); Thu, 19 Oct 2017 04:19:18 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49424 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752277AbdJSITQ (ORCPT ); Thu, 19 Oct 2017 04:19:16 -0400 Received: from localhost ([::1]:43964 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e562t-0003oE-1Q; Thu, 19 Oct 2017 10:19:15 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 6/7] libnftables: Provide an API for include path handling Date: Thu, 19 Oct 2017 10:18:46 +0200 Message-Id: <20171019081847.16171-7-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org In order to keep the API simple, remove INCLUDE_PATHS_MAX restraint and dynamically allocate nft_ctx field include_paths instead. Signed-off-by: Phil Sutter --- include/nftables/nftables.h | 6 +++--- src/libnftables.c | 34 ++++++++++++++++++++++++++++++++-- src/main.c | 9 ++++----- src/scanner.l | 4 +--- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h index f0c9bbf3ba3fe..a752f20d74132 100644 --- a/include/nftables/nftables.h +++ b/include/nftables/nftables.h @@ -17,8 +17,6 @@ struct nft_cache { uint32_t seqnum; }; -#define INCLUDE_PATHS_MAX 16 - struct output_ctx { unsigned int numeric; unsigned int stateless; @@ -30,7 +28,7 @@ struct output_ctx { struct nft_ctx { struct mnl_socket *nf_sock; - const char *include_paths[INCLUDE_PATHS_MAX]; + char **include_paths; unsigned int num_include_paths; unsigned int parser_max_errors; unsigned int debug_mask; @@ -78,6 +76,8 @@ void nft_ctx_free(struct nft_ctx *ctx); FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry); +int nft_ctx_add_include_path(struct nft_ctx *ctx, const char *path); +void nft_ctx_clear_include_paths(struct nft_ctx *ctx); void nft_ctx_flush_cache(struct nft_ctx *ctx); diff --git a/src/libnftables.c b/src/libnftables.c index 817f537e32618..2f4275c9a0a94 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -6,10 +6,13 @@ * published by the Free Software Foundation. * */ +#define _GNU_SOURCE #include #include #include #include +#include +#include #include #include #include @@ -122,6 +125,33 @@ static void nft_exit(void) mark_table_exit(); } +int nft_ctx_add_include_path(struct nft_ctx *ctx, const char *path) +{ + char **tmp; + int pcount = ctx->num_include_paths; + + tmp = realloc(ctx->include_paths, (pcount + 1) * sizeof(char *)); + if (!tmp) + return -1; + + ctx->include_paths = tmp; + + if (asprintf(&ctx->include_paths[pcount], "%s", path) < 0) + return -1; + + ctx->num_include_paths++; + return 0; +} + +void nft_ctx_clear_include_paths(struct nft_ctx *ctx) +{ + while (ctx->num_include_paths) + xfree(ctx->include_paths[--ctx->num_include_paths]); + + xfree(ctx->include_paths); + ctx->include_paths = NULL; +} + static void nft_ctx_netlink_init(struct nft_ctx *ctx) { ctx->nf_sock = netlink_open_sock(); @@ -134,8 +164,7 @@ struct nft_ctx *nft_ctx_new(uint32_t flags) nft_init(); ctx = xzalloc(sizeof(struct nft_ctx)); - ctx->include_paths[0] = DEFAULT_INCLUDE_PATH; - ctx->num_include_paths = 1; + nft_ctx_add_include_path(ctx, DEFAULT_INCLUDE_PATH); ctx->parser_max_errors = 10; init_list_head(&ctx->cache.list); ctx->flags = flags; @@ -158,6 +187,7 @@ void nft_ctx_free(struct nft_ctx *ctx) netlink_close_sock(ctx->nf_sock); nft_ctx_flush_cache(ctx); + nft_ctx_clear_include_paths(ctx); xfree(ctx); nft_exit(); } diff --git a/src/main.c b/src/main.c index 8359367b78654..de5c115757f44 100644 --- a/src/main.c +++ b/src/main.c @@ -196,13 +196,12 @@ int main(int argc, char * const *argv) interactive = true; break; case OPT_INCLUDEPATH: - if (nft->num_include_paths >= INCLUDE_PATHS_MAX) { - fprintf(stderr, "Too many include paths " - "specified, max. %u\n", - INCLUDE_PATHS_MAX - 1); + if (nft_ctx_add_include_path(nft, optarg)) { + fprintf(stderr, + "Failed to add include path '%s'\n", + optarg); exit(NFT_EXIT_FAILURE); } - nft->include_paths[nft->num_include_paths++] = optarg; break; case OPT_NUMERIC: if (++nft->output.numeric > NUMERIC_ALL) { diff --git a/src/scanner.l b/src/scanner.l index 594073660c6b1..ee09775ebf1d9 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -794,9 +794,7 @@ int scanner_include_file(struct nft_ctx *nft, void *scanner, int ret = -1; if (search_in_include_path(filename)) { - for (i = 0; i < INCLUDE_PATHS_MAX; i++) { - if (nft->include_paths[i] == NULL) - break; + for (i = 0; i < nft->num_include_paths; i++) { ret = snprintf(buf, sizeof(buf), "%s/%s", nft->include_paths[i], filename); if (ret < 0 || ret >= PATH_MAX) { From patchwork Thu Oct 19 08:18:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 827965 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yHhfJ0q8mz9t3n for ; Thu, 19 Oct 2017 19:19:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752130AbdJSITC (ORCPT ); Thu, 19 Oct 2017 04:19:02 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:49392 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751908AbdJSITA (ORCPT ); Thu, 19 Oct 2017 04:19:00 -0400 Received: from localhost ([::1]:43934 helo=xsao) by orbyte.nwl.cc with esmtp (Exim 4.89) (envelope-from ) id 1e562c-0003nW-88; Thu, 19 Oct 2017 10:18:58 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: Eric Leblond , netfilter-devel@vger.kernel.org, Florian Westphal Subject: [nft PATCH 7/7] libnftables: Add remaining getters and setters Date: Thu, 19 Oct 2017 10:18:47 +0200 Message-Id: <20171019081847.16171-8-phil@nwl.cc> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171019081847.16171-1-phil@nwl.cc> References: <20171019081847.16171-1-phil@nwl.cc> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Provide API functions for remaining context settings changed by main.c, then hide struct nft_ctx definition from applications. This allows us to later change data structures internally without risk of breaking applications. Signed-off-by: Phil Sutter --- include/nftables.h | 27 +++++++++++++++++++++ include/nftables/nftables.h | 41 ++++++++++--------------------- src/libnftables.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 18 +++++++++----- 4 files changed, 111 insertions(+), 34 deletions(-) diff --git a/include/nftables.h b/include/nftables.h index a633e1a2cc2e2..ad72383303bdb 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -6,6 +6,33 @@ #include #include +struct nft_cache { + bool initialized; + struct list_head list; + uint32_t seqnum; +}; + +struct output_ctx { + unsigned int numeric; + unsigned int stateless; + unsigned int ip2name; + unsigned int handle; + unsigned int echo; + FILE *output_fp; +}; + +struct nft_ctx { + struct mnl_socket *nf_sock; + char **include_paths; + unsigned int num_include_paths; + unsigned int parser_max_errors; + unsigned int debug_mask; + struct output_ctx output; + bool check; + struct nft_cache cache; + uint32_t flags; +}; + struct input_descriptor; struct location { const struct input_descriptor *indesc; diff --git a/include/nftables/nftables.h b/include/nftables/nftables.h index a752f20d74132..2bc3061457257 100644 --- a/include/nftables/nftables.h +++ b/include/nftables/nftables.h @@ -9,34 +9,7 @@ #ifndef LIB_NFTABLES_H #define LIB_NFTABLES_H -struct mnl_socket; - -struct nft_cache { - bool initialized; - struct list_head list; - uint32_t seqnum; -}; - -struct output_ctx { - unsigned int numeric; - unsigned int stateless; - unsigned int ip2name; - unsigned int handle; - unsigned int echo; - FILE *output_fp; -}; - -struct nft_ctx { - struct mnl_socket *nf_sock; - char **include_paths; - unsigned int num_include_paths; - unsigned int parser_max_errors; - unsigned int debug_mask; - struct output_ctx output; - bool check; - struct nft_cache cache; - uint32_t flags; -}; +struct nft_ctx; enum debug_level { DEBUG_SCANNER = 0x1, @@ -78,6 +51,18 @@ FILE *nft_ctx_set_output(struct nft_ctx *ctx, FILE *fp); void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry); int nft_ctx_add_include_path(struct nft_ctx *ctx, const char *path); void nft_ctx_clear_include_paths(struct nft_ctx *ctx); +enum numeric_level nft_ctx_output_get_numeric(struct nft_ctx *ctx); +void nft_ctx_output_set_numeric(struct nft_ctx *ctx, enum numeric_level level); +bool nft_ctx_output_get_stateless(struct nft_ctx *ctx); +void nft_ctx_output_set_stateless(struct nft_ctx *ctx, bool val); +bool nft_ctx_output_get_ip2name(struct nft_ctx *ctx); +void nft_ctx_output_set_ip2name(struct nft_ctx *ctx, bool val); +unsigned int nft_ctx_output_get_debug(struct nft_ctx *ctx); +void nft_ctx_output_set_debug(struct nft_ctx *ctx, unsigned int mask); +bool nft_ctx_output_get_handle(struct nft_ctx *ctx); +void nft_ctx_output_set_handle(struct nft_ctx *ctx, bool val); +bool nft_ctx_output_get_echo(struct nft_ctx *ctx); +void nft_ctx_output_set_echo(struct nft_ctx *ctx, bool val); void nft_ctx_flush_cache(struct nft_ctx *ctx); diff --git a/src/libnftables.c b/src/libnftables.c index 2f4275c9a0a94..925c96d1272a3 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -206,6 +206,65 @@ void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry) ctx->check = dry; } +enum numeric_level nft_ctx_output_get_numeric(struct nft_ctx *ctx) +{ + return ctx->output.numeric; +} + +void nft_ctx_output_set_numeric(struct nft_ctx *ctx, enum numeric_level level) +{ + ctx->output.numeric = level; +} + +bool nft_ctx_output_get_stateless(struct nft_ctx *ctx) +{ + return ctx->output.stateless; +} + +void nft_ctx_output_set_stateless(struct nft_ctx *ctx, bool val) +{ + ctx->output.stateless = val; +} + +bool nft_ctx_output_get_ip2name(struct nft_ctx *ctx) +{ + return ctx->output.ip2name; +} + +void nft_ctx_output_set_ip2name(struct nft_ctx *ctx, bool val) +{ + ctx->output.ip2name = val; +} + +unsigned int nft_ctx_output_get_debug(struct nft_ctx *ctx) +{ + return ctx->debug_mask; +} +void nft_ctx_output_set_debug(struct nft_ctx *ctx, unsigned int mask) +{ + ctx->debug_mask = mask; +} + +bool nft_ctx_output_get_handle(struct nft_ctx *ctx) +{ + return ctx->output.handle; +} + +void nft_ctx_output_set_handle(struct nft_ctx *ctx, bool val) +{ + ctx->output.handle = val; +} + +bool nft_ctx_output_get_echo(struct nft_ctx *ctx) +{ + return ctx->output.echo; +} + +void nft_ctx_output_set_echo(struct nft_ctx *ctx, bool val) +{ + ctx->output.echo = val; +} + static const struct input_descriptor indesc_cmdline = { .type = INDESC_BUFFER, .name = "", diff --git a/src/main.c b/src/main.c index de5c115757f44..c65966bcf5995 100644 --- a/src/main.c +++ b/src/main.c @@ -169,6 +169,8 @@ int main(int argc, char * const *argv) unsigned int len; bool interactive = false; int i, val, rc; + enum numeric_level numeric; + unsigned int debug_mask; nft = nft_ctx_new(NFT_CTX_DEFAULT); nft_ctx_set_output(nft, stdout); @@ -204,20 +206,23 @@ int main(int argc, char * const *argv) } break; case OPT_NUMERIC: - if (++nft->output.numeric > NUMERIC_ALL) { + numeric = nft_ctx_output_get_numeric(nft); + if (numeric == NUMERIC_ALL) { fprintf(stderr, "Too many numeric options " "used, max. %u\n", NUMERIC_ALL); exit(NFT_EXIT_FAILURE); } + nft_ctx_output_set_numeric(nft, numeric + 1); break; case OPT_STATELESS: - nft->output.stateless++; + nft_ctx_output_set_stateless(nft, true); break; case OPT_IP2NAME: - nft->output.ip2name++; + nft_ctx_output_set_ip2name(nft, true); break; case OPT_DEBUG: + debug_mask = nft_ctx_output_get_debug(nft); for (;;) { unsigned int i; char *end; @@ -229,7 +234,7 @@ int main(int argc, char * const *argv) for (i = 0; i < array_size(debug_param); i++) { if (strcmp(debug_param[i].name, optarg)) continue; - nft->debug_mask |= debug_param[i].level; + debug_mask |= debug_param[i].level; break; } @@ -243,12 +248,13 @@ int main(int argc, char * const *argv) break; optarg = end + 1; } + nft_ctx_output_set_debug(nft, debug_mask); break; case OPT_HANDLE_OUTPUT: - nft->output.handle++; + nft_ctx_output_set_handle(nft, true); break; case OPT_ECHO: - nft->output.echo++; + nft_ctx_output_set_echo(nft, true); break; case OPT_INVALID: exit(NFT_EXIT_FAILURE);