Re: [nft PATCH 0/8] Convert tests/py to use libnftables directly

2018-04-11 Thread Phil Sutter
Hi Pablo,

On Wed, Apr 11, 2018 at 09:39:01AM +0200, Pablo Neira Ayuso wrote:
> Two comments, both related to 'struct cookie':
> 
> * How is 'struct cookie' going to be used? Do you have follow up
>   patches to update the codebase to use this?

It's already there, please have a look at
nft_ctx_{un,}buffer_{output,error} functions and those they call
(init_cookie, exit_cookie). The API interface they establish can be used
as such:

| struct nft_ctx *ctx;
| const char *cmd;
| int rc;
| 
| ctx = nft_ctx_new(0);
| nft_buffer_output(ctx);
| nft_buffer_error(ctx);
| 
| cmd = "list ruleset";
| rc = nft_run_cmd_from_buffer(ctx, cmd, sizeof(cmd));
| 
| if (rc) {
|   printf("FAIL: nftables says: %s\n",
|  nft_ctx_get_error_buffer(ctx));
| } else {
|   /* this prints 'list ruleset' output */
|   printf("%s\n", nft_ctx_get_output_buffer(ctx));
| }
| 
| nft_ctx_free(ctx);

So these nft_ctx_buffer_* and nft_ctx_get_*_buffer functions are an
alternative to nft_ctx_set_{output,error} functions for cases where it
is more convenient to have all output available in a char buffer instead
of being written to an open FILE pointer.

> * Can we avoid the union around struct cookie and FILE *fp? I mean, I
>   don't think it makes sense to start exposing lots of toggles through
>   the API, the more we expose, the more combinations are possible and
>   then more chances we get to support all kind of strange combinations
>   in the future.

That union is simply for convenience: {init,exit}_cookie functions take
a pointer to struct cookie as parameter and since it is part of that
union they get access to the "standard" FILE pointer which is used if
no buffering was requested.

That union is introduced by commit 4885331de84cb ("libnftables: Simplify
cookie integration"), a followup to 40d94ca1dcd8e ("libnftables: Support
buffering output and error") - please have a look at the latter to see
how things were without it.

>   So what I'm suggesting is: Can we turn 'struct cookie' into the
>   default way to print messages?

Sure, we could do that. OTOH there is e.g. nft cli, which doesn't care
about what's printed to stdout and stderr. Changing the default would
mean cli has to manually print to stdout and stderr after each command.

Internally, this buffering infrastructure is an add-on to FILE pointer
output we already have (which was introduced as the quickest path from
plain printf's everywhere to giving API users control over library
output).

I really think we should keep the FILE pointer output (i.e. nft_print())
internally, simply because changing everything to snprintf() is tedious
due to buffer length checks everywhere (I'm having libnftnl's
SNPRINTF_BUFFER_SIZE macro in mind ;).

The buffering add-on doesn't necessarily add complexity to API users'
implementations - prior to it, there were two options:

* Don't care and go with the default, i.e. output goes to stdout and
  stderr.

* Provide a FILE pointer to print into, i.e. call nft_ctx_set_output().

The add-on adds a third, completely separate option to them:

* Get output in a buffer, i.e. call nft_ctx_buffer_output() and use
  nft_ctx_get_output_buffer() afterwards to receive a pointer to the
  buffer.

>   Regarding the name 'struct cookie', is this refering to something
>   related to Python? I mean, this name tells me very little. What I
>   can see there is a new class that allows us to do buffering, so
>   probably using 'struct nft_buffer' or such sound more convenient to
>   me?

I chose it simply because it all evolves around fopencookie(3), which
provides the needed functionality (create a FILE pointer with
customizable write() backend). In the documentation, the opaque data
pointer passed around to callbacks is referred to as 'cookie'.

On Wed, Apr 11, 2018 at 09:48:25AM +0200, Pablo Neira Ayuso wrote:
> On Tue, Apr 10, 2018 at 07:00:21PM +0200, Phil Sutter wrote:
[...]
> > diff --git a/src/libnftables.c b/src/libnftables.c
> > index 8bf989b08cc54..d6622d51aba33 100644
> > --- a/src/libnftables.c
> > +++ b/src/libnftables.c
> > @@ -169,6 +169,7 @@ struct nft_ctx *nft_ctx_new(uint32_t flags)
> > init_list_head(&ctx->cache.list);
> > ctx->flags = flags;
> > ctx->output.output_fp = stdout;
> > +   ctx->output.error_fp = stderr;
> 
> I understand you may need this new toggle. But can we probably
> reasonable defaults? I mean, if no error_fp is specified, then use the
> one set by output_fp.

This was already the default, see this chunk from commit 4176e24e14f07
("libnftables: Introduce nft_ctx_set_error()"):

| @@ -297,9 +309,7 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, char 
*buf, size_t buflen)
| if (nft_run(nft, nft->nf_sock, scanner, &state, &msgs) != 0)
| rc = -1;
|  
| -   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);
| iface_cache_release();
| 

