From patchwork Sat Apr 19 15:58:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Rife X-Patchwork-Id: 14057915 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (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 DBF0D1DFE0A for ; Sat, 19 Apr 2025 15:58:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745078295; cv=none; b=pN2ljf5gwjBYUAvXRZXftjPYZbZl2/q1XeOxfelgpP8POhTyNSze+hfB93ubNYffWpVEI1nWhPyOjOyOaIVmHzp8Er9q46mmvdImA9dGiFqwTd+MsIXNct3OhYttjaoZmiVv5uOdczazCLlT9dwlklSz0VgeQW63XmV2Mkfc5RM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745078295; c=relaxed/simple; bh=8D3K8jEJFy2ljx8/dNSQp4nr5+k3ju7eECDWQX6lssg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OQEiq/wFleQCR0T+8aqO2mGIT9BHZQ6Lk02CufhWAkalI26F8MVFND4LgnaIhHk6Y6xdOk4Ad7dqx3k1HeDdPV/H3TmVWPSdQ9N3EzrEz4qj3hCnuwYErzFwmiHww9c1wP1xkcqZEMSdHIfxBznGDQawPAgk5J7KYbCN5cOrSBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=jrife.io; spf=none smtp.mailfrom=jrife.io; dkim=pass (2048-bit key) header.d=jrife-io.20230601.gappssmtp.com header.i=@jrife-io.20230601.gappssmtp.com header.b=gH1UmjI0; arc=none smtp.client-ip=209.85.216.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=jrife.io Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=jrife.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=jrife-io.20230601.gappssmtp.com header.i=@jrife-io.20230601.gappssmtp.com header.b="gH1UmjI0" Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-2ff53b26af2so389003a91.0 for ; Sat, 19 Apr 2025 08:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jrife-io.20230601.gappssmtp.com; s=20230601; t=1745078293; x=1745683093; 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=4N8moraxYLNX0qhNglQq0LQLGcDgagzwGmqz/6Y4IFY=; b=gH1UmjI0EHDLFeK+GirBxHFTbur0MeU2LRL/3sm6IiojmEwwf1UDwbv8QVcnvIyoP3 mkE6AScOevvfnnmqWpgusvoSdtMbGr7vW4CaEz9YljR+6vRTfaTmdGntsMRpmqZn5yeT 6zEUd9eLuhibLmXPJqf99S61pUbG8I6pkES/ae8Y6EcMWnXm0dx7poHg6wxfsSm6cHht C+foV+1vRXkSYuqBZLxJVBq36f66eGcnNgfnaYc/8RjFMGteDHw9QuJETKcSqxc2Hssq sN1t12MXN3mQMDz+QHees9fASD0OQTtLcB3LwfA8SbAMI/VsBYeGqI9sPWez3Xk+qio7 NqOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745078293; x=1745683093; 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=4N8moraxYLNX0qhNglQq0LQLGcDgagzwGmqz/6Y4IFY=; b=F1KP6z49CAGiGEOoYXwGGlBVR/CkcUPk8iocFct9Oliygl7k/HZrexXtgXIcLWN/1e Zbzj8sX5tXEQhnUGoQyd42XZkMPHg/cCZcpGLelRMPI+BJcUt7Bh0ti0rrxZhCavIB1G 8rsMblymTAGhwHk1za7SY6wEzIGQArnL/0UAyH0Bf6Nuu5A7GnQalhcfXjO2kyzpV0el j5sIsGbK9RWZdrePbvHvlD9WmH6mV4mab8trXVIlriob48EUFzh9HTTnAjQ5Op157ANu JPXulafabbFgspsi1KI5ctedWzleHmJoiTGUY/Blnhfd8Ew4+4aUB4O3BTmpDaic5lDP n9+Q== X-Forwarded-Encrypted: i=1; AJvYcCWGjIwYWXEk+HvsEueDmLFAAZNs8Fl0yU6vNM3DChzOwXNiS6pi9g8elHKQyi2Rc5LKvZ8=@vger.kernel.org X-Gm-Message-State: AOJu0YxcVuKNZfWInb9l0ShhsXiFzSCKrUbYTR/uCEORkUEJJa3Mdg3B XZqxwt+wSCILpR0R7iFM7+zBrUTWTnerspNJM7qnnE3MYOE6H7rEZddhHI30dEg= X-Gm-Gg: ASbGncvroN5b9GU7KHyPLHRXTyL0LTfWQUEcPEVILCMiVuOOyKpzlBZ5wnVWhTsZFpp 1Njpq6nMdVeCLnfiZCKOsPud8niJcHgEfXdF89o6yc4MiCwwMpa1fMnyJ3uoJVlN69utxhPNHgD L4tIneyehVcjVDWt4heygGNgSvvSEIQQMb/Z1Mx3tW/3iK7ZTnft7EcTnCqsWtD5rRKuZXebGfA xNxEnyYV7a02PUGKTqlUZYfY+3fbPG+TLBQZouT4MBqLrdOChIiA726gsiU/hPtge8Q+LnXVv8g kP7ZtHK+7Sb+piLhGjvQ+wymehlZhNTVCG9clgLl X-Google-Smtp-Source: AGHT+IGwr1IoVc4T9jwUrTdcFgxHzIfi4vUqD/KzsCN1sRmqeSTCogZygbF0wjg5Ag7ap8jFKeKlnw== X-Received: by 2002:a05:6a00:3984:b0:730:8c9d:5842 with SMTP id d2e1a72fcca58-73dc1612e3dmr2724601b3a.5.1745078292998; Sat, 19 Apr 2025 08:58:12 -0700 (PDT) Received: from t14.. ([2001:5a8:4528:b100:1195:fa96:2874:6b2c]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73dbf8be876sm3464157b3a.36.2025.04.19.08.58.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Apr 2025 08:58:12 -0700 (PDT) From: Jordan Rife To: netdev@vger.kernel.org, bpf@vger.kernel.org Cc: Jordan Rife , Aditi Ghag , Daniel Borkmann , Martin KaFai Lau , Willem de Bruijn , Kuniyuki Iwashima Subject: [PATCH v4 bpf-next 5/6] selftests/bpf: Return socket cookies from sock_iter_batch progs Date: Sat, 19 Apr 2025 08:58:02 -0700 Message-ID: <20250419155804.2337261-6-jordan@jrife.io> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250419155804.2337261-1-jordan@jrife.io> References: <20250419155804.2337261-1-jordan@jrife.io> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Extend the iter_udp_soreuse and iter_tcp_soreuse programs to write the cookie of the current socket, so that we can track the identity of the sockets that the iterator has seen so far. Update the existing do_test function to account for this change to the iterator program output. At the same time, teach both programs to work with AF_INET as well. Signed-off-by: Jordan Rife --- .../bpf/prog_tests/sock_iter_batch.c | 33 +++++++++++-------- .../selftests/bpf/progs/bpf_tracing_net.h | 1 + .../selftests/bpf/progs/sock_iter_batch.c | 24 +++++++++++--- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c b/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c index d56e18b25528..74dbe91806a0 100644 --- a/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c +++ b/tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c @@ -9,12 +9,18 @@ static const int nr_soreuse = 4; +struct iter_out { + int idx; + __u64 cookie; +} __packed; + static void do_test(int sock_type, bool onebyone) { int err, i, nread, to_read, total_read, iter_fd = -1; - int first_idx, second_idx, indices[nr_soreuse]; + struct iter_out outputs[nr_soreuse]; struct bpf_link *link = NULL; struct sock_iter_batch *skel; + int first_idx, second_idx; int *fds[2] = {}; skel = sock_iter_batch__open(); @@ -34,6 +40,7 @@ static void do_test(int sock_type, bool onebyone) goto done; skel->rodata->ports[i] = ntohs(local_port); } + skel->rodata->sf = AF_INET6; err = sock_iter_batch__load(skel); if (!ASSERT_OK(err, "sock_iter_batch__load")) @@ -55,38 +62,38 @@ static void do_test(int sock_type, bool onebyone) * from a bucket and leave one socket out from * that bucket on purpose. */ - to_read = (nr_soreuse - 1) * sizeof(*indices); + to_read = (nr_soreuse - 1) * sizeof(*outputs); total_read = 0; first_idx = -1; do { - nread = read(iter_fd, indices, onebyone ? sizeof(*indices) : to_read); - if (nread <= 0 || nread % sizeof(*indices)) + nread = read(iter_fd, outputs, onebyone ? sizeof(*outputs) : to_read); + if (nread <= 0 || nread % sizeof(*outputs)) break; total_read += nread; if (first_idx == -1) - first_idx = indices[0]; - for (i = 0; i < nread / sizeof(*indices); i++) - ASSERT_EQ(indices[i], first_idx, "first_idx"); + first_idx = outputs[0].idx; + for (i = 0; i < nread / sizeof(*outputs); i++) + ASSERT_EQ(outputs[i].idx, first_idx, "first_idx"); } while (total_read < to_read); - ASSERT_EQ(nread, onebyone ? sizeof(*indices) : to_read, "nread"); + ASSERT_EQ(nread, onebyone ? sizeof(*outputs) : to_read, "nread"); ASSERT_EQ(total_read, to_read, "total_read"); free_fds(fds[first_idx], nr_soreuse); fds[first_idx] = NULL; /* Read the "whole" second bucket */ - to_read = nr_soreuse * sizeof(*indices); + to_read = nr_soreuse * sizeof(*outputs); total_read = 0; second_idx = !first_idx; do { - nread = read(iter_fd, indices, onebyone ? sizeof(*indices) : to_read); - if (nread <= 0 || nread % sizeof(*indices)) + nread = read(iter_fd, outputs, onebyone ? sizeof(*outputs) : to_read); + if (nread <= 0 || nread % sizeof(*outputs)) break; total_read += nread; - for (i = 0; i < nread / sizeof(*indices); i++) - ASSERT_EQ(indices[i], second_idx, "second_idx"); + for (i = 0; i < nread / sizeof(*outputs); i++) + ASSERT_EQ(outputs[i].idx, second_idx, "second_idx"); } while (total_read <= to_read); ASSERT_EQ(nread, 0, "nread"); /* Both so_reuseport ports should be in different buckets, so diff --git a/tools/testing/selftests/bpf/progs/bpf_tracing_net.h b/tools/testing/selftests/bpf/progs/bpf_tracing_net.h index 659694162739..17db400f0e0d 100644 --- a/tools/testing/selftests/bpf/progs/bpf_tracing_net.h +++ b/tools/testing/selftests/bpf/progs/bpf_tracing_net.h @@ -128,6 +128,7 @@ #define sk_refcnt __sk_common.skc_refcnt #define sk_state __sk_common.skc_state #define sk_net __sk_common.skc_net +#define sk_rcv_saddr __sk_common.skc_rcv_saddr #define sk_v6_daddr __sk_common.skc_v6_daddr #define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr #define sk_flags __sk_common.skc_flags diff --git a/tools/testing/selftests/bpf/progs/sock_iter_batch.c b/tools/testing/selftests/bpf/progs/sock_iter_batch.c index 96531b0d9d55..8f483337e103 100644 --- a/tools/testing/selftests/bpf/progs/sock_iter_batch.c +++ b/tools/testing/selftests/bpf/progs/sock_iter_batch.c @@ -17,6 +17,12 @@ static bool ipv6_addr_loopback(const struct in6_addr *a) a->s6_addr32[2] | (a->s6_addr32[3] ^ bpf_htonl(1))) == 0; } +static bool ipv4_addr_loopback(__be32 a) +{ + return a == bpf_ntohl(0x7f000001); +} + +volatile const unsigned int sf; volatile const __u16 ports[2]; unsigned int bucket[2]; @@ -26,16 +32,20 @@ int iter_tcp_soreuse(struct bpf_iter__tcp *ctx) struct sock *sk = (struct sock *)ctx->sk_common; struct inet_hashinfo *hinfo; unsigned int hash; + __u64 sock_cookie; struct net *net; int idx; if (!sk) return 0; + sock_cookie = bpf_get_socket_cookie(sk); sk = bpf_core_cast(sk, struct sock); - if (sk->sk_family != AF_INET6 || + if (sk->sk_family != sf || sk->sk_state != TCP_LISTEN || - !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr)) + sk->sk_family == AF_INET6 ? + !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr) : + !ipv4_addr_loopback(sk->sk_rcv_saddr)) return 0; if (sk->sk_num == ports[0]) @@ -52,6 +62,7 @@ int iter_tcp_soreuse(struct bpf_iter__tcp *ctx) hinfo = net->ipv4.tcp_death_row.hashinfo; bucket[idx] = hash & hinfo->lhash2_mask; bpf_seq_write(ctx->meta->seq, &idx, sizeof(idx)); + bpf_seq_write(ctx->meta->seq, &sock_cookie, sizeof(sock_cookie)); return 0; } @@ -63,14 +74,18 @@ int iter_udp_soreuse(struct bpf_iter__udp *ctx) { struct sock *sk = (struct sock *)ctx->udp_sk; struct udp_table *udptable; + __u64 sock_cookie; int idx; if (!sk) return 0; + sock_cookie = bpf_get_socket_cookie(sk); sk = bpf_core_cast(sk, struct sock); - if (sk->sk_family != AF_INET6 || - !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr)) + if (sk->sk_family != sf || + sk->sk_family == AF_INET6 ? + !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr) : + !ipv4_addr_loopback(sk->sk_rcv_saddr)) return 0; if (sk->sk_num == ports[0]) @@ -84,6 +99,7 @@ int iter_udp_soreuse(struct bpf_iter__udp *ctx) udptable = sk->sk_net.net->ipv4.udp_table; bucket[idx] = udp_sk(sk)->udp_portaddr_hash & udptable->mask; bpf_seq_write(ctx->meta->seq, &idx, sizeof(idx)); + bpf_seq_write(ctx->meta->seq, &sock_cookie, sizeof(sock_cookie)); return 0; }