From patchwork Wed Aug 14 16:17:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Luczaj X-Patchwork-Id: 13763688 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 076F81B9B26 for ; Wed, 14 Aug 2024 16:17:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652283; cv=none; b=l5VT0YmSJchdhvvL34YXy+OpCA8M5T2FJP5L2htCciT5XkJLdoQ0gRe8jcI02hdoXqzjNKz149x+Mv3ewJOKJxjU6++kXWpDDt4mVUXmvNG/A3ox8ofGfU2ldd7eRrlMuwRWhtmNsNbT+WVxyoJOD9xzxufAEKVEN1aYFknEBZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652283; c=relaxed/simple; bh=NQTpemzt4Tj8++a5VIsyfyK7+ZLyBcJfu2xffJVhs0k=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=qwdInt5/w98Sp1vwS968nmQASh0hXmwfVK7h7Ucc2OpVifwH+HrlZnzp7y2an5J3XMIDC3EW2UghfirG2uho9MlTYbxZFsSSEwy6e/CGFF0dXGBaa8zQGPdtWsV7oKih+NxYWSwrqhSJ6Ncc1EmA2YqduUQTbv4KaRhYbYsug+k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co; spf=pass smtp.mailfrom=rbox.co; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b=QQkhUmtw; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rbox.co Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b="QQkhUmtw" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1seGh1-00GwYx-35; Wed, 14 Aug 2024 18:17:47 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rbox.co; s=selector1; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:References: Cc:To:From:Subject:MIME-Version:Date:Message-ID; bh=eO5sD2wD20qYLIyQAYTr+NiDMBMypw6HCWvaYXpaa6s=; b=QQkhUmtwnl8ckO8bW0pQNcbx2m gyEKnUqLeYNWPm3KCygcbh+QFQGqL3H7Qkt8c3EDXk6xjjU1fHzKyBs6QltpBiu1n0adkfj5S2QKQ ygHDNDPKGq1v+KVKZbK9XaWKjKThS/fUVmsyax5sKkXl9ZVhw1s+NgapuTE49iTX8LgVNbCNs0oF4 6W9mZxjSumKrdmPDh6TZdOYVI8RmPjT3kljfg2kTOV4fwM8UetI7Yo8E9/CLQE6OUK9muPDOw14fD OLvaqseKMRpDgi6O71HoD1lhuxIOu4+tNoFm34s8f1JPOXioFsceOiPBi3b+NFLoASfjcmp0AWWwN hzeDIF7Q==; Received: from [10.9.9.74] (helo=submission03.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1seGh0-0005Xd-9h; Wed, 14 Aug 2024 18:17:46 +0200 Received: by submission03.runbox with esmtpsa [Authenticated ID (604044)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1seGgw-00EOyD-7r; Wed, 14 Aug 2024 18:17:42 +0200 Message-ID: <55559365-8dea-4458-a6f3-3b0cff9f051f@rbox.co> Date: Wed, 14 Aug 2024 18:17:40 +0200 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 1/3] selftests/bpf: Support AF_UNIX SOCK_DGRAM socket pair creation From: Michal Luczaj To: Jakub Sitnicki Cc: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org References: <20240731-selftest-sockmap-fixes-v2-0-08a0c73abed2@rbox.co> <87y159yi5m.fsf@cloudflare.com> <249a7dc3-34e2-4579-aae7-8b38b145e4bb@rbox.co> <87ttfxy28s.fsf@cloudflare.com> <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Content-Language: pl-PL, en-GB In-Reply-To: <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Handle AF_UNIX in init_addr_loopback(). For pair creation, bind() the peer socket to make SOCK_DGRAM connect() happy. Signed-off-by: Michal Luczaj --- .../bpf/prog_tests/sockmap_helpers.h | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h index 38e35c72bdaa..c50efa834a11 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h @@ -1,6 +1,7 @@ #ifndef __SOCKMAP_HELPERS__ #define __SOCKMAP_HELPERS__ +#include #include /* include/linux/net.h */ @@ -283,6 +284,15 @@ static inline void init_addr_loopback6(struct sockaddr_storage *ss, *len = sizeof(*addr6); } +static inline void init_addr_loopback_unix(struct sockaddr_storage *ss, + socklen_t *len) +{ + struct sockaddr_un *addr = memset(ss, 0, sizeof(*ss)); + + addr->sun_family = AF_UNIX; + *len = sizeof(sa_family_t); +} + static inline void init_addr_loopback_vsock(struct sockaddr_storage *ss, socklen_t *len) { @@ -304,6 +314,9 @@ static inline void init_addr_loopback(int family, struct sockaddr_storage *ss, case AF_INET6: init_addr_loopback6(ss, len); return; + case AF_UNIX: + init_addr_loopback_unix(ss, len); + return; case AF_VSOCK: init_addr_loopback_vsock(ss, len); return; @@ -390,21 +403,27 @@ static inline int create_pair(int family, int sotype, int *p0, int *p1) { __close_fd int s, c = -1, p = -1; struct sockaddr_storage addr; - socklen_t len = sizeof(addr); + socklen_t len; int err; s = socket_loopback(family, sotype); if (s < 0) return s; - err = xgetsockname(s, sockaddr(&addr), &len); - if (err) - return err; - c = xsocket(family, sotype, 0); if (c < 0) return c; + init_addr_loopback(family, &addr, &len); + err = xbind(c, sockaddr(&addr), len); + if (err) + return err; + + len = sizeof(addr); + err = xgetsockname(s, sockaddr(&addr), &len); + if (err) + return err; + err = connect(c, sockaddr(&addr), len); if (err) { if (errno != EINPROGRESS) { From patchwork Wed Aug 14 16:18:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Luczaj X-Patchwork-Id: 13763689 Received: from mailtransmit04.runbox.com (mailtransmit04.runbox.com [185.226.149.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BCA71B8EB0; Wed, 14 Aug 2024 16:18:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652337; cv=none; b=rklbzYUyYDhrXw+CbDg+ispt87+oQVRRUUKC+QzqhKr7JQ2ye6PoamzxMbGG886isRhYInkaDP7pVwbsl0MfvmEwvFAvynkOhqzyj13HAfU4haNBEGR1U+G1tE1eRzugkxH3Dx5Di7akvBe/bPXUVACPlZqo7pgUlrrPNcWYLps= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652337; c=relaxed/simple; bh=zNsgASF057wFi7VlnTNfAZFkCOhBpYb4cACDi4WyeMo=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=DvIerFkRP1OvJ4PTMFzVjRmQDfI1z61gXAOw95UEaVgCGLE00k15YRU1KPSJUsc1ITOw+CPG3LI6OPnk5TcXWTglza+P/ykMhLzoINxZi6d0hoXXMwqaYDUP4tn1X1WC2TXu1m+/nC4IvpyE0Zp6cBlxunYy7o6bDyTqHk8JiRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co; spf=pass smtp.mailfrom=rbox.co; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b=QteaoSks; arc=none smtp.client-ip=185.226.149.37 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rbox.co Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b="QteaoSks" Received: from mailtransmit03.runbox ([10.9.9.163] helo=aibo.runbox.com) by mailtransmit04.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1seGhz-00Gwg5-3y; Wed, 14 Aug 2024 18:18:47 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rbox.co; s=selector1; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:References: Cc:To:From:Subject:MIME-Version:Date:Message-ID; bh=c0KMUdttV/wxsl2RrtTC21pfQ1ygNN4cevwFVGM0qjg=; b=QteaoSksiufHwLg3pf+KM+JE5p 0ZDOrShK+UOBanQgzqj3ENoiu/fkXlTQ1kvgSvDjokwmM9GS4rQPkSoOrdItmqf3qLRnRsIekjA4M NDAJDaiIBFe6G4DcQ2hGyUshmh1hcrNCVmNT5Kx6n5zBkDo271O2/Zd430XS+WlTWwYnssIRvejwF a2qEmMZEgnBNnxajvjKVMbKRhhkaCXZfkF7aGL6pVddH+idU0T3++A+6IwQIgeeDITqlrmXtgyuOa x4K9fv6d3HDTZ+XcKjfkiqdB/cYu97FKeWQ3lTXwSfmv0yhWVnNm1ZrdCL8fAA6KONuGgpCTuL4rJ UPH94oCw==; Received: from [10.9.9.74] (helo=submission03.runbox) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1seGhy-0005dL-FF; Wed, 14 Aug 2024 18:18:46 +0200 Received: by submission03.runbox with esmtpsa [Authenticated ID (604044)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1seGhg-00EP3T-2v; Wed, 14 Aug 2024 18:18:28 +0200 Message-ID: Date: Wed, 14 Aug 2024 18:18:26 +0200 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 2/3] selftests/bpf: Allow setting BPF_F_INGRESS in prog_msg_verdict() From: Michal Luczaj To: Jakub Sitnicki Cc: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org References: <20240731-selftest-sockmap-fixes-v2-0-08a0c73abed2@rbox.co> <87y159yi5m.fsf@cloudflare.com> <249a7dc3-34e2-4579-aae7-8b38b145e4bb@rbox.co> <87ttfxy28s.fsf@cloudflare.com> <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Content-Language: pl-PL, en-GB In-Reply-To: <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Let a selftest set BPF_F_INGRESS for map/hash redirect. In run_tests(), explicitly reset skel->bss->test_ingress to false. Earlier tests might have left it flipped. Signed-off-by: Michal Luczaj --- tools/testing/selftests/bpf/prog_tests/sockmap_listen.c | 2 ++ tools/testing/selftests/bpf/progs/test_sockmap_listen.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c index da5a6fb03b69..a5e7d27760cf 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c @@ -1850,6 +1850,8 @@ static void test_udp_unix_redir(struct test_sockmap_listen *skel, struct bpf_map static void run_tests(struct test_sockmap_listen *skel, struct bpf_map *map, int family) { + skel->bss->test_ingress = false; + test_ops(skel, map, family, SOCK_STREAM); test_ops(skel, map, family, SOCK_DGRAM); test_redir(skel, map, family, SOCK_STREAM); diff --git a/tools/testing/selftests/bpf/progs/test_sockmap_listen.c b/tools/testing/selftests/bpf/progs/test_sockmap_listen.c index b7250eb9c30c..5a3504d5dfc3 100644 --- a/tools/testing/selftests/bpf/progs/test_sockmap_listen.c +++ b/tools/testing/selftests/bpf/progs/test_sockmap_listen.c @@ -106,9 +106,11 @@ int prog_msg_verdict(struct sk_msg_md *msg) int verdict; if (test_sockmap) - verdict = bpf_msg_redirect_map(msg, &sock_map, zero, 0); + verdict = bpf_msg_redirect_map(msg, &sock_map, zero, + test_ingress ? BPF_F_INGRESS : 0); else - verdict = bpf_msg_redirect_hash(msg, &sock_hash, &zero, 0); + verdict = bpf_msg_redirect_hash(msg, &sock_hash, &zero, + test_ingress ? BPF_F_INGRESS : 0); count = bpf_map_lookup_elem(&verdict_map, &verdict); if (count) From patchwork Wed Aug 14 16:20:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Michal Luczaj X-Patchwork-Id: 13763690 Received: from mailtransmit05.runbox.com (mailtransmit05.runbox.com [185.226.149.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 994C91B86C4; Wed, 14 Aug 2024 16:20:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.226.149.38 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652456; cv=none; b=oiqwrDKvuL3APG0cYuepEQ3pX8HaRK1aYRAJgp0aPc9uJD8L//2hVwT69SKt/f5T4fFiuNCzVIuXsHKoA9FiUSUdIXRh3eEA2HGKgtJ8lCq9IZSCGmS7HMEzp36XbrDWNBaI6Q4maMuBTKPisI+mBrFQ4awkT90xq06ZEGeYzrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723652456; c=relaxed/simple; bh=rgAu4K6r7WzSzmmJO1fCrQvT3MGA3+T/oM3XbKnZQXw=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=JBrF8ClTerM7a9fDK/AYwXWTdw5jQI5LSfJpNbLv7pJCJMsLQ34skTsRIpN0pEeWNqgiF8M1A6cPGSu/sKWGJcWI7ugDQga6VPRr4XettKwLRa0mHtAf02GJG1mGqMEcVxYoiMMoM0HV8LsPAy8N09ETFGyiIY4rYIzEWN9u7Fs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co; spf=pass smtp.mailfrom=rbox.co; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b=ZANC8TFY; arc=none smtp.client-ip=185.226.149.38 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=rbox.co Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rbox.co Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rbox.co header.i=@rbox.co header.b="ZANC8TFY" Received: from mailtransmit02.runbox ([10.9.9.162] helo=aibo.runbox.com) by mailtransmit05.runbox.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1seGjt-00H1bf-Ja; Wed, 14 Aug 2024 18:20:45 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=rbox.co; s=selector1; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:References: Cc:To:From:Subject:MIME-Version:Date:Message-ID; bh=U8otZwZzZZvDkhW6NIBLeajqA7W4gQUWgdPnnL8wM3g=; b=ZANC8TFYLlVReXcZGhpcD+EJcg TKpD/ukYn6q9SHK+GCvEr445iJjGaHrI/9jLm62CS5HuBm+AazesjFGakekO8nJ84XLz8Y/7FoYMo voVWhDyGywXsmY77D18MukZsVwi/V6O4p1bXITsjgZyVWDBpWpy9xSMdvhfbvP4y3wmJxNRRtCWZn P92rb8SoQXO5R1JJGaw+Xn1vUS409mHwvLrqBtB3AJSe1M+X6sy29VV6OwK81QlGsul+26QNnB5t2 L/OcqHFxJRh1+3HNtyWMfOYi3H1MaJOsuqbEPvingZsJKI/z3AhjDaQObc+zd1VeH0w1eUjc1nR9U UifbXgCQ==; Received: from [10.9.9.72] (helo=submission01.runbox) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1seGjs-0003ro-RX; Wed, 14 Aug 2024 18:20:45 +0200 Received: by submission01.runbox with esmtpsa [Authenticated ID (604044)] (TLS1.2:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) id 1seGjb-00ETRD-U3; Wed, 14 Aug 2024 18:20:27 +0200 Message-ID: <7ccedf8d-56e2-4c20-b463-7566bfcb50e0@rbox.co> Date: Wed, 14 Aug 2024 18:20:26 +0200 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 3/3] selftests/bpf: Add selftest for sockmap/hashmap redirection From: Michal Luczaj To: Jakub Sitnicki Cc: Andrii Nakryiko , Eduard Zingerman , Mykola Lysenko , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org References: <20240731-selftest-sockmap-fixes-v2-0-08a0c73abed2@rbox.co> <87y159yi5m.fsf@cloudflare.com> <249a7dc3-34e2-4579-aae7-8b38b145e4bb@rbox.co> <87ttfxy28s.fsf@cloudflare.com> <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Content-Language: pl-PL, en-GB In-Reply-To: <42939687-20f9-4a45-b7c2-342a0e11a014@rbox.co> Test redirection logic. BPF_MAP_TYPE_SOCKMAP BPF_MAP_TYPE_SOCKHASH ✕ sk_msg-to-egress sk_msg-to-ingress sk_skb-to-egress sk_skb-to-ingress ✕ AF_INET, SOCK_STREAM AF_INET6, SOCK_STREAM AF_INET, SOCK_DGRAM AF_INET6, SOCK_DGRAM AF_UNIX, SOCK_STREAM AF_UNIX, SOCK_DGRAM AF_VSOCK, SOCK_STREAM AF_VSOCK, SOCK_SEQPACKET Suggested-by: Jakub Sitnicki Signed-off-by: Michal Luczaj --- .../bpf/prog_tests/sockmap_helpers.h | 58 ++++ .../selftests/bpf/prog_tests/sockmap_redir.c | 315 ++++++++++++++++++ 2 files changed, 373 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/sockmap_redir.c diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h index c50efa834a11..db0a7b4dc8be 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h @@ -16,6 +16,9 @@ #define VMADDR_CID_LOCAL 1 #endif +#define u32(v) ((u32){(v)}) +#define u64(v) ((u64){(v)}) + #define __always_unused __attribute__((__unused__)) /* include/linux/cleanup.h */ @@ -485,4 +488,59 @@ static inline int create_socket_pairs(int family, int sotype, int *c0, int *c1, return err; } +static inline const char *socket_kind_to_str(int sock_fd) +{ + int domain = 0, type = 0; + socklen_t opt_len; + + opt_len = sizeof(domain); + if (getsockopt(sock_fd, SOL_SOCKET, SO_DOMAIN, &domain, &opt_len)) + FAIL_ERRNO("getsockopt(SO_DOMAIN)"); + + opt_len = sizeof(type); + if (getsockopt(sock_fd, SOL_SOCKET, SO_TYPE, &type, &opt_len)) + FAIL_ERRNO("getsockopt(SO_TYPE)"); + + switch (domain) { + case AF_INET: + switch (type) { + case SOCK_STREAM: + return "tcp4"; + case SOCK_DGRAM: + return "udp4"; + } + break; + case AF_INET6: + switch (type) { + case SOCK_STREAM: + return "tcp6"; + case SOCK_DGRAM: + return "udp6"; + } + break; + case AF_UNIX: + switch (type) { + case SOCK_STREAM: + return "u_str"; + case SOCK_DGRAM: + return "u_dgr"; + case SOCK_SEQPACKET: + return "u_seq"; + } + break; + case AF_VSOCK: + switch (type) { + case SOCK_STREAM: + return "v_str"; + case SOCK_DGRAM: + return "v_dgr"; + case SOCK_SEQPACKET: + return "v_seq"; + } + break; + } + + return "???"; +} + #endif // __SOCKMAP_HELPERS__ diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_redir.c b/tools/testing/selftests/bpf/prog_tests/sockmap_redir.c new file mode 100644 index 000000000000..335dd348b019 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_redir.c @@ -0,0 +1,315 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "test_progs.h" +#include "sockmap_helpers.h" +#include "test_sockmap_listen.skel.h" + +enum prog_kind { + SK_MSG_EGRESS, + SK_MSG_INGRESS, + SK_SKB_EGRESS, + SK_SKB_INGRESS, +}; + +struct { + enum prog_kind prog_kind; + const char *in, *out; +} supported[] = { + /* Send to local: TCP -> any but vsock */ + { SK_MSG_INGRESS, "tcp", "tcp" }, + { SK_MSG_INGRESS, "tcp", "udp" }, + { SK_MSG_INGRESS, "tcp", "u_str" }, + { SK_MSG_INGRESS, "tcp", "u_dgr" }, + /* Send to egress: TCP -> TCP */ + { SK_MSG_EGRESS, "tcp", "tcp" }, + /* Ingress to egress: any -> any */ + { SK_SKB_EGRESS, "any", "any" }, + /* Ingress to local: any -> any but vsock */ + { SK_SKB_INGRESS, "any", "tcp" }, + { SK_SKB_INGRESS, "any", "udp" }, + { SK_SKB_INGRESS, "any", "u_str" }, + { SK_SKB_INGRESS, "any", "u_dgr" }, +}; + +enum { + SEND_INNER = 0, + SEND_OUTER, +}; + +enum { + RECV_INNER = 0, + RECV_OUTER, +}; + +enum map_kind { + SOCKMAP, + SOCKHASH, +}; + +struct redir_spec { + const char *name; + int idx_send; + int idx_recv; + enum prog_kind prog_kind; +}; + +struct socket_spec { + int family; + int sotype; + int send_flags; + int in[2]; + int out[2]; +}; + +static int socket_spec_pairs(struct socket_spec *s) +{ + return create_socket_pairs(s->family, s->sotype, + &s->in[0], &s->out[0], + &s->in[1], &s->out[1]); +} + +static void socket_spec_close(struct socket_spec *s) +{ + xclose(s->in[0]); + xclose(s->in[1]); + xclose(s->out[0]); + xclose(s->out[1]); +} + +static void get_redir_params(struct redir_spec *redir, + struct test_sockmap_listen *skel, + int *prog_fd, enum bpf_attach_type *attach_type, + bool *ingress_flag) +{ + enum prog_kind kind = redir->prog_kind; + struct bpf_program *prog; + bool sk_msg; + + sk_msg = kind == SK_MSG_INGRESS || kind == SK_MSG_EGRESS; + prog = sk_msg ? skel->progs.prog_msg_verdict : skel->progs.prog_skb_verdict; + + *prog_fd = bpf_program__fd(prog); + *attach_type = sk_msg ? BPF_SK_MSG_VERDICT : BPF_SK_SKB_VERDICT; + *ingress_flag = kind == SK_MSG_INGRESS || kind == SK_SKB_INGRESS; +} + +static void test_send_redir_recv(int sd_send, int send_flags, int sd_in, + int sd_out, int sd_recv, int map_in, int map_out) +{ + char *send_buf = "ab"; + char recv_buf = '\0'; + ssize_t n, len = 1; + + if (xbpf_map_update_elem(map_in, &u32(0), &u64(sd_in), BPF_NOEXIST)) + return; + + if (xbpf_map_update_elem(map_out, &u32(0), &u64(sd_out), BPF_NOEXIST)) + goto del_in; + + /* Last byte is OOB data when send_flags has MSG_OOB bit set */ + if (send_flags & MSG_OOB) + len++; + n = send(sd_send, send_buf, len, send_flags); + if (n >= 0 && n < len) + FAIL("incomplete send"); + if (n < len && errno != EACCES) { + FAIL_ERRNO("send"); + goto out; + } + + /* sk_msg redirect combo not supported */ + if (errno == EACCES) { + test__skip(); + goto out; + } + + n = recv_timeout(sd_recv, &recv_buf, 1, 0, IO_TIMEOUT_SEC); + if (n != 1) { + FAIL_ERRNO("recv"); + goto out; + } + if (recv_buf != send_buf[0]) + FAIL("recv: payload check, %02x != %02x", recv_buf, send_buf[0]); + + if (send_flags & MSG_OOB) { + /* Check that we can't read OOB while in sockmap */ + errno = 0; + n = recv(sd_out, &recv_buf, 1, MSG_OOB | MSG_DONTWAIT); + if (n != -1) + FAIL("recv(MSG_OOB): expected failure: retval=%zd errno=%d", + n, errno); + + /* Remove sd_out from sockmap */ + xbpf_map_delete_elem(map_out, &u32(0)); + + /* Check that OOB was dropped on redirect */ + errno = 0; + n = recv(sd_out, &recv_buf, 1, MSG_OOB | MSG_DONTWAIT); + if (n != -1) + FAIL("recv(MSG_OOB): expected failure: retval=%zd errno=%d", + n, errno); + + goto del_in; + } +out: + xbpf_map_delete_elem(map_out, &u32(0)); +del_in: + xbpf_map_delete_elem(map_in, &u32(0)); +} + +static bool is_supported(enum prog_kind prog_kind, const char *in, const char *out) +{ + for (int i = 0; i < ARRAY_SIZE(supported); ++i) { + if (supported[i].prog_kind == prog_kind && + (!strcmp(supported[i].in, "any") || strstr(in, supported[i].in)) && + (!strcmp(supported[i].out, "any") || strstr(out, supported[i].out))) + return true; + } + + return false; +} + +static void test_socket(enum map_kind map_kind, struct redir_spec *redir, + int map_in, int map_out, struct socket_spec *s_in, + struct socket_spec *s_out) +{ + int fd_in, fd_out, fd_send, fd_recv, send_flags; + const char *in_str, *out_str; + char s[MAX_TEST_NAME]; + + fd_in = s_in->in[0]; + fd_out = s_out->out[0]; + fd_send = s_in->in[redir->idx_send]; + fd_recv = s_out->out[redir->idx_recv]; + send_flags = s_in->send_flags; + + in_str = socket_kind_to_str(fd_in); + out_str = socket_kind_to_str(fd_out); + + snprintf(s, sizeof(s), + "%-4s %-17s %-5s → %-5s%6s", + /* hash sk_skb-to-ingress u_str → v_str (OOB) */ + map_kind == SOCKMAP ? "map" : "hash", + redir->name, + in_str, + out_str, + send_flags & MSG_OOB ? "(OOB)" : ""); + + if (!test__start_subtest(s)) + return; + + if (!is_supported(redir->prog_kind, in_str, out_str)) { + test__skip(); + return; + } + + test_send_redir_recv(fd_send, send_flags, fd_in, fd_out, fd_recv, + map_in, map_out); +} + +static void test_redir(enum map_kind map_kind, struct redir_spec *redir, + int map_in, int map_out) +{ + struct socket_spec *s, sockets[] = { + { AF_INET, SOCK_STREAM }, + // { AF_INET, SOCK_STREAM, MSG_OOB }, /* Known to be broken */ + { AF_INET6, SOCK_STREAM }, + { AF_INET, SOCK_DGRAM }, + { AF_INET6, SOCK_DGRAM }, + { AF_UNIX, SOCK_STREAM }, + { AF_UNIX, SOCK_STREAM, MSG_OOB }, + { AF_UNIX, SOCK_DGRAM }, + // { AF_UNIX, SOCK_SEQPACKET}, /* Not supported */ + { AF_VSOCK, SOCK_STREAM }, + // { AF_VSOCK, SOCK_DGRAM }, /* Not supported */ + { AF_VSOCK, SOCK_SEQPACKET }, + }; + + for (s = sockets; s < sockets + ARRAY_SIZE(sockets); s++) + if (socket_spec_pairs(s)) + goto out; + + /* Intra-proto */ + for (s = sockets; s < sockets + ARRAY_SIZE(sockets); s++) + test_socket(map_kind, redir, map_in, map_out, s, s); + + /* Cross-proto */ + for (int i = 0; i < ARRAY_SIZE(sockets); i++) { + for (int j = 0; j < ARRAY_SIZE(sockets); j++) { + struct socket_spec *in = &sockets[i]; + struct socket_spec *out = &sockets[j]; + + /* Skip intra-proto and between variants */ + if (out->send_flags || + (in->family == out->family && + in->sotype == out->sotype)) + continue; + + test_socket(map_kind, redir, map_in, map_out, in, out); + } + } +out: + while (--s >= sockets) + socket_spec_close(s); +} + +static void test_map(enum map_kind map_kind) +{ + struct redir_spec *r, redirs[] = { + { "sk_msg-to-egress", SEND_INNER, RECV_OUTER, SK_MSG_EGRESS }, + { "sk_msg-to-ingress", SEND_INNER, RECV_INNER, SK_MSG_INGRESS }, + { "sk_skb-to-egress", SEND_OUTER, RECV_OUTER, SK_SKB_EGRESS }, + { "sk_skb-to-ingress", SEND_OUTER, RECV_INNER, SK_SKB_INGRESS }, + }; + + for (r = redirs; r < redirs + ARRAY_SIZE(redirs); r++) { + struct test_sockmap_listen *skel; + enum bpf_attach_type attach_type; + int prog, map_in, map_out; + + skel = test_sockmap_listen__open_and_load(); + if (!skel) { + FAIL("open_and_load"); + return; + } + + if (map_kind == SOCKMAP) { + skel->bss->test_sockmap = true; + map_out = bpf_map__fd(skel->maps.sock_map); + } else { + skel->bss->test_sockmap = false; + map_out = bpf_map__fd(skel->maps.sock_hash); + } + + map_in = bpf_map__fd(skel->maps.nop_map); + get_redir_params(r, skel, &prog, &attach_type, + &skel->bss->test_ingress); + + if (xbpf_prog_attach(prog, map_in, attach_type, 0)) + return; + + test_redir(map_kind, r, map_in, map_out); + + if (xbpf_prog_detach2(prog, map_in, attach_type)) + return; + + test_sockmap_listen__destroy(skel); + } +} + +void serial_test_sockmap_redir(void) +{ + test_map(SOCKMAP); + test_map(SOCKHASH); +}