Re: [nft PATCH 0/8] Convert tests/py to use libnftables directly

2018-04-11 Thread Pablo Neira Ayuso
Hi Phil,

On Tue, Apr 10, 2018 at 07:00:18PM +0200, Phil Sutter wrote:
> This series of patches results in tests/py/nft-test.py using libnftables
> API directly via ctypes module which leads to significant performance
> improvement of the test script.

Series looks good, applied.

Two comments, both related to 'struct cookie':

* How is 'struct cookie' going to be used? Do you have follow up
  patches to update the codebase to use this?

* Can we avoid the union around struct cookie and FILE *fp? I mean, I
  don't think it makes sense to start exposing lots of toggles through
  the API, the more we expose, the more combinations are possible and
  then more chances we get to support all kind of strange combinations
  in the future.

  So what I'm suggesting is: Can we turn 'struct cookie' into the
  default way to print messages?

  Regarding the name 'struct cookie', is this refering to something
  related to Python? I mean, this name tells me very little. What I
  can see there is a new class that allows us to do buffering, so
  probably using 'struct nft_buffer' or such sound more convenient to
  me?

If you think these two comments are relevant, please follow up with
patches.

Thanks.

> The first five patches are preparational work:
> 
> * Patch 1 fixes a missed conversion to nft_print() in src/ct.c which
>   became obvious after nft-test.py started using libnftables API and
>   therefore ignored anything not written into output_fp.
> 
> * Patch 2 moves a necessary workaround from main() into
>   run_cmd_from_buffer() which is required to accept non-newline
>   terminated strings. While being at it, reading input from files
>   without trailing newline is fixed as well. (Yes, this never worked.)
> 
> * Patch 3 makes error output configurable by users, which is required if
>   one wants to redirect stderr without dirty hacks.
> 
> * Patch 4 adds convenience functions for using fopencookie() to buffer
>   standard and error output. Doing so from within Python code is
>   non-trivial and therefore an unnecessary burden on (already chastened)
>   Python programmers.
> 
> * Patch 5 simplifies the code introduced in patch 4. Though since it also
>   increases the size of struct nft_ctx quite a bit, it is kept separate
>   in case that side-effect is unwanted upstream.
> 
> Finally, patch 6 introduces a simple Python class Nftables and changes
> nft-test.py accordingly to make good use of it. Since we might at some
> point want to ship that class as a Python module, it is placed in a new
> topdir subdirectory named 'py'.
> 
> Patches 7 and 8 are more or less fall-out from the actual
> implementation. A bit of cleanup in the first one and a minor
> enhancement in the latter.
> 
> Phil Sutter (8):
>   ct: Fix output_fp bypass in ct_print()
>   libnftables: Fix for input without trailing newline
>   libnftables: Introduce nft_ctx_set_error()
>   libnftables: Support buffering output and error
>   libnftables: Simplify cookie integration
>   tests/py: Use libnftables instead of calling nft binary
>   tests/py: Review print statements in nft-test.py
>   tests/py: Allow passing multiple files to nft-test.py
> 
>  include/nftables.h|  17 ++-
>  include/nftables/nftables.h   |   9 ++
>  py/.gitignore |   1 +
>  py/nftables.py| 224 ++
>  src/ct.c  |   2 +-
>  src/erec.c|   2 +-
>  src/libnftables.c | 135 -
>  src/main.c|   5 +-
>  src/scanner.l |   2 +-
>  tests/py/any/ct.t |  14 +--
>  tests/py/any/ct.t.payload |  12 +-
>  tests/py/any/log.t|   2 +-
>  tests/py/any/log.t.payload|   2 +-
>  tests/py/any/meta.t   |   4 +-
>  tests/py/arp/arp.t|   2 +-
>  tests/py/arp/arp.t.payload|   2 +-
>  tests/py/arp/arp.t.payload.netdev |   2 +-
>  tests/py/inet/tcp.t   |   2 +-
>  tests/py/inet/tcp.t.payload   |   2 +-
>  tests/py/ip/ip.t  |   6 +-
>  tests/py/ip/ip.t.payload  |   6 +-
>  tests/py/ip/ip.t.payload.bridge   |   6 +-
>  tests/py/ip/ip.t.payload.inet |   6 +-
>  tests/py/ip/ip.t.payload.netdev   |   6 +-
>  tests/py/ip/objects.t |   4 +-
>  tests/py/nft-test.py  | 247 
> ++
>  26 files changed, 545 insertions(+), 177 deletions(-)
>  create mode 100644 py/.gitignore
>  create mode 100644 py/nftables.py
> 
> -- 
> 2.16.1
> 
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[nft PATCH 0/8] Convert tests/py to use libnftables directly

2018-04-10 Thread Phil Sutter
This series of patches results in tests/py/nft-test.py using libnftables
API directly via ctypes module which leads to significant performance
improvement of the test script.

The first five patches are preparational work:

* Patch 1 fixes a missed conversion to nft_print() in src/ct.c which
  became obvious after nft-test.py started using libnftables API and
  therefore ignored anything not written into output_fp.

* Patch 2 moves a necessary workaround from main() into
  run_cmd_from_buffer() which is required to accept non-newline
  terminated strings. While being at it, reading input from files
  without trailing newline is fixed as well. (Yes, this never worked.)

* Patch 3 makes error output configurable by users, which is required if
  one wants to redirect stderr without dirty hacks.

* Patch 4 adds convenience functions for using fopencookie() to buffer
  standard and error output. Doing so from within Python code is
  non-trivial and therefore an unnecessary burden on (already chastened)
  Python programmers.

* Patch 5 simplifies the code introduced in patch 4. Though since it also
  increases the size of struct nft_ctx quite a bit, it is kept separate
  in case that side-effect is unwanted upstream.

Finally, patch 6 introduces a simple Python class Nftables and changes
nft-test.py accordingly to make good use of it. Since we might at some
point want to ship that class as a Python module, it is placed in a new
topdir subdirectory named 'py'.

Patches 7 and 8 are more or less fall-out from the actual
implementation. A bit of cleanup in the first one and a minor
enhancement in the latter.

Phil Sutter (8):
  ct: Fix output_fp bypass in ct_print()
  libnftables: Fix for input without trailing newline
  libnftables: Introduce nft_ctx_set_error()
  libnftables: Support buffering output and error
  libnftables: Simplify cookie integration
  tests/py: Use libnftables instead of calling nft binary
  tests/py: Review print statements in nft-test.py
  tests/py: Allow passing multiple files to nft-test.py

 include/nftables.h|  17 ++-
 include/nftables/nftables.h   |   9 ++
 py/.gitignore |   1 +
 py/nftables.py| 224 ++
 src/ct.c  |   2 +-
 src/erec.c|   2 +-
 src/libnftables.c | 135 -
 src/main.c|   5 +-
 src/scanner.l |   2 +-
 tests/py/any/ct.t |  14 +--
 tests/py/any/ct.t.payload |  12 +-
 tests/py/any/log.t|   2 +-
 tests/py/any/log.t.payload|   2 +-
 tests/py/any/meta.t   |   4 +-
 tests/py/arp/arp.t|   2 +-
 tests/py/arp/arp.t.payload|   2 +-
 tests/py/arp/arp.t.payload.netdev |   2 +-
 tests/py/inet/tcp.t   |   2 +-
 tests/py/inet/tcp.t.payload   |   2 +-
 tests/py/ip/ip.t  |   6 +-
 tests/py/ip/ip.t.payload  |   6 +-
 tests/py/ip/ip.t.payload.bridge   |   6 +-
 tests/py/ip/ip.t.payload.inet |   6 +-
 tests/py/ip/ip.t.payload.netdev   |   6 +-
 tests/py/ip/objects.t |   4 +-
 tests/py/nft-test.py  | 247 ++
 26 files changed, 545 insertions(+), 177 deletions(-)
 create mode 100644 py/.gitignore
 create mode 100644 py/nftables.py

-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html