summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-03-07 06:36:23 +0300
committerJakub Kicinski <kuba@kernel.org>2026-03-10 03:02:26 +0300
commit7e3effbc76278bfe3c452074c301233c8e69101f (patch)
treed08b518113b36772259a4e03e36c8a2d1e39a160
parent285804d63f35b333b216f90255104264c590514b (diff)
downloadlinux-7e3effbc76278bfe3c452074c301233c8e69101f.tar.xz
tools: ynl: convert ovs sample to selftest
Convert ovs.c to produce KTAP output with kselftest_harness. The single "crud" test creates a new OVS datapath, fetches it back by name, then dumps all datapaths verifying the new one appears. IIRC I added this test because ovs is a genetlink family but has a family-specific fixed header. TAP version 13 1..1 # Starting 1 tests from 1 test cases. # RUN ovs.crud ... # get: # ynl-test(3): pid:0 cache:256 # dump: # ynl-test(3): pid:0 cache:256 # OK ovs.crud ok 1 ovs.crud # PASSED: 1 / 1 tests passed. # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0 Reviewed-by: Donald Hunter <donald.hunter@gmail.com> Tested-by: Donald Hunter <donald.hunter@gmail.com> Link: https://patch.msgid.link/20260307033630.1396085-4-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--tools/net/ynl/tests/Makefile3
-rw-r--r--tools/net/ynl/tests/config1
-rw-r--r--tools/net/ynl/tests/ovs.c122
3 files changed, 88 insertions, 38 deletions
diff --git a/tools/net/ynl/tests/Makefile b/tools/net/ynl/tests/Makefile
index 1d77d3662f46..df9d37c8b2a4 100644
--- a/tools/net/ynl/tests/Makefile
+++ b/tools/net/ynl/tests/Makefile
@@ -20,12 +20,12 @@ TEST_PROGS := \
TEST_GEN_PROGS := \
netdev \
+ ovs \
# end of TEST_GEN_PROGS
BINS := \
devlink \
ethtool \
- ovs \
rt-addr \
rt-link \
rt-route \
@@ -34,6 +34,7 @@ BINS := \
# end of BINS
CFLAGS_netdev:=$(CFLAGS_netdev) $(CFLAGS_rt-link)
+CFLAGS_ovs:=$(CFLAGS_ovs_datapath)
CFLAGS_tc-filter-add:=$(CFLAGS_tc)
include $(wildcard *.d)
diff --git a/tools/net/ynl/tests/config b/tools/net/ynl/tests/config
index 339f1309c03f..357b34611da4 100644
--- a/tools/net/ynl/tests/config
+++ b/tools/net/ynl/tests/config
@@ -3,4 +3,5 @@ CONFIG_INET_DIAG=y
CONFIG_IPV6=y
CONFIG_NET_NS=y
CONFIG_NETDEVSIM=m
+CONFIG_OPENVSWITCH=m
CONFIG_VETH=m
diff --git a/tools/net/ynl/tests/ovs.c b/tools/net/ynl/tests/ovs.c
index 3e975c003d77..d49f5a8e647e 100644
--- a/tools/net/ynl/tests/ovs.c
+++ b/tools/net/ynl/tests/ovs.c
@@ -4,57 +4,105 @@
#include <ynl.h>
+#include <kselftest_harness.h>
+
#include "ovs_datapath-user.h"
-int main(int argc, char **argv)
+static void ovs_print_datapath(struct __test_metadata *_metadata,
+ struct ovs_datapath_get_rsp *dp)
+{
+ EXPECT_TRUE((bool)dp->_len.name);
+ if (!dp->_len.name)
+ return;
+
+ EXPECT_TRUE((bool)dp->_hdr.dp_ifindex);
+ ksft_print_msg("%s(%d): pid:%u cache:%u\n",
+ dp->name, dp->_hdr.dp_ifindex,
+ dp->upcall_pid, dp->masks_cache_size);
+}
+
+FIXTURE(ovs)
{
struct ynl_sock *ys;
- int err;
+ char *dp_name;
+};
- ys = ynl_sock_create(&ynl_ovs_datapath_family, NULL);
- if (!ys)
- return 1;
+FIXTURE_SETUP(ovs)
+{
+ self->ys = ynl_sock_create(&ynl_ovs_datapath_family, NULL);
+ ASSERT_NE(NULL, self->ys)
+ TH_LOG("failed to create OVS datapath socket");
+}
- if (argc > 1) {
- struct ovs_datapath_new_req *req;
+FIXTURE_TEARDOWN(ovs)
+{
+ if (self->dp_name) {
+ struct ovs_datapath_del_req *req;
- req = ovs_datapath_new_req_alloc();
- if (!req)
- goto err_close;
+ req = ovs_datapath_del_req_alloc();
+ if (req) {
+ ovs_datapath_del_req_set_name(req, self->dp_name);
+ ovs_datapath_del(self->ys, req);
+ ovs_datapath_del_req_free(req);
+ }
+ }
+ ynl_sock_destroy(self->ys);
+}
- ovs_datapath_new_req_set_upcall_pid(req, 1);
- ovs_datapath_new_req_set_name(req, argv[1]);
+TEST_F(ovs, crud)
+{
+ struct ovs_datapath_get_req_dump *dreq;
+ struct ovs_datapath_new_req *new_req;
+ struct ovs_datapath_get_list *dps;
+ struct ovs_datapath_get_rsp *dp;
+ struct ovs_datapath_get_req *req;
+ bool found = false;
+ int err;
- err = ovs_datapath_new(ys, req);
- ovs_datapath_new_req_free(req);
- if (err)
- goto err_close;
- } else {
- struct ovs_datapath_get_req_dump *req;
- struct ovs_datapath_get_list *dps;
+ new_req = ovs_datapath_new_req_alloc();
+ ASSERT_NE(NULL, new_req);
+ ovs_datapath_new_req_set_upcall_pid(new_req, 1);
+ ovs_datapath_new_req_set_name(new_req, "ynl-test");
- printf("Dump:\n");
- req = ovs_datapath_get_req_dump_alloc();
+ err = ovs_datapath_new(self->ys, new_req);
+ ovs_datapath_new_req_free(new_req);
+ ASSERT_EQ(0, err) {
+ TH_LOG("new failed: %s", self->ys->err.msg);
+ }
+ self->dp_name = "ynl-test";
- dps = ovs_datapath_get_dump(ys, req);
- ovs_datapath_get_req_dump_free(req);
- if (!dps)
- goto err_close;
+ ksft_print_msg("get:\n");
+ req = ovs_datapath_get_req_alloc();
+ ASSERT_NE(NULL, req);
+ ovs_datapath_get_req_set_name(req, "ynl-test");
- ynl_dump_foreach(dps, dp) {
- printf(" %s(%d): pid:%u cache:%u\n",
- dp->name, dp->_hdr.dp_ifindex,
- dp->upcall_pid, dp->masks_cache_size);
- }
- ovs_datapath_get_list_free(dps);
+ dp = ovs_datapath_get(self->ys, req);
+ ovs_datapath_get_req_free(req);
+ ASSERT_NE(NULL, dp) {
+ TH_LOG("get failed: %s", self->ys->err.msg);
}
- ynl_sock_destroy(ys);
+ ovs_print_datapath(_metadata, dp);
+ EXPECT_STREQ("ynl-test", dp->name);
+ ovs_datapath_get_rsp_free(dp);
+
+ ksft_print_msg("dump:\n");
+ dreq = ovs_datapath_get_req_dump_alloc();
+ ASSERT_NE(NULL, dreq);
- return 0;
+ dps = ovs_datapath_get_dump(self->ys, dreq);
+ ovs_datapath_get_req_dump_free(dreq);
+ ASSERT_NE(NULL, dps) {
+ TH_LOG("dump failed: %s", self->ys->err.msg);
+ }
-err_close:
- fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg);
- ynl_sock_destroy(ys);
- return 2;
+ ynl_dump_foreach(dps, d) {
+ ovs_print_datapath(_metadata, d);
+ if (d->name && !strcmp(d->name, "ynl-test"))
+ found = true;
+ }
+ ovs_datapath_get_list_free(dps);
+ EXPECT_TRUE(found);
}
+
+TEST_HARNESS_MAIN