Merge branch 'Enable bpf_setsockopt() on ktls enabled sockets.'
Kui-Feng Lee says: ==================== This patchset implements a change to bpf_setsockopt() which allows ktls enabled sockets to be used with the SOL_TCP level. This is necessary as when ktls is enabled, it changes the function pointer of setsockopt of the socket, which bpf_setsockopt() checks in order to make sure that the socket is a TCP socket. Checking sk_protocol instead of the function pointer will ensure that bpf_setsockopt() with the SOL_TCP level still works on sockets with ktls enabled. The major differences form v2 are: - Add a read() call to make sure that the FIN has arrived. - Remove the dependency on other test's header. The major differences from v1 are: - Test with a IPv6 connect as well. - Use ASSERT_OK() v2: https://lore.kernel.org/bpf/20230124181220.2871611-1-kuifeng@meta.com/ v1: https://lore.kernel.org/bpf/20230121025716.3039933-1-kuifeng@meta.com/ ==================== Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
commit
0164776a2c
|
@ -5204,7 +5204,7 @@ static int sol_tcp_sockopt(struct sock *sk, int optname,
|
|||
char *optval, int *optlen,
|
||||
bool getopt)
|
||||
{
|
||||
if (sk->sk_prot->setsockopt != tcp_setsockopt)
|
||||
if (sk->sk_protocol != IPPROTO_TCP)
|
||||
return -EINVAL;
|
||||
|
||||
switch (optname) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/tls.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "test_progs.h"
|
||||
|
@ -83,6 +84,76 @@ static void test_udp(int family)
|
|||
ASSERT_EQ(bss->nr_binddev, 1, "nr_bind");
|
||||
}
|
||||
|
||||
static void test_ktls(int family)
|
||||
{
|
||||
struct tls12_crypto_info_aes_gcm_128 aes128;
|
||||
struct setget_sockopt__bss *bss = skel->bss;
|
||||
int cfd = -1, sfd = -1, fd = -1, ret;
|
||||
char buf;
|
||||
|
||||
memset(bss, 0, sizeof(*bss));
|
||||
|
||||
sfd = start_server(family, SOCK_STREAM,
|
||||
family == AF_INET6 ? addr6_str : addr4_str, 0, 0);
|
||||
if (!ASSERT_GE(sfd, 0, "start_server"))
|
||||
return;
|
||||
fd = connect_to_fd(sfd, 0);
|
||||
if (!ASSERT_GE(fd, 0, "connect_to_fd"))
|
||||
goto err_out;
|
||||
|
||||
cfd = accept(sfd, NULL, 0);
|
||||
if (!ASSERT_GE(cfd, 0, "accept"))
|
||||
goto err_out;
|
||||
|
||||
close(sfd);
|
||||
sfd = -1;
|
||||
|
||||
/* Setup KTLS */
|
||||
ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
|
||||
if (!ASSERT_OK(ret, "setsockopt"))
|
||||
goto err_out;
|
||||
ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
|
||||
if (!ASSERT_OK(ret, "setsockopt"))
|
||||
goto err_out;
|
||||
|
||||
memset(&aes128, 0, sizeof(aes128));
|
||||
aes128.info.version = TLS_1_2_VERSION;
|
||||
aes128.info.cipher_type = TLS_CIPHER_AES_GCM_128;
|
||||
|
||||
ret = setsockopt(fd, SOL_TLS, TLS_TX, &aes128, sizeof(aes128));
|
||||
if (!ASSERT_OK(ret, "setsockopt"))
|
||||
goto err_out;
|
||||
|
||||
ret = setsockopt(cfd, SOL_TLS, TLS_RX, &aes128, sizeof(aes128));
|
||||
if (!ASSERT_OK(ret, "setsockopt"))
|
||||
goto err_out;
|
||||
|
||||
/* KTLS is enabled */
|
||||
|
||||
close(fd);
|
||||
/* At this point, the cfd socket is at the CLOSE_WAIT state
|
||||
* and still run TLS protocol. The test for
|
||||
* BPF_TCP_CLOSE_WAIT should be run at this point.
|
||||
*/
|
||||
ret = read(cfd, &buf, sizeof(buf));
|
||||
ASSERT_EQ(ret, 0, "read");
|
||||
close(cfd);
|
||||
|
||||
ASSERT_EQ(bss->nr_listen, 1, "nr_listen");
|
||||
ASSERT_EQ(bss->nr_connect, 1, "nr_connect");
|
||||
ASSERT_EQ(bss->nr_active, 1, "nr_active");
|
||||
ASSERT_EQ(bss->nr_passive, 1, "nr_passive");
|
||||
ASSERT_EQ(bss->nr_socket_post_create, 2, "nr_socket_post_create");
|
||||
ASSERT_EQ(bss->nr_binddev, 2, "nr_bind");
|
||||
ASSERT_EQ(bss->nr_fin_wait1, 1, "nr_fin_wait1");
|
||||
return;
|
||||
|
||||
err_out:
|
||||
close(fd);
|
||||
close(cfd);
|
||||
close(sfd);
|
||||
}
|
||||
|
||||
void test_setget_sockopt(void)
|
||||
{
|
||||
cg_fd = test__join_cgroup(CG_NAME);
|
||||
|
@ -118,6 +189,8 @@ void test_setget_sockopt(void)
|
|||
test_tcp(AF_INET);
|
||||
test_udp(AF_INET6);
|
||||
test_udp(AF_INET);
|
||||
test_ktls(AF_INET6);
|
||||
test_ktls(AF_INET);
|
||||
|
||||
done:
|
||||
setget_sockopt__destroy(skel);
|
||||
|
|
|
@ -22,6 +22,7 @@ int nr_active;
|
|||
int nr_connect;
|
||||
int nr_binddev;
|
||||
int nr_socket_post_create;
|
||||
int nr_fin_wait1;
|
||||
|
||||
struct sockopt_test {
|
||||
int opt;
|
||||
|
@ -386,6 +387,13 @@ int skops_sockopt(struct bpf_sock_ops *skops)
|
|||
nr_passive += !(bpf_test_sockopt(skops, sk) ||
|
||||
test_tcp_maxseg(skops, sk) ||
|
||||
test_tcp_saved_syn(skops, sk));
|
||||
bpf_sock_ops_cb_flags_set(skops,
|
||||
skops->bpf_sock_ops_cb_flags |
|
||||
BPF_SOCK_OPS_STATE_CB_FLAG);
|
||||
break;
|
||||
case BPF_SOCK_OPS_STATE_CB:
|
||||
if (skops->args[1] == BPF_TCP_CLOSE_WAIT)
|
||||
nr_fin_wait1 += !bpf_test_sockopt(skops, sk);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue