* [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags
@ 2023-07-20 14:26 Thomas Haller
2023-07-20 14:27 ` [nft v3 PATCH 1/4] src: add input flags for nft_ctx Thomas Haller
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Thomas Haller @ 2023-07-20 14:26 UTC (permalink / raw)
To: NetFilter; +Cc: Pablo Neira Ayuso, Phil Sutter, Thomas Haller
v3. Changes:
- new patch to add NFT_CTX_INPUT_JSON as hinted by Phil.
- no longer introduce parse_ctx_init() helper function
- various rewording
The Python API is still as before. I am not opposed to change it, once
consensus is found.
Thomas Haller (4):
src: add input flags for nft_ctx
src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking
src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing
py: add Nftables.input_{set,get}_flags() API
doc/libnftables.adoc | 26 +++++++++++++
include/datatype.h | 1 +
include/nftables.h | 5 +++
include/nftables/libnftables.h | 8 ++++
py/nftables.py | 54 +++++++++++++++++++++++++++
src/datatype.c | 68 ++++++++++++++++++++--------------
src/evaluate.c | 10 ++++-
src/libnftables.c | 18 ++++++++-
src/libnftables.map | 5 +++
9 files changed, 163 insertions(+), 32 deletions(-)
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [nft v3 PATCH 1/4] src: add input flags for nft_ctx
2023-07-20 14:26 [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags Thomas Haller
@ 2023-07-20 14:27 ` Thomas Haller
2023-07-20 14:27 ` [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking Thomas Haller
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Thomas Haller @ 2023-07-20 14:27 UTC (permalink / raw)
To: NetFilter; +Cc: Pablo Neira Ayuso, Phil Sutter, Thomas Haller
Similar to the existing output flags, add input flags. No flags are yet
implemented, that will follow.
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
doc/libnftables.adoc | 12 ++++++++++++
include/nftables.h | 5 +++++
include/nftables/libnftables.h | 3 +++
src/libnftables.c | 12 ++++++++++++
src/libnftables.map | 5 +++++
5 files changed, 37 insertions(+)
diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc
index 7ea0d56e9b1d..96a580469ee0 100644
--- a/doc/libnftables.adoc
+++ b/doc/libnftables.adoc
@@ -18,6 +18,9 @@ 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'*);
+unsigned int nft_ctx_input_get_flags(struct nft_ctx* '\*ctx'*);
+void nft_ctx_input_set_flags(struct nft_ctx* '\*ctx'*, unsigned int* 'flags'*);
+
unsigned int nft_ctx_output_get_flags(struct nft_ctx* '\*ctx'*);
void nft_ctx_output_set_flags(struct nft_ctx* '\*ctx'*, unsigned int* 'flags'*);
@@ -78,6 +81,15 @@ The *nft_ctx_get_dry_run*() function returns the dry-run setting's value contain
The *nft_ctx_set_dry_run*() function sets the dry-run setting in 'ctx' to the value of 'dry'.
+=== nft_ctx_input_get_flags() and nft_ctx_input_set_flags()
+The flags setting controls the input format.
+
+Currently not flags are implemented.
+
+The *nft_ctx_input_get_flags*() function returns the input flags setting's value in 'ctx'.
+
+The *nft_ctx_input_set_flags*() function sets the input flags setting in 'ctx' to the value of 'val'.
+
=== nft_ctx_output_get_flags() and nft_ctx_output_set_flags()
The flags setting controls the output format.
diff --git a/include/nftables.h b/include/nftables.h
index d49eb579dc04..7d35a95a89de 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -23,6 +23,10 @@ struct symbol_tables {
const struct symbol_table *realm;
};
+struct input_ctx {
+ unsigned int flags;
+};
+
struct output_ctx {
unsigned int flags;
union {
@@ -119,6 +123,7 @@ struct nft_ctx {
unsigned int num_vars;
unsigned int parser_max_errors;
unsigned int debug_mask;
+ struct input_ctx input;
struct output_ctx output;
bool check;
struct nft_cache cache;
diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h
index 85e08c9bc98b..7fb621be1f12 100644
--- a/include/nftables/libnftables.h
+++ b/include/nftables/libnftables.h
@@ -48,6 +48,9 @@ enum nft_optimize_flags {
uint32_t nft_ctx_get_optimize(struct nft_ctx *ctx);
void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags);
+unsigned int nft_ctx_input_get_flags(struct nft_ctx *ctx);
+void nft_ctx_input_set_flags(struct nft_ctx *ctx, unsigned int flags);
+
enum {
NFT_CTX_OUTPUT_REVERSEDNS = (1 << 0),
NFT_CTX_OUTPUT_SERVICE = (1 << 1),
diff --git a/src/libnftables.c b/src/libnftables.c
index 6fc4f7db6760..6832f0486d6d 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -401,6 +401,18 @@ void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags)
ctx->optimize_flags = flags;
}
+EXPORT_SYMBOL(nft_ctx_input_get_flags);
+unsigned int nft_ctx_input_get_flags(struct nft_ctx *ctx)
+{
+ return ctx->input.flags;
+}
+
+EXPORT_SYMBOL(nft_ctx_input_set_flags);
+void nft_ctx_input_set_flags(struct nft_ctx *ctx, unsigned int flags)
+{
+ ctx->input.flags = flags;
+}
+
EXPORT_SYMBOL(nft_ctx_output_get_flags);
unsigned int nft_ctx_output_get_flags(struct nft_ctx *ctx)
{
diff --git a/src/libnftables.map b/src/libnftables.map
index a46a3ad53ff6..9369f44f3536 100644
--- a/src/libnftables.map
+++ b/src/libnftables.map
@@ -33,3 +33,8 @@ LIBNFTABLES_3 {
nft_ctx_set_optimize;
nft_ctx_get_optimize;
} LIBNFTABLES_2;
+
+LIBNFTABLES_4 {
+ nft_ctx_input_get_flags;
+ nft_ctx_input_set_flags;
+} LIBNFTABLES_3;
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking
2023-07-20 14:26 [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags Thomas Haller
2023-07-20 14:27 ` [nft v3 PATCH 1/4] src: add input flags for nft_ctx Thomas Haller
@ 2023-07-20 14:27 ` Thomas Haller
2023-07-27 16:52 ` Phil Sutter
2023-07-20 14:27 ` [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing Thomas Haller
2023-07-20 14:27 ` [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API Thomas Haller
3 siblings, 1 reply; 8+ messages in thread
From: Thomas Haller @ 2023-07-20 14:27 UTC (permalink / raw)
To: NetFilter; +Cc: Pablo Neira Ayuso, Phil Sutter, Thomas Haller
getaddrinfo() blocks while trying to resolve the name. Blocking the
caller of the library is in many cases undesirable. Also, while
reconfiguring the firewall, it's not clear that resolving names via
the network will work or makes sense.
Add a new input flag NFT_CTX_INPUT_NO_DNS to opt-out from getaddrinfo()
and only accept plain IP addresses.
We could also use AI_NUMERICHOST with getaddrinfo() instead of
inet_pton(). By parsing via inet_pton(), we are better aware of
what we expect and can generate a better error message in case of
failure.
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
doc/libnftables.adoc | 10 ++++-
include/datatype.h | 1 +
include/nftables/libnftables.h | 4 ++
src/datatype.c | 68 ++++++++++++++++++++--------------
src/evaluate.c | 10 ++++-
5 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc
index 96a580469ee0..77f3a0fd5659 100644
--- a/doc/libnftables.adoc
+++ b/doc/libnftables.adoc
@@ -84,7 +84,15 @@ The *nft_ctx_set_dry_run*() function sets the dry-run setting in 'ctx' to the va
=== nft_ctx_input_get_flags() and nft_ctx_input_set_flags()
The flags setting controls the input format.
-Currently not flags are implemented.
+----
+enum {
+ NFT_CTX_INPUT_NO_DNS = (1 << 0),
+};
+----
+
+NFT_CTX_INPUT_NO_DNS::
+ Avoid resolving IP addresses with blocking getaddrinfo(). In that case,
+ only plain IP addresses are accepted.
The *nft_ctx_input_get_flags*() function returns the input flags setting's value in 'ctx'.
diff --git a/include/datatype.h b/include/datatype.h
index 4b59790b67f9..be5c6d1b4011 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -182,6 +182,7 @@ struct datatype *dtype_clone(const struct datatype *orig_dtype);
struct parse_ctx {
struct symbol_tables *tbl;
+ const struct input_ctx *input;
};
extern struct error_record *symbol_parse(struct parse_ctx *ctx,
diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h
index 7fb621be1f12..2f5f079efff0 100644
--- a/include/nftables/libnftables.h
+++ b/include/nftables/libnftables.h
@@ -48,6 +48,10 @@ enum nft_optimize_flags {
uint32_t nft_ctx_get_optimize(struct nft_ctx *ctx);
void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags);
+enum {
+ NFT_CTX_INPUT_NO_DNS = (1 << 0),
+};
+
unsigned int nft_ctx_input_get_flags(struct nft_ctx *ctx);
void nft_ctx_input_set_flags(struct nft_ctx *ctx, unsigned int flags);
diff --git a/src/datatype.c b/src/datatype.c
index da802a18bccd..8629a38da56a 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -599,27 +599,33 @@ static struct error_record *ipaddr_type_parse(struct parse_ctx *ctx,
const struct expr *sym,
struct expr **res)
{
- struct addrinfo *ai, hints = { .ai_family = AF_INET,
- .ai_socktype = SOCK_DGRAM};
- struct in_addr *addr;
- int err;
+ struct in_addr addr;
- err = getaddrinfo(sym->identifier, NULL, &hints, &ai);
- if (err != 0)
- return error(&sym->location, "Could not resolve hostname: %s",
- gai_strerror(err));
+ if (ctx->input->flags & NFT_CTX_INPUT_NO_DNS) {
+ if (inet_pton(AF_INET, sym->identifier, &addr) != 1)
+ return error(&sym->location, "Invalid IPv4 address");
+ } else {
+ struct addrinfo *ai, hints = { .ai_family = AF_INET,
+ .ai_socktype = SOCK_DGRAM};
+ int err;
- if (ai->ai_next != NULL) {
+ err = getaddrinfo(sym->identifier, NULL, &hints, &ai);
+ if (err != 0)
+ return error(&sym->location, "Could not resolve hostname: %s",
+ gai_strerror(err));
+
+ if (ai->ai_next != NULL) {
+ freeaddrinfo(ai);
+ return error(&sym->location,
+ "Hostname resolves to multiple addresses");
+ }
+ addr = ((struct sockaddr_in *)ai->ai_addr)->sin_addr;
freeaddrinfo(ai);
- return error(&sym->location,
- "Hostname resolves to multiple addresses");
}
- addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
*res = constant_expr_alloc(&sym->location, &ipaddr_type,
BYTEORDER_BIG_ENDIAN,
- sizeof(*addr) * BITS_PER_BYTE, addr);
- freeaddrinfo(ai);
+ sizeof(addr) * BITS_PER_BYTE, &addr);
return NULL;
}
@@ -658,27 +664,33 @@ static struct error_record *ip6addr_type_parse(struct parse_ctx *ctx,
const struct expr *sym,
struct expr **res)
{
- struct addrinfo *ai, hints = { .ai_family = AF_INET6,
- .ai_socktype = SOCK_DGRAM};
- struct in6_addr *addr;
- int err;
+ struct in6_addr addr;
- err = getaddrinfo(sym->identifier, NULL, &hints, &ai);
- if (err != 0)
- return error(&sym->location, "Could not resolve hostname: %s",
- gai_strerror(err));
+ if (ctx->input->flags & NFT_CTX_INPUT_NO_DNS) {
+ if (inet_pton(AF_INET6, sym->identifier, &addr) != 1)
+ return error(&sym->location, "Invalid IPv6 address");
+ } else {
+ struct addrinfo *ai, hints = { .ai_family = AF_INET6,
+ .ai_socktype = SOCK_DGRAM};
+ int err;
- if (ai->ai_next != NULL) {
+ err = getaddrinfo(sym->identifier, NULL, &hints, &ai);
+ if (err != 0)
+ return error(&sym->location, "Could not resolve hostname: %s",
+ gai_strerror(err));
+
+ if (ai->ai_next != NULL) {
+ freeaddrinfo(ai);
+ return error(&sym->location,
+ "Hostname resolves to multiple addresses");
+ }
+ addr = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
freeaddrinfo(ai);
- return error(&sym->location,
- "Hostname resolves to multiple addresses");
}
- addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
*res = constant_expr_alloc(&sym->location, &ip6addr_type,
BYTEORDER_BIG_ENDIAN,
- sizeof(*addr) * BITS_PER_BYTE, addr);
- freeaddrinfo(ai);
+ sizeof(addr) * BITS_PER_BYTE, &addr);
return NULL;
}
diff --git a/src/evaluate.c b/src/evaluate.c
index 33e4ac93e89a..cf7590c8e5b2 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -277,7 +277,10 @@ static int flowtable_not_found(struct eval_ctx *ctx, const struct location *loc,
*/
static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
{
- struct parse_ctx parse_ctx = { .tbl = &ctx->nft->output.tbl, };
+ struct parse_ctx parse_ctx = {
+ .tbl = &ctx->nft->output.tbl,
+ .input = &ctx->nft->input,
+ };
struct error_record *erec;
struct table *table;
struct set *set;
@@ -3432,7 +3435,10 @@ static int stmt_evaluate_reject_default(struct eval_ctx *ctx,
static int stmt_evaluate_reject_icmp(struct eval_ctx *ctx, struct stmt *stmt)
{
- struct parse_ctx parse_ctx = { .tbl = &ctx->nft->output.tbl, };
+ struct parse_ctx parse_ctx = {
+ .tbl = &ctx->nft->output.tbl,
+ .input = &ctx->nft->input,
+ };
struct error_record *erec;
struct expr *code;
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing
2023-07-20 14:26 [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags Thomas Haller
2023-07-20 14:27 ` [nft v3 PATCH 1/4] src: add input flags for nft_ctx Thomas Haller
2023-07-20 14:27 ` [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking Thomas Haller
@ 2023-07-20 14:27 ` Thomas Haller
2023-07-27 16:57 ` Phil Sutter
2023-07-20 14:27 ` [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API Thomas Haller
3 siblings, 1 reply; 8+ messages in thread
From: Thomas Haller @ 2023-07-20 14:27 UTC (permalink / raw)
To: NetFilter; +Cc: Pablo Neira Ayuso, Phil Sutter, Thomas Haller
By default, the input is parsed using the nftables grammar. When setting
NFT_CTX_OUTPUT_JSON flag, nftables will first try to parse the input as
JSON before falling back to the nftables grammar.
But NFT_CTX_OUTPUT_JSON flag also turns on JSON for the output. Add a
flag NFT_CTX_INPUT_JSON which allows to treat only the input in JSON
format, but keep the output mode unchanged.
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
doc/libnftables.adoc | 6 ++++++
include/nftables/libnftables.h | 1 +
src/libnftables.c | 6 ++++--
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc
index 77f3a0fd5659..27e230281edb 100644
--- a/doc/libnftables.adoc
+++ b/doc/libnftables.adoc
@@ -87,6 +87,7 @@ The flags setting controls the input format.
----
enum {
NFT_CTX_INPUT_NO_DNS = (1 << 0),
+ NFT_CTX_INPUT_JSON = (1 << 1),
};
----
@@ -94,6 +95,11 @@ NFT_CTX_INPUT_NO_DNS::
Avoid resolving IP addresses with blocking getaddrinfo(). In that case,
only plain IP addresses are accepted.
+NFT_CTX_INPUT_JSON:
+ When parsing the input, first try to interpret the input as JSON before
+ falling back to the nftables format. This behavior is implied when setting
+ the NFT_CTX_OUTPUT_JSON flag.
+
The *nft_ctx_input_get_flags*() function returns the input flags setting's value in 'ctx'.
The *nft_ctx_input_set_flags*() function sets the input flags setting in 'ctx' to the value of 'val'.
diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h
index 2f5f079efff0..152c7a5b75da 100644
--- a/include/nftables/libnftables.h
+++ b/include/nftables/libnftables.h
@@ -50,6 +50,7 @@ void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags);
enum {
NFT_CTX_INPUT_NO_DNS = (1 << 0),
+ NFT_CTX_INPUT_JSON = (1 << 1),
};
unsigned int nft_ctx_input_get_flags(struct nft_ctx *ctx);
diff --git a/src/libnftables.c b/src/libnftables.c
index 6832f0486d6d..a2e0ae6b5843 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -578,7 +578,8 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, const char *buf)
nlbuf = xzalloc(strlen(buf) + 2);
sprintf(nlbuf, "%s\n", buf);
- if (nft_output_json(&nft->output))
+ if (nft_output_json(&nft->output) ||
+ (nft_ctx_input_get_flags(nft) & NFT_CTX_INPUT_JSON))
rc = nft_parse_json_buffer(nft, nlbuf, &msgs, &cmds);
if (rc == -EINVAL)
rc = nft_parse_bison_buffer(nft, nlbuf, &msgs, &cmds,
@@ -677,7 +678,8 @@ static int __nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename
goto err;
rc = -EINVAL;
- if (nft_output_json(&nft->output))
+ if (nft_output_json(&nft->output) ||
+ (nft_ctx_input_get_flags(nft) & NFT_CTX_INPUT_JSON))
rc = nft_parse_json_filename(nft, filename, &msgs, &cmds);
if (rc == -EINVAL)
rc = nft_parse_bison_filename(nft, filename, &msgs, &cmds);
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API
2023-07-20 14:26 [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags Thomas Haller
` (2 preceding siblings ...)
2023-07-20 14:27 ` [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing Thomas Haller
@ 2023-07-20 14:27 ` Thomas Haller
2023-07-27 17:02 ` Phil Sutter
3 siblings, 1 reply; 8+ messages in thread
From: Thomas Haller @ 2023-07-20 14:27 UTC (permalink / raw)
To: NetFilter; +Cc: Pablo Neira Ayuso, Phil Sutter, Thomas Haller
Add new API to expose the input flags in the Python API.
Note that the chosen approach differs from the existing
nft_ctx_output_get_flags() and nft_ctx_output_get_debug()
API, which themselves are inconsistent approaches.
The new API directly exposes the underlying C API, that is, the numeric
flags.
Signed-off-by: Thomas Haller <thaller@redhat.com>
---
py/nftables.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/py/nftables.py b/py/nftables.py
index 68fcd7dd103c..e2417b7598c0 100644
--- a/py/nftables.py
+++ b/py/nftables.py
@@ -21,6 +21,29 @@ import os
NFTABLES_VERSION = "0.1"
+"""Prevent blocking DNS lookups for IP addresses.
+
+By default, nftables will try to resolve IP addresses with blocking getaddrinfo() API.
+By setting this flag, only literal IP addresses are supported in input.
+
+This numeric flag can be passed to Nftables.input_get_flags() and is returned
+by Nftables.input_set_flags().
+"""
+NFT_CTX_INPUT_NO_DNS = 1
+
+"""Attempt to parse input in JSON format.
+
+By default, input will be parsed using the nftables format. By setting
+this flag, the parsing will first attempt to read the input in the
+JSON format as documented in libnftables-json manual. This flag is
+implied by NFT_CTX_OUTPUT_JSON flag (Nftables.set_json_output()).
+
+This numeric flag can be passed to Nftables.input_get_flags() and is returned
+by Nftables.input_set_flags().
+"""
+NFT_CTX_INPUT_JSON = 2
+
+
class SchemaValidator:
"""Libnftables JSON validator using jsonschema"""
@@ -82,6 +105,13 @@ class Nftables:
self.nft_ctx_new.restype = c_void_p
self.nft_ctx_new.argtypes = [c_int]
+ self.nft_ctx_input_get_flags = lib.nft_ctx_input_get_flags
+ self.nft_ctx_input_get_flags.restype = c_uint
+ self.nft_ctx_input_get_flags.argtypes = [c_void_p]
+
+ self.nft_ctx_input_set_flags = lib.nft_ctx_input_set_flags
+ self.nft_ctx_input_set_flags.argtypes = [c_void_p, c_uint]
+
self.nft_ctx_output_get_flags = lib.nft_ctx_output_get_flags
self.nft_ctx_output_get_flags.restype = c_uint
self.nft_ctx_output_get_flags.argtypes = [c_void_p]
@@ -152,6 +182,30 @@ class Nftables:
def __del__(self):
self.nft_ctx_free(self.__ctx)
+ def input_get_flags(self):
+ """Query input flags for the nft context.
+
+ See input_get_flags() for supported flags.
+
+ Returns the currently set input flags as number.
+ """
+ return self.nft_ctx_input_get_flags(self.__ctx)
+
+ def input_set_flags(self, flags):
+ """Set input flags for the nft context as number.
+
+ By default, a new context objects has flags set to zero.
+
+ The following flags are currently supported.
+ NFT_CTX_INPUT_NO_DNS (0x1) disables blocking address lookup.
+ NFT_CTX_INPUT_JSON (0x2) enables JSON mode for input.
+
+ Unknown flags are silently accepted.
+
+ Returns nothing.
+ """
+ self.nft_ctx_input_set_flags(self.__ctx, flags)
+
def __get_output_flag(self, name):
flag = self.output_flags[name]
return (self.nft_ctx_output_get_flags(self.__ctx) & flag) != 0
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking
2023-07-20 14:27 ` [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking Thomas Haller
@ 2023-07-27 16:52 ` Phil Sutter
0 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-07-27 16:52 UTC (permalink / raw)
To: Thomas Haller; +Cc: NetFilter, Pablo Neira Ayuso
On Thu, Jul 20, 2023 at 04:27:01PM +0200, Thomas Haller wrote:
[...]
> diff --git a/src/datatype.c b/src/datatype.c
> index da802a18bccd..8629a38da56a 100644
> --- a/src/datatype.c
> +++ b/src/datatype.c
> @@ -599,27 +599,33 @@ static struct error_record *ipaddr_type_parse(struct parse_ctx *ctx,
> const struct expr *sym,
> struct expr **res)
> {
> - struct addrinfo *ai, hints = { .ai_family = AF_INET,
> - .ai_socktype = SOCK_DGRAM};
> - struct in_addr *addr;
> - int err;
> + struct in_addr addr;
>
> - err = getaddrinfo(sym->identifier, NULL, &hints, &ai);
> - if (err != 0)
> - return error(&sym->location, "Could not resolve hostname: %s",
> - gai_strerror(err));
> + if (ctx->input->flags & NFT_CTX_INPUT_NO_DNS) {
There are a bunch of getters defined in include/nftables.h for output
flags. I'd keep things consistent by introducing the same for input
flags, so the above becomes 'if (nft_input_no_dns(ctx->input))'.
In this spot it doesn't quite matter, but in the next patch you
introduce mixed use of a getter (for output flags) and the binary op as
seen here which is confusing.
Cheers, Phil
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing
2023-07-20 14:27 ` [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing Thomas Haller
@ 2023-07-27 16:57 ` Phil Sutter
0 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-07-27 16:57 UTC (permalink / raw)
To: Thomas Haller; +Cc: NetFilter, Pablo Neira Ayuso
On Thu, Jul 20, 2023 at 04:27:02PM +0200, Thomas Haller wrote:
[...]
> diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc
> index 77f3a0fd5659..27e230281edb 100644
> --- a/doc/libnftables.adoc
> +++ b/doc/libnftables.adoc
> @@ -87,6 +87,7 @@ The flags setting controls the input format.
> ----
> enum {
> NFT_CTX_INPUT_NO_DNS = (1 << 0),
> + NFT_CTX_INPUT_JSON = (1 << 1),
> };
> ----
>
> @@ -94,6 +95,11 @@ NFT_CTX_INPUT_NO_DNS::
> Avoid resolving IP addresses with blocking getaddrinfo(). In that case,
> only plain IP addresses are accepted.
>
> +NFT_CTX_INPUT_JSON:
> + When parsing the input, first try to interpret the input as JSON before
> + falling back to the nftables format. This behavior is implied when setting
> + the NFT_CTX_OUTPUT_JSON flag.
I would drop the last sentence here and extend NFT_CTX_OUTPUT_JSON docs
instead, illustrating that it implicitly enables NFT_CTX_INPUT_JSON. Or
keep the sentence here, if you prefer. But JSON input being enabled when
enabling JSON output is the actually unintuitive part for people aware
of input flags' existence.
[...]
> diff --git a/src/libnftables.c b/src/libnftables.c
> index 6832f0486d6d..a2e0ae6b5843 100644
> --- a/src/libnftables.c
> +++ b/src/libnftables.c
> @@ -578,7 +578,8 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, const char *buf)
> nlbuf = xzalloc(strlen(buf) + 2);
> sprintf(nlbuf, "%s\n", buf);
>
> - if (nft_output_json(&nft->output))
> + if (nft_output_json(&nft->output) ||
> + (nft_ctx_input_get_flags(nft) & NFT_CTX_INPUT_JSON))
As pointed out before, this reads much nicer with a getter:
| if (nft_output_json(&nft->output) ||
| nft_input_json(&nft->input))
Cheers, Phil
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API
2023-07-20 14:27 ` [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API Thomas Haller
@ 2023-07-27 17:02 ` Phil Sutter
0 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2023-07-27 17:02 UTC (permalink / raw)
To: Thomas Haller; +Cc: NetFilter, Pablo Neira Ayuso
On Thu, Jul 20, 2023 at 04:27:03PM +0200, Thomas Haller wrote:
> Add new API to expose the input flags in the Python API.
>
> Note that the chosen approach differs from the existing
> nft_ctx_output_get_flags() and nft_ctx_output_get_debug()
> API, which themselves are inconsistent approaches.
>
> The new API directly exposes the underlying C API, that is, the numeric
> flags.
Insisting on forcing users to set input flags differently than output
flags is a bit odd, but once complaints come in we can still follow-up I
guess.
[...]
> diff --git a/py/nftables.py b/py/nftables.py
> index 68fcd7dd103c..e2417b7598c0 100644
> --- a/py/nftables.py
> +++ b/py/nftables.py
[...]
> @@ -152,6 +182,30 @@ class Nftables:
> def __del__(self):
> self.nft_ctx_free(self.__ctx)
>
> + def input_get_flags(self):
> + """Query input flags for the nft context.
> +
> + See input_get_flags() for supported flags.
> +
> + Returns the currently set input flags as number.
> + """
> + return self.nft_ctx_input_get_flags(self.__ctx)
> +
> + def input_set_flags(self, flags):
> + """Set input flags for the nft context as number.
> +
> + By default, a new context objects has flags set to zero.
> +
> + The following flags are currently supported.
> + NFT_CTX_INPUT_NO_DNS (0x1) disables blocking address lookup.
> + NFT_CTX_INPUT_JSON (0x2) enables JSON mode for input.
> +
> + Unknown flags are silently accepted.
> +
> + Returns nothing.
> + """
> + self.nft_ctx_input_set_flags(self.__ctx, flags)
Please make this return the old flags. It makes temporary flag setting
much easier, see this snippet from tests/py/nft-test.py for instance:
| # Check for matching ruleset listing
| numeric_proto_old = nftables.set_numeric_proto_output(True)
| stateless_old = nftables.set_stateless_output(True)
| list_cmd = 'list table %s' % table
| rc, pre_output, err = nftables.cmd(list_cmd)
| nftables.set_numeric_proto_output(numeric_proto_old)
| nftables.set_stateless_output(stateless_old)
Thanks, Phil
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-07-27 17:02 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-20 14:26 [nft v3 PATCH 0/4] add input flags and "no-dns"/"json" flags Thomas Haller
2023-07-20 14:27 ` [nft v3 PATCH 1/4] src: add input flags for nft_ctx Thomas Haller
2023-07-20 14:27 ` [nvt v3 PATCH 2/4] src: add input flag NFT_CTX_INPUT_NO_DNS to avoid blocking Thomas Haller
2023-07-27 16:52 ` Phil Sutter
2023-07-20 14:27 ` [nft v3 PATCH 3/4] src: add input flag NFT_CTX_INPUT_JSON to enable JSON parsing Thomas Haller
2023-07-27 16:57 ` Phil Sutter
2023-07-20 14:27 ` [nft v3 PATCH 4/4] py: add Nftables.input_{set,get}_flags() API Thomas Haller
2023-07-27 17:02 ` Phil Sutter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).