All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Safonov <dima@arista.com>
To: Shuah Khan <skhan@linuxfoundation.org>,
	Eric Dumazet <edumazet@google.com>,
	"David S. Miller" <davem@davemloft.net>,
	linux-kernel@vger.kernel.org
Cc: Andy Lutomirski <luto@amacapital.net>,
	Ard Biesheuvel <ardb@kernel.org>,
	Bob Gilligan <gilligan@arista.com>,
	David Ahern <dsahern@kernel.org>,
	Dmitry Safonov <0x7f454c46@gmail.com>,
	Eric Biggers <ebiggers@kernel.org>,
	Francesco Ruggeri <fruggeri@arista.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
	Ivan Delalande <colona@arista.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Leonard Crestez <cdleonard@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	Salam Noureddine <noureddine@arista.com>,
	Shuah Khan <shuah@kernel.org>,
	netdev@vger.kernel.org, linux-crypto@vger.kernel.org
Subject: Re: [PATCH 25/31] selftests/net: Add TCP-AO library
Date: Tue, 6 Sep 2022 17:34:41 +0100	[thread overview]
Message-ID: <8fb27342-2b32-b0e7-09d9-622ce16e8e76@arista.com> (raw)
In-Reply-To: <aa0143bc-b0d1-69fb-c117-1e7241f0ad89@linuxfoundation.org>

On 8/23/22 16:47, Shuah Khan wrote:
> On 8/18/22 10:59 AM, Dmitry Safonov wrote:
[..]
>> +
>> +__attribute__((__format__(__printf__, 2, 3)))
>> +static inline void __test_print(void (*fn)(const char *), const char
>> *fmt, ...)
>> +{
>> +#define TEST_MSG_BUFFER_SIZE 4096
>> +    char buf[TEST_MSG_BUFFER_SIZE];
>> +    va_list arg;
>> +
>> +    va_start(arg, fmt);
>> +    vsnprintf(buf, sizeof(buf), fmt, arg);
>> +    va_end(arg);
>> +    fn(buf);
>> +}
>> +
> 
> Is there a reason add these instead of using kselftest_* print
> functions?

Inside __test_ok(), __test_msg(), __test_fail() and __test_error() are
calling ksft_*() functions. kselftest_*() by themselves are not
thread-safe and I was not sure if you would want them to be.

> 
>> +#define test_print(fmt, ...)                        \
>> +    __test_print(__test_msg, "%ld[%s:%u] " fmt "\n",        \
>> +             syscall(SYS_gettid),                \
>> +             __FILE__, __LINE__, ##__VA_ARGS__)
>> +
>> +#define test_ok(fmt, ...)                        \
>> +    __test_print(__test_ok, fmt "\n", ##__VA_ARGS__)
>> +
>> +#define test_fail(fmt, ...)                        \
>> +do {                                    \
>> +    if (errno)                            \
>> +        __test_print(__test_fail, fmt ": %m\n", ##__VA_ARGS__);    \
>> +    else                                \
>> +        __test_print(__test_fail, fmt "\n", ##__VA_ARGS__);    \
>> +    test_failed();                            \
>> +} while(0)
>> +
>> +#define KSFT_FAIL  1
>> +#define test_error(fmt, ...)                        \
>> +do {                                    \
>> +    if (errno)                            \
>> +        __test_print(__test_error, "%ld[%s:%u] " fmt ": %m\n",    \
>> +                 syscall(SYS_gettid), __FILE__, __LINE__,    \
>> +                 ##__VA_ARGS__);                \
>> +    else                                \
>> +        __test_print(__test_error, "%ld[%s:%u] " fmt "\n",    \
>> +                 syscall(SYS_gettid), __FILE__, __LINE__,    \
>> +                 ##__VA_ARGS__);                \
>> +    exit(KSFT_FAIL);                        \
>> +} while(0)
>> +
> 
> Is there a reason add these instead of using kselftest_* print
> functions?

The same reason: two or more threads my fail the test at the same
moment, I needed some way of protecting the output.

>> + * Timeout on syscalls where failure is not expected.
>> + * You may want to rise it if the test machine is very busy.
>> + */
>> +#ifndef TEST_TIMEOUT_SEC
>> +#define TEST_TIMEOUT_SEC    5
>> +#endif
>> +
> 
> Where is the TEST_TIMEOUT_SEC usually defined? Does this come
> from shell wrapper that runs this test? Can we add a message before
> starting the test print the timeout used?

Usually it's not re-defined and used as-is. Ifndef here is only to make
it easier to recompile with another timeout const: one can just add
CFLAGS+=-DTEST_TIMEOUT_SEC=10 and check if that helps on the busy hardware.


>> +/*
>> + * Timeout on connect() where a failure is expected.
>> + * If set to 0 - kernel will try to retransmit SYN number of times,
>> set in
>> + * /proc/sys/net/ipv4/tcp_syn_retries
>> + * By default set to 1 to make tests pass faster on non-busy machine.
>> + */
>> +#ifndef TEST_RETRANSMIT_SEC
>> +#define TEST_RETRANSMIT_SEC    1
>> +#endif
>> +
> 
> Where would this TEST_RETRANSMIT_SEC defined usually?

The same: I always used the default value, but protected by ifndef if
one wants to increase the value.

>> +
>> +static inline int _test_connect_socket(int sk, const union tcp_addr
>> taddr,
>> +                    unsigned port, time_t timeout)
>> +{
>> +#ifdef IPV6_TEST
>> +    struct sockaddr_in6 addr = {
>> +        .sin6_family    = AF_INET6,
>> +        .sin6_port    = htons(port),
>> +        .sin6_addr    = taddr.a6,
>> +    };
>> +#else
>> +    struct sockaddr_in addr = {
>> +        .sin_family    = AF_INET,
>> +        .sin_port    = htons(port),
>> +        .sin_addr    = taddr.a4,
>> +    };
>> +#endif
> 
> Why do we defined these here - are they also defined in a kernel
> header?

No, those functions are helpers that process family-specific members.
IPV6_TEST is coming from Makefile:
$(OUTPUT)/%_ipv6: %.c
	$(LINK.c) -DIPV6_TEST $^ $(LDLIBS) -o $@

This way all tests can be compiled from the same code for both address
families, resulting in *_ipv4 and *_ipv6 binaries that reuse all the
code, but just have those #ifdef IPV6_TEST in places where test converts
or produces IP addresses.

[..]
>> +static inline int test_prepare_ao(struct tcp_ao *ao,
>> +        const char *alg, uint16_t flags,
>> +        union tcp_addr in_addr, uint8_t prefix,
>> +        uint8_t sndid, uint8_t rcvid, uint8_t maclen,
>> +        uint8_t keyflags, uint8_t keylen, const char *key)
>> +{
>> +#ifdef IPV6_TEST
>> +    struct sockaddr_in6 addr = {
>> +        .sin6_family    = AF_INET6,
>> +        .sin6_port    = 0,
>> +        .sin6_addr    = in_addr.a6,
>> +    };
>> +#else
>> +    struct sockaddr_in addr = {
>> +        .sin_family    = AF_INET,
>> +        .sin_port    = 0,
>> +        .sin_addr    = in_addr.a4,
>> +    };
>> +#endif
>> +
> 
> Same question here. In general having these ifdefs isn't ideal without
> a good reason.

Same as above.

> 
>> +    return test_prepare_ao_sockaddr(ao, alg, flags,
>> +            (void *)&addr, sizeof(addr), prefix, sndid, rcvid,
>> +            maclen, keyflags, keylen, key);
>> +}
>> +
>> +static inline int test_prepare_def_ao(struct tcp_ao *ao,
>> +        const char *key, uint16_t flags,
>> +        union tcp_addr in_addr, uint8_t prefix,
>> +        uint8_t sndid, uint8_t rcvid)
>> +{
>> +    if (prefix > DEFAULT_TEST_PREFIX)
>> +        prefix = DEFAULT_TEST_PREFIX;
>> +
>> +    return test_prepare_ao(ao, DEFAULT_TEST_ALGO, flags, in_addr,
>> +            prefix, sndid, rcvid, 0, 0, strlen(key), key);
>> +}
>> +
>> +extern int test_get_one_ao(int sk, struct tcp_ao_getsockopt *out,
>> +               uint16_t flags, void *addr, size_t addr_sz,
>> +               uint8_t prefix, uint8_t sndid, uint8_t rcvid);
>> +extern int test_cmp_getsockopt_setsockopt(const struct tcp_ao *a,
>> +                      const struct tcp_ao_getsockopt *b);
>> +
>> +static inline int test_verify_socket_ao(int sk, struct tcp_ao *ao)
>> +{
>> +    struct tcp_ao_getsockopt tmp;
>> +    int err;
>> +
>> +    err = test_get_one_ao(sk, &tmp, 0, &ao->tcpa_addr,
>> +            sizeof(ao->tcpa_addr), ao->tcpa_prefix,
>> +            ao->tcpa_sndid, ao->tcpa_rcvid);
>> +    if (err)
>> +        return err;
> 
> Is this always an error or could this a skip if dependencies aren't
> met to run the test? This is a global comment for all error cases.

Yeah, at this moment all tests will FAIL if CONFIG_TCP_AO is disabled.
I'll look into making them SKIP when getsockopt()/setsockopt() returns
ENOPROTOOPT in next versions of patches.

> 
>> +
>> +    return test_cmp_getsockopt_setsockopt(ao, &tmp);
>> +}
>> +
>> +static inline int test_set_ao(int sk, const char *key, uint16_t flags,
>> +                  union tcp_addr in_addr, uint8_t prefix,
>> +                  uint8_t sndid, uint8_t rcvid)
>> +{
>> +    struct tcp_ao tmp;
>> +    int err;
>> +
>> +    err = test_prepare_def_ao(&tmp, key, flags, in_addr,
>> +            prefix, sndid, rcvid);
>> +    if (err)
>> +        return err;
> 
> Same comment as above here.
> 
>> +
>> +    if (setsockopt(sk, IPPROTO_TCP, TCP_AO, &tmp, sizeof(tmp)) < 0)
>> +        return -errno;
>> +
>> +    return test_verify_socket_ao(sk, &tmp);
>> +}
>> +
>> +extern ssize_t test_server_run(int sk, ssize_t quota, time_t
>> timeout_sec);
>> +extern ssize_t test_client_loop(int sk, char *buf, size_t buf_sz,
>> +                const size_t msg_len, time_t timeout_sec);
>> +extern int test_client_verify(int sk, const size_t msg_len, const
>> size_t nr,
>> +                  time_t timeout_sec);
>> +
>> +struct netstat;
>> +extern struct netstat *netstat_read(void);
>> +extern void netstat_free(struct netstat *ns);
>> +extern void netstat_print_diff(struct netstat *nsa, struct netstat
>> *nsb);
>> +extern uint64_t netstat_get(struct netstat *ns,
>> +                const char *name, bool *not_found);
>> +
>> +static inline uint64_t netstat_get_one(const char *name, bool
>> *not_found)
>> +{
>> +    struct netstat *ns = netstat_read();
>> +    uint64_t ret;
>> +
>> +    ret = netstat_get(ns, name, not_found);
>> +
>> +    netstat_free(ns);
>> +    return ret;
>> +}
>> +
>> +#endif /* _AOLIB_H_ */
>> diff --git a/tools/testing/selftests/net/tcp_ao/lib/netlink.c
>> b/tools/testing/selftests/net/tcp_ao/lib/netlink.c
>> new file mode 100644
>> index 000000000000..f04757c921d0
>> --- /dev/null
>> +++ b/tools/testing/selftests/net/tcp_ao/lib/netlink.c
>> @@ -0,0 +1,341 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Original from tools/testing/selftests/net/ipsec.c */
>> +#include <linux/netlink.h>
>> +#include <linux/random.h>
>> +#include <linux/rtnetlink.h>
>> +#include <linux/veth.h>
>> +#include <net/if.h>
>> +#include <stdint.h>
>> +#include <string.h>
>> +#include <sys/socket.h>
>> +
>> +#include "aolib.h"
>> +
>> +#define MAX_PAYLOAD        2048
> 
> tools/testing/selftests/net/gro.c seem to define this as:
> 
> #define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) -
> sizeof(struct ipv6hdr))
> 
> Can you do the same instead of hard-coding?

I think I could look into way of dynamically allocate netlink buffer for
requests, but I would say it's not as bad as it looks: the functions
always use constant size of messages for the netlink messages, so the
buffer size is always constant. And if anything doesn't fit, the helper
rtattr_pack() will just fail the test and it'll be visible straight away.
So, in my point of view, it could have been nicer, but this is the
easiest and simplest way by allocating const buffer on stack, rather
than dynamically.

>> +
>> +const struct sockaddr_in6 addr_any6 = {
>> +    .sin6_family    = AF_INET6,
>> +};
>> +
>> +const struct sockaddr_in addr_any4 = {
>> +    .sin_family    = AF_INET,
>> +};
>>
> 
> A couple of things to look at closely. For some failures such as
> memory allocation for the test or not being able to open a file
> 
> fnetstat = fopen("/proc/net/netstat", "r");
> 
> Is this a failure or missing config or not having the right permissions
> to open the fail. All of these cases would be a SKIP and not a test fail.

That makes sense, I'll look into making tests SKIP on failed memory
allocations or failed fopen()s.

Thank you for the review,
          Dmitry

  parent reply	other threads:[~2022-09-06 16:49 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-18 16:59 [PATCH 00/31] net/tcp: Add TCP-AO support Dmitry Safonov
2022-08-18 16:59 ` [PATCH 01/31] crypto: Introduce crypto_pool Dmitry Safonov
2022-08-18 16:59 ` [PATCH 02/31] crypto_pool: Add crypto_pool_reserve_scratch() Dmitry Safonov
2022-08-18 16:59 ` [PATCH 03/31] net/tcp: Separate tcp_md5sig_info allocation into tcp_md5sig_info_add() Dmitry Safonov
2022-08-18 16:59 ` [PATCH 04/31] net/tcp: Disable TCP-MD5 static key on tcp_md5sig_info destruction Dmitry Safonov
2022-08-18 16:59 ` [PATCH 05/31] net/tcp: Use crypto_pool for TCP-MD5 Dmitry Safonov
2022-08-18 16:59 ` [PATCH 06/31] net/ipv6: sr: Switch to using crypto_pool Dmitry Safonov
2022-08-18 16:59 ` [PATCH 07/31] tcp: Add TCP-AO config and structures Dmitry Safonov
2022-08-18 16:59 ` [PATCH 08/31] net/tcp: Introduce TCP_AO setsockopt()s Dmitry Safonov
2022-08-18 18:50   ` kernel test robot
2022-08-18 18:50   ` kernel test robot
2022-08-23 14:45   ` Leonard Crestez
2022-08-31 18:48     ` Dmitry Safonov
2022-09-03  9:35       ` Leonard Crestez
2022-08-25 15:31   ` David Ahern
2022-08-25 18:21     ` David Laight
2022-08-18 16:59 ` [PATCH 09/31] net/tcp: Prevent TCP-MD5 with TCP-AO being set Dmitry Safonov
2022-08-18 16:59 ` [PATCH 10/31] net/tcp: Calculate TCP-AO traffic keys Dmitry Safonov
2022-08-18 16:59 ` [PATCH 11/31] net/tcp: Add TCP-AO sign to outgoing packets Dmitry Safonov
2022-08-18 16:59 ` [PATCH 12/31] net/tcp: Add tcp_parse_auth_options() Dmitry Safonov
2022-08-18 19:00   ` kernel test robot
2022-08-18 16:59 ` [PATCH 13/31] net/tcp: Add AO sign to RST packets Dmitry Safonov
2022-08-18 16:59 ` [PATCH 14/31] net/tcp: Add TCP-AO sign to twsk Dmitry Safonov
2022-08-18 16:59 ` [PATCH 15/31] net/tcp: Wire TCP-AO to request sockets Dmitry Safonov
2022-08-18 16:59 ` [PATCH 16/31] net/tcp: Sign SYN-ACK segments with TCP-AO Dmitry Safonov
2022-08-18 16:59 ` [PATCH 17/31] net/tcp: Verify inbound TCP-AO signed segments Dmitry Safonov
2022-08-18 16:59 ` [PATCH 18/31] net/tcp: Add TCP-AO segments counters Dmitry Safonov
2022-08-18 16:59 ` [PATCH 19/31] net/tcp: Add TCP-AO SNE support Dmitry Safonov
2022-08-23 14:50   ` Leonard Crestez
2022-08-23 22:40     ` Francesco Ruggeri
2022-08-18 16:59 ` [PATCH 20/31] net/tcp: Add tcp_hash_fail() ratelimited logs Dmitry Safonov
2022-08-18 16:59 ` [PATCH 21/31] net/tcp: Ignore specific ICMPs for TCP-AO connections Dmitry Safonov
2022-08-18 16:59 ` [PATCH 22/31] net/tcp: Add option for TCP-AO to (not) hash header Dmitry Safonov
2022-08-18 16:59 ` [PATCH 23/31] net/tcp: Add getsockopt(TCP_AO_GET) Dmitry Safonov
2022-08-23 14:45   ` Leonard Crestez
2022-08-18 16:59 ` [PATCH 24/31] net/tcp: Allow asynchronous delete for TCP-AO keys (MKTs) Dmitry Safonov
2022-08-18 16:59 ` [PATCH 25/31] selftests/net: Add TCP-AO library Dmitry Safonov
2022-08-23 15:47   ` Shuah Khan
2022-09-05 20:24     ` Dmitry Safonov
2022-09-06 16:34     ` Dmitry Safonov [this message]
2022-08-18 17:00 ` [PATCH 26/31] selftests/net: Verify that TCP-AO complies with ignoring ICMPs Dmitry Safonov
2022-08-18 17:00 ` [PATCH 27/31] selftest/net: Add TCP-AO ICMPs accept test Dmitry Safonov
2022-08-18 17:00 ` [PATCH 28/31] selftest/tcp-ao: Add a test for MKT matching Dmitry Safonov
2022-08-18 17:00 ` [PATCH 29/31] selftest/tcp-ao: Add test for TCP-AO add setsockopt() command Dmitry Safonov
2022-08-18 17:00 ` [PATCH 30/31] selftests/tcp-ao: Add TCP-AO + TCP-MD5 + no sign listen socket tests Dmitry Safonov
2022-08-18 17:00 ` [PATCH 31/31] selftests/aolib: Add test/benchmark for removing MKTs Dmitry Safonov
2022-08-21 20:34 ` [PATCH 00/31] net/tcp: Add TCP-AO support Leonard Crestez
2022-08-21 23:51   ` David Ahern
2022-08-22 20:35     ` Dmitry Safonov
2022-08-23 15:30       ` Leonard Crestez
2022-08-23 16:31         ` Dmitry Safonov
2022-08-24 12:46         ` Andrew Lunn
2022-08-24 17:55           ` Jakub Kicinski
2022-08-27  8:55           ` Leonard Crestez
2022-08-22 18:42   ` Salam Noureddine
2022-08-22 10:21 [PATCH 02/31] crypto_pool: Add crypto_pool_reserve_scratch() kernel test robot
2022-08-22 10:45 ` Dan Carpenter
2022-08-22 10:45 ` Dan Carpenter
2022-08-26 14:42 ` Dmitry Safonov
2022-08-26 14:42   ` Dmitry Safonov
2022-08-22 11:22 [PATCH 11/31] net/tcp: Add TCP-AO sign to outgoing packets kernel test robot
2022-08-22 12:03 ` [kbuild] " Dan Carpenter
2022-08-22 12:03 ` Dan Carpenter
2022-08-29 17:55 ` Dmitry Safonov
2022-08-29 17:55   ` Dmitry Safonov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8fb27342-2b32-b0e7-09d9-622ce16e8e76@arista.com \
    --to=dima@arista.com \
    --cc=0x7f454c46@gmail.com \
    --cc=ardb@kernel.org \
    --cc=cdleonard@gmail.com \
    --cc=colona@arista.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=ebiggers@kernel.org \
    --cc=edumazet@google.com \
    --cc=fruggeri@arista.com \
    --cc=gilligan@arista.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kuba@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=netdev@vger.kernel.org \
    --cc=noureddine@arista.com \
    --cc=pabeni@redhat.com \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=yoshfuji@linux-ipv6.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.