Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp6409397rdb; Thu, 14 Dec 2023 18:50:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IE3eELNuqfGgav2w9IVBb5HLDumuuoD9/Ly4EhHqrIbZUYlPKanJ+u1DfHOnC8SerQvhn87 X-Received: by 2002:a17:903:984:b0:1d3:73a5:7675 with SMTP id mb4-20020a170903098400b001d373a57675mr2064548plb.41.1702608658785; Thu, 14 Dec 2023 18:50:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702608658; cv=none; d=google.com; s=arc-20160816; b=BsHB8rjSXlGriruq9tphN11jmBjUbchakVLq6UGz2eKNaRVV6Q0UDSbiY5NDPUAwiR XY+yQlRHtCtZMDNgJDmQ8mSHJNSB8PkNSAOxKAF5w19QpSOu71nTwqUkFoago2DvV2Xc +3EXesIsNmZmiFrAkYhyBFLkGIVpRHm4Ox/33PFncHl9S+ipuTXAH5uP00JawanCTLwc NCvnY0KtzdnpWuEbAzkcddTEhAwt9hlLax4PUlYyAinOQWWb4RFJCW18RYDBReTeRgd3 66pMmPLslQASQ+S8sy5/mbn/ppr8yCTcC3RozKgMabAfBg0NsaqGEULK5Vm1ZD16KEwM n5kw== 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=NSHMuEM4mkXgiV/o3pzgHKa8VeGG/uOU+Zc5RrKY7ps=; fh=///qgQEIMYIiBNpkHMNxGZI8A9bpQ6rOjD597FkX+Tg=; b=E+n1i3ss5BLspcqO5ATpPfBieChA4uiL/SU4gBf7eWnUENTIonr6D805fp71IEbw0d kK8sztsX92ZMNtWbupf/8ROByd+rwQa/JPjqpSTCa7Ge+ozAgfhZltmYBJvvwFWDQMjH jhmm0MTN9Z+DGDpIYBBrBG0PJrIqnI1LkwHiAMpV7/BHGnjYt9545qRm66EUZpJ8dcZm LH+pttoSeEq033wMqPZPLd8ecQFOP0EUaszCvb5wJShDXJN8ctdu68HLwNanY+su0Nvd HSolxoIiEwdsLEbZrx/C6IlXytP5hI5wY4k90bHvDlyD8IvztPVtu4rIuR0LIl4vyLLh 1sAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@arista.com header.s=google header.b=iiyB+OOo; spf=pass (google.com: domain of linux-kernel+bounces-362-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-362-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 bb8-20020a170902bc8800b001cfd66f31ccsi12333096plb.55.2023.12.14.18.50.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:50:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-362-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=iiyB+OOo; spf=pass (google.com: domain of linux-kernel+bounces-362-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-362-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 2C11D285B75 for ; Fri, 15 Dec 2023 02:41:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EF64618B16; Fri, 15 Dec 2023 02:37:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=arista.com header.i=@arista.com header.b="iiyB+OOo" X-Original-To: linux-kernel@vger.kernel.org Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 47595171DE for ; Fri, 15 Dec 2023 02:37:40 +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-f45.google.com with SMTP id 5b1f17b1804b1-40c2db2ee28so2529925e9.2 for ; Thu, 14 Dec 2023 18:37:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=google; t=1702607858; x=1703212658; 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=NSHMuEM4mkXgiV/o3pzgHKa8VeGG/uOU+Zc5RrKY7ps=; b=iiyB+OOoRTHaz2eL7AuDioVYqt3Wt+NQSDo6V0UJWa1ZhrxGT2LkHJCu5NoX5eR/TM UGlwPERqdkDa9eqgx09sKF7jXDO4lNm6B7qBD1NZi39RzFdSSV/cg0dHCBe+59DleYw/ fweaOFQJ0KRIP2lDriTWijwoaVPx3Nakgp5LfkvsQHRGYNPhF/1timXij7rZWtaZyEXr QiBVdbIj+cvpIKeyL3uR75Bm+T87HpPxuGNN17Z0Yx617zfVKAUyuR6uVKxQZH0FOg20 Ev+osKiohivneUd14c4nfxf6ZMgLRipFqCzBXz3fH7i8W6bmNxChrzJM2C1B4Q/LvyBg X8hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702607858; x=1703212658; 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=NSHMuEM4mkXgiV/o3pzgHKa8VeGG/uOU+Zc5RrKY7ps=; b=GaEDekhQ8RTMqLzUPMtzuv+LZvYtxmqQevNTMvqjrnoVDc+4Tf8o91EevagJnme7f1 fhIJ01qeEpM30B2wq6F6muUkGxo0RhgJROfbV5M+w5a9el9c5ER3G7AoBIuj78ntY2xR KmI/lcDQPJnY6LwIGSpPhFhSsNmJR2QRPtAnP0WohGPMIk07jBzbPUv/rBht9PxQ9+8X D1s4hLfIs5UTodHmqnuvoBVrY2Xclt98rXB437iku4nrOVykj8n36WUzqDPtoyAuUC0d l42J7Zzr1/V778nfcP4u9YYAlU7YZmrtMCJNb/RrDEA2eYBbxhaB61BOy2+X8uiMAqmD cKBw== X-Gm-Message-State: AOJu0YxU1a2D/dPkN88IYTF54S3LKddpEbBuzCbKhidf3+l2gLp6SlS5 vFIgYeAHkuuGbt+w5auzNVcc1Q== X-Received: by 2002:a05:600c:4d0d:b0:40c:3555:e233 with SMTP id u13-20020a05600c4d0d00b0040c3555e233mr5747650wmp.69.1702607858645; Thu, 14 Dec 2023 18:37:38 -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.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 18:37:38 -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 11/12] selftests/net: Add TCP-AO selfconnect/simultaneous connect test Date: Fri, 15 Dec 2023 02:36:25 +0000 Message-ID: <20231215-tcp-ao-selftests-v1-11-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=8008; i=dima@arista.com; s=20231212; h=from:subject:message-id; bh=+tWgmGWacvQuSpFv6ELIBYa/m0joOM6XsOHGZFm+/F0=; b=db1PWVjFm/G/6sJvTxRyKwxhWIW0IIX0712kQsGH3HYz4FbpKCEq01Lm2CHYKPb0rR/3J9gY5 mNibxITY5hEBjaG9dMXndYxtthXCAKqRQaswUmVEjQgwxYACpM8gF3b X-Developer-Key: i=dima@arista.com; a=ed25519; pk=hXINUhX25b0D/zWBKvd6zkvH7W2rcwh/CH6cjEa3OTk= Content-Transfer-Encoding: 8bit Check that a rare functionality of TCP named self-connect works with TCP-AO. This "under the cover" also checks TCP simultaneous connect (TCP_SYN_RECV socket state), which would be harder to check other ways. In order to verify that it's indeed TCP simultaneous connect, check the counters TCPChallengeACK and TCPSYNChallenge. Sample of the output: > # ./self-connect_ipv6 > 1..4 > # 1738[lib/setup.c:254] rand seed 1696451931 > TAP version 13 > ok 1 self-connect(same keyids): connect TCPAOGood 0 => 24 > ok 2 self-connect(different keyids): connect TCPAOGood 26 => 50 > ok 3 self-connect(restore): connect TCPAOGood 52 => 97 > ok 4 self-connect(restore, different keyids): connect TCPAOGood 99 => 144 > # Totals: pass:4 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/self-connect.c | 197 ++++++++++++++++++++++ 2 files changed, 198 insertions(+) diff --git a/tools/testing/selftests/net/tcp_ao/Makefile b/tools/testing/selftests/net/tcp_ao/Makefile index 1d4f7576d774..9286f9b99c86 100644 --- a/tools/testing/selftests/net/tcp_ao/Makefile +++ b/tools/testing/selftests/net/tcp_ao/Makefile @@ -5,6 +5,7 @@ TEST_BOTH_AF += connect-deny TEST_BOTH_AF += icmps-accept icmps-discard TEST_BOTH_AF += restore TEST_BOTH_AF += rst +TEST_BOTH_AF += self-connect TEST_BOTH_AF += seq-ext TEST_BOTH_AF += setsockopt-closed TEST_BOTH_AF += unsigned-md5 diff --git a/tools/testing/selftests/net/tcp_ao/self-connect.c b/tools/testing/selftests/net/tcp_ao/self-connect.c new file mode 100644 index 000000000000..e154d9e198a9 --- /dev/null +++ b/tools/testing/selftests/net/tcp_ao/self-connect.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Author: Dmitry Safonov */ +#include +#include "aolib.h" + +static union tcp_addr local_addr; + +static void __setup_lo_intf(const char *lo_intf, + const char *addr_str, uint8_t prefix) +{ + if (inet_pton(TEST_FAMILY, addr_str, &local_addr) != 1) + test_error("Can't convert local ip address"); + + if (ip_addr_add(lo_intf, TEST_FAMILY, local_addr, prefix)) + test_error("Failed to add %s ip address", lo_intf); + + if (link_set_up(lo_intf)) + test_error("Failed to bring %s up", lo_intf); +} + +static void setup_lo_intf(const char *lo_intf) +{ +#ifdef IPV6_TEST + __setup_lo_intf(lo_intf, "::1", 128); +#else + __setup_lo_intf(lo_intf, "127.0.0.1", 8); +#endif +} + +static void tcp_self_connect(const char *tst, unsigned int port, + bool different_keyids, bool check_restore) +{ + uint64_t before_challenge_ack, after_challenge_ack; + uint64_t before_syn_challenge, after_syn_challenge; + struct tcp_ao_counters before_ao, after_ao; + uint64_t before_aogood, after_aogood; + struct netstat *ns_before, *ns_after; + const size_t nr_packets = 20; + struct tcp_ao_repair ao_img; + struct tcp_sock_state img; + sockaddr_af addr; + int sk; + + tcp_addr_to_sockaddr_in(&addr, &local_addr, htons(port)); + + sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); + if (sk < 0) + test_error("socket()"); + + if (different_keyids) { + if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 5, 7)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 7, 5)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + } else { + if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 100, 100)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + } + + if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) + test_error("bind()"); + + ns_before = netstat_read(); + before_aogood = netstat_get(ns_before, "TCPAOGood", NULL); + before_challenge_ack = netstat_get(ns_before, "TCPChallengeACK", NULL); + before_syn_challenge = netstat_get(ns_before, "TCPSYNChallenge", NULL); + if (test_get_tcp_ao_counters(sk, &before_ao)) + test_error("test_get_tcp_ao_counters()"); + + if (__test_connect_socket(sk, "lo", (struct sockaddr *)&addr, + sizeof(addr), TEST_TIMEOUT_SEC) < 0) { + ns_after = netstat_read(); + netstat_print_diff(ns_before, ns_after); + test_error("failed to connect()"); + } + + if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) { + test_fail("%s: tcp connection verify failed", tst); + close(sk); + return; + } + + ns_after = netstat_read(); + after_aogood = netstat_get(ns_after, "TCPAOGood", NULL); + after_challenge_ack = netstat_get(ns_after, "TCPChallengeACK", NULL); + after_syn_challenge = netstat_get(ns_after, "TCPSYNChallenge", NULL); + if (test_get_tcp_ao_counters(sk, &after_ao)) + test_error("test_get_tcp_ao_counters()"); + if (!check_restore) { + /* to debug: netstat_print_diff(ns_before, ns_after); */ + netstat_free(ns_before); + } + netstat_free(ns_after); + + if (after_aogood <= before_aogood) { + test_fail("%s: TCPAOGood counter mismatch: %zu <= %zu", + tst, after_aogood, before_aogood); + close(sk); + return; + } + if (after_challenge_ack <= before_challenge_ack || + after_syn_challenge <= before_syn_challenge) { + /* + * It's also meant to test simultaneous open, so check + * these counters as well. + */ + test_fail("%s: Didn't challenge SYN or ACK: %zu <= %zu OR %zu <= %zu", + tst, after_challenge_ack, before_challenge_ack, + after_syn_challenge, before_syn_challenge); + close(sk); + return; + } + + if (test_tcp_ao_counters_cmp(tst, &before_ao, &after_ao, TEST_CNT_GOOD)) { + close(sk); + return; + } + + if (!check_restore) { + test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64, + tst, before_aogood, after_aogood); + close(sk); + return; + } + + test_enable_repair(sk); + test_sock_checkpoint(sk, &img, &addr); +#ifdef IPV6_TEST + addr.sin6_port = htons(port + 1); +#else + addr.sin_port = htons(port + 1); +#endif + test_ao_checkpoint(sk, &ao_img); + test_kill_sk(sk); + + sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP); + if (sk < 0) + test_error("socket()"); + + test_enable_repair(sk); + __test_sock_restore(sk, "lo", &img, &addr, &addr, sizeof(addr)); + if (different_keyids) { + if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0, + local_addr, -1, 7, 5)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0, + local_addr, -1, 5, 7)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + } else { + if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0, + local_addr, -1, 100, 100)) + test_error("setsockopt(TCP_AO_ADD_KEY)"); + } + test_ao_restore(sk, &ao_img); + test_disable_repair(sk); + test_sock_state_free(&img); + if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) { + test_fail("%s: tcp connection verify failed", tst); + close(sk); + return; + } + ns_after = netstat_read(); + after_aogood = netstat_get(ns_after, "TCPAOGood", NULL); + /* to debug: netstat_print_diff(ns_before, ns_after); */ + netstat_free(ns_before); + netstat_free(ns_after); + close(sk); + if (after_aogood <= before_aogood) { + test_fail("%s: TCPAOGood counter mismatch: %zu <= %zu", + tst, after_aogood, before_aogood); + return; + } + test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64, + tst, before_aogood, after_aogood); +} + +static void *client_fn(void *arg) +{ + unsigned int port = test_server_port; + + setup_lo_intf("lo"); + + tcp_self_connect("self-connect(same keyids)", port++, false, false); + tcp_self_connect("self-connect(different keyids)", port++, true, false); + tcp_self_connect("self-connect(restore)", port, false, true); + port += 2; + tcp_self_connect("self-connect(restore, different keyids)", port, true, true); + port += 2; + + return NULL; +} + +int main(int argc, char *argv[]) +{ + test_init(4, client_fn, NULL); + return 0; +} -- 2.43.0