Commit 2593a0a1 authored by Joe Damato's avatar Joe Damato Committed by Jakub Kicinski
Browse files

selftests: drv-net: Test that NAPI ID is non-zero



Test that the SO_INCOMING_NAPI_ID of a network file descriptor is
non-zero. This ensures that either the core networking stack or, in some
cases like netdevsim, the driver correctly sets the NAPI ID.

Signed-off-by: default avatarJoe Damato <jdamato@fastly.com>
Link: https://patch.msgid.link/20250424002746.16891-4-jdamato@fastly.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 2b6d490b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
napi_id_helper
xdp_helper
+5 −1
Original line number Diff line number Diff line
@@ -6,9 +6,13 @@ TEST_INCLUDES := $(wildcard lib/py/*.py) \
		 ../../net/net_helper.sh \
		 ../../net/lib.sh \

TEST_GEN_FILES := xdp_helper
TEST_GEN_FILES := \
	napi_id_helper \
	xdp_helper \
# end of TEST_GEN_FILES

TEST_PROGS := \
	napi_id.py \
	netcons_basic.sh \
	netcons_fragmented_msg.sh \
	netcons_overflow.sh \
+23 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0

from lib.py import ksft_run, ksft_exit
from lib.py import ksft_eq, NetDrvEpEnv
from lib.py import bkg, cmd, rand_port, NetNSEnter

def test_napi_id(cfg) -> None:
    port = rand_port()
    listen_cmd = f"{cfg.test_dir}/napi_id_helper {cfg.addr_v['4']} {port}"

    with bkg(listen_cmd, ksft_wait=3) as server:
        cmd(f"echo a | socat - TCP:{cfg.addr_v['4']}:{port}", host=cfg.remote, shell=True)

    ksft_eq(0, server.ret)

def main() -> None:
    with NetDrvEpEnv(__file__) as cfg:
        ksft_run([test_napi_id], args=(cfg,))
    ksft_exit()

if __name__ == "__main__":
    main()
+83 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include "ksft.h"

int main(int argc, char *argv[])
{
	struct sockaddr_in address;
	unsigned int napi_id;
	unsigned int port;
	socklen_t optlen;
	char buf[1024];
	int opt = 1;
	int server;
	int client;
	int ret;

	server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (server < 0) {
		perror("socket creation failed");
		if (errno == EAFNOSUPPORT)
			return -1;
		return 1;
	}

	port = atoi(argv[2]);

	if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
		perror("setsockopt");
		return 1;
	}

	address.sin_family = AF_INET;
	inet_pton(AF_INET, argv[1], &address.sin_addr);
	address.sin_port = htons(port);

	if (bind(server, (struct sockaddr *)&address, sizeof(address)) < 0) {
		perror("bind failed");
		return 1;
	}

	if (listen(server, 1) < 0) {
		perror("listen");
		return 1;
	}

	ksft_ready();

	client = accept(server, NULL, 0);
	if (client < 0) {
		perror("accept");
		return 1;
	}

	optlen = sizeof(napi_id);
	ret = getsockopt(client, SOL_SOCKET, SO_INCOMING_NAPI_ID, &napi_id,
			 &optlen);
	if (ret != 0) {
		perror("getsockopt");
		return 1;
	}

	read(client, buf, 1024);

	ksft_wait();

	if (napi_id == 0) {
		fprintf(stderr, "napi ID is 0\n");
		return 1;
	}

	close(client);
	close(server);

	return 0;
}