|
Packit |
c5a612 |
libnftables(3)
|
|
Packit |
c5a612 |
==============
|
|
Packit |
c5a612 |
Phil Sutter <phil@nwl.cc>
|
|
Packit |
c5a612 |
:doctype: manpage
|
|
Packit |
c5a612 |
:compat-mode!:
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
== NAME
|
|
Packit |
c5a612 |
libnftables - nftables frontend library
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
== SYNOPSIS
|
|
Packit |
c5a612 |
[verse]
|
|
Packit |
c5a612 |
____
|
|
Packit |
c5a612 |
*#include <nftables/libnftables.h>
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
struct nft_ctx *nft_ctx_new(uint32_t* 'flags'*);
|
|
Packit |
c5a612 |
void nft_ctx_free(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
bool nft_ctx_get_dry_run(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
void nft_ctx_set_dry_run(struct nft_ctx* '\*ctx'*, bool* 'dry'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
unsigned int nft_ctx_output_get_flags(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
void nft_ctx_output_set_flags(struct nft_ctx* '\*ctx'*, unsigned int* 'flags'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
unsigned int nft_ctx_output_get_debug(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
void nft_ctx_output_set_debug(struct nft_ctx* '\*ctx'*, unsigned int* 'mask'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
FILE *nft_ctx_set_output(struct nft_ctx* '\*ctx'*, FILE* '\*fp'*);
|
|
Packit |
c5a612 |
int nft_ctx_buffer_output(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
int nft_ctx_unbuffer_output(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
const char *nft_ctx_get_output_buffer(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
FILE *nft_ctx_set_error(struct nft_ctx* '\*ctx'*, FILE* '\*fp'*);
|
|
Packit |
c5a612 |
int nft_ctx_buffer_error(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
int nft_ctx_unbuffer_error(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
const char *nft_ctx_get_error_buffer(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
int nft_ctx_add_include_path(struct nft_ctx* '\*ctx'*, const char* '\*path'*);
|
|
Packit |
c5a612 |
void nft_ctx_clear_include_paths(struct nft_ctx* '\*ctx'*);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
int nft_run_cmd_from_buffer(struct nft_ctx* '\*nft'*, const char* '\*buf'*);
|
|
Packit |
c5a612 |
int nft_run_cmd_from_filename(struct nft_ctx* '\*nft'*,
|
|
Packit |
c5a612 |
const char* '\*filename'*);*
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
Link with '-lnftables'.
|
|
Packit |
c5a612 |
____
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
== DESCRIPTION
|
|
Packit |
c5a612 |
This library was designed with nftables integration into applications in mind.
|
|
Packit |
c5a612 |
Its API is therefore kept as simple as possible, which somewhat limits its flexibility.
|
|
Packit |
c5a612 |
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*.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
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.
|
|
Packit |
c5a612 |
By default, any output is written to *stdout* (or *stderr* for error messages).
|
|
Packit |
c5a612 |
These file pointers may be changed using *nft_ctx_set_output*() and *nft_ctx_set_error*() functions.
|
|
Packit |
c5a612 |
On top of that, it is possible to have any output buffered by the library for later retrieval as a static buffer.
|
|
Packit |
c5a612 |
See *nft_ctx_buffer_output*() and *nft_ctx_buffer_error*() functions for details.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_ctx_new() and nft_ctx_free()
|
|
Packit |
c5a612 |
These functions aid in nft context management.
|
|
Packit |
c5a612 |
In order to make use of the library, at least one context object has to be allocated.
|
|
Packit |
c5a612 |
The context holds temporary data such as caches, library configuration and (if enabled) output and error buffers.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_new*() function allocates and returns a new context object.
|
|
Packit |
c5a612 |
The parameter 'flags' is unused at this point and should be set to zero.
|
|
Packit |
c5a612 |
For convenience, the macro *NFT_CTX_DEFAULT* is defined to that value.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_free*() function frees the context object pointed to by 'ctx', including any caches or buffers it may hold.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_ctx_get_dry_run() and nft_ctx_set_dry_run()
|
|
Packit |
c5a612 |
Dry-run setting controls whether ruleset changes are actually committed on kernel side or not.
|
|
Packit |
c5a612 |
It allows to check whether a given operation would succeed without making actual changes to the ruleset.
|
|
Packit |
c5a612 |
The default setting is *false*.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_get_dry_run*() function returns the dry-run setting's value contained in 'ctx'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_set_dry_run*() function sets the dry-run setting in 'ctx' to the value of 'dry'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_ctx_output_get_flags() and nft_ctx_output_set_flags()
|
|
Packit |
c5a612 |
The flags setting controls the output format.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
enum {
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_REVERSEDNS = (1 << 0),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_SERVICE = (1 << 1),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_STATELESS = (1 << 2),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_HANDLE = (1 << 3),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_JSON = (1 << 4),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_ECHO = (1 << 5),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_GUID = (1 << 6),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_PROTO = (1 << 7),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_PRIO = (1 << 8),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_SYMBOL = (1 << 9),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_TIME = (1 << 10),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_ALL = (NFT_CTX_OUTPUT_NUMERIC_PROTO |
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_PRIO |
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_TIME),
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_TERSE = (1 << 11),
|
|
Packit |
c5a612 |
};
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_REVERSEDNS::
|
|
Packit |
c5a612 |
Reverse DNS lookups are performed for IP addresses when printing.
|
|
Packit |
c5a612 |
Note that this may add significant delay to *list* commands depending on DNS resolver speed.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_SERVICE::
|
|
Packit |
c5a612 |
Print port numbers as services as described in the /etc/services file.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_STATELESS::
|
|
Packit |
c5a612 |
If stateless output has been requested, then stateful data is not printed.
|
|
Packit |
c5a612 |
Stateful data refers to those objects that carry run-time data, e.g. the *counter* statement holds packet and byte counter values, making it stateful.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_HANDLE::
|
|
Packit |
c5a612 |
Upon insertion into the ruleset, some elements are assigned a unique handle for identification purposes.
|
|
Packit |
c5a612 |
For example, when deleting a table or chain, it may be identified either by name or handle.
|
|
Packit |
c5a612 |
Rules on the other hand must be deleted by handle, because there is no other way to uniquely identify them.
|
|
Packit |
c5a612 |
This flag makes ruleset listings include handle values.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_JSON::
|
|
Packit |
c5a612 |
If enabled at compile-time, libnftables accepts input in JSON format and is able to print output in JSON format as well.
|
|
Packit |
c5a612 |
See *libnftables-json*(5) for a description of the supported schema.
|
|
Packit |
c5a612 |
This flag controls JSON output format, input is auto-detected.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_ECHO::
|
|
Packit |
c5a612 |
The echo setting makes libnftables print the changes once they are committed to the kernel, just like a running instance of *nft monitor* would.
|
|
Packit |
c5a612 |
Amongst other things, this allows to retrieve an added rule's handle atomically.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_GUID::
|
|
Packit |
c5a612 |
Display UID and GID as described in the /etc/passwd and /etc/group files.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_PROTO::
|
|
Packit |
c5a612 |
Display layer 4 protocol numerically.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_PRIO::
|
|
Packit |
c5a612 |
Display base chain priority numerically.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_SYMBOL::
|
|
Packit |
c5a612 |
Display expression datatype as numeric value.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_TIME::
|
|
Packit |
c5a612 |
Display time, day and hour values in numeric format.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_NUMERIC_ALL::
|
|
Packit |
c5a612 |
Display all numerically.
|
|
Packit |
c5a612 |
NFT_CTX_OUTPUT_TERSE::
|
|
Packit |
c5a612 |
If terse output has been requested, then the contents of sets are not printed.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_output_get_flags*() function returns the output flags setting's value in 'ctx'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_output_set_flags*() function sets the output flags setting in 'ctx' to the value of 'val'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_ctx_output_get_debug() and nft_ctx_output_set_debug()
|
|
Packit |
c5a612 |
Libnftables supports separate debugging of different parts of its internals.
|
|
Packit |
c5a612 |
To facilitate this, debugging output is controlled via a bit mask.
|
|
Packit |
c5a612 |
The bits are defined as such:
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
enum nft_debug_level {
|
|
Packit |
c5a612 |
NFT_DEBUG_SCANNER = 0x1,
|
|
Packit |
c5a612 |
NFT_DEBUG_PARSER = 0x2,
|
|
Packit |
c5a612 |
NFT_DEBUG_EVALUATION = 0x4,
|
|
Packit |
c5a612 |
NFT_DEBUG_NETLINK = 0x8,
|
|
Packit |
c5a612 |
NFT_DEBUG_MNL = 0x10,
|
|
Packit |
c5a612 |
NFT_DEBUG_PROTO_CTX = 0x20,
|
|
Packit |
c5a612 |
NFT_DEBUG_SEGTREE = 0x40,
|
|
Packit |
c5a612 |
};
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
NFT_DEBUG_SCANNER::
|
|
Packit |
c5a612 |
Print LEX debug output.
|
|
Packit |
c5a612 |
NFT_DEBUG_PARSER::
|
|
Packit |
c5a612 |
Print YACC debug output.
|
|
Packit |
c5a612 |
NFT_DEBUG_EVALUATION::
|
|
Packit |
c5a612 |
Print debug information about evaluation phase.
|
|
Packit |
c5a612 |
NFT_DEBUG_NETLINK::
|
|
Packit |
c5a612 |
Print netlink debug output.
|
|
Packit |
c5a612 |
NFT_DEBUG_MNL::
|
|
Packit |
c5a612 |
Print libmnl debug output.
|
|
Packit |
c5a612 |
NFT_DEBUG_PROTO_CTX::
|
|
Packit |
c5a612 |
Print protocol context debug output.
|
|
Packit |
c5a612 |
NFT_DEBUG_SEGTREE::
|
|
Packit |
c5a612 |
Print segtree (i.e. interval sets) debug output.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_output_get_debug*() function returns the debug output setting's value in 'ctx'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_output_set_debug*() function sets the debug output setting in 'ctx' to the value of 'mask'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== Controlling library standard and error output
|
|
Packit |
c5a612 |
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'.
|
|
Packit |
c5a612 |
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.
|
|
Packit |
c5a612 |
This buffer is guaranteed to be null-terminated and must not be freed.
|
|
Packit |
c5a612 |
Note that the retrieval functions rewind the buffer position indicator.
|
|
Packit |
c5a612 |
Further library output will probably overwrite the buffer content and potentially render it invalid (due to reallocation).
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
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'.
|
|
Packit |
c5a612 |
They return the previous value to aid in temporary file pointer overrides.
|
|
Packit |
c5a612 |
On error, these functions return NULL.
|
|
Packit |
c5a612 |
This happens only if 'fp' is NULL or invalid (tested using *ferror*() function).
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_buffer_output*() and *nft_ctx_buffer_error*() functions enable library standard or error output buffering.
|
|
Packit |
c5a612 |
The functions return zero on success, non-zero otherwise.
|
|
Packit |
c5a612 |
This may happen if the internal call to *fopencookie*() failed.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_unbuffer_output*() and *nft_ctx_unbuffer_error*() functions disable library standard or error output buffering.
|
|
Packit |
c5a612 |
On failure, the functions return non-zero which may only happen if buffering was not enabled at the time the function was called.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_get_output_buffer*() and *nft_ctx_get_error_buffer*() functions return a pointer to the buffered output (which may be empty).
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_ctx_add_include_path() and nft_ctx_clear_include_path()
|
|
Packit |
c5a612 |
The *include* command in nftables rulesets allows to outsource parts of the ruleset into a different file.
|
|
Packit |
c5a612 |
The include path defines where these files are searched for.
|
|
Packit |
c5a612 |
Libnftables allows to have a list of those paths which are searched in order.
|
|
Packit |
c5a612 |
The default include path list contains a single compile-time defined entry (typically '/etc/').
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_add_include_path*() function extends the list of include paths in 'ctx' by the one given in 'path'.
|
|
Packit |
c5a612 |
The function returns zero on success or non-zero if memory allocation failed.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_ctx_clear_include_paths*() function removes all include paths, even the built-in default one.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
=== nft_run_cmd_from_buffer() and nft_run_cmd_from_filename()
|
|
Packit |
c5a612 |
These functions perform the actual work of parsing user input into nftables commands and executing them.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_run_cmd_from_buffer*() function passes the command(s) contained in 'buf' (which must be null-terminated) to the library, respecting settings and state in 'nft'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
The *nft_run_cmd_from_filename*() function passes the content of 'filename' to the library, respecting settings and state in 'nft'.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
Both functions return zero on success.
|
|
Packit |
c5a612 |
A non-zero return code indicates an error while parsing or executing the command.
|
|
Packit |
c5a612 |
This event should be accompanied by an error message written to library error output.
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
== EXAMPLE
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
#include <stdio.h>
|
|
Packit |
c5a612 |
#include <string.h>
|
|
Packit |
c5a612 |
#include <nftables/libnftables.h>
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
int main(void)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
char *list_cmd = "list ruleset";
|
|
Packit |
c5a612 |
struct nft_ctx *nft;
|
|
Packit |
c5a612 |
const char *output, *p;
|
|
Packit |
c5a612 |
char buf[256];
|
|
Packit |
c5a612 |
int rc = 0;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
nft = nft_ctx_new(NFT_CTX_DEFAULT);
|
|
Packit |
c5a612 |
if (!nft)
|
|
Packit |
c5a612 |
return 1;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
while (1) {
|
|
Packit |
c5a612 |
if (nft_ctx_buffer_output(nft) ||
|
|
Packit |
c5a612 |
nft_run_cmd_from_buffer(nft, list_cmd)) {
|
|
Packit |
c5a612 |
rc = 1;
|
|
Packit |
c5a612 |
break;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
output = nft_ctx_get_output_buffer(nft);
|
|
Packit |
c5a612 |
if (strlen(output)) {
|
|
Packit |
c5a612 |
printf("\nThis is the current ruleset:\n| ");
|
|
Packit |
c5a612 |
for (p = output; *(p + 1); p++) {
|
|
Packit |
c5a612 |
if (*p == '\n')
|
|
Packit |
c5a612 |
printf("\n| ");
|
|
Packit |
c5a612 |
else
|
|
Packit |
c5a612 |
putchar(*p);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
putchar('\n');
|
|
Packit |
c5a612 |
} else {
|
|
Packit |
c5a612 |
printf("\nCurrent ruleset is empty.\n");
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
nft_ctx_unbuffer_output(nft);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
printf("\nEnter command ('q' to quit): ");
|
|
Packit |
c5a612 |
fflush(stdout);
|
|
Packit |
c5a612 |
fgets(buf, 256, stdin);
|
|
Packit |
c5a612 |
if (strlen(buf))
|
|
Packit |
c5a612 |
buf[strlen(buf) - 1] = '\0';
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (buf[0] == 'q' && buf[1] == '\0')
|
|
Packit |
c5a612 |
break;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (nft_run_cmd_from_buffer(nft, buf)) {
|
|
Packit |
c5a612 |
rc = 1;
|
|
Packit |
c5a612 |
break;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
nft_ctx_free(nft);
|
|
Packit |
c5a612 |
return rc;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
----
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
== SEE ALSO
|
|
Packit |
c5a612 |
*libnftables-json*(5), *nft*(8)
|