From nobody Thu Oct 2 19:38:18 2025 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16E4E2BF00D for ; Fri, 12 Sep 2025 19:53:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757706838; cv=none; b=dOwYQt5Nh6N9kfMSz/GbtThm1W/+gbMu69BvsiGiIgLIegzXGVhnp6ScjIBZxRs7u9oJJsrDPT0E2rCHydFpF9Orp4ZhOFdwJ5TVEWJ4gcSXY8n7RHWkWpB2CYUTlJt54RZ4aPqFRf7NbTWXuFWseiCsy0zOtXRisHsCQZy/lZ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757706838; c=relaxed/simple; bh=lhd5AYLmKg8v4K7bBXuozBSRlAkojKZ1+DM9PPiC2jU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SI96+cvJfe9GHFKzXfV2h/6i6dxjc8AeCt4XH48wq3rdujJD5DBpF3AWZrcQsh0aqcBcu8jYFiafzevuVB8JT0EVomX2Chy3JvfBLzUB4noO6HXn3zeBq0vb2Wce+CxVlcfF+6kwOpI1n8cW4owjPLbx5a7AVkMbyf3VTX7cv9E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GJoqqZmO; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GJoqqZmO" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-45b9a856dc2so15375775e9.0 for ; Fri, 12 Sep 2025 12:53:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1757706834; x=1758311634; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AdhvlJqUr3WoGW1dbO0ZFsF3L6hbFYftz4yhGQrniP4=; b=GJoqqZmOY7G/4cLlS6yOMlnXof76O2fBigIFhHu2/SXCvFBo/2TJhAkZyIM/E0Alne QKgveCCwl9p2lEU+uSADoKujeHBN+awNfdBRu8Lua713K6IElfLgEnlVLyYkIdwOlQpr gUu3l4YnccAOt2DkJo52vXBNlnDC7ZwGbsDZ0Zmve0485U0XRd/FwlQFpZpiNKQJN7bH 5tk2K85F0Ra1lVzXNSUDMnpp6P80gQJaS+sPIQovMdlNtJsL73jVr4Hu+NgOcgkqh355 8zqgIaWZqc4xEd9HRbBYTdgk6R13takIchQmC2JiouHrH47D8jWmezi5XWb/1lnKnTnB UkoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757706834; x=1758311634; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AdhvlJqUr3WoGW1dbO0ZFsF3L6hbFYftz4yhGQrniP4=; b=pACSjaAtLunv2sIBqPx7ZKNxatKUtDRxofnwF1ZPERXSjUxHFsNlQvL5uWPhIbXO8U WImPO+z9F0mFKOi+3KHSVMhewSRVzxjd4Xo6JjiPwPX5vqo/GL4UkjcH9sVJy3kwLkuF ONkMctEo6AA43Nnrhw3y8a6jlijui97AGd7Ds3kHox+ZJggskvawuddEz8d1YFGvhbW3 htvIb0xiS39+OsaWLThrws/O/4rpsPqguW1NY8QC7+lxe1h1W6I6400LUrs3iHRSBGfN X7/lJ0WsCSat1gF2AoYaXCatJhVIdmVdCjWAwnWwdqcM2tloV96PXhkpTEdBoVzez6z7 D6iw== X-Forwarded-Encrypted: i=1; AJvYcCX7uDGnZJILvqyYgm1cUZjHHnipx2ueIjjpcGkJ4Q6BIb3fpLC0TRUK0qNgCnGo/nFjYR5SRAJugBLWM0o=@vger.kernel.org X-Gm-Message-State: AOJu0YyB9CeFoyu9FRtrenk7E5V0N6OQpZ8P12uccrN9JTH2AF3bRWtO Qv75Tua4FvD+88+9BZ812CLy7gLLZKsfZwEqvIrBuzz/tzVXKOUoj44s X-Gm-Gg: ASbGncslg+kFhfauhVQhOT3SJ1ib8bcjnlJW3CyQKyVcgW5uwq1wGsa/Cmz0AqHsQ+r 34x7sRuB3bLgdHhvABGSzQM0e4IpTnzgiibpr330PK9NRTwKjNWVWT/ZEcm+IEb9aWdmTBoDQ1q nYg82zgBc7aEbMDYvpK1ugU/sAXdGpZBqUxwzI7RsN++dACguwGqxrHv7+EWmVkonQvlRBKhfUa 9PHNTeF7cQLFsTsT8++ya0ksCSk8Qcd22EJCPSkWZyuNNCw8GsQbCDd2To5tZKbVBeDsA42oDyt HfuSgIw8NHO37eWQz6fGKlPVFyUgPoRSBII8SbvXbrVW5ZUq9jy1dQHcoz8tWONyShz09WG2PJg Wy6Yz4pAifZfOk/H91O0O9BUogeteEsyeTApxp+WoV0AdfQm+n0BxGP43nGjDeA== X-Google-Smtp-Source: AGHT+IFqrA3KZsShkhOTFLrSGP4/PH2y/guZeiY2IMih0gP0HYC7djwhcyI0ThOjanigZ0fIM1AgtA== X-Received: by 2002:a05:600c:4454:b0:45d:cfee:7058 with SMTP id 5b1f17b1804b1-45f211e5f98mr44613895e9.22.1757706834189; Fri, 12 Sep 2025 12:53:54 -0700 (PDT) Received: from yanesskka.. (node-188-187-35-212.domolink.tula.net. [212.35.187.188]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-45e017bfd14sm74650375e9.21.2025.09.12.12.53.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Sep 2025 12:53:53 -0700 (PDT) From: Yana Bashlykova To: "David S. Miller" Cc: Yana Bashlykova , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, lvc-project@linuxtesting.org Subject: [PATCH 6.1 01/15] genetlink: add sysfs test module for Generic Netlink Date: Fri, 12 Sep 2025 22:53:24 +0300 Message-Id: <20250912195339.20635-2-yana2bsh@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250912195339.20635-1-yana2bsh@gmail.com> References: <20250912195339.20635-1-yana2bsh@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a test module that creates sysfs interfaces for Generic Netlink testing: - /sys/kernel/genl_test with value/message/info attributes - /sys/kernel/parallel_genl with message attribute - /sys/kernel/third_genl with message attribute Implements basic read/write operations with proper error handling and clean= up. Will be used as foundation for netlink testing infrastructure. Signed-off-by: Yana Bashlykova --- drivers/net/Kconfig | 2 + drivers/net/Makefile | 2 + drivers/net/genetlink/Kconfig | 8 + drivers/net/genetlink/Makefile | 3 + .../net-pf-16-proto-16-family-PARALLEL_GENL.c | 288 ++++++++++++++++++ 5 files changed, 303 insertions(+) create mode 100644 drivers/net/genetlink/Kconfig create mode 100644 drivers/net/genetlink/Makefile create mode 100644 drivers/net/genetlink/net-pf-16-proto-16-family-PARALLE= L_GENL.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9e63b8c43f3e..2f5f74185da5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -631,4 +631,6 @@ config NETDEV_LEGACY_INIT Drivers that call netdev_boot_setup_check() should select this symbol, everything else no longer needs it. =20 +source "drivers/net/genetlink/Kconfig" + endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6ce076462dbf..934dff748416 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -89,3 +89,5 @@ thunderbolt-net-y +=3D thunderbolt.o obj-$(CONFIG_USB4_NET) +=3D thunderbolt-net.o obj-$(CONFIG_NETDEVSIM) +=3D netdevsim/ obj-$(CONFIG_NET_FAILOVER) +=3D net_failover.o + +obj-$(CONFIG_NETLINK_TEST) +=3D genetlink/ diff --git a/drivers/net/genetlink/Kconfig b/drivers/net/genetlink/Kconfig new file mode 100644 index 000000000000..e1fd8da50488 --- /dev/null +++ b/drivers/net/genetlink/Kconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + +config NETLINK_TEST + tristate "Test module for netlink communication" + depends on NET + help + This module provides testing interface for netlink communication. + Used by selftests in tools/testing/selftests/net/. diff --git a/drivers/net/genetlink/Makefile b/drivers/net/genetlink/Makefile new file mode 100644 index 000000000000..0336eac4cc28 --- /dev/null +++ b/drivers/net/genetlink/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_NETLINK_TEST) +=3D net-pf-16-proto-16-family-PARALLEL_GENL.o diff --git a/drivers/net/genetlink/net-pf-16-proto-16-family-PARALLEL_GENL.= c b/drivers/net/genetlink/net-pf-16-proto-16-family-PARALLEL_GENL.c new file mode 100644 index 000000000000..c50c0daae392 --- /dev/null +++ b/drivers/net/genetlink/net-pf-16-proto-16-family-PARALLEL_GENL.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static struct kobject *kobj_genl_test; +static struct device *dev_genl_test; +static struct kobject *kobj_parallel_genl; +static struct kobject *kobj_third_genl; + +#define MAX_DATA_LEN 256 + +struct { + char genl_test_message[MAX_DATA_LEN]; + char genl_test_info[MAX_DATA_LEN]; + u32 genl_test_value; + char parallel_genl_message[MAX_DATA_LEN]; + char third_genl_message[MAX_DATA_LEN]; +} + +sysfs_data =3D { + .genl_test_message =3D "default", + .genl_test_info =3D "default", + .genl_test_value =3D -20, + .parallel_genl_message =3D "default", + .third_genl_message =3D "default", +}; + +static ssize_t show_genl_test_info(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%s\n", sysfs_data.genl_test_info); +} + +static ssize_t store_genl_test_info(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + snprintf(sysfs_data.genl_test_info, sizeof(sysfs_data.genl_test_info), + "%.*s", (int)min(count, sizeof(sysfs_data.genl_test_info) - 1), + buf); + return count; +} + +static ssize_t show_genl_test_message(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%s", sysfs_data.genl_test_message); +} + +static ssize_t store_genl_test_message(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + size_t len =3D min(count, sizeof(sysfs_data.genl_test_message) - 1); + + strncpy(sysfs_data.genl_test_message, buf, len); + sysfs_data.genl_test_message[len] =3D '\0'; + return count; +} + +static ssize_t show_genl_test_value(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d", sysfs_data.genl_test_value); +} + +static ssize_t store_genl_test_value(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int rt; + + rt =3D kstrtouint(buf, 0, &sysfs_data.genl_test_value); + return count; +} + +static ssize_t show_parallel_genl_message(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s", sysfs_data.parallel_genl_message); +} + +static ssize_t store_parallel_genl_message(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + size_t len =3D min(count, sizeof(sysfs_data.parallel_genl_message) - 1); + + strncpy(sysfs_data.parallel_genl_message, buf, len); + sysfs_data.parallel_genl_message[len] =3D '\0'; + return count; +} + +static ssize_t show_third_genl_message(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%s", sysfs_data.third_genl_message); +} + +static ssize_t store_third_genl_message(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + size_t len =3D min(count, sizeof(sysfs_data.third_genl_message) - 1); + + strncpy(sysfs_data.third_genl_message, buf, len); + sysfs_data.third_genl_message[len] =3D '\0'; + return count; +} + +static struct device_attribute dev_attr_info_genl_test =3D + __ATTR(some_info, 0664, show_genl_test_info, store_genl_test_info); + +static struct kobj_attribute my_attr_str_genl_test =3D + __ATTR(message, 0664, show_genl_test_message, store_genl_test_message); + +static struct kobj_attribute my_attr_u32_genl_test =3D + __ATTR(value, 0664, show_genl_test_value, store_genl_test_value); + +static struct kobj_attribute my_attr_str_parallel_genl =3D + __ATTR(message, 0664, show_parallel_genl_message, store_parallel_genl_mes= sage); + +static struct kobj_attribute my_attr_str_third_genl =3D + __ATTR(message, 0664, show_third_genl_message, store_third_genl_message); + +static int __init init_sysfs_third_genl(void) +{ + int ret; + + kobj_third_genl =3D kobject_create_and_add("third_genl", kernel_kobj); + + if (!kobj_third_genl) { + pr_err("%s: Failed to create kobject\n", __func__); + return -ENOMEM; + } + + ret =3D sysfs_create_file(kobj_third_genl, &my_attr_str_third_genl.attr); + if (ret) { + pr_err("%s: Failed to create sysfs file\n", __func__); + goto err_sysfs; + } + + return 0; + +err_sysfs: + kobject_put(kobj_third_genl); + return ret; +} + +static int __init init_sysfs_parallel_genl(void) +{ + int ret; + + kobj_parallel_genl =3D + kobject_create_and_add("parallel_genl", kernel_kobj); + + if (!kobj_parallel_genl) { + pr_err("%s: Failed to create kobject\n", __func__); + return -ENOMEM; + } + + ret =3D sysfs_create_file(kobj_parallel_genl, + &my_attr_str_parallel_genl.attr); + if (ret) { + pr_err("%s: Failed to create sysfs file\n", __func__); + goto err_sysfs; + } + + return 0; + +err_sysfs: + kobject_put(kobj_parallel_genl); + return ret; +} + +static int __init init_sysfs_genl_test(void) +{ + int ret; + + kobj_genl_test =3D kobject_create_and_add("genl_test", kernel_kobj); + dev_genl_test =3D kobj_to_dev(kobj_genl_test); + + if (!kobj_genl_test) { + pr_err("%s: Failed to create kobject\n", __func__); + return -ENOMEM; + } + + ret =3D sysfs_create_file(kobj_genl_test, &my_attr_u32_genl_test.attr); + if (ret) { + pr_err("%s: Failed to create sysfs file 1\n", __func__); + goto err_sysfs; + } + + ret =3D sysfs_create_file(kobj_genl_test, &my_attr_str_genl_test.attr); + if (ret) { + pr_err("%s: Failed to create sysfs file 2\n", __func__); + goto err_sysfs_2; + } + + ret =3D device_create_file(dev_genl_test, &dev_attr_info_genl_test); + if (ret) { + pr_err("%s: Failed to create device file\n", __func__); + goto err_device; + }; + + return 0; + +err_device: + sysfs_remove_file(kobj_genl_test, &my_attr_str_genl_test.attr); +err_sysfs_2: + sysfs_remove_file(kobj_genl_test, &my_attr_u32_genl_test.attr); +err_sysfs: + kobject_put(kobj_genl_test); + return ret; +} + +static int __init module_netlink_init(void) +{ + int ret; + + ret =3D init_sysfs_genl_test(); + if (ret) + goto err_sysfs; + + ret =3D init_sysfs_parallel_genl(); + if (ret) + goto err_sysfs; + + ret =3D init_sysfs_third_genl(); + if (ret) + goto err_sysfs; + + return 0; + +err_sysfs: + sysfs_remove_file(kobj_genl_test, &my_attr_u32_genl_test.attr); + sysfs_remove_file(kobj_genl_test, &my_attr_str_genl_test.attr); + device_remove_file(dev_genl_test, &dev_attr_info_genl_test); + kobject_put(kobj_genl_test); + + sysfs_remove_file(kobj_parallel_genl, &my_attr_str_parallel_genl.attr); + kobject_put(kobj_parallel_genl); + + sysfs_remove_file(kobj_third_genl, &my_attr_str_third_genl.attr); + kobject_put(kobj_third_genl); + return ret; +} + +static void __exit module_netlink_exit(void) +{ + sysfs_remove_file(kobj_genl_test, &my_attr_u32_genl_test.attr); + sysfs_remove_file(kobj_genl_test, &my_attr_str_genl_test.attr); + device_remove_file(dev_genl_test, &dev_attr_info_genl_test); + kobject_put(kobj_genl_test); + + sysfs_remove_file(kobj_parallel_genl, &my_attr_str_parallel_genl.attr); + kobject_put(kobj_parallel_genl); + + sysfs_remove_file(kobj_third_genl, &my_attr_str_third_genl.attr); + kobject_put(kobj_third_genl); + pr_info("%s: Module is exited\n", __func__); +} + +module_init(module_netlink_init); +module_exit(module_netlink_exit); --=20 2.34.1