From patchwork Thu Jun 14 12:02:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phil Sutter X-Patchwork-Id: 929388 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=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=nwl.cc Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4162L85HWxz9s19 for ; Thu, 14 Jun 2018 22:02:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936003AbeFNMCX (ORCPT ); Thu, 14 Jun 2018 08:02:23 -0400 Received: from orbyte.nwl.cc ([151.80.46.58]:55614 "EHLO orbyte.nwl.cc" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755010AbeFNMCW (ORCPT ); Thu, 14 Jun 2018 08:02:22 -0400 Received: from localhost ([::1]:42658 helo=tatos) by orbyte.nwl.cc with esmtp (Exim 4.90_1) (envelope-from ) id 1fTQxJ-0004w3-7z; Thu, 14 Jun 2018 14:02:21 +0200 From: Phil Sutter To: Pablo Neira Ayuso Cc: netfilter-devel@vger.kernel.org Subject: [nft PATCH] doc: Add libnftables man page Date: Thu, 14 Jun 2018 14:02:11 +0200 Message-Id: <20180614120211.4950-1-phil@nwl.cc> X-Mailer: git-send-email 2.17.0 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org For now, use a single man page to describe all the functions exported by libnftables. Signed-off-by: Phil Sutter --- doc/.gitignore | 2 + doc/Makefile.am | 10 +- doc/libnftables.adoc | 315 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 doc/libnftables.adoc diff --git a/doc/.gitignore b/doc/.gitignore index 9a2e16a01cf95..30ec6a357d487 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,3 +1,5 @@ +libnftables.3 +libnftables.pdf libnftables-json.5 libnftables-json.pdf nft.8 diff --git a/doc/Makefile.am b/doc/Makefile.am index a4ba30b87da5f..a774987d9c938 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,9 +1,9 @@ if BUILD_MAN -man_MANS = nft.8 libnftables-json.5 +man_MANS = nft.8 libnftables-json.5 libnftables.3 endif if BUILD_PDF -pdf_DATA = nft.pdf libnftables-json.pdf +pdf_DATA = nft.pdf libnftables-json.pdf libnftables.pdf endif pdfdir=${docdir}/pdf @@ -17,12 +17,16 @@ pdfdir=${docdir}/pdf .adoc.pdf: a2x --doctype manpage --format pdf $< +.adoc.3: + a2x --doctype manpage --format manpage $< + .adoc.5: a2x --doctype manpage --format manpage $< -EXTRA_DIST = nft.xml libnftables-json.adoc +EXTRA_DIST = nft.xml libnftables-json.adoc libnftables.adoc CLEANFILES = \ nft.pdf nft.8 \ libnftables-json.pdf libnftables-json.5 \ + libnftables.pdf libnftables.3 *~ diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc new file mode 100644 index 0000000000000..c947ef37f8f1d --- /dev/null +++ b/doc/libnftables.adoc @@ -0,0 +1,315 @@ +libnftables(3) +============== +Phil Sutter +:doctype: manpage +:compat-mode!: + +== NAME +libnftables - nftables frontend library + +== SYNOPSIS +[verse] +____ +*#include + +struct nft_ctx *nft_ctx_new(uint32_t* 'flags'*); +void nft_ctx_free(struct nft_ctx* '\*ctx'*); + +bool nft_ctx_get_dry_run(struct nft_ctx* '\*ctx'*); +void nft_ctx_set_dry_run(struct nft_ctx* '\*ctx'*, bool* 'dry'*); + +enum nft_numeric_level nft_ctx_output_get_numeric(struct nft_ctx* '\*ctx'*); +void nft_ctx_output_set_numeric(struct nft_ctx* '\*ctx'*, + enum nft_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'*); + +bool nft_ctx_output_get_json(struct nft_ctx* '\*ctx'*); +void nft_ctx_output_set_json(struct nft_ctx* '\*ctx'*, bool* 'val'*); + +FILE *nft_ctx_set_output(struct nft_ctx* '\*ctx'*, FILE* '\*fp'*); +int nft_ctx_buffer_output(struct nft_ctx* '\*ctx'*); +int nft_ctx_unbuffer_output(struct nft_ctx* '\*ctx'*); +const char *nft_ctx_get_output_buffer(struct nft_ctx* '\*ctx'*); + +FILE *nft_ctx_set_error(struct nft_ctx* '\*ctx'*, FILE* '\*fp'*); +int nft_ctx_buffer_error(struct nft_ctx* '\*ctx'*); +int nft_ctx_unbuffer_error(struct nft_ctx* '\*ctx'*); +const char *nft_ctx_get_error_buffer(struct nft_ctx* '\*ctx'*); + +int nft_ctx_add_include_path(struct nft_ctx* '\*ctx'*, const char* '\*path'*); +void nft_ctx_clear_include_paths(struct nft_ctx* '\*ctx'*); + +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'*);* + +Link with '-lnftables'. +____ + +== DESCRIPTION +This library was designed with nftables integration into applications in mind. +It's API is therefore kept as simple as possible, which somewhat limits its flexibility. +Due to support for JSON markup of input and output though, convenience in constructing and parsing of input and output data may be achieved by using a third-party library such as *libjansson*. + +At the very basic level, one has to allocate a new object of type *struct nft_ctx* using *nft_ctx_new*() function, then pass commands via *nft_run_cmd_from_buffer*() or *nft_run_cmd_from_filename*() functions. +By default, any output is written to *stdout* (or *stderr* for error messages). +These file pointers may be changed using *nft_ctx_set_output*() and *nft_ctx_set_error*() functions. +On top of that, it is possible to have any output buffered by the library for later retrieval as a static buffer. +See *nft_ctx_buffer_output*() and *nft_ctx_buffer_error*() functions for details. + +=== nft_ctx_new() and nft_ctx_free() +These functions aid in nft context management. +In order to make use of the library, at least one context object has to be allocated. +The context holds temporary data such as caches, library configuration and (if enabled) output and error buffers. + +The *nft_ctx_new*() function allocates and returns a new context object. +The parameter 'flags' is unused at this point and should be set to zero. +For convenience, the macro *NFT_CTX_DEFAULT* is defined to that value. + +The *nft_ctx_free*() function frees the context object pointed to by 'ctx' including any caches or buffers it may hold. + +=== nft_ctx_get_dry_run() and nft_ctx_set_dry_run() +Dry-run setting controls whether ruleset changes are actually committed on kernel side or not. +It allows to check whether a given operation would succeed without making actual changes to the ruleset. +The default setting is *false*. + +The *nft_ctx_get_dry_run*() function returns the dry-run setting's value contained in 'ctx'. + +The *nft_ctx_set_dry_run*() function sets the dry-run setting in 'ctx' to the value of 'dry'. + +=== nft_ctx_output_get_numeric() and nft_ctx_output_set_numeric() +These functions allow control over value representation in library output. +For instance, port numbers by default are printed by their name (as listed in '/etc/services' file), if known. +In libnftables, numeric output is leveled, defined as such: + +---- +enum nft_numeric_level { + NFT_NUMERIC_NONE, + NFT_NUMERIC_ADDR, + NFT_NUMERIC_PORT, + NFT_NUMERIC_ALL, +}; +---- + +Each numeric level includes all previous ones: + +NFT_NUMERIC_NONE:: + No conversion into numeric format happens, this is the default. +NFT_NUMERIC_ADDR:: + Network addresses are always converted into numeric format. +NFT_NUMERIC_PORT:: + Network services are always converted into numeric format. +NFT_NUMERIC_ALL:: + Everything is converted into numeric format. + +The default numeric level is *NFT_NUMERIC_NONE*. + +The *nft_ctx_output_get_numeric*() function returns the numeric output setting's value contained in 'ctx'. + +The *nft_ctx_output_set_numeric*() function sets the numeric output setting in 'ctx' to the value of 'level'. + +=== nft_ctx_output_get_stateless() and nft_ctx_output_set_stateless() +In nftables, there are stateful objects, i.e. ruleset elements which carry run-time data. +For example the *counter* statement holds packet and byte counter values, making it stateful. +If stateless output has been requested, this data is omitted when printing ruleset elements. +The default setting is *false*. + + +The *nft_ctx_output_get_stateless*() function returns the stateless output setting's value in 'ctx'. + +The *nft_ctx_output_set_stateless*() function sets the stateless output setting in 'ctx' to the value of 'val'. + +=== nft_ctx_output_get_ip2name() and nft_ctx_output_set_ip2name() +The ip2name setting controls whether reverse DNS lookups are performed for IP addresses when printing them. +Note that this may add significant delay to *list* commands depending on DNS resolver speed. +The default setting is *false*. + +The *nft_ctx_output_get_ip2name*() function returns the ip2name output setting's value in 'ctx'. + +The *nft_ctx_output_set_ip2name*() function sets the ip2name output setting in 'ctx' to the value of 'val'. + +=== nft_ctx_output_get_debug() and nft_ctx_output_set_debug() +Libnftables supports separate debugging of different parts of its internals. +To facilitate this, debugging output is controlled via a bit mask. +The bits are defined as such: + +---- +enum nft_debug_level { + NFT_DEBUG_SCANNER = 0x1, + NFT_DEBUG_PARSER = 0x2, + NFT_DEBUG_EVALUATION = 0x4, + NFT_DEBUG_NETLINK = 0x8, + NFT_DEBUG_MNL = 0x10, + NFT_DEBUG_PROTO_CTX = 0x20, + NFT_DEBUG_SEGTREE = 0x40, +}; +---- + +NFT_DEBUG_SCANNER:: + Print LEX debug output. +NFT_DEBUG_PARSER:: + Print YACC debug output. +NFT_DEBUG_EVALUATION:: + Print debug information about evaluation phase. +NFT_DEBUG_NETLINK:: + Print netlink debug output. +NFT_DEBUG_MNL:: + Print libmnl debug output. +NFT_DEBUG_PROTO_CTX:: + Print protocol context debug output. +NFT_DEBUG_SEGTREE:: + Print segtree (i.e. interval sets) debug output. + +The *nft_ctx_output_get_debug*() function returns the debug output setting's value in 'ctx'. + +The *nft_ctx_output_set_debug*() function sets the debug output setting in 'ctx' to the value of 'mask'. + +=== nft_ctx_output_get_handle() and nft_ctx_output_set_handle() +Upon insertion into the ruleset, some elements are assigned a unique handle for identification purposes. +For example, when deleting a table or chain, it may be identified either by name or handle. +Rules on the other hand must be deleted by handle because there is no other way to uniquely identify them. +These functions allow to control whether ruleset listings should include handles or not. +The default setting is *false*. + +The *nft_ctx_output_get_handle*() function returns the handle output setting's value in 'ctx'. + +The *nft_ctx_output_set_handle*() function sets the handle output setting in 'ctx' to the value of 'val'. + +=== nft_ctx_output_get_echo() and nft_ctx_output_set_echo() +The echo setting makes libnftables print the changes once they are committed to the kernel, just like a running instance of *nft monitor* would. +Amongst other things, this allows to retrieve an added rule's handle atomically. +The default setting is *false*. + +The *nft_ctx_output_get_echo*() function returns the echo output setting's value in 'ctx'. + +The *nft_ctx_output_set_echo*() function sets the echo output setting in 'ctx' to the value of 'val'. + +=== nft_ctx_output_get_json() and nft_ctx_output_set_json() +If enabled at compile-time, libnftables accepts input in JSON format and is able to print output in JSON format as well. +See *libnftables-json*(5) for a description of the supported schema. +These functions control JSON output format, input is auto-detected. +The default setting is *false*. + +The *nft_ctx_output_get_json*() function returns the JSON output setting's value in 'ctx'. + +The *nft_ctx_output_set_json*() function sets the JSON output setting in 'ctx' to the value of 'val'. + +=== Controlling library standard and error output +By default, any output from the library (e.g., after a *list* command) is written to 'stdout' and any error messages are written to 'stderr'. +To give applications control over them, there are functions to assign custom file pointers as well as having the library buffer what would be written for later retrieval in a static buffer. +This buffer is guaranteed to be null-terminated and must not be freed. +Note that the retrieval functions rewind the buffer position indicator. +Further library output will probably overwrite the buffer content and potentially render it invalid (due to reallocation). + +The *nft_ctx_set_output*() and *nft_ctx_set_error*() functions set the output or error file pointer in 'ctx' to the value of 'fp'. +They return the previous value to aid in temporary file pointer overrides. +On error, these functions return NULL. +This happens only if 'fp' is NULL or invalid (tested using *ferror*() function). + +The *nft_ctx_buffer_output*() and *nft_ctx_buffer_error*() functions enable library standard or error output buffering. +The functions return zero on success, non-zero otherwise. +This may happen if the internal call to *fopencookie*() failed. + +The *nft_ctx_unbuffer_output*() and *nft_ctx_unbuffer_error*() functions disable library standard or error output buffering. +On failure, the functions return non-zero which may only happen if buffering wasn't enabled at the time the function was called. + +The *nft_ctx_get_output_buffer*() and *nft_ctx_get_error_buffer*() functions return a pointer to the buffered output (which may be empty). + +=== nft_ctx_add_include_path() and nft_ctx_clear_include_path() +The *include* command in nftables rulesets allows to outsource parts of the ruleset into a different file. +The include path defines where these files are searched for. +Libnftables allows to have a list of those paths which are searched in order. +The default include path list contains a single compile-time defined entry (typically '/etc/'). + +The *nft_ctx_add_include_path*() function extends the list of include paths in 'ctx' by the one pointed to in 'path'. +The function returns zero on success or non-zero if memory allocation failed. + +The *nft_ctx_clear_include_paths*() function removes all include paths, even the built-in default one. + +=== nft_run_cmd_from_buffer() and nft_run_cmd_from_filename() +These functions perform the actual work of parsing user input into nftables commands and executing them. + +The *nft_run_cmd_from_buffer*() function passes the command(s) contained in 'buf' with size 'buflen' to the library, respecting settings and state in 'nft'. + +The *nft_run_cmd_from_filename*() function passes the content of 'filename' to the library, respecting settings and state in 'nft'. + +Both functions return zero on success. +A non-zero return code indicates an error while parsing or executing the command. +This event should be accompanied by an error message written to library error output. + +== EXAMPLE +---- +#include +#include +#include + +int main(void) +{ + char *list_cmd = "list ruleset"; + struct nft_ctx *nft; + const char *output, *p; + char buf[256]; + int rc = 0; + + nft = nft_ctx_new(NFT_CTX_DEFAULT); + if (!nft) + return 1; + + while (1) { + if (nft_ctx_buffer_output(nft) || + nft_run_cmd_from_buffer(nft, list_cmd, strlen(list_cmd))) { + rc = 1; + break; + } + output = nft_ctx_get_output_buffer(nft); + if (strlen(output)) { + printf("\nThis is the current ruleset:\n| "); + for (p = output; *(p + 1); p++) { + if (*p == '\n') + printf("\n| "); + else + putchar(*p); + } + putchar('\n'); + } else { + printf("\nCurrent ruleset is empty.\n"); + } + nft_ctx_unbuffer_output(nft); + + printf("\nEnter command ('q' to quit): "); + fflush(stdout); + fgets(buf, 256, stdin); + if (strlen(buf)) + buf[strlen(buf) - 1] = '\0'; + + if (buf[0] == 'q' && buf[1] == '\0') + break; + + if (nft_run_cmd_from_buffer(nft, buf, strlen(buf))) { + rc = 1; + break; + } + } + + nft_ctx_free(nft); + return rc; +} +---- + +== SEE ALSO +*libnftables-json*(5), *nft*(8)