selftests: ncdevmem: Switch to AF_INET6

Use dualstack socket to support both v4 and v6. v4-mapped-v6 address
can be used to do v4.

Reviewed-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Joe Damato <jdamato@fastly.com>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20241107181211.3934153-7-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Stanislav Fomichev 2024-11-07 10:12:05 -08:00 committed by Jakub Kicinski
parent d3ca35c64d
commit 933056357a

View File

@ -242,13 +242,26 @@ static int configure_channels(unsigned int rx, unsigned int tx)
return run_command("sudo ethtool -L %s rx %u tx %u", ifname, rx, tx);
}
static int configure_flow_steering(void)
static int configure_flow_steering(struct sockaddr_in6 *server_sin)
{
return run_command("sudo ethtool -N %s flow-type tcp4 %s %s dst-ip %s %s %s dst-port %s queue %d >&2",
const char *type = "tcp6";
const char *server_addr;
char buf[40];
inet_ntop(AF_INET6, &server_sin->sin6_addr, buf, sizeof(buf));
server_addr = buf;
if (IN6_IS_ADDR_V4MAPPED(&server_sin->sin6_addr)) {
type = "tcp4";
server_addr = strrchr(server_addr, ':') + 1;
}
return run_command("sudo ethtool -N %s flow-type %s %s %s dst-ip %s %s %s dst-port %s queue %d >&2",
ifname,
type,
client_ip ? "src-ip" : "",
client_ip ?: "",
server_ip,
server_addr,
client_ip ? "src-port" : "",
client_ip ? port : "",
port, start_queue);
@ -299,13 +312,51 @@ err_close:
return -1;
}
static void enable_reuseaddr(int fd)
{
int opt = 1;
int ret;
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
if (ret)
error(1, errno, "%s: [FAIL, SO_REUSEPORT]\n", TEST_PREFIX);
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (ret)
error(1, errno, "%s: [FAIL, SO_REUSEADDR]\n", TEST_PREFIX);
}
static int parse_address(const char *str, int port, struct sockaddr_in6 *sin6)
{
int ret;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
ret = inet_pton(sin6->sin6_family, str, &sin6->sin6_addr);
if (ret != 1) {
/* fallback to plain IPv4 */
ret = inet_pton(AF_INET, str, &sin6->sin6_addr.s6_addr32[3]);
if (ret != 1)
return -1;
/* add ::ffff prefix */
sin6->sin6_addr.s6_addr32[0] = 0;
sin6->sin6_addr.s6_addr32[1] = 0;
sin6->sin6_addr.s6_addr16[4] = 0;
sin6->sin6_addr.s6_addr16[5] = 0xffff;
}
return 0;
}
int do_server(struct memory_buffer *mem)
{
char ctrl_data[sizeof(int) * 20000];
struct netdev_queue_id *queues;
size_t non_page_aligned_frags = 0;
struct sockaddr_in client_addr;
struct sockaddr_in server_sin;
struct sockaddr_in6 client_addr;
struct sockaddr_in6 server_sin;
size_t page_aligned_frags = 0;
size_t total_received = 0;
socklen_t client_addr_len;
@ -317,9 +368,12 @@ int do_server(struct memory_buffer *mem)
int socket_fd;
int client_fd;
size_t i = 0;
int opt = 1;
int ret;
ret = parse_address(server_ip, atoi(port), &server_sin);
if (ret < 0)
error(1, 0, "parse server address");
if (reset_flow_steering())
error(1, 0, "Failed to reset flow steering\n");
@ -328,7 +382,7 @@ int do_server(struct memory_buffer *mem)
error(1, 0, "Failed to configure rss\n");
/* Flow steer our devmem flows to start_queue */
if (configure_flow_steering())
if (configure_flow_steering(&server_sin))
error(1, 0, "Failed to configure flow steering\n");
sleep(1);
@ -349,29 +403,14 @@ int do_server(struct memory_buffer *mem)
if (!tmp_mem)
error(1, ENOMEM, "malloc failed");
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(atoi(port));
ret = inet_pton(server_sin.sin_family, server_ip, &server_sin.sin_addr);
if (ret < 0)
error(1, errno, "%s: [FAIL, create socket]\n", TEST_PREFIX);
socket_fd = socket(server_sin.sin_family, SOCK_STREAM, 0);
socket_fd = socket(AF_INET6, SOCK_STREAM, 0);
if (socket_fd < 0)
error(1, errno, "%s: [FAIL, create socket]\n", TEST_PREFIX);
ret = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &opt,
sizeof(opt));
if (ret)
error(1, errno, "%s: [FAIL, set sock opt]\n", TEST_PREFIX);
ret = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
if (ret)
error(1, errno, "%s: [FAIL, set sock opt]\n", TEST_PREFIX);
enable_reuseaddr(socket_fd);
fprintf(stderr, "binding to address %s:%d\n", server_ip,
ntohs(server_sin.sin_port));
ntohs(server_sin.sin6_port));
ret = bind(socket_fd, &server_sin, sizeof(server_sin));
if (ret)
@ -383,16 +422,16 @@ int do_server(struct memory_buffer *mem)
client_addr_len = sizeof(client_addr);
inet_ntop(server_sin.sin_family, &server_sin.sin_addr, buffer,
inet_ntop(AF_INET6, &server_sin.sin6_addr, buffer,
sizeof(buffer));
fprintf(stderr, "Waiting or connection on %s:%d\n", buffer,
ntohs(server_sin.sin_port));
ntohs(server_sin.sin6_port));
client_fd = accept(socket_fd, &client_addr, &client_addr_len);
inet_ntop(client_addr.sin_family, &client_addr.sin_addr, buffer,
inet_ntop(AF_INET6, &client_addr.sin6_addr, buffer,
sizeof(buffer));
fprintf(stderr, "Got connection from %s:%d\n", buffer,
ntohs(client_addr.sin_port));
ntohs(client_addr.sin6_port));
while (1) {
struct iovec iov = { .iov_base = iobuf,