Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp6409348rdb; Thu, 14 Dec 2023 18:50:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IFUcANS3haTSVRtBfCvkHANVfZ0Ek2lUqzdG8QSG7UE+5PjLvmP4XjKZ5ZY2zwz9U2buqOh X-Received: by 2002:a05:6e02:180c:b0:35d:59a2:a335 with SMTP id a12-20020a056e02180c00b0035d59a2a335mr13853164ilv.55.1702608647073; Thu, 14 Dec 2023 18:50:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702608647; cv=none; d=google.com; s=arc-20160816; b=e7RNiVIvxy+rnKIKkzUq+JCo1vQ8iNiwqLdm4In3XxzuW301LOD6JLbgL6VN7fOdcC fHxRt0vbFL9xUIUsju+uLSkqa+VcAsdSWTSNKutbP4FOl0YDB3ugwuHeR53dMuI5Fn9L 3NXPcJ4DIHQJkGaiSeR7ACTw3RGmdrjUd0dN/pPezwguDoOX38rTc1fAz9zluhFq3PKo w4vC2EmP7QOZbTgdEWEryFZ7B1L/zWh492JJDw+jiHep1lKBvQG74Bx0CUv0yTZhtJ8u sZyBAuFpY6lA5o6LbGU92DI6Rj5RCvNu9fBxRHMrrDrZ8LhO5x+8EEVkVEuDC3PIy5Z6 WmXg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=lSjB1EB5SWfTFjxbNKGGEdmP2s9s8plvjxkaEGvyTqk=; fh=///qgQEIMYIiBNpkHMNxGZI8A9bpQ6rOjD597FkX+Tg=; b=l5vnXQ1Ls7YMBns0yfZ1nbvLncIeDUTWwvzF6hTxAJvS4ov4nj277FWhODTUD02YkU xiP/ljGHYIXAoxpaTdibH4LRXEcLmp8OTAjA4E38TlwA/eIvxe7j1Nldkxeb86hmnt7D s1ToJi7qpa4DpHuT7ZRLMq1rAp4ephdThNKC2ujdjQ1cbb7qq+Cc4r1+jUwskcpBHIS1 bB9u7MMruYkWmBMMxxG1I1LR5ay18Qga41uz4cdj7LWbZQUBjJFSXMYbEu2wVu2tMMdO mydIWz30tyuo8uqDdvqPrz3z50o/x7DzBuPyzEqC8ByGRvQR4bozUdLq21sVJf5fOo14 GHqQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@arista.com header.s=google header.b="c/y/G3x7"; spf=pass (google.com: domain of linux-kernel+bounces-360-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-360-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=arista.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id a10-20020a170902ee8a00b001d372ed9a0asi1481319pld.90.2023.12.14.18.50.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:50:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-360-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@arista.com header.s=google header.b="c/y/G3x7"; spf=pass (google.com: domain of linux-kernel+bounces-360-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-360-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=arista.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id A37EA285436 for ; Fri, 15 Dec 2023 02:41:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EC224168B9; Fri, 15 Dec 2023 02:37:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=arista.com header.i=@arista.com header.b="c/y/G3x7" X-Original-To: linux-kernel@vger.kernel.org Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DBAF10A37 for ; Fri, 15 Dec 2023 02:37:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=arista.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arista.com Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-40c2c65e6aaso2322225e9.2 for ; Thu, 14 Dec 2023 18:37:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=google; t=1702607856; x=1703212656; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lSjB1EB5SWfTFjxbNKGGEdmP2s9s8plvjxkaEGvyTqk=; b=c/y/G3x7tvrYSqrZEKT/j5ACpvcN7x2/TX3TWzl7TEoRk6lgichWXfligN9ZxsUlE4 gMQhCi7Fa2aYOLqAfTn06hmaqNBnSY3IgQ46pq1nfBifMReFgIpNpNTrCGf1wWWOIuay zGidwxQgONUwAT0/wVoY97Rq5I7lwAEdmclJxk1lpjpklqOwCDO/KE3CoRpwxCpWU9hi NWJMiFkY5jT2ARMf1T1s0nfC597PgUJWMbXivhbCgkgeFIBwL2hUVFtwnvO+pm07rpBM iF+TQaBgrBDPgZvL40x6VivK7arbYDKnWNVKqOnkCVoIdUadNrejQx3HkFjTBg8Zi65x gJ1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702607856; x=1703212656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lSjB1EB5SWfTFjxbNKGGEdmP2s9s8plvjxkaEGvyTqk=; b=GmcVSR9GHDNRvsg8n/GYQDNuVauHolaR9pFKIpPLvtFqD9vabcuyVhiA+1Y1pGc62h DlWuF3KKiMe3j03GaPNeIQDwsdic10iv+GxuxvC/5r7v17jgU2jhVNXdIDVDHixgBPTD e/BuDPA1O5AGq8Xyr5ppA6wJz7sjhzPq8vBxczCl+DQ51PlkoGdkGOmZRth4AFVLm7n9 R4YLxGCc5lSkkBxhhzeN8ilyhM9mNWs8no+d1/9vfPCAHoXo5zukAIWHa9w34ddi/u5q fwJZ2JcD5ESFZYWyW5QkDyAVYb0NJUibgLNRMlDCRl1P8z0KSxMJUpV0R1AIqudHlKlk tILQ== X-Gm-Message-State: AOJu0Yz0eigwjdGR94y4SkC1rXUmyXTcL7gErvvO/OFFc0tifTCzNjn1 YVEVgCsuWNtAyQ4DfZM8zyDRDw== X-Received: by 2002:a05:600c:d4:b0:40b:5e4a:405f with SMTP id u20-20020a05600c00d400b0040b5e4a405fmr4571641wmm.127.1702607855788; Thu, 14 Dec 2023 18:37:35 -0800 (PST) Received: from Mindolluin.ire.aristanetworks.com ([217.173.96.166]) by smtp.gmail.com with ESMTPSA id fc17-20020a05600c525100b0040c42681fcesm20096363wmb.15.2023.12.14.18.37.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:37:35 -0800 (PST) From: Dmitry Safonov To: Shuah Khan , David Ahern , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Dmitry Safonov , Salam Noureddine , Bob Gilligan , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, netdev@vger.kernel.org, Dmitry Safonov <0x7f454c46@gmail.com> Subject: [PATCH 09/12] selftests/net: Add SEQ number extension test Date: Fri, 15 Dec 2023 02:36:23 +0000 Message-ID: <20231215-tcp-ao-selftests-v1-9-f6c08180b985@arista.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231215-tcp-ao-selftests-v1-0-f6c08180b985@arista.com> References: <20231215-tcp-ao-selftests-v1-0-f6c08180b985@arista.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.13-dev-b6b4b X-Developer-Signature: v=1; a=ed25519-sha256; t=1702607833; l=9155; i=dima@arista.com; s=20231212; h=from:subject:message-id; bh=B7iG09khirCmF9VSsv4r9LOgI8ZVE+bnTGQVQqS3z4U=; b=5w8OCIzHj3CIX5nYlGQ4jpkImbosZSVSrjmCV4WStHSCe70oQodPo0aPEFqGvkYWh1LUvxWlB 80ajEIL/Q5/C/iBDUDFB9QmSyNSeEpp/L5Lt4K+zdUSTISP1LCpGTZt X-Developer-Key: i=dima@arista.com; a=ed25519; pk=hXINUhX25b0D/zWBKvd6zkvH7W2rcwh/CH6cjEa3OTk= Content-Transfer-Encoding: 8bit Check that on SEQ number wraparound there is no disruption or TCPAOBad segments produced. Sample of expected output: > # ./seq-ext_ipv4 > 1..7 > # 1436[lib/setup.c:254] rand seed 1686611079 > TAP version 13 > ok 1 server alive > ok 2 post-migrate connection alive > ok 3 TCPAOGood counter increased 1002 => 3002 > ok 4 TCPAOGood counter increased 1003 => 3003 > ok 5 TCPAOBad counter didn't increase > ok 6 TCPAOBad counter didn't increase > ok 7 SEQ extension incremented: 1/1999, 1/998999 > # Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0 Signed-off-by: Dmitry Safonov --- tools/testing/selftests/net/tcp_ao/Makefile | 1 + tools/testing/selftests/net/tcp_ao/seq-ext.c | 245 +++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) diff --git a/tools/testing/selftests/net/tcp_ao/Makefile b/tools/testing/selftests/net/tcp_ao/Makefile index aa11a855c3e0..5408c7233460 100644 --- a/tools/testing/selftests/net/tcp_ao/Makefile +++ b/tools/testing/selftests/net/tcp_ao/Makefile @@ -4,6 +4,7 @@ TEST_BOTH_AF += connect TEST_BOTH_AF += connect-deny TEST_BOTH_AF += icmps-accept icmps-discard TEST_BOTH_AF += restore +TEST_BOTH_AF += seq-ext TEST_BOTH_AF += setsockopt-closed TEST_BOTH_AF += unsigned-md5 diff --git a/tools/testing/selftests/net/tcp_ao/seq-ext.c b/tools/testing/selftests/net/tcp_ao/seq-ext.c new file mode 100644 index 000000000000..ad4e77d6823e --- /dev/null +++ b/tools/testing/selftests/net/tcp_ao/seq-ext.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Check that after SEQ number wrap-around: + * 1. SEQ-extension has upper bytes set + * 2. TCP conneciton is alive and no TCPAOBad segments + * In order to test (2), the test doesn't just adjust seq number for a queue + * on a connected socket, but migrates it to another sk+port number, so + * that there won't be any delayed packets that will fail to verify + * with the new SEQ numbers. + */ +#include +#include "aolib.h" + +const unsigned int nr_packets = 1000; +const unsigned int msg_len = 1000; +const unsigned int quota = nr_packets * msg_len; +unsigned int client_new_port; + +/* Move them closer to roll-over */ +static void test_adjust_seqs(struct tcp_sock_state *img, + struct tcp_ao_repair *ao_img, + bool server) +{ + uint32_t new_seq1, new_seq2; + + /* make them roll-over during quota, but on different segments */ + if (server) { + new_seq1 = ((uint32_t)-1) - msg_len; + new_seq2 = ((uint32_t)-1) - (quota - 2 * msg_len); + } else { + new_seq1 = ((uint32_t)-1) - (quota - 2 * msg_len); + new_seq2 = ((uint32_t)-1) - msg_len; + } + + img->in.seq = new_seq1; + img->trw.snd_wl1 = img->in.seq - msg_len; + img->out.seq = new_seq2; + img->trw.rcv_wup = img->in.seq; +} + +static int test_sk_restore(struct tcp_sock_state *img, + struct tcp_ao_repair *ao_img, sockaddr_af *saddr, + const union tcp_addr daddr, unsigned int dport, + struct tcp_ao_counters *cnt) +{ + int sk; + + sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); + if (sk < 0) + test_error("socket()"); + + test_enable_repair(sk); + test_sock_restore(sk, img, saddr, daddr, dport); + if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0, daddr, -1, 100, 100)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + test_ao_restore(sk, ao_img); + + if (test_get_tcp_ao_counters(sk, cnt)) + test_error("test_get_tcp_ao_counters()"); + + test_disable_repair(sk); + test_sock_state_free(img); + return sk; +} + +static void *server_fn(void *arg) +{ + uint64_t before_good, after_good, after_bad; + struct tcp_ao_counters ao1, ao2; + struct tcp_sock_state img; + struct tcp_ao_repair ao_img; + sockaddr_af saddr; + ssize_t bytes; + int sk, lsk; + + lsk = test_listen_socket(this_ip_addr, test_server_port, 1); + + if (test_add_key(lsk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + + synchronize_threads(); /* 1: MKT added => connect() */ + + if (test_wait_fd(lsk, TEST_TIMEOUT_SEC, 0)) + test_error("test_wait_fd()"); + + sk = accept(lsk, NULL, NULL); + if (sk < 0) + test_error("accept()"); + + synchronize_threads(); /* 2: accepted => send data */ + close(lsk); + + bytes = test_server_run(sk, quota, TEST_TIMEOUT_SEC); + if (bytes != quota) { + if (bytes > 0) + test_fail("server served: %zd", bytes); + else + test_fail("server returned: %zd", bytes); + goto out; + } + + before_good = netstat_get_one("TCPAOGood", NULL); + + synchronize_threads(); /* 3: restore the connection on another port */ + + test_enable_repair(sk); + test_sock_checkpoint(sk, &img, &saddr); + test_ao_checkpoint(sk, &ao_img); + test_kill_sk(sk); +#ifdef IPV6_TEST + saddr.sin6_port = htons(ntohs(saddr.sin6_port) + 1); +#else + saddr.sin_port = htons(ntohs(saddr.sin_port) + 1); +#endif + test_adjust_seqs(&img, &ao_img, true); + synchronize_threads(); /* 4: dump finished */ + sk = test_sk_restore(&img, &ao_img, &saddr, this_ip_dest, + client_new_port, &ao1); + + synchronize_threads(); /* 5: verify counters during SEQ-number rollover */ + bytes = test_server_run(sk, quota, TEST_TIMEOUT_SEC); + if (bytes != quota) { + if (bytes > 0) + test_fail("server served: %zd", bytes); + else + test_fail("server returned: %zd", bytes); + } else { + test_ok("server alive"); + } + + if (test_get_tcp_ao_counters(sk, &ao2)) + test_error("test_get_tcp_ao_counters()"); + after_good = netstat_get_one("TCPAOGood", NULL); + + test_tcp_ao_counters_cmp(NULL, &ao1, &ao2, TEST_CNT_GOOD); + + if (after_good <= before_good) { + test_fail("TCPAOGood counter did not increase: %zu <= %zu", + after_good, before_good); + } else { + test_ok("TCPAOGood counter increased %zu => %zu", + before_good, after_good); + } + after_bad = netstat_get_one("TCPAOBad", NULL); + if (after_bad) + test_fail("TCPAOBad counter is non-zero: %zu", after_bad); + else + test_ok("TCPAOBad counter didn't increase"); + test_enable_repair(sk); + test_ao_checkpoint(sk, &ao_img); + if (ao_img.snd_sne && ao_img.rcv_sne) { + test_ok("SEQ extension incremented: %u/%u", + ao_img.snd_sne, ao_img.rcv_sne); + } else { + test_fail("SEQ extension was not incremented: %u/%u", + ao_img.snd_sne, ao_img.rcv_sne); + } + + synchronize_threads(); /* 6: verified => closed */ +out: + close(sk); + return NULL; +} + +static void *client_fn(void *arg) +{ + uint64_t before_good, after_good, after_bad; + struct tcp_ao_counters ao1, ao2; + struct tcp_sock_state img; + struct tcp_ao_repair ao_img; + sockaddr_af saddr; + int sk; + + sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); + if (sk < 0) + test_error("socket()"); + + if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + + synchronize_threads(); /* 1: MKT added => connect() */ + if (test_connect_socket(sk, this_ip_dest, test_server_port) <= 0) + test_error("failed to connect()"); + + synchronize_threads(); /* 2: accepted => send data */ + if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) { + test_fail("pre-migrate verify failed"); + return NULL; + } + + before_good = netstat_get_one("TCPAOGood", NULL); + + synchronize_threads(); /* 3: restore the connection on another port */ + test_enable_repair(sk); + test_sock_checkpoint(sk, &img, &saddr); + test_ao_checkpoint(sk, &ao_img); + test_kill_sk(sk); +#ifdef IPV6_TEST + client_new_port = ntohs(saddr.sin6_port) + 1; + saddr.sin6_port = htons(ntohs(saddr.sin6_port) + 1); +#else + client_new_port = ntohs(saddr.sin_port) + 1; + saddr.sin_port = htons(ntohs(saddr.sin_port) + 1); +#endif + test_adjust_seqs(&img, &ao_img, false); + synchronize_threads(); /* 4: dump finished */ + sk = test_sk_restore(&img, &ao_img, &saddr, this_ip_dest, + test_server_port + 1, &ao1); + + synchronize_threads(); /* 5: verify counters during SEQ-number rollover */ + if (test_client_verify(sk, msg_len, nr_packets, TEST_TIMEOUT_SEC)) + test_fail("post-migrate verify failed"); + else + test_ok("post-migrate connection alive"); + + if (test_get_tcp_ao_counters(sk, &ao2)) + test_error("test_get_tcp_ao_counters()"); + after_good = netstat_get_one("TCPAOGood", NULL); + + test_tcp_ao_counters_cmp(NULL, &ao1, &ao2, TEST_CNT_GOOD); + + if (after_good <= before_good) { + test_fail("TCPAOGood counter did not increase: %zu <= %zu", + after_good, before_good); + } else { + test_ok("TCPAOGood counter increased %zu => %zu", + before_good, after_good); + } + after_bad = netstat_get_one("TCPAOBad", NULL); + if (after_bad) + test_fail("TCPAOBad counter is non-zero: %zu", after_bad); + else + test_ok("TCPAOBad counter didn't increase"); + + synchronize_threads(); /* 6: verified => closed */ + close(sk); + + synchronize_threads(); /* don't race to exit: let server exit() */ + return NULL; +} + +int main(int argc, char *argv[]) +{ + test_init(7, server_fn, client_fn); + return 0; +} -- 2.43.0