mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge branch 'selftests-bpf-networking-test-cleanups'
Hoyeon Lee says: ==================== selftests/bpf: networking test cleanups This series finishes the sockaddr_storage migration in the networking selftests by removing the remaining open-coded IPv4/IPv6 wrappers (addr_port/tuple in cls_redirect, sa46 in select_reuseport). The tests now use sockaddr_storage directly. No other custom socket-address wrappers remain after this series, so the churn stops here and behavior is unchanged. ==================== Link: https://patch.msgid.link/20251121081332.2309838-1-hoyeon.lee@suse.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
@@ -22,79 +22,37 @@
|
||||
|
||||
static int duration = 0;
|
||||
|
||||
struct addr_port {
|
||||
in_port_t port;
|
||||
union {
|
||||
struct in_addr in_addr;
|
||||
struct in6_addr in6_addr;
|
||||
};
|
||||
};
|
||||
|
||||
struct tuple {
|
||||
int family;
|
||||
struct addr_port src;
|
||||
struct addr_port dst;
|
||||
};
|
||||
|
||||
static bool fill_addr_port(const struct sockaddr *sa, struct addr_port *ap)
|
||||
{
|
||||
const struct sockaddr_in6 *in6;
|
||||
const struct sockaddr_in *in;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
in = (const struct sockaddr_in *)sa;
|
||||
ap->in_addr = in->sin_addr;
|
||||
ap->port = in->sin_port;
|
||||
return true;
|
||||
|
||||
case AF_INET6:
|
||||
in6 = (const struct sockaddr_in6 *)sa;
|
||||
ap->in6_addr = in6->sin6_addr;
|
||||
ap->port = in6->sin6_port;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool set_up_conn(const struct sockaddr *addr, socklen_t len, int type,
|
||||
int *server, int *conn, struct tuple *tuple)
|
||||
static bool set_up_conn(const struct sockaddr_storage *addr, socklen_t len, int type,
|
||||
int *server, int *conn,
|
||||
struct sockaddr_storage *src,
|
||||
struct sockaddr_storage *dst)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen = sizeof(ss);
|
||||
struct sockaddr *sa = (struct sockaddr *)&ss;
|
||||
|
||||
*server = start_server_addr(type, (struct sockaddr_storage *)addr, len, NULL);
|
||||
*server = start_server_addr(type, addr, len, NULL);
|
||||
if (*server < 0)
|
||||
return false;
|
||||
|
||||
if (CHECK_FAIL(getsockname(*server, sa, &slen)))
|
||||
if (CHECK_FAIL(getsockname(*server, (struct sockaddr *)&ss, &slen)))
|
||||
goto close_server;
|
||||
|
||||
*conn = connect_to_addr(type, (struct sockaddr_storage *)sa, slen, NULL);
|
||||
*conn = connect_to_addr(type, &ss, slen, NULL);
|
||||
if (*conn < 0)
|
||||
goto close_server;
|
||||
|
||||
/* We want to simulate packets arriving at conn, so we have to
|
||||
* swap src and dst.
|
||||
*/
|
||||
slen = sizeof(ss);
|
||||
if (CHECK_FAIL(getsockname(*conn, sa, &slen)))
|
||||
slen = sizeof(*dst);
|
||||
if (CHECK_FAIL(getsockname(*conn, (struct sockaddr *)dst, &slen)))
|
||||
goto close_conn;
|
||||
|
||||
if (CHECK_FAIL(!fill_addr_port(sa, &tuple->dst)))
|
||||
slen = sizeof(*src);
|
||||
if (CHECK_FAIL(getpeername(*conn, (struct sockaddr *)src, &slen)))
|
||||
goto close_conn;
|
||||
|
||||
slen = sizeof(ss);
|
||||
if (CHECK_FAIL(getpeername(*conn, sa, &slen)))
|
||||
goto close_conn;
|
||||
|
||||
if (CHECK_FAIL(!fill_addr_port(sa, &tuple->src)))
|
||||
goto close_conn;
|
||||
|
||||
tuple->family = ss.ss_family;
|
||||
return true;
|
||||
|
||||
close_conn:
|
||||
@@ -110,17 +68,16 @@ static socklen_t prepare_addr(struct sockaddr_storage *addr, int family)
|
||||
{
|
||||
struct sockaddr_in *addr4;
|
||||
struct sockaddr_in6 *addr6;
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
addr4 = (struct sockaddr_in *)addr;
|
||||
memset(addr4, 0, sizeof(*addr4));
|
||||
addr4->sin_family = family;
|
||||
addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
return sizeof(*addr4);
|
||||
case AF_INET6:
|
||||
addr6 = (struct sockaddr_in6 *)addr;
|
||||
memset(addr6, 0, sizeof(*addr6));
|
||||
addr6->sin6_family = family;
|
||||
addr6->sin6_addr = in6addr_loopback;
|
||||
return sizeof(*addr6);
|
||||
@@ -242,9 +199,15 @@ static void encap_init(encap_headers_t *encap, uint8_t hop_count, uint8_t proto)
|
||||
}
|
||||
|
||||
static size_t build_input(const struct test_cfg *test, void *const buf,
|
||||
const struct tuple *tuple)
|
||||
const struct sockaddr_storage *src,
|
||||
const struct sockaddr_storage *dst)
|
||||
{
|
||||
in_port_t sport = tuple->src.port;
|
||||
struct sockaddr_in6 *src_in6 = (struct sockaddr_in6 *)src;
|
||||
struct sockaddr_in6 *dst_in6 = (struct sockaddr_in6 *)dst;
|
||||
struct sockaddr_in *src_in = (struct sockaddr_in *)src;
|
||||
struct sockaddr_in *dst_in = (struct sockaddr_in *)dst;
|
||||
sa_family_t family = src->ss_family;
|
||||
in_port_t sport, dport;
|
||||
encap_headers_t encap;
|
||||
struct iphdr ip;
|
||||
struct ipv6hdr ipv6;
|
||||
@@ -254,8 +217,11 @@ static size_t build_input(const struct test_cfg *test, void *const buf,
|
||||
uint8_t *p = buf;
|
||||
int proto;
|
||||
|
||||
sport = (family == AF_INET) ? src_in->sin_port : src_in6->sin6_port;
|
||||
dport = (family == AF_INET) ? dst_in->sin_port : dst_in6->sin6_port;
|
||||
|
||||
proto = IPPROTO_IPIP;
|
||||
if (tuple->family == AF_INET6)
|
||||
if (family == AF_INET6)
|
||||
proto = IPPROTO_IPV6;
|
||||
|
||||
encap_init(&encap, test->hops == ONE_HOP ? 1 : 0, proto);
|
||||
@@ -270,15 +236,15 @@ static size_t build_input(const struct test_cfg *test, void *const buf,
|
||||
if (test->type == UDP)
|
||||
proto = IPPROTO_UDP;
|
||||
|
||||
switch (tuple->family) {
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
ip = (struct iphdr){
|
||||
.ihl = 5,
|
||||
.version = 4,
|
||||
.ttl = IPDEFTTL,
|
||||
.protocol = proto,
|
||||
.saddr = tuple->src.in_addr.s_addr,
|
||||
.daddr = tuple->dst.in_addr.s_addr,
|
||||
.saddr = src_in->sin_addr.s_addr,
|
||||
.daddr = dst_in->sin_addr.s_addr,
|
||||
};
|
||||
p = mempcpy(p, &ip, sizeof(ip));
|
||||
break;
|
||||
@@ -287,8 +253,8 @@ static size_t build_input(const struct test_cfg *test, void *const buf,
|
||||
.version = 6,
|
||||
.hop_limit = IPDEFTTL,
|
||||
.nexthdr = proto,
|
||||
.saddr = tuple->src.in6_addr,
|
||||
.daddr = tuple->dst.in6_addr,
|
||||
.saddr = src_in6->sin6_addr,
|
||||
.daddr = dst_in6->sin6_addr,
|
||||
};
|
||||
p = mempcpy(p, &ipv6, sizeof(ipv6));
|
||||
break;
|
||||
@@ -303,18 +269,16 @@ static size_t build_input(const struct test_cfg *test, void *const buf,
|
||||
case TCP:
|
||||
tcp = (struct tcphdr){
|
||||
.source = sport,
|
||||
.dest = tuple->dst.port,
|
||||
.dest = dport,
|
||||
.syn = (test->flags == SYN),
|
||||
.ack = (test->flags == ACK),
|
||||
};
|
||||
if (test->flags == SYN)
|
||||
tcp.syn = true;
|
||||
if (test->flags == ACK)
|
||||
tcp.ack = true;
|
||||
p = mempcpy(p, &tcp, sizeof(tcp));
|
||||
break;
|
||||
case UDP:
|
||||
udp = (struct udphdr){
|
||||
.source = sport,
|
||||
.dest = tuple->dst.port,
|
||||
.dest = dport,
|
||||
};
|
||||
p = mempcpy(p, &udp, sizeof(udp));
|
||||
break;
|
||||
@@ -339,27 +303,26 @@ static void test_cls_redirect_common(struct bpf_program *prog)
|
||||
LIBBPF_OPTS(bpf_test_run_opts, tattr);
|
||||
int families[] = { AF_INET, AF_INET6 };
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr *addr;
|
||||
socklen_t slen;
|
||||
int i, j, err, prog_fd;
|
||||
int servers[__NR_KIND][ARRAY_SIZE(families)] = {};
|
||||
int conns[__NR_KIND][ARRAY_SIZE(families)] = {};
|
||||
struct tuple tuples[__NR_KIND][ARRAY_SIZE(families)];
|
||||
struct sockaddr_storage srcs[__NR_KIND][ARRAY_SIZE(families)];
|
||||
struct sockaddr_storage dsts[__NR_KIND][ARRAY_SIZE(families)];
|
||||
|
||||
addr = (struct sockaddr *)&ss;
|
||||
for (i = 0; i < ARRAY_SIZE(families); i++) {
|
||||
slen = prepare_addr(&ss, families[i]);
|
||||
if (CHECK_FAIL(!slen))
|
||||
goto cleanup;
|
||||
|
||||
if (CHECK_FAIL(!set_up_conn(addr, slen, SOCK_DGRAM,
|
||||
if (CHECK_FAIL(!set_up_conn(&ss, slen, SOCK_DGRAM,
|
||||
&servers[UDP][i], &conns[UDP][i],
|
||||
&tuples[UDP][i])))
|
||||
&srcs[UDP][i], &dsts[UDP][i])))
|
||||
goto cleanup;
|
||||
|
||||
if (CHECK_FAIL(!set_up_conn(addr, slen, SOCK_STREAM,
|
||||
if (CHECK_FAIL(!set_up_conn(&ss, slen, SOCK_STREAM,
|
||||
&servers[TCP][i], &conns[TCP][i],
|
||||
&tuples[TCP][i])))
|
||||
&srcs[TCP][i], &dsts[TCP][i])))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -368,11 +331,12 @@ static void test_cls_redirect_common(struct bpf_program *prog)
|
||||
struct test_cfg *test = &tests[i];
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(families); j++) {
|
||||
struct tuple *tuple = &tuples[test->type][j];
|
||||
struct sockaddr_storage *src = &srcs[test->type][j];
|
||||
struct sockaddr_storage *dst = &dsts[test->type][j];
|
||||
char input[256];
|
||||
char tmp[256];
|
||||
|
||||
test_str(tmp, sizeof(tmp), test, tuple->family);
|
||||
test_str(tmp, sizeof(tmp), test, families[j]);
|
||||
if (!test__start_subtest(tmp))
|
||||
continue;
|
||||
|
||||
@@ -380,7 +344,7 @@ static void test_cls_redirect_common(struct bpf_program *prog)
|
||||
tattr.data_size_out = sizeof(tmp);
|
||||
|
||||
tattr.data_in = input;
|
||||
tattr.data_size_in = build_input(test, input, tuple);
|
||||
tattr.data_size_in = build_input(test, input, src, dst);
|
||||
if (CHECK_FAIL(!tattr.data_size_in))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -41,11 +41,7 @@ static struct bpf_object *obj;
|
||||
static __u32 index_zero;
|
||||
static int epfd;
|
||||
|
||||
static union sa46 {
|
||||
struct sockaddr_in6 v6;
|
||||
struct sockaddr_in v4;
|
||||
sa_family_t family;
|
||||
} srv_sa;
|
||||
static struct sockaddr_storage srv_sa;
|
||||
|
||||
#define RET_IF(condition, tag, format...) ({ \
|
||||
if (CHECK_FAIL(condition)) { \
|
||||
@@ -135,24 +131,24 @@ static int prepare_bpf_obj(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sa46_init_loopback(union sa46 *sa, sa_family_t family)
|
||||
static void ss_init_loopback(struct sockaddr_storage *sa, sa_family_t family)
|
||||
{
|
||||
memset(sa, 0, sizeof(*sa));
|
||||
sa->family = family;
|
||||
if (sa->family == AF_INET6)
|
||||
sa->v6.sin6_addr = in6addr_loopback;
|
||||
sa->ss_family = family;
|
||||
if (sa->ss_family == AF_INET6)
|
||||
((struct sockaddr_in6 *)sa)->sin6_addr = in6addr_loopback;
|
||||
else
|
||||
sa->v4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
((struct sockaddr_in *)sa)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
}
|
||||
|
||||
static void sa46_init_inany(union sa46 *sa, sa_family_t family)
|
||||
static void ss_init_inany(struct sockaddr_storage *sa, sa_family_t family)
|
||||
{
|
||||
memset(sa, 0, sizeof(*sa));
|
||||
sa->family = family;
|
||||
if (sa->family == AF_INET6)
|
||||
sa->v6.sin6_addr = in6addr_any;
|
||||
sa->ss_family = family;
|
||||
if (sa->ss_family == AF_INET6)
|
||||
((struct sockaddr_in6 *)sa)->sin6_addr = in6addr_any;
|
||||
else
|
||||
sa->v4.sin_addr.s_addr = INADDR_ANY;
|
||||
((struct sockaddr_in *)sa)->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
static int read_int_sysctl(const char *sysctl)
|
||||
@@ -228,7 +224,7 @@ static void check_data(int type, sa_family_t family, const struct cmd *cmd,
|
||||
int cli_fd)
|
||||
{
|
||||
struct data_check expected = {}, result;
|
||||
union sa46 cli_sa;
|
||||
struct sockaddr_storage cli_sa;
|
||||
socklen_t addrlen;
|
||||
int err;
|
||||
|
||||
@@ -251,26 +247,32 @@ static void check_data(int type, sa_family_t family, const struct cmd *cmd,
|
||||
}
|
||||
|
||||
if (family == AF_INET6) {
|
||||
expected.eth_protocol = htons(ETH_P_IPV6);
|
||||
expected.bind_inany = !srv_sa.v6.sin6_addr.s6_addr32[3] &&
|
||||
!srv_sa.v6.sin6_addr.s6_addr32[2] &&
|
||||
!srv_sa.v6.sin6_addr.s6_addr32[1] &&
|
||||
!srv_sa.v6.sin6_addr.s6_addr32[0];
|
||||
struct sockaddr_in6 *srv_v6 = (struct sockaddr_in6 *)&srv_sa;
|
||||
struct sockaddr_in6 *cli_v6 = (struct sockaddr_in6 *)&cli_sa;
|
||||
|
||||
memcpy(&expected.skb_addrs[0], cli_sa.v6.sin6_addr.s6_addr32,
|
||||
sizeof(cli_sa.v6.sin6_addr));
|
||||
expected.eth_protocol = htons(ETH_P_IPV6);
|
||||
expected.bind_inany = !srv_v6->sin6_addr.s6_addr32[3] &&
|
||||
!srv_v6->sin6_addr.s6_addr32[2] &&
|
||||
!srv_v6->sin6_addr.s6_addr32[1] &&
|
||||
!srv_v6->sin6_addr.s6_addr32[0];
|
||||
|
||||
memcpy(&expected.skb_addrs[0], cli_v6->sin6_addr.s6_addr32,
|
||||
sizeof(cli_v6->sin6_addr));
|
||||
memcpy(&expected.skb_addrs[4], &in6addr_loopback,
|
||||
sizeof(in6addr_loopback));
|
||||
expected.skb_ports[0] = cli_sa.v6.sin6_port;
|
||||
expected.skb_ports[1] = srv_sa.v6.sin6_port;
|
||||
expected.skb_ports[0] = cli_v6->sin6_port;
|
||||
expected.skb_ports[1] = srv_v6->sin6_port;
|
||||
} else {
|
||||
expected.eth_protocol = htons(ETH_P_IP);
|
||||
expected.bind_inany = !srv_sa.v4.sin_addr.s_addr;
|
||||
struct sockaddr_in *srv_v4 = (struct sockaddr_in *)&srv_sa;
|
||||
struct sockaddr_in *cli_v4 = (struct sockaddr_in *)&cli_sa;
|
||||
|
||||
expected.skb_addrs[0] = cli_sa.v4.sin_addr.s_addr;
|
||||
expected.eth_protocol = htons(ETH_P_IP);
|
||||
expected.bind_inany = !srv_v4->sin_addr.s_addr;
|
||||
|
||||
expected.skb_addrs[0] = cli_v4->sin_addr.s_addr;
|
||||
expected.skb_addrs[1] = htonl(INADDR_LOOPBACK);
|
||||
expected.skb_ports[0] = cli_sa.v4.sin_port;
|
||||
expected.skb_ports[1] = srv_sa.v4.sin_port;
|
||||
expected.skb_ports[0] = cli_v4->sin_port;
|
||||
expected.skb_ports[1] = srv_v4->sin_port;
|
||||
}
|
||||
|
||||
if (memcmp(&result, &expected, offsetof(struct data_check,
|
||||
@@ -364,16 +366,15 @@ static void check_results(void)
|
||||
static int send_data(int type, sa_family_t family, void *data, size_t len,
|
||||
enum result expected)
|
||||
{
|
||||
union sa46 cli_sa;
|
||||
struct sockaddr_storage cli_sa;
|
||||
int fd, err;
|
||||
|
||||
fd = socket(family, type, 0);
|
||||
RET_ERR(fd == -1, "socket()", "fd:%d errno:%d\n", fd, errno);
|
||||
|
||||
sa46_init_loopback(&cli_sa, family);
|
||||
ss_init_loopback(&cli_sa, family);
|
||||
err = bind(fd, (struct sockaddr *)&cli_sa, sizeof(cli_sa));
|
||||
RET_ERR(fd == -1, "bind(cli_sa)", "err:%d errno:%d\n", err, errno);
|
||||
|
||||
err = sendto(fd, data, len, MSG_FASTOPEN, (struct sockaddr *)&srv_sa,
|
||||
sizeof(srv_sa));
|
||||
RET_ERR(err != len && expected >= PASS,
|
||||
@@ -589,9 +590,9 @@ static void prepare_sk_fds(int type, sa_family_t family, bool inany)
|
||||
socklen_t addrlen;
|
||||
|
||||
if (inany)
|
||||
sa46_init_inany(&srv_sa, family);
|
||||
ss_init_inany(&srv_sa, family);
|
||||
else
|
||||
sa46_init_loopback(&srv_sa, family);
|
||||
ss_init_loopback(&srv_sa, family);
|
||||
addrlen = sizeof(srv_sa);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user