From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 591ABA00BE; Sun, 24 Apr 2022 12:35:58 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F382940042; Sun, 24 Apr 2022 12:35:57 +0200 (CEST) Received: from mail-il1-f178.google.com (mail-il1-f178.google.com [209.85.166.178]) by mails.dpdk.org (Postfix) with ESMTP id 8998E4003F for ; Sun, 24 Apr 2022 12:35:56 +0200 (CEST) Received: by mail-il1-f178.google.com with SMTP id i8so7679501ila.5 for ; Sun, 24 Apr 2022 03:35:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=Yr7vEG/rTc1uCnN2fPHbmDIKeH5aT8YPDtP84eO6ITM=; b=QBFt9Rjw/JnJk05DrKjqjS+tMq/K32eoZ2PCeHrwtjqCRWxcOWKSBsk2AkKCXGUnPu YTksXngTURmP5CZzrUnRfhresWRtJohm77sqm/HX3hkrV6hrDcVPhJUbhabTs19kB4gr 5dRhUn8PNMrp/90qGFKsqAIyNuocSSYDVbL3qThjIWVVuxiRgl7V8hu3j4tmR5F2O1zw wGDutl6InevRCu/UfNn65DeIgyOstVIQwwMFiopBnyDzXfmrHHBKCv2s/k76OVyV8+Fn R9HDvG0kWBF6XU9QFxB/ins0p3VXC7SlN8LmF6NQApdxi7/bEs4hF99IitvxPJBr+aZP u5eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=Yr7vEG/rTc1uCnN2fPHbmDIKeH5aT8YPDtP84eO6ITM=; b=ep+HKL5R2qM1zsnkiuVh2ZQuPC24y6Gx7WzQwFMkCrUEXIfh0NCYSenO3cEA2S5xMy 79+gZt/6jI1+20KdxwOdjkHSGFLCLmpLZj8edKYbT73p8YOGEk8mlPsOX7bv7KsZduc1 ZEM9sWUq8RsIqzgNEXSfd0A876wQkENRyzLiyarX5MhDjkS4aQHFPzFBAD+M0ERbTYKO 9EtKDsnBGDqbLSxfuwe9TcJ9GPuTs4u+qppCD2UF68yhGmdPqYLMnzlhsB6bypz36LQg R9cyYCzkTRntA5UpXclkoPYTzYcogxK832X6cI0hTwnK9U+mR9C4QGF/sjaI8TxKiWVo gNxQ== X-Gm-Message-State: AOAM5321XGvV0oeLIkIZmhYaBlPHxHOD1i1sZUcCJg4ikb8zJE+orzXl 4zuURY0g1VBWokm+0c1eFyzb1DNrXUU+RXDMGbXwM/1mFkq5ab+jRkI= X-Google-Smtp-Source: ABdhPJy3rXPt+UZI2vbtCIDJkR8D0d/6xHeCrBsFSTd9c0oueQjjmaF3ALr1MjTr3TakxEErflUEqYSGBKxsOD48wQc= X-Received: by 2002:a05:6e02:8ae:b0:2c7:90a5:90b8 with SMTP id a14-20020a056e0208ae00b002c790a590b8mr5323301ilt.19.1650796555839; Sun, 24 Apr 2022 03:35:55 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a4f:9c4:0:0:0:0:0 with HTTP; Sun, 24 Apr 2022 03:35:55 -0700 (PDT) In-Reply-To: <20220424085153.925314-1-omegacoleman@gmail.com> References: <20220424085153.925314-1-omegacoleman@gmail.com> From: Stephen Coleman Date: Sun, 24 Apr 2022 18:35:55 +0800 Message-ID: Subject: Re: kni: check abi version between kmod and lib To: "dev@dpdk.org" Cc: Ray Kinsella , Stephen Hemminger , Ferruh Yigit , youcai Content-Type: multipart/alternative; boundary="0000000000004ead1405dd64065f" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --0000000000004ead1405dd64065f Content-Type: text/plain; charset="UTF-8" execuse me, one of the Windows check is failing but I didn't find where's the build log, nor to determine whether it is related. > KNI ioctl functions copy data from userspace lib, and this interface > of kmod is not compatible indeed. If the user use incompatible rte_kni.ko > bad things happen: sometimes various fields contain garbage value, > sometimes it cause a kmod soft lockup. > > Some common distros ship their own rte_kni.ko, so this is likely to > happen. > > This patch add abi version checking between userland lib and kmod so > that: > > * if kmod ioctl got a wrong abi magic, it refuse to go on > * if userland lib, probed a wrong abi version via newly added ioctl, it > also refuse to go on > > Bugzilla ID: 998 > > Signed-off-by: youcai > > --- > V3: fix code format issues > > V2: use ABI_VERSION instead of a new magic > V2: fix some indent > --- > kernel/linux/kni/kni_misc.c | 42 ++++++++++++++++++++++++++++++++++++ > kernel/linux/kni/meson.build | 4 ++-- > lib/kni/meson.build | 1 + > lib/kni/rte_kni.c | 18 ++++++++++++++++ > lib/kni/rte_kni_abi.h | 17 +++++++++++++++ > lib/kni/rte_kni_common.h | 3 +++ > 6 files changed, 83 insertions(+), 2 deletions(-) > create mode 100644 lib/kni/rte_kni_abi.h > > diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c > index 780187d8bf..d92500414d 100644 > --- a/kernel/linux/kni/kni_misc.c > +++ b/kernel/linux/kni/kni_misc.c > @@ -17,6 +17,7 @@ > #include > > #include > +#include > > #include "compat.h" > #include "kni_dev.h" > @@ -236,12 +237,26 @@ kni_release(struct inode *inode, struct file *file) > return 0; > } > > +static int > +kni_check_abi_version_magic(uint16_t abi_version_magic) > +{ > + if (abi_version_magic != RTE_KNI_ABI_VERSION_MAGIC) { > + pr_err("KNI kmod ABI incompatible with librte_kni -- %u\n", > + RTE_KNI_ABI_VERSION_FROM_MAGIC(abi_version_magic)); > + return -1; > + } > + return 0; > +} > + > static int > kni_check_param(struct kni_dev *kni, struct rte_kni_device_info *dev) > { > if (!kni || !dev) > return -1; > > + if (kni_check_abi_version_magic(dev->abi_version_magic) < 0) > + return -1; > + > /* Check if network name has been used */ > if (!strncmp(kni->name, dev->name, RTE_KNI_NAMESIZE)) { > pr_err("KNI name %s duplicated\n", dev->name); > @@ -301,12 +316,19 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, > struct rte_kni_device_info dev_info; > struct net_device *net_dev = NULL; > struct kni_dev *kni, *dev, *n; > + uint16_t abi_version_magic; > > pr_info("Creating kni...\n"); > /* Check the buffer size, to avoid warning */ > if (_IOC_SIZE(ioctl_num) > sizeof(dev_info)) > return -EINVAL; > > + /* perform abi check ahead of copy, to avoid possible violation */ > + if (copy_from_user(&abi_version_magic, (void *)ioctl_param, sizeof(uint16_t))) > + return -EFAULT; > + if (kni_check_abi_version_magic(abi_version_magic) < 0) > + return -EINVAL; > + > /* Copy kni info from user space */ > if (copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info))) > return -EFAULT; > @@ -451,10 +473,17 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num, > int ret = -EINVAL; > struct kni_dev *dev, *n; > struct rte_kni_device_info dev_info; > + uint16_t abi_version_magic; > > if (_IOC_SIZE(ioctl_num) > sizeof(dev_info)) > return -EINVAL; > > + /* perform abi check ahead of copy, to avoid possible violation */ > + if (copy_from_user(&abi_version_magic, (void *)ioctl_param, sizeof(uint16_t))) > + return -EFAULT; > + if (kni_check_abi_version_magic(abi_version_magic) < 0) > + return -EINVAL; > + > if (copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info))) > return -EFAULT; > > @@ -484,6 +513,16 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num, > return ret; > } > > +static int > +kni_ioctl_abi_version(struct net *net, uint32_t ioctl_num, > + unsigned long ioctl_param) > +{ > + uint16_t abi_version = ABI_VERSION_MAJOR; > + if (copy_to_user((void *)ioctl_param, &abi_version, sizeof(uint16_t))) > + return -EFAULT; > + return 0; > +} > + > static long > kni_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) > { > @@ -505,6 +544,9 @@ kni_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) > case _IOC_NR(RTE_KNI_IOCTL_RELEASE): > ret = kni_ioctl_release(net, ioctl_num, ioctl_param); > break; > + case _IOC_NR(RTE_KNI_IOCTL_ABI_VERSION): > + ret = kni_ioctl_abi_version(net, ioctl_num, ioctl_param); > + break; > default: > pr_debug("IOCTL default\n"); > break; > diff --git a/kernel/linux/kni/meson.build b/kernel/linux/kni/meson.build > index 4c90069e99..c8cd23acd9 100644 > --- a/kernel/linux/kni/meson.build > +++ b/kernel/linux/kni/meson.build > @@ -3,12 +3,12 @@ > > # For SUSE build check function arguments of ndo_tx_timeout API > # Ref: https://jira.devtools.intel.com/browse/DPDK-29263 > -kmod_cflags = '' > +kmod_cflags = '-DABI_VERSION_MAJOR=@0@'.format(abi_version.split('.')[0]) > file_path = kernel_source_dir + '/include/linux/netdevice.h' > run_cmd = run_command('grep', 'ndo_tx_timeout', file_path, check: false) > > if run_cmd.stdout().contains('txqueue') == true > - kmod_cflags = '-DHAVE_ARG_TX_QUEUE' > + kmod_cflags += ' -DHAVE_ARG_TX_QUEUE' > endif > > > diff --git a/lib/kni/meson.build b/lib/kni/meson.build > index 8a71d8ba6f..f22a27b15b 100644 > --- a/lib/kni/meson.build > +++ b/lib/kni/meson.build > @@ -14,3 +14,4 @@ endif > sources = files('rte_kni.c') > headers = files('rte_kni.h', 'rte_kni_common.h') > deps += ['ethdev', 'pci'] > +cflags += ['-DABI_VERSION_MAJOR=@0@'.format(abi_version.split('.')[0])] > diff --git a/lib/kni/rte_kni.c b/lib/kni/rte_kni.c > index 7971c56bb4..9bdeeb3806 100644 > --- a/lib/kni/rte_kni.c > +++ b/lib/kni/rte_kni.c > @@ -22,6 +22,7 @@ > #include > #include > #include "rte_kni_fifo.h" > +#include "rte_kni_abi.h" > > #define MAX_MBUF_BURST_NUM 32 > > @@ -113,6 +114,20 @@ rte_kni_init(unsigned int max_kni_ifaces __rte_unused) > } > } > > + uint16_t abi_version; > + int ret = ioctl(kni_fd, RTE_KNI_IOCTL_ABI_VERSION, &abi_version); > + if (ret < 0) { > + RTE_LOG(ERR, KNI, "Cannot verify rte_kni kmod ABI version: ioctl failed\n"); > + return -1; > + } > + if (abi_version != ABI_VERSION_MAJOR) { > + RTE_LOG(ERR, KNI, > + "rte_kni kmod ABI version mismatch: " > + "need %" PRIu16 " got %" PRIu16 "\n", > + ABI_VERSION_MAJOR, abi_version); > + return -1; > + } > + > return 0; > } > > @@ -255,6 +270,7 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool, > kni->ops.port_id = UINT16_MAX; > > memset(&dev_info, 0, sizeof(dev_info)); > + dev_info.abi_version_magic = RTE_KNI_ABI_VERSION_MAGIC; > dev_info.core_id = conf->core_id; > dev_info.force_bind = conf->force_bind; > dev_info.group_id = conf->group_id; > @@ -409,6 +425,8 @@ rte_kni_release(struct rte_kni *kni) > if (!kni) > return -1; > > + dev_info.abi_version_magic = RTE_KNI_ABI_VERSION_MAGIC; > + > kni_list = RTE_TAILQ_CAST(rte_kni_tailq.head, rte_kni_list); > > rte_mcfg_tailq_write_lock(); > diff --git a/lib/kni/rte_kni_abi.h b/lib/kni/rte_kni_abi.h > new file mode 100644 > index 0000000000..7dde394c72 > --- /dev/null > +++ b/lib/kni/rte_kni_abi.h > @@ -0,0 +1,17 @@ > +/* SPDX-License-Identifier: (BSD-3-Clause OR LGPL-2.1) */ > +/* > + * Copyright(c) 2007-2014 Intel Corporation. > + */ > + > +#ifndef _RTE_KNI_ABI_H_ > +#define _RTE_KNI_ABI_H_ > + > +#ifndef ABI_VERSION_MAJOR > +#error Need ABI_VERSION_MAJOR being the major part of dpdk/ABI_VERSION > +#endif > +#define RTE_KNI_ABI_VERSION_MAGIC_MASK 0xAAAA > +#define RTE_KNI_ABI_VERSION_MAGIC (((ABI_VERSION_MAJOR) ^ RTE_KNI_ABI_VERSION_MAGIC_MASK)) > +#define RTE_KNI_ABI_VERSION_FROM_MAGIC(__magic) (((__magic) ^ RTE_KNI_ABI_VERSION_MAGIC_MASK)) > + > +#endif > + > diff --git a/lib/kni/rte_kni_common.h b/lib/kni/rte_kni_common.h > index 8d3ee0fa4f..f9432b742c 100644 > --- a/lib/kni/rte_kni_common.h > +++ b/lib/kni/rte_kni_common.h > @@ -102,6 +102,8 @@ struct rte_kni_mbuf { > */ > > struct rte_kni_device_info { > + uint16_t abi_version_magic; > + > char name[RTE_KNI_NAMESIZE]; /**< Network device name for KNI */ > > phys_addr_t tx_phys; > @@ -139,6 +141,7 @@ struct rte_kni_device_info { > #define RTE_KNI_IOCTL_TEST _IOWR(0, 1, int) > #define RTE_KNI_IOCTL_CREATE _IOWR(0, 2, struct rte_kni_device_info) > #define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info) > +#define RTE_KNI_IOCTL_ABI_VERSION _IOWR(0, 4, uint16_t) > > #ifdef __cplusplus > } > -- > 2.35.1 > > --0000000000004ead1405dd64065f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable execuse me, one of the Windows check is failing but I didn't find where= 's the build log, nor to determine whether it is related.

> K= NI ioctl functions copy data from userspace lib, and this interface
>= of kmod is not compatible indeed. If the user use incompatible rte_kni.ko<= br>> bad things happen: sometimes various fields contain garbage value,<= br>> sometimes it cause a kmod soft lockup.
>
> Some common = distros ship their own rte_kni.ko, so this is likely to
> happen.
= >
> This patch add abi version checking between userland lib and k= mod so
> that:
>
> * if kmod ioctl got a wrong abi magic,= it refuse to go on
> * if userland lib, probed a wrong abi version v= ia newly added ioctl, it
> =C2=A0 also refuse to go on
>
>= ; Bugzilla ID: 998
>
> Signed-off-by: youcai <omegacoleman@gmail.com>
>
> = ---
> V3: fix code format issues
>
> V2: use ABI_VERSION = instead of a new magic
> V2: fix some indent
> ---
> =C2= =A0kernel/linux/kni/kni_misc.c=C2=A0 | 42 +++++++++++++++++++++++++++++++++= +++
> =C2=A0kernel/linux/kni/meson.build |=C2=A0 4 ++--
> =C2= =A0lib/kni/meson.build=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 1 +
>= ; =C2=A0lib/kni/rte_kni.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 18 +++= +++++++++++++
> =C2=A0lib/kni/rte_kni_abi.h=C2=A0 =C2=A0 =C2=A0 =C2= =A0 | 17 +++++++++++++++
> =C2=A0lib/kni/rte_kni_common.h=C2=A0 =C2= =A0 =C2=A0|=C2=A0 3 +++
> =C2=A06 files changed, 83 insertions(+), 2 = deletions(-)
> =C2=A0create mode 100644 lib/kni/rte_kni_abi.h
>=
> diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_mi= sc.c
> index 780187d8bf..d92500414d 100644
> --- a/kernel/linux= /kni/kni_misc.c
> +++ b/kernel/linux/kni/kni_misc.c
> @@ -17,6 = +17,7 @@
> =C2=A0#include <net/netns/generic.h>
>
>= =C2=A0#include <rte_kni_common.h>
> +#include <rte_kni_abi.= h>
>
> =C2=A0#include "compat.h"
> =C2=A0#in= clude "kni_dev.h"
> @@ -236,12 +237,26 @@ kni_release(struc= t inode *inode, struct file *file)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 retu= rn 0;
> =C2=A0}
>
> +static int
> +kni_check_abi_ve= rsion_magic(uint16_t abi_version_magic)
> +{
> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0if (abi_version_magic !=3D RTE_KNI_ABI_VERSION_MAGIC) {
>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pr_err("KNI = kmod ABI incompatible with librte_kni -- %u\n",
> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0RTE_KNI_ABI_VERSION_FROM_MAGIC(abi_version_magic));=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0= return 0;
> +}
> +
> =C2=A0static int
> =C2=A0kni_c= heck_param(struct kni_dev *kni, struct rte_kni_device_info *dev)
> = =C2=A0{
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!kni || !dev)
> =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
>
= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0if (kni_check_abi_version_magic(dev->ab= i_version_magic) < 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0return -1;
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* C= heck if network name has been used */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 i= f (!strncmp(kni->name, dev->name, RTE_KNI_NAMESIZE)) {
> =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_err("KNI name %s = duplicated\n", dev->name);
> @@ -301,12 +316,19 @@ kni_ioctl_= create(struct net *net, uint32_t ioctl_num,
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 struct rte_kni_device_info dev_info;
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 struct net_device *net_dev =3D NULL;
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 struct kni_dev *kni, *dev, *n;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0u= int16_t abi_version_magic;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_i= nfo("Creating kni...\n");
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* = Check the buffer size, to avoid warning */
> =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if (_IOC_SIZE(ioctl_num) > sizeof(dev_info))
> =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
>
> += =C2=A0 =C2=A0 =C2=A0 =C2=A0/* perform abi check ahead of copy, to avoid pos= sible violation */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0if (copy_from_user(&= amp;abi_version_magic, (void *)ioctl_param, sizeof(uint16_t)))
> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EFAULT;
>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0if (kni_check_abi_version_magic(abi_version_ma= gic) < 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0return -EINVAL;
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Copy kn= i info from user space */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (copy_from= _user(&dev_info, (void *)ioctl_param, sizeof(dev_info)))
> =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EFAULT;
> @= @ -451,10 +473,17 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num,=
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 int ret =3D -EINVAL;
> =C2=A0 = =C2=A0 =C2=A0 =C2=A0 struct kni_dev *dev, *n;
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 struct rte_kni_device_info dev_info;
> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0uint16_t abi_version_magic;
>
> =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if (_IOC_SIZE(ioctl_num) > sizeof(dev_info))
> =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
>
> += =C2=A0 =C2=A0 =C2=A0 =C2=A0/* perform abi check ahead of copy, to avoid pos= sible violation */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0if (copy_from_user(&= amp;abi_version_magic, (void *)ioctl_param, sizeof(uint16_t)))
> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EFAULT;
>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0if (kni_check_abi_version_magic(abi_version_ma= gic) < 0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0return -EINVAL;
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (copy_f= rom_user(&dev_info, (void *)ioctl_param, sizeof(dev_info)))
> =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EFAULT;
>= ;
> @@ -484,6 +513,16 @@ kni_ioctl_release(struct net *net, uint32_t = ioctl_num,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;
> =C2=A0}<= br>>
> +static int
> +kni_ioctl_abi_version(struct net *net,= uint32_t ioctl_num,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0unsigned long ioctl_param)
> +{
> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0uint16_t abi_version =3D ABI_VERSION_MAJOR;
> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0if (copy_to_user((void *)ioctl_param, &abi_version, si= zeof(uint16_t)))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0return -EFAULT;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>= +}
> +
> =C2=A0static long
> =C2=A0kni_ioctl(struct file= *file, unsigned int ioctl_num, unsigned long ioctl_param)
> =C2=A0{<= br>> @@ -505,6 +544,9 @@ kni_ioctl(struct file *file, unsigned int ioctl= _num, unsigned long ioctl_param)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 case _= IOC_NR(RTE_KNI_IOCTL_RELEASE):
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 ret =3D kni_ioctl_release(net, ioctl_num, ioctl_param)= ;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;> +=C2=A0 =C2=A0 =C2=A0 =C2=A0case _IOC_NR(RTE_KNI_IOCTL_ABI_VERSION):<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D kni= _ioctl_abi_version(net, ioctl_num, ioctl_param);
> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 default:
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 pr_debug("IOCTL default\n");
> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
> diff --git a/kernel/linux= /kni/meson.build b/kernel/linux/kni/meson.build
> index 4c90069e99..c= 8cd23acd9 100644
> --- a/kernel/linux/kni/meson.build
> +++ b/k= ernel/linux/kni/meson.build
> @@ -3,12 +3,12 @@
>
> =C2= =A0# For SUSE build check function arguments of ndo_tx_timeout API
> = =C2=A0# Ref: = https://jira.devtools.intel.com/browse/DPDK-29263
> -kmod_cflags = =3D ''
> +kmod_cflags =3D '-DABI_VERSION_MAJOR=3D@0@'= .format(abi_version.split('.')[0])
> =C2=A0file_path =3D kern= el_source_dir + '/include/linux/netdevice.h'
> =C2=A0run_cmd = =3D run_command('grep', 'ndo_tx_timeout', file_path, check:= false)
>
> =C2=A0if run_cmd.stdout().contains('txqueue'= ;) =3D=3D true
> -=C2=A0 =C2=A0kmod_cflags =3D '-DHAVE_ARG_TX_QUE= UE'
> +=C2=A0 =C2=A0kmod_cflags +=3D ' -DHAVE_ARG_TX_QUEUE= 9;
> =C2=A0endif
>
>
> diff --git a/lib/kni/meson.b= uild b/lib/kni/meson.build
> index 8a71d8ba6f..f22a27b15b 100644
&= gt; --- a/lib/kni/meson.build
> +++ b/lib/kni/meson.build
> @@ = -14,3 +14,4 @@ endif
> =C2=A0sources =3D files('rte_kni.c')> =C2=A0headers =3D files('rte_kni.h', 'rte_kni_common.h&#= 39;)
> =C2=A0deps +=3D ['ethdev', 'pci']
> +cfl= ags +=3D ['-DABI_VERSION_MAJOR=3D@0@'.format(abi_version.split('= ;.')[0])]
> diff --git a/lib/kni/rte_kni.c b/lib/kni/rte_kni.c> index 7971c56bb4..9bdeeb3806 100644
> --- a/lib/kni/rte_kni.c> +++ b/lib/kni/rte_kni.c
> @@ -22,6 +22,7 @@
> =C2=A0#inc= lude <rte_eal_memconfig.h>
> =C2=A0#include <rte_kni_common.= h>
> =C2=A0#include "rte_kni_fifo.h"
> +#include &= quot;rte_kni_abi.h"
>
> =C2=A0#define MAX_MBUF_BURST_NUM= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 32
>
> @@ -113,6 +114= ,20 @@ rte_kni_init(unsigned int max_kni_ifaces __rte_unused)
> =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> =C2=A0 =C2= =A0 =C2=A0 =C2=A0 }
>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0uint16_t ab= i_version;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0int ret =3D ioctl(kni_fd, RT= E_KNI_IOCTL_ABI_VERSION, &abi_version);
> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0if (ret < 0) {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0RTE_LOG(ERR, KNI, "Cannot verify rte_kni kmod ABI version= : ioctl failed\n");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0return -1;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0}
> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0if (abi_version !=3D ABI_VERSION_MAJOR) {
> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RTE_LOG(ERR, KNI,> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"rte_kni kmod ABI version= mismatch: "
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"need %= " PRIu16 " got %" PRIu16 "\n",
> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0ABI_VERSION_MAJOR, abi_version);
> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
> +=C2=A0= =C2=A0 =C2=A0 =C2=A0}
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 return= 0;
> =C2=A0}
>
> @@ -255,6 +270,7 @@ rte_kni_alloc(struc= t rte_mempool *pktmbuf_pool,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 kni->ops.port_id =3D UINT16_MAX;
>
> =C2= =A0 =C2=A0 =C2=A0 =C2=A0 memset(&dev_info, 0, sizeof(dev_info));
>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0dev_info.abi_version_magic =3D RTE_KNI_ABI_VE= RSION_MAGIC;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_info.core_id =3D conf-= >core_id;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_info.force_bind =3D co= nf->force_bind;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_info.group_id = =3D conf->group_id;
> @@ -409,6 +425,8 @@ rte_kni_release(struct r= te_kni *kni)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!kni)
> =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
>
>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0dev_info.abi_version_magic =3D RTE_KNI_ABI_VER= SION_MAGIC;
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 kni_list =3D RTE_= TAILQ_CAST(rte_kni_tailq.head, rte_kni_list);
>
> =C2=A0 =C2=A0= =C2=A0 =C2=A0 rte_mcfg_tailq_write_lock();
> diff --git a/lib/kni/rt= e_kni_abi.h b/lib/kni/rte_kni_abi.h
> new file mode 100644
> in= dex 0000000000..7dde394c72
> --- /dev/null
> +++ b/lib/kni/rte_= kni_abi.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: (BS= D-3-Clause OR LGPL-2.1) */
> +/*
> + * Copyright(c) 2007-2014 I= ntel Corporation.
> + */
> +
> +#ifndef _RTE_KNI_ABI_H_> +#define _RTE_KNI_ABI_H_
> +
> +#ifndef ABI_VERSION_MAJO= R
> +#error Need ABI_VERSION_MAJOR being the major part of dpdk/ABI_V= ERSION
> +#endif
> +#define RTE_KNI_ABI_VERSION_MAGIC_MASK 0xAA= AA
> +#define RTE_KNI_ABI_VERSION_MAGIC (((ABI_VERSION_MAJOR) ^ RTE_K= NI_ABI_VERSION_MAGIC_MASK))
> +#define RTE_KNI_ABI_VERSION_FROM_MAGIC= (__magic) (((__magic) ^ RTE_KNI_ABI_VERSION_MAGIC_MASK))
> +
> = +#endif
> +
> diff --git a/lib/kni/rte_kni_common.h b/lib/kni/r= te_kni_common.h
> index 8d3ee0fa4f..f9432b742c 100644
> --- a/l= ib/kni/rte_kni_common.h
> +++ b/lib/kni/rte_kni_common.h
> @@ -= 102,6 +102,8 @@ struct rte_kni_mbuf {
> =C2=A0 */
>
> =C2= =A0struct rte_kni_device_info {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0uint16_= t abi_version_magic;
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 char nam= e[RTE_KNI_NAMESIZE];=C2=A0 /**< Network device name for KNI */
>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 phys_addr_t tx_phys;
> @@ -139,6 += 141,7 @@ struct rte_kni_device_info {
> =C2=A0#define RTE_KNI_IOCTL_T= EST=C2=A0 =C2=A0 _IOWR(0, 1, int)
> =C2=A0#define RTE_KNI_IOCTL_CREAT= E=C2=A0 _IOWR(0, 2, struct rte_kni_device_info)
> =C2=A0#define RTE_K= NI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info)
> +#define R= TE_KNI_IOCTL_ABI_VERSION _IOWR(0, 4, uint16_t)
>
> =C2=A0#ifdef= __cplusplus
> =C2=A0}
> --
> 2.35.1
>
> --0000000000004ead1405dd64065f--