From nobody Sun Feb 8 19:57:11 2026 Received: from mout.gmx.net (mout.gmx.net [212.227.17.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0BBDD25A62E; Fri, 17 Jan 2025 14:16:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.22 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123383; cv=none; b=FrYbwpdlKd0F5S5Wnu9v227d4OfhZLnv8BvCgZgv5DT3ax7J1Gtt1G7SCstABMTIqPT/5omDSNH8C+5N/rBbixO7WnV3JH4fNCQL8RaE/Nb4uEpbRxIsN3wNzbT1DgMcPZFX5/H1AytGtF+Mk3RgmqZU5ebb1UNmYTdKQv5qU8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123383; c=relaxed/simple; bh=dpHTiq37g4gxen68QdVNBAH4djW7txUk7SnJ5N1RKSI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iCdGvBiURk/3f35pPb3tSAbJgBunHhHTlWRKCVWwZDfd3c844AthnGFTLbQoLK5rS0kf/SGWkioDJshqwClbVp4TGa8ea1sYRrnTkULwymEF/QlbA9vzKljG9uYAVtaPkPAiYDdT/bkrO7nFP7u++Fz5RC17EgFhMlcxw2vMcCg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net; spf=pass smtp.mailfrom=gmx.net; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b=S9V1jYSm; arc=none smtp.client-ip=212.227.17.22 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmx.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b="S9V1jYSm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.net; s=s31663417; t=1737123379; x=1737728179; i=ps.report@gmx.net; bh=dpHTiq37g4gxen68QdVNBAH4djW7txUk7SnJ5N1RKSI=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:cc: content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=S9V1jYSmX7ocrCNiopxU43gh0mraPUVaBdrO1tXkMRZWfxgTcWyUnJwvYSWVaISN IDxXxpbbZn7A9D16X3QoCbttGK4/Dix8yE8MTleYZC9F3v2m7/5ajKhCGo455LAMg ZYYpeaPWSxiWOWuU/Fl9F/DluM3zEotksTAGLFzD8Ynr4wm3yaNkYoEVpINUMvr2p urhCR1Dq2VRswRNbUnOOpaUqlS5UPBWo3HRd0fH5qlu+pACcjbjChEQ0uq0kO+Zs8 iLwUJR3sOzyGKqF2dTcNB6AVohuTVFkb6jBzKuVa0C6sJ3vRYOd+qleCP+yUWSVkn AcsvR/yjv2Bq8Kd7lw== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.fritz.box ([82.135.81.138]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MiJVG-1t4gz63UXu-00jlfx; Fri, 17 Jan 2025 15:16:18 +0100 From: Peter Seiderer To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Frederic Weisbecker , Artem Chernyshev , Nam Cao , Peter Seiderer Subject: [PATCH net-next v1 1/5] net: pktgen: replace ENOTSUPP with EOPNOTSUPP Date: Fri, 17 Jan 2025 15:16:09 +0100 Message-ID: <20250117141613.691452-2-ps.report@gmx.net> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117141613.691452-1-ps.report@gmx.net> References: <20250117141613.691452-1-ps.report@gmx.net> 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 X-Provags-ID: V03:K1:b1ul4GHA6s9CYulb/E6UFjhWwbhzbaJ8f4b3CNwOKIk/rMvk1jB IHc3zGCEJQGcH7wzL6rUgXdUjVPbbTtvVelvFxJCaDxhgfK3JztSQOipB4NcqFUX5t5C40X teqYku6ZrEHAL258T9V1jR+MMY5aPyDgs+ce8ppzvbYi5JeTgJSpx1D4nUZft69yFsQblzJ yQJUDpoz1EGsudxzvH1HQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:sIB85bAxRiw=;X3b+TZ/VEpgOTQ5pEbmI2gcI6Rj IGL/poDCCz2Ov2ElirkgpaR6iZyvUL58HcCsWaVqD1yzvRCjPYCPlKIZOQStIhM9V758K57SK JXwr4WqoyJqsXqkMan1KpXsE/OVRH3eo79ot5AGbpPksH/yXSJaHW2cppOLk/727/GTWpXopw 9gTanf9deZKBkYKOT5Y4DKe2MoXwJVw0/LBygZ6FXGW1GdGEAFWZ3fMOBppZPKX7O2MnWf6J3 u3EbMpgBySH0Yedrz9asCHdv8mP+c5KGl9NyVlbtLDIoGy4Q9bo+yMuaUSrVYZVJVbznD4VZu XeAQtMB1r/epRIqdeFbjUndkLlxk4gpjs7hg+7RuZVT05BQR4v1w2RdpDKAK+DAJiLdxiMTAg OkU/jgtumfC5v1bJGL7TBZK8spL3vFEMRF9ZfDmwb3EmblvVkkviN8Ud9R7tVw+wW6yjnDDuh lP4sTBq2spaIB0BvmeANn996FK4YHXAXTpSzN/5udBfNoXgl5Q0kQ0DV+pZeSOOoHjxaGP4Dr nxUqNapmP2BSGBHx3EoUtAwv+BqOwEU3iF+Nkhlm04thSgur8osVvERRzNei/5dZMzCUSNPiR uMQKiqAhNsnqwRU+1f4Dsjr9AzLul0aXCZxZ/N6xNDaztlfevC+6okys8apOvJRBhzvKiyLtq 6AQYLFPfwz7jCfY0zqQFQsrJvfG6ehBSWZbZ8VXSY6YdULM3OncDFFg1Cif12y9vU/62rtFlm NUDVHZ9c25Q5O2j+7GUWaBVbjVGE9SpYBTzrt+5yZlmUX7JJfyptS0sm9lvCGV0ZuMHYnQiBT E4Y1QI4u25+xqVRFFtXhyVhswrBCaxB/vmlvzTgp21pQKKS8wI01ohWH8Rd36I2Os1+qXicQh MowQjoYFRycxjplpJot/METHkeI4S2XaYF7GBfKhRLNvCSmIflzc7TeDyyrMZBw4fNUEH1jYR X3QPybAnLAz2TvzN9wpmcQVkdbWBcrT+wq12/gOziqEePCzHP42mANhevTtcCit93XEB25qQk 4kYqr8h8CmOFohrBdjjSKvGF3Pinq8aWJkqp10G1U3G2PauCEXpavOmVao2QWG2TqM6vO7x5n LgqAofno6iSXu8VB4iyLMtUvgMFEECctKVEL6laLpGoYvYfpWErNWdenT4Av6vkdPka+wf7jk fHZDr6YW3nsyoolqXEmLrcmhKucUiAi4HlAn21L4F/A== Content-Type: text/plain; charset="utf-8" Replace ENOTSUPP with EOPNOTSUPP, fixes checkpatch hint WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP and e.g. $ echo "clone_skb 1" > /proc/net/pktgen/lo\@0 -bash: echo: write error: Unknown error 524 Signed-off-by: Peter Seiderer --- net/core/pktgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 82b6a2c3c141..496aa16773e7 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1198,7 +1198,7 @@ static ssize_t pktgen_if_write(struct file *file, if ((value > 0) && ((pkt_dev->xmit_mode =3D=3D M_NETIF_RECEIVE) || !(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) - return -ENOTSUPP; + return -EOPNOTSUPP; if (value > 0 && (pkt_dev->n_imix_entries > 0 || !(pkt_dev->flags & F_SHARED))) return -EINVAL; @@ -1258,7 +1258,7 @@ static ssize_t pktgen_if_write(struct file *file, ((pkt_dev->xmit_mode =3D=3D M_QUEUE_XMIT) || ((pkt_dev->xmit_mode =3D=3D M_START_XMIT) && (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))))) - return -ENOTSUPP; + return -EOPNOTSUPP; =20 if (value > 1 && !(pkt_dev->flags & F_SHARED)) return -EINVAL; @@ -1303,7 +1303,7 @@ static ssize_t pktgen_if_write(struct file *file, } else if (strcmp(f, "netif_receive") =3D=3D 0) { /* clone_skb set earlier, not supported in this mode */ if (pkt_dev->clone_skb > 0) - return -ENOTSUPP; + return -EOPNOTSUPP; =20 pkt_dev->xmit_mode =3D M_NETIF_RECEIVE; =20 --=20 2.48.0 From nobody Sun Feb 8 19:57:11 2026 Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B736038DEC; Fri, 17 Jan 2025 14:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123385; cv=none; b=ei99Pi2SiNsVZB3sp25ottHpz0ADvuCUV5HLk+PnCUt2UjBMrvWlxHWZ9agvnionCQSIoQkAa30sxwcM2MweyIM/INCBVnleAECSFBJ1kJg2RM6uf7xPcDiNfBJqLHdfR9+4IzG0g9rhNTJiNoufXnOyYTIWE8aj1Qfoa9tKOeY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123385; c=relaxed/simple; bh=X0PZDGXscjXwT1DNiHrdE78d1I74q9KXi1uOjvY3Qu0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WDqZ35uT/x8vyU+fXBbXoi8e8HTRXcPk7wdK9kgmXiTsg71WWwZay7RA5QQCBsDTO8IFkj/ruwTXU9QJQhCZKgbQzI0dtfbTaGayqYEMWAoC1x07Nt+aiqfaDh6ziJTBfRgzRRj9anKeFaibcXa6QOXQdi/b/o8D10QdjA5dbpU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net; spf=pass smtp.mailfrom=gmx.net; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b=A3cjlzI3; arc=none smtp.client-ip=212.227.17.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmx.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b="A3cjlzI3" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.net; s=s31663417; t=1737123380; x=1737728180; i=ps.report@gmx.net; bh=X0PZDGXscjXwT1DNiHrdE78d1I74q9KXi1uOjvY3Qu0=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:cc: content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=A3cjlzI3JwBUQnuQij6DMIGbahnM7xUf29qJ4XXtEq4s0ZzlyRrGVgNVWT0bg8YV riLGmIgrGan9f15XnJ/+f81fh6xmK36Z7D92RdXNCkBEjruQroV04wED9vySze6nH s/9zm33iwoq1pZUUinppe37L9I5gkBpG6VTbSjm6w4Bdb0aU3pwZok7bAJw3FGgPo UXiuMdboio2p5dMX/52PgwkGhZmspzalVCL98965h9KaqwmSpAKLB5ldVUZ9Ip1ph k6VmJV0tKJ0R8AVV1lrr0Y2NZWiiiGSoyIHLX/oMnCgOmpF944Z0sA+nwYFise4bv KbkWlV8WVUlQlJ4u7Q== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.fritz.box ([82.135.81.138]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MLzFx-1tqb931Djl-00VFco; Fri, 17 Jan 2025 15:16:20 +0100 From: Peter Seiderer To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Frederic Weisbecker , Artem Chernyshev , Nam Cao , Peter Seiderer Subject: [PATCH net-next v1 2/5] net: pktgen: enable 'param=value' parsing Date: Fri, 17 Jan 2025 15:16:10 +0100 Message-ID: <20250117141613.691452-3-ps.report@gmx.net> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117141613.691452-1-ps.report@gmx.net> References: <20250117141613.691452-1-ps.report@gmx.net> 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 X-Provags-ID: V03:K1:OE7esmNLKbCijPCW5KDVIpw5ecau+K9fCt9up619VngP6l8Rhj8 01fOSaa5/jOSAZrzQsqUNUQp4nUm8f+IFyK9N41pEc1Xpo3Kikne9zESjRq6gLvUfTlHUQy sk4xMht4xb+SBf1vTg6/KIlir1iwHRvryjr7mRJ5RO+YjcpDGW9XZP/YyeKLZnPu66FWaji hY7+f9H5Mvda85JecZgpQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:V6FFWbIazfA=;POI4WEb5dBZ7PPkn78qFG9joOc4 SrOK3OCh2kTRCzoiFRKArdGC69zp1dHbgezvI273GmcD8bdbtrUuRkX6GdrXdvYWByqtpAAvk nX9HAtMYt5U6a7rlt3Hsj52rSctRPXZzblGUQJ4y4njrDGJEAeLDbuz+IJycwh87eRbiGF+GN JP9M6dQ8lCrHDFe9PfrE+yblZ3lBXkPyY0Mg2J90JiMUEWaqlB0IUjbME6Td+nK6EjHZ3HYyr KMBr7BaiqhXP+Nr9Q0DF+TYmyWiji94gEVEvH+lAxakGuN8T+0tLcmMKF9KT9t5RnXA2M/soB 3YpS7kCCp0GRVXv+UTHo6CuMlLzx6h2FV8XZuoB/Q6Ml+H55oUUS61dQKeXxHPmE6X2oUAMM5 wGrWZ0ZTgwbh4EsT5je32sYP7DlZSNmJN4/YYjGGObPR7wu1sTaOcgNBxme9z3kJd326Sko/U mzsrtpDkprjmMs3lXJ+W1Q62wA6AZuW0Yt4p6EIFE9CSr3rR770xFIvtbl2/RMhjhBAZKyQe8 2tLUxB5CXwNPjtHV+K28Jh+tFtpjmlceBbdfnEUTQZ/8Bx9esErv6iuBJLdiwfgqZRIonZuPt fDtQUTW/VGmZmFQRBYsWTWKr/+7jXIJbB3CUsklccHgqlItMI/ze4HjNbSR1DlzgvtvalPl9b QUgGSJHTSAN6KDWcOHOCC1iOThEcX2yJKS3JgIfxzJjd1P1jjxSrf1qU+k3JO3RpuWF5TFrlL xjOpXtCvUT647aLnHjgGIT5W7GfK4YZpTMUeT9ojoIQwUrGj2hyKEdcX5iGTOPyQXgkp52PV5 xS0wj0Mz5jT/O7jQDW2hXJwD3OGX65loXLUhddMHDEZKT6pIBkihrVhfAExJCofWsFAOQvGQ3 VbdVwpUJ1oUP0CH/XuRNfx2gWkCznkgF7cf/x0eTxc7bN9u8VsVcKw0RSoW8jHic+vsX8uRN/ WPlZefH107ETgpGgXuVWteBLCq50ezUylReHYYoN/12yJx5edoi+kj0CHlLJ/FGpGfJExGius ntMqdtQRtT3d6lY1YN2HuLg6+Zli/o0rGdBCbUMrWtqnJ5sWcer5FYUCGkYotC6BEG4lwIzXc hF1gKuoKjFU+tBQLFp183zcUf9L1HQSufV1nPUe+SlgxNjiNlq++9PRJWxXuNOy3WdR4o8DjY uujsVRkjOEM+b/k88uHXiyEtK/hXCJRE+meKTzknirA== Content-Type: text/plain; charset="utf-8" Enable additional to 'parm value' the 'param=3Dvalue' parsing (otherwise skipping '=3D' in count_trail_chars() is useless). Tested with: $ echo "min_pkt_size 999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size=3D999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size =3D999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size=3D 999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size =3D 999" > /proc/net/pktgen/lo\@0 Signed-off-by: Peter Seiderer --- net/core/pktgen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 496aa16773e7..4f8ec6c9bed4 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -823,6 +823,7 @@ static int strn_len(const char __user * user_buffer, un= signed int maxlen) case '\r': case '\t': case ' ': + case '=3D': goto done_str; default: break; --=20 2.48.0 From nobody Sun Feb 8 19:57:11 2026 Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2AA51E89C; Fri, 17 Jan 2025 14:16:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123396; cv=none; b=LslpMxQ6FSyEeUUnO31+y34SdKqKF0oqsaw2Pa6KNQgYnYaEbjihzMEkQAbyeJeYZpGhpuxsrKhi1fPFnuND5ju8wluJwMh+aDfjJhTG662tidX5UIslrv840LKMTJtismLswtsqI9H6Kmha76HvtLBkcNFr0ENLIA1jxWd5s00= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123396; c=relaxed/simple; bh=/jrqqObcI+9mzm9OIPdnKRMAf0DMTi89JU7pGm/d9wA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T4w4oifw1DvKmIgvb49hZEk9Ne0kALBXkAdpPLiIOIBLEEU2AQfGdzZcW/UD2kiCIvki/z0+0dyQaqySkhwQD1LydFxSaL0jnsEkiJR2uoGaxui0orwabu7xLugrfULY1/3LfRG3KmN0fz4Jse35uUjECd4Jj+8AKj8QnTKp55o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net; spf=pass smtp.mailfrom=gmx.net; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b=KON8Zid8; arc=none smtp.client-ip=212.227.17.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmx.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b="KON8Zid8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.net; s=s31663417; t=1737123381; x=1737728181; i=ps.report@gmx.net; bh=/jrqqObcI+9mzm9OIPdnKRMAf0DMTi89JU7pGm/d9wA=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:cc: content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=KON8Zid8hrerfPMstZ7udmkv/1f4OGw6mLSjVHmgNowjxeC8EXfv72Q5c97Fymh7 Lg0BOpXf8Ig04iYauJ1Urd3tWA98pDZcklsMslEXZQAJ6nds9/QJg6qLQZgQpnhpL vK1hELBYqluSGE1y2PhK300nPbulTcTIlVSKcft74DJfmFQuHQL5l3s1JsMfm8MJq lR99QO1GT6iUcOdldK9O7nqhZYc8/CA6RSgFw8bGqiW7DncQfDOyQiNxRxo0s5Z8H MJj8q2X0f0EL2zDtGPjfha5FQ2XKUJJXYhC9mPLBwa8QtaGfYFhE0FMe31J3Xuo3/ Tq3Oywj2C/CAO1AMcw== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.fritz.box ([82.135.81.138]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MAfUe-1tfMiL1oE4-006p0d; Fri, 17 Jan 2025 15:16:21 +0100 From: Peter Seiderer To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Frederic Weisbecker , Artem Chernyshev , Nam Cao , Peter Seiderer Subject: [PATCH net-next v1 3/5] net: pktgen: fix access outside of user given buffer in pktgen_thread_write() Date: Fri, 17 Jan 2025 15:16:11 +0100 Message-ID: <20250117141613.691452-4-ps.report@gmx.net> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117141613.691452-1-ps.report@gmx.net> References: <20250117141613.691452-1-ps.report@gmx.net> 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 X-Provags-ID: V03:K1:Ee9OMSptfaQVhKbBDX/bzUQ6/0WFIcJ1A+syMzJEUFnnpGdFlil xx7cNi/QeNZWfRcLYq1Ugjw80vmUFB0vQpOtTg1jAPCG1mD6k50ppY8Az5DpH4rJuRoX4e1 fMW7SXjpxBMCX4s3guvsmN85Ak85lDxG8I0fCUp3+dtfUeOWL19mkZzex5aidKhliFJ89sO nl9Q2BiJobZfx1qCfVcZQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:3Gq2azVcoio=;J49MGBfWgRSvdbn6Jloud5CacDU H22CLZ8LOmqpbz8XaX05N9OdlIar+oWSgvrTcXW3Ua0gUN0IVe+ey9Nu9/HI6GldW0W1jzWbm eiXegFVt2Ep7NfpvlnaphmSCttEW8fSilEbAu7RG8mbWLBeSLf/ILDvD+VwwvCRogbNu8ukur 4VMd3QZwl9XCAqGb5VfzLLUdmQOFcfRSm+w3aNlzYm0/N4EhnMBnmdXQQhDNQx3Uc3yGtvt4Z gtZWiVt4jPcyetGiJIRRCD77q457UB9UWFbfDU8dCY9LesmLjBA90Q2lv6NF6nG5/ZbC8bmPP jzFqX6Svhtta0UvJEI0cbWMIUxXS/5rkrdTze8D17z3I2OnD07V6Y1A/0Yk0wDPJG9sREOPre UiiC9TSipF0TKjOvPiGYEQ+QUgB2jalAcVER+HKvusrdgRmIv9qomos0bAZ7LTGzscEvXaLVB nYto7/qprsaNPr5lj+++n7f+7z5IYAK6kiQzcTxjJfypx1jHkbJTpbVR2FKkfP5TLywgh0+Rf aTbFyk1iWG9dibo6WFy8vY7d3UhkyiTSgxGOh75NYsWXVCIEWlIhaKILwL0XDlAwZnfBfGsKm qXVsJAN2Go7EvbwnsCLKreCTeK9DGc6Izcc9akn5bWBGq0g7dM2lQTPhoI1u30FUFGP8bzXJQ R/sWBh026ayr0tEMI2odQ1aplWeiAIwCVsL88nLCiWovADPJC9WLAp0J01K7WIUynKcgO43p4 rbOp55rnBNFwlnr7cmbDI+22VrIloZd/KD7HsDtxE30hgujGWk8GyXQFcw4SPhWLCMTJdUJxx hPWz/YSPIfNERdov7qL39hZxT3jRbvSBg/wsqtJQEmLXBEqplXtil2WBoH2KQ6RHyTNQqR0DR QYLfwnSo5nTrzdmVjT475Qzuur1KxBhIOqw4W12OzpwOdeVie0a5Nz6Dumz/4ptt9j7eVvKcj vmCs83r8v2kN5iWVr5T0aZ3Zyb5DiR/FtdEsau56kIBx+HkiQvE9m1auvde6QY7Lz5y7WRY0M zQAwmcxi1uycRj4kb7VT7dFNz2nce6DiSFEyMUoyqth1SPBz7eQLhP6cNijGT0sFJM3dcUUoH FIlcS8bV+huHShb/gRJ2rWTSEP55pRK4yRf5Pws8/yDq8CcpSBRokFZnaiShriwRzTC5dHes2 w9K8+IUj0o3Uc+Vy4+K7Yw0mmeB+cSKDvBDafkPLU6Q== Content-Type: text/plain; charset="utf-8" Honour the user given buffer size for the strn_len() calls (otherwise strn_len() will access memory outside of the user given buffer). Signed-off-by: Peter Seiderer --- net/core/pktgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 4f8ec6c9bed4..9536f9c4d9ef 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1897,8 +1897,8 @@ static ssize_t pktgen_thread_write(struct file *file, i =3D len; =20 /* Read variable name */ - - len =3D strn_len(&user_buffer[i], sizeof(name) - 1); + max =3D min(sizeof(name) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1928,7 +1928,8 @@ static ssize_t pktgen_thread_write(struct file *file, if (!strcmp(name, "add_device")) { char f[32]; memset(f, 0, 32); - len =3D strn_len(&user_buffer[i], sizeof(f) - 1); + max =3D min(sizeof(f) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) { ret =3D len; goto out; --=20 2.48.0 From nobody Sun Feb 8 19:57:11 2026 Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCCFB347CC; Fri, 17 Jan 2025 14:16:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123397; cv=none; b=KVjZaKpHw90aM4/RyeMKkPUMhF6+4ab3I0bsGGfff62vbNhdAitARNGil6uq/g93dMF+e/ImXsquL6QpxSOQOMQMuOqOMoYDRBMkkiXZx9LO0P/SMBjeboK1S00pQya7qNkxTvrdoxa7ZrNWg7TgXCWH2VF7m0zC7wT47GGboQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123397; c=relaxed/simple; bh=cT+Ulo1/Xar64Mj2jDeX4PDN1R8bjGBg3hh1V8lSTv4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cXdoSuQt1gVESVS8Qy5nHKA6Y8OCMfEJUqfyS4oyefHIAZk2lFlv36Y4hCHS7mZTuD6EBDDUwKBeI40k6VNT+oxyCR/qZQfV4ZmdbwzQk0w3XbK6/UGD+RmCNKDBw3HTZOB3Lq9KdYqRHTZ7x7NrxL/bt0w/qMC5X+LVtu4b8ks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net; spf=pass smtp.mailfrom=gmx.net; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b=FcMcZteg; arc=none smtp.client-ip=212.227.17.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmx.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b="FcMcZteg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.net; s=s31663417; t=1737123382; x=1737728182; i=ps.report@gmx.net; bh=cT+Ulo1/Xar64Mj2jDeX4PDN1R8bjGBg3hh1V8lSTv4=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:cc: content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=FcMcZtegApGR8taobktXfUnObEJzNZza436Ek/rkHRfLyQxsKs9KvVEo7UxqzJAO 7vxlDL1FrMaQurilezIgx2dfPyW6UbzdgeKh4wL60TK+lkyHZFoWFMN6BIphayj2O bp57G8bPc0Ee9uk+yjuytg8PgoPc3mcc+6dfAZxim54zITrkfXuyWEErAby6GMtAI kGQiQRMf6TnOrGws133kiu+d+tZW/XcUGMxjHXKuVVdGoodTOzbKJLY5jvvxwm7xE fuaztKHHUpPgOwecH6pGycsUFAEy1LSixur0VihJLDar96iJ3XnA3mJjSBxvNbPnA vPocdxkgdcXOVlwyig== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.fritz.box ([82.135.81.138]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MAwbp-1tfdpX39TN-0075zW; Fri, 17 Jan 2025 15:16:22 +0100 From: Peter Seiderer To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Frederic Weisbecker , Artem Chernyshev , Nam Cao , Peter Seiderer Subject: [PATCH net-next v1 4/5] net: pktgen: fix access outside of user given buffer in pktgen_if_write() Date: Fri, 17 Jan 2025 15:16:12 +0100 Message-ID: <20250117141613.691452-5-ps.report@gmx.net> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117141613.691452-1-ps.report@gmx.net> References: <20250117141613.691452-1-ps.report@gmx.net> 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 X-Provags-ID: V03:K1:c1KGeR0MUtlmrc5YvOoEc15EahOuqq4XgfYWa8rkKl42Fw5m+Be TWBzh+HQ+fioNQVJymwugc9qvNHvLeixncVOdyD3W49IKVL5J+7+6EkZJyHShSpkK9hprGu w1bXJ3BTj3Skq4jLH/Fgw2u0Y3Joyjg5XnIMhvVB319bpYj4wmwqlmwRGhMlwf1K7jlrnfD 4qDxoEsSTeyb8NEoRADpQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:HT+kgfTzmrM=;dIEVUmMlMg4wbC6jrt4nGrUHkfN KTHWytsVrY3UNlrg8iIsL2RDdxuhF4xZr0U+tgZSc+N9owZC3hVLXyVPC5opDzAWOckBSk9wo 1LQfXNfYETLr200tvrELCQapL+SgB/w+ql6mRxUMZe9Xem6w5Ut3ESEiJWpXT5Le/dulW0laZ 2QbIBhy1lwZQ4Bc9+Q5l1XaJvXdafxIPLAD8+3sbDH/ZK+4q4UIKdzwfFPxbmxKNMBmvXeBfa gM3caErpfQUWArXDwMaXngk0YA0zHypeKvwO4DTfX0qwbzbLGMh0a3AsVyvuU4zgcGduAFogP GK8YYw9VTNa/4yzVWWfuwPqGMQj+Z64ymqzzdWgIAecHQFGPv86c8yiVyjgjj27gsNssCXTHU 21iT3FL4hQJTJ00HNTI/OrU6UqGiWV5Waak9GRcsjKxFV59uTbpPXNtP+FbZHcLMs5Zy0OW9D 1biZQuRBrGgeDO5WMu8oOgLp2LEd44LTV7ren8ljFze6afngxa9nPit9wgv31pW50WY7HU6Aq GymLpMbx2My+tee0JrTTMyUnJP/Q1UKVNX0ahzvtYeKZxZLee3+LI6toX2s8omiaeZ1yhKm5F KgjDA9JvmdEG2EIbejBIzjUdX9l+4/nI8cYmFHBxlWh7RNa1GiXAmYy4Lxh8AWgURf9FwfHmN mcwBv4aaDV6IZh7KSS2U5QCPs2UBhOGM4MahUMoChnsu2tCaowI7V0XRscrKnVCMuU9qtgFhk NuAjUexZfyxURvKep/UKob6CVNGFQqiWVCJNgcUCVomQ+yXFEJf8gR+3Xq7Zif/EB9Z04z4b8 KD01YPt4pyZH5VY6gjhjOPnJWqWpOKipwh7WzHKAN+XXYtcYSIzFh4L+ppnpF1WfVWAIYX72N tbEHQNKj015jE444gLmWpa4v+Rcm6Zu+trNG6fGgCw+gXXdAb5Ks+E48b8uX49sigWeosA6CI 2LJr63J+JEEZYrxjdAyBmmjEjOUXE/Mcen4Ed/H6osq0/KhFRrIzEcNtIvl/5SvRLn8h8Px+m /GNQUSsEG9sOBD4UJLNrZ99WRj7EHjH+cyFGY5WERrF1ddv2DVWat6k3+u/Kor9f5pA8x5rAc ydx7xGKr2d12Nlwn9vg/l42y9tajLcSAXjIvMaLwRQAdlK7aNY6wevhBcqydZipdj8oH+lWtV ptrK6npj3RaEysnfv6158wHOfxtUyNT3anNfa/6mBaA== Content-Type: text/plain; charset="utf-8" Honour the user given buffer size for the hex32_arg(), num_arg() and strn_len() calls (otherwise they will access memory outside of the user given buffer). In all three functions error out in case no characters a available (maxlen =3D 0), in num_arg() additional error out in case no valid character is parsed. Additional remove some superfluous variable initializing and align some variable declarations to the most common pattern. Signed-off-by: Peter Seiderer --- net/core/pktgen.c | 196 ++++++++++++++++++++++++++++++---------------- 1 file changed, 128 insertions(+), 68 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 9536f9c4d9ef..5f54a056fa7c 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -750,6 +750,9 @@ static int hex32_arg(const char __user *user_buffer, un= signed long maxlen, int i =3D 0; *num =3D 0; =20 + if (!maxlen) + return -EINVAL; + for (; i < maxlen; i++) { int value; char c; @@ -796,6 +799,9 @@ static long num_arg(const char __user *user_buffer, uns= igned long maxlen, int i; *num =3D 0; =20 + if (!maxlen) + return -EINVAL; + for (i =3D 0; i < maxlen; i++) { char c; if (get_user(c, &user_buffer[i])) @@ -803,6 +809,9 @@ static long num_arg(const char __user *user_buffer, uns= igned long maxlen, if ((c >=3D '0') && (c <=3D '9')) { *num *=3D 10; *num +=3D c - '0'; + } else if (i =3D=3D 0) { + // no valid character parsed, error out + return -EINVAL; } else break; } @@ -813,6 +822,9 @@ static int strn_len(const char __user * user_buffer, un= signed int maxlen) { int i; =20 + if (!maxlen) + return -EINVAL; + for (i =3D 0; i < maxlen; i++) { char c; if (get_user(c, &user_buffer[i])) @@ -839,11 +851,10 @@ static int strn_len(const char __user * user_buffer, = unsigned int maxlen) * "size1,weight_1 size2,weight_2 ... size_n,weight_n" for example. */ static ssize_t get_imix_entries(const char __user *buffer, + unsigned int maxlen, struct pktgen_dev *pkt_dev) { - const int max_digits =3D 10; - int i =3D 0; - long len; + int i =3D 0, max, len; char c; =20 pkt_dev->n_imix_entries =3D 0; @@ -855,7 +866,8 @@ static ssize_t get_imix_entries(const char __user *buff= er, if (pkt_dev->n_imix_entries >=3D MAX_IMIX_ENTRIES) return -E2BIG; =20 - len =3D num_arg(&buffer[i], max_digits, &size); + max =3D min(10, maxlen - i); + len =3D num_arg(&buffer[i], max, &size); if (len < 0) return len; i +=3D len; @@ -869,7 +881,8 @@ static ssize_t get_imix_entries(const char __user *buff= er, if (size < 14 + 20 + 8) size =3D 14 + 20 + 8; =20 - len =3D num_arg(&buffer[i], max_digits, &weight); + max =3D min(10, maxlen - i); + len =3D num_arg(&buffer[i], max, &weight); if (len < 0) return len; if (weight <=3D 0) @@ -889,18 +902,19 @@ static ssize_t get_imix_entries(const char __user *bu= ffer, return i; } =20 -static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pk= t_dev) +static ssize_t get_labels(const char __user *buffer, int maxlen, struct pk= tgen_dev *pkt_dev) { unsigned int n =3D 0; char c; - ssize_t i =3D 0; - int len; + int i =3D 0, max, len; =20 pkt_dev->nr_labels =3D 0; do { __u32 tmp; - len =3D hex32_arg(&buffer[i], 8, &tmp); - if (len <=3D 0) + + max =3D min(8, maxlen - i); + len =3D hex32_arg(&buffer[i], max, &tmp); + if (len < 0) return len; pkt_dev->labels[n] =3D htonl(tmp); if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM) @@ -957,7 +971,6 @@ static ssize_t pktgen_if_write(struct file *file, char name[16], valstr[32]; unsigned long value =3D 0; char *pg_result =3D NULL; - int tmp =3D 0; char buf[128]; =20 pg_result =3D &(pkt_dev->result[0]); @@ -967,17 +980,16 @@ static ssize_t pktgen_if_write(struct file *file, return -EINVAL; } =20 - max =3D count; - tmp =3D count_trail_chars(user_buffer, max); - if (tmp < 0) { + len =3D count_trail_chars(user_buffer, count); + if (len < 0) { pr_warn("illegal format\n"); - return tmp; + return len; } - i =3D tmp; + i =3D len; =20 /* Read variable name */ - - len =3D strn_len(&user_buffer[i], sizeof(name) - 1); + max =3D min(sizeof(name) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1005,7 +1017,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "min_pkt_size")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1022,7 +1035,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "max_pkt_size")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1041,7 +1055,8 @@ static ssize_t pktgen_if_write(struct file *file, /* Shortcut for min =3D max */ =20 if (!strcmp(name, "pkt_size")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1061,7 +1076,8 @@ static ssize_t pktgen_if_write(struct file *file, if (pkt_dev->clone_skb > 0) return -EINVAL; =20 - len =3D get_imix_entries(&user_buffer[i], pkt_dev); + max =3D count - i; + len =3D get_imix_entries(&user_buffer[i], max, pkt_dev); if (len < 0) return len; =20 @@ -1072,7 +1088,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "debug")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1083,7 +1100,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "frags")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1093,7 +1111,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "delay")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1108,7 +1127,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "rate")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1123,7 +1143,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "ratep")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1138,7 +1159,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "udp_src_min")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1151,7 +1173,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "udp_dst_min")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1164,7 +1187,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "udp_src_max")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1177,7 +1201,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "udp_dst_max")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1190,7 +1215,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "clone_skb")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; /* clone_skb is not supported for netif_receive xmit_mode and @@ -1211,7 +1237,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "count")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1222,7 +1249,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "src_mac_count")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1236,7 +1264,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst_mac_count")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1250,7 +1279,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "burst")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1269,7 +1299,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "node")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1290,11 +1321,12 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "xmit_mode")) { char f[32]; =20 - memset(f, 0, 32); - len =3D strn_len(&user_buffer[i], sizeof(f) - 1); + max =3D min(sizeof(f) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 + memset(f, 0, sizeof(f)); if (copy_from_user(f, &user_buffer[i], len)) return -EFAULT; i +=3D len; @@ -1330,11 +1362,12 @@ static ssize_t pktgen_if_write(struct file *file, char f[32]; char *end; =20 - memset(f, 0, 32); - len =3D strn_len(&user_buffer[i], sizeof(f) - 1); + max =3D min(sizeof(f) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 + memset(f, 0, 32); if (copy_from_user(f, &user_buffer[i], len)) return -EFAULT; i +=3D len; @@ -1379,7 +1412,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { - len =3D strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); + max =3D min(sizeof(pkt_dev->dst_min) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1399,7 +1433,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst_max")) { - len =3D strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); + max =3D min(sizeof(pkt_dev->dst_max) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1419,7 +1454,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst6")) { - len =3D strn_len(&user_buffer[i], sizeof(buf) - 1); + max =3D min(sizeof(buf) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1442,7 +1478,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst6_min")) { - len =3D strn_len(&user_buffer[i], sizeof(buf) - 1); + max =3D min(sizeof(buf) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1464,7 +1501,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst6_max")) { - len =3D strn_len(&user_buffer[i], sizeof(buf) - 1); + max =3D min(sizeof(buf) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1485,7 +1523,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "src6")) { - len =3D strn_len(&user_buffer[i], sizeof(buf) - 1); + max =3D min(sizeof(buf) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1508,7 +1547,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "src_min")) { - len =3D strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); + max =3D min(sizeof(pkt_dev->src_min) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1528,7 +1568,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "src_max")) { - len =3D strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); + max =3D min(sizeof(pkt_dev->src_max) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1548,7 +1589,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "dst_mac")) { - len =3D strn_len(&user_buffer[i], sizeof(valstr) - 1); + max =3D min(sizeof(valstr) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1565,7 +1607,8 @@ static ssize_t pktgen_if_write(struct file *file, return count; } if (!strcmp(name, "src_mac")) { - len =3D strn_len(&user_buffer[i], sizeof(valstr) - 1); + max =3D min(sizeof(valstr) - 1, count - i); + len =3D strn_len(&user_buffer[i], max); if (len < 0) return len; =20 @@ -1589,7 +1632,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "flows")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1603,7 +1647,8 @@ static ssize_t pktgen_if_write(struct file *file, } #ifdef CONFIG_XFRM if (!strcmp(name, "spi")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1614,7 +1659,8 @@ static ssize_t pktgen_if_write(struct file *file, } #endif if (!strcmp(name, "flowlen")) { - len =3D num_arg(&user_buffer[i], 10, &value); + max =3D min(10, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1625,7 +1671,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "queue_map_min")) { - len =3D num_arg(&user_buffer[i], 5, &value); + max =3D min(5, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1636,7 +1683,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "queue_map_max")) { - len =3D num_arg(&user_buffer[i], 5, &value); + max =3D min(5, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1649,7 +1697,8 @@ static ssize_t pktgen_if_write(struct file *file, if (!strcmp(name, "mpls")) { unsigned int n, cnt; =20 - len =3D get_labels(&user_buffer[i], pkt_dev); + max =3D count - i; + len =3D get_labels(&user_buffer[i], max, pkt_dev); if (len < 0) return len; i +=3D len; @@ -1670,7 +1719,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "vlan_id")) { - len =3D num_arg(&user_buffer[i], 4, &value); + max =3D min(4, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1697,7 +1747,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "vlan_p")) { - len =3D num_arg(&user_buffer[i], 1, &value); + max =3D min(1, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1712,7 +1763,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "vlan_cfi")) { - len =3D num_arg(&user_buffer[i], 1, &value); + max =3D min(1, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1727,7 +1779,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "svlan_id")) { - len =3D num_arg(&user_buffer[i], 4, &value); + max =3D min(4, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1754,7 +1807,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "svlan_p")) { - len =3D num_arg(&user_buffer[i], 1, &value); + max =3D min(1, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1769,7 +1823,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "svlan_cfi")) { - len =3D num_arg(&user_buffer[i], 1, &value); + max =3D min(1, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 @@ -1784,8 +1839,10 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "tos")) { - __u32 tmp_value =3D 0; - len =3D hex32_arg(&user_buffer[i], 2, &tmp_value); + __u32 tmp_value; + + max =3D min(2, count - i); + len =3D hex32_arg(&user_buffer[i], max, &tmp_value); if (len < 0) return len; =20 @@ -1800,8 +1857,10 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "traffic_class")) { - __u32 tmp_value =3D 0; - len =3D hex32_arg(&user_buffer[i], 2, &tmp_value); + __u32 tmp_value; + + max =3D min(2, count - i); + len =3D hex32_arg(&user_buffer[i], max, &tmp_value); if (len < 0) return len; =20 @@ -1816,7 +1875,8 @@ static ssize_t pktgen_if_write(struct file *file, } =20 if (!strcmp(name, "skb_priority")) { - len =3D num_arg(&user_buffer[i], 9, &value); + max =3D min(9, count - i); + len =3D num_arg(&user_buffer[i], max, &value); if (len < 0) return len; =20 --=20 2.48.0 From nobody Sun Feb 8 19:57:11 2026 Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2388D13C9D4; Fri, 17 Jan 2025 14:16:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123409; cv=none; b=jnK3Cz6IpNc3cZL12XSRG7ZexScrTa6Krg1m5aj8E+O55oBxYL6vYEI/zW22W3Sq1h5qJune+xAlRZuo6gN8VzUoSQvfyDdbE61ZC8NznVzTdsi2hSdga5jcYiYnKA3UMW4qfGM36wJigeJp/oObYbyG7Tb7XhxczhaFKiUzHJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737123409; c=relaxed/simple; bh=tDpGxlUjgzCrUkb+LA5g5Ksb/vYRXwQJ366h8g9Zm7I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S85Gk415KP7+1t7XNNoLW0hTheZ/1D5ugIvveROVw/J3jJccPRroVMkODg1W+WuUOpegUA3JWti77avlTzib7sIbKWWUr2t5ZxdEEzTh1m7A2i2Pmv5lCNhrI5wsBTNQVEHIJ5KChXCz55oFhbL7TkKzsQT10iwWKXjMaX1zC+M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net; spf=pass smtp.mailfrom=gmx.net; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b=RYUGvHgG; arc=none smtp.client-ip=212.227.17.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=gmx.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmx.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmx.net header.i=ps.report@gmx.net header.b="RYUGvHgG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmx.net; s=s31663417; t=1737123384; x=1737728184; i=ps.report@gmx.net; bh=tDpGxlUjgzCrUkb+LA5g5Ksb/vYRXwQJ366h8g9Zm7I=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:cc: content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=RYUGvHgGvKvRret/teD+dgg53/1SxGYgDpn7tUlewxJ2AGygkhWuGxK9GbgyJNcF 7+zRHfDvo6ZaIEsMWUidfPyWw1quNQPVd6jRA57d8O52gL893/z5MaJzeOsvgpEEJ lm6oxjQQNZXG1UhRlV7u11cA3g33zWQ6sZ8lhlFZIhcJALBhFu5hN5G9+IMjjrANL NVlBFiQDVjHRb9P5QYsQKJO98CKzhvT2hNzSheNGgbu2AuhhPGMpMhk1n/0yZ5pJ4 MSyX2/YLQt+9DY0M6V2QX4Rl9+TCq7hjA5Z8syREV3x9Z8rM8dU54Wf2YbKcHayE6 0n2Od1THA3Abh/pK4w== X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a Received: from localhost.fritz.box ([82.135.81.138]) by mail.gmx.net (mrgmx104 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MOiHf-1ttMpT0DsN-00UijE; Fri, 17 Jan 2025 15:16:24 +0100 From: Peter Seiderer To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , Frederic Weisbecker , Artem Chernyshev , Nam Cao , Peter Seiderer Subject: [PATCH net-next v1 5/5] selftest: net: add proc_net_pktgen Date: Fri, 17 Jan 2025 15:16:13 +0100 Message-ID: <20250117141613.691452-6-ps.report@gmx.net> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250117141613.691452-1-ps.report@gmx.net> References: <20250117141613.691452-1-ps.report@gmx.net> 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 X-Provags-ID: V03:K1:P369FKAzsZh96gtwAuCNgLtKXpp0IOwctMaHSoLtBu3l5pug8z4 Fu+hWhgqlNf79oK4jV/PGIRSdRMHSUlSCW9EHJRdqzVspu+NMVAWQwYwqf4+IRx6tOQJlF8 gJAV+q7EFzJy3FdN+7Otge7i882447HLlyxO5HFeB3SpDxvrzOesjJUa8NH21bT6+qNa/0I jk7/SUbnY+Yuu/KGOYSFg== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:CypgL9uUFms=;90RFjsdt/PBFM3fzeyAlume+/Qb 3qY9zwcpwumvUkh7P/xjFfFTKxG61LTZY5W9PqrRyjL43UWwMR5xaPVIVWgw1XSdCHVseCP9N uPZsVHmasTkWuhK5O6LBMrhS7zt+fWeTrS2T0120+VWy4V+XCp3XcUJKW2iYpHD+PhGan+/XT lrwsId8S3r1os/7FXyVadPPEwUNZd84Nyu5FrlAnIac3FfnxYW079lwnukGy+f5D5Cst2WAMj c7U8osSRQicNDIipqttB425RpL1vlZaTFmjzyzbHiy8YyJPUGxnOeyrK9WGI3qgH5wzS0cXSI 5u1PAe5t8YYCxq63br0/rQWQNuUxIArbQOCuJ90WWrH2VyFNiXfOqhzu7ZA4DMbLQf6wYT5h/ 2+2Mqufor5QYWgK1HdVEoijSH4JAJ1SiMAje2QuGvzPM3yfZuRCJA2si8H8H1BKk4Sw8Pg1gK 0zu8dTqSXukRCHZHyPve1NmEt3vsbeudcItVlQAd+Ng/g2D7Pe5OQaiGAus0IN2blSinexT1B UosIE3vHj9smwSTmdddcoc9dxZcXk5YG33FG3K5aCCKDTg4OxgOrRPeaJDj7H8btHnqEQx1ZJ 2OZld3FQRxQ0Dn/Fik4PeOwhEeXk/5hfNpeaVAfBWIIJB5+8kjZOGqOAoY3eR3UT+ZfkGBxhe mgGnn9O/8ADQVHnDU554BeJt9xGViMZKrX5V7dqsbJWOPhYNq0f51PY1tL5mm+xP/JrM4j+2v OGMH6ewJYWGHK7MVWiSjWUIuEVBgVSp7SM210Nvg+fk48beo2CxeF0gIW/zr1twF7NZ5GTnSg s2n5J79TaYbQ6iVwDcvvd31DVrkxprDHCu+7hBf+vKnoe29dIATWuQS8P7+RAYhjTl8Z1ZTXT VYr4va0mryWFHlB3h0QH768kzGfoz+5x+pLoEyV9f4Lp4fjBKObd82GY9a10N3XYpxStpP3WP Iy8Y/LflPeOlQUT0bK1R2S3EebCI/yMgpOXyKTQezudyYksraOLgR58Kbr5A/EpVYhMLCXU7x hmYs25RtLRUpGsDK6QJw1jTzydJCfUpytEnQAl3RjAmSV0KJhKviFbx7Mi3FkPFyEExq8cdQN WM+HCjCZ536p/pYSviAoQrDhrP+gJs2rwe+ZujSFUMPNCymwFOjmVbpcRgkI77cu9wpuBYLbu 3873qv76YIHiQbLSLjnrXpk70tDcnRI1SgQ66QMwM4Pwcl7/1Baieuu2PrJKQWDo= Content-Type: text/plain; charset="utf-8" Add some test for /proc/net/pktgen/... interface. Signed-off-by: Peter Seiderer --- tools/testing/selftests/net/Makefile | 1 + tools/testing/selftests/net/proc_net_pktgen.c | 575 ++++++++++++++++++ 2 files changed, 576 insertions(+) create mode 100644 tools/testing/selftests/net/proc_net_pktgen.c diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 73ee88d6b043..095708cd8345 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -100,6 +100,7 @@ TEST_PROGS +=3D vlan_bridge_binding.sh TEST_PROGS +=3D bpf_offload.py TEST_PROGS +=3D ipv6_route_update_soft_lockup.sh TEST_PROGS +=3D busy_poll_test.sh +TEST_GEN_PROGS +=3D proc_net_pktgen =20 # YNL files, must be before "include ..lib.mk" YNL_GEN_FILES :=3D busy_poller netlink-dumps diff --git a/tools/testing/selftests/net/proc_net_pktgen.c b/tools/testing/= selftests/net/proc_net_pktgen.c new file mode 100644 index 000000000000..1d01fa2a96e9 --- /dev/null +++ b/tools/testing/selftests/net/proc_net_pktgen.c @@ -0,0 +1,575 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * proc_net_pktgen: kselftest for /proc/net/pktgen interface + * + * Copyright (c) 2025 Peter Seiderer + * + */ +#include +#include +#include + +#include "../kselftest_harness.h" + +static const char add_loopback_0[] =3D "add_device lo@0"; +static const char rm_loopback_0[] =3D "rem_device_all"; + +static const char wrong_ctrl_command[] =3D "forsureawrongcommand"; +static const char legacy_ctrl_command[] =3D "max_before_softirq"; + +static const char wrong_device_command[] =3D "forsurewrongcommand"; +static const char device_command_min_pkt_size_0[] =3D "min_pkt_size"; +static const char device_command_min_pkt_size_1[] =3D "min_pkt_size "; +static const char device_command_min_pkt_size_2[] =3D "min_pkt_size 0"; +static const char device_command_min_pkt_size_3[] =3D "min_pkt_size 1"; +static const char device_command_min_pkt_size_4[] =3D "min_pkt_size 100"; +static const char device_command_min_pkt_size_5[] =3D "min_pkt_size=3D1001= "; +static const char device_command_min_pkt_size_6[] =3D "min_pkt_size =3D200= 2"; +static const char device_command_min_pkt_size_7[] =3D "min_pkt_size=3D 300= 3"; +static const char device_command_min_pkt_size_8[] =3D "min_pkt_size =3D 40= 04"; +static const char device_command_max_pkt_size_0[] =3D "max_pkt_size 200"; +static const char device_command_pkt_size_0[] =3D "pkt_size 300"; +static const char device_command_imix_weights_0[] =3D "imix_weights 0,7 57= 6,4 1500,1"; +static const char device_command_imix_weights_1[] =3D "imix_weights 101,1 = 102,2 103,3 104,4 105,5 106,6 107,7 108,8 109,9 110,10 111,11 112,12 113,13= 114,14 115,15 116,16 117,17 118,18 119,19 120,20"; +static const char device_command_imix_weights_2[] =3D "imix_weights 100,1 = 102,2 103,3 104,4 105,5 106,6 107,7 108,8 109,9 110,10 111,11 112,12 113,13= 114,14 115,15 116,16 117,17 118,18 119,19 120,20 121,21"; +static const char device_command_debug_0[] =3D "debug 1"; +static const char device_command_debug_1[] =3D "debug 0"; +static const char device_command_frags_0[] =3D "frags 100"; +static const char device_command_delay_0[] =3D "delay 100"; +static const char device_command_delay_1[] =3D "delay 2147483647"; +static const char device_command_rate_0[] =3D "rate 100"; +static const char device_command_ratep_0[] =3D "ratep 200"; +static const char device_command_udp_src_min_0[] =3D "udp_src_min 1"; +static const char device_command_udp_dst_min_0[] =3D "udp_dst_min 2"; +static const char device_command_udp_src_max_0[] =3D "udp_src_max 3"; +static const char device_command_udp_dst_max_0[] =3D "udp_dst_max 4"; +static const char device_command_clone_skb_0[] =3D "clone_skb 1"; +static const char device_command_clone_skb_1[] =3D "clone_skb 0"; +static const char device_command_count_0[] =3D "count 100"; +static const char device_command_src_mac_count_0[] =3D "src_mac_count 100"; +static const char device_command_dst_mac_count_0[] =3D "dst_mac_count 100"; +static const char device_command_burst_0[] =3D "burst 0"; +static const char device_command_node_0[] =3D "node 100"; +static const char device_command_xmit_mode_0[] =3D "xmit_mode start_xmit"; +static const char device_command_xmit_mode_1[] =3D "xmit_mode netif_receiv= e"; +static const char device_command_xmit_mode_2[] =3D "xmit_mode queue_xmit"; +static const char device_command_xmit_mode_3[] =3D "xmit_mode nonsense"; +static const char device_command_flag_0[] =3D "flag UDPCSUM"; +static const char device_command_flag_1[] =3D "flag !UDPCSUM"; +static const char device_command_flag_2[] =3D "flag nonsense"; +static const char device_command_dst_min_0[] =3D "dst_min 101.102.103.104"; +static const char device_command_dst_0[] =3D "dst 101.102.103.104"; +static const char device_command_dst_max_0[] =3D "dst_max 201.202.203.204"; +static const char device_command_dst6_0[] =3D "dst6 2001:db38:1234:0000:00= 00:0000:0000:0000"; +static const char device_command_dst6_min_0[] =3D "dst6_min 2001:db8:1234:= 0000:0000:0000:0000:0000"; +static const char device_command_dst6_max_0[] =3D "dst6_max 2001:db8:1234:= 0000:0000:0000:0000:0000"; +static const char device_command_src6_0[] =3D "src6 2001:db38:1234:0000:00= 00:0000:0000:0000"; +static const char device_command_src_min_0[] =3D "src_min 101.102.103.104"; +static const char device_command_src_max_0[] =3D "src_max 201.202.203.204"; +static const char device_command_dst_mac_0[] =3D "dst_mac 01:02:03:04:05:0= 6"; +static const char device_command_src_mac_0[] =3D "src_mac 11:12:13:14:15:1= 6"; +static const char device_command_clear_counters_0[] =3D "clear_counters"; +static const char device_command_flows_0[] =3D "flows 100"; +#if 0 // needs CONFIG_XFRM +static const char device_command_spi_0[] =3D "spi 100"; +#endif +static const char device_command_flowlen_0[] =3D "flowlen 100"; +static const char device_command_queue_map_min_0[] =3D "queue_map_min 1"; +static const char device_command_queue_map_max_0[] =3D "queue_map_max 2"; +static const char device_command_mpls_0[] =3D "mpls 00000001,000000f2,0000= 0ff3,0000fff4,000ffff5,00fffff6,0ffffff7,fffffff8"; +static const char device_command_vlan_id_0[] =3D "vlan_id 1"; +static const char device_command_vlan_p_0[] =3D "vlan_p 1"; +static const char device_command_vlan_cfi_0[] =3D "vlan_cfi 1"; +static const char device_command_vlan_id_1[] =3D "vlan_id 4096"; +static const char device_command_svlan_id_0[] =3D "svlan_id 1"; +static const char device_command_svlan_p_0[] =3D "svlan_p 1"; +static const char device_command_svlan_cfi_0[] =3D "svlan_cfi 1"; +static const char device_command_svlan_id_1[] =3D "svlan_id 4096"; +static const char device_command_tos_0[] =3D "tos 0"; +static const char device_command_tos_1[] =3D "tos 0f"; +static const char device_command_tos_2[] =3D "tos 0ff"; +static const char device_command_traffic_class_0[] =3D "traffic_class f0"; +static const char device_command_skb_priority_0[] =3D "skb_priority 999"; + +FIXTURE(proc_net_pktgen) { + int ctrl_fd; + int device_fd; +}; + +FIXTURE_SETUP(proc_net_pktgen) { + ssize_t len; + + self->ctrl_fd =3D open("/proc/net/pktgen/kpktgend_0", O_RDWR); + ASSERT_GE(self->ctrl_fd, 0) TH_LOG("CONFIG_NET_PKTGEN not enabled, module= pktgen nod loaded?"); + + len =3D write(self->ctrl_fd, add_loopback_0, sizeof(add_loopback_0)); + ASSERT_EQ(len, sizeof(add_loopback_0)) TH_LOG("device lo@0 already regist= ered?"); + + self->device_fd =3D open("/proc/net/pktgen/lo@0", O_RDWR); + ASSERT_GE(self->device_fd, 0) TH_LOG("device entry for lo@0 missing?"); +} + +FIXTURE_TEARDOWN(proc_net_pktgen) { + int ret; + ssize_t len; + + ret =3D close(self->device_fd); + EXPECT_EQ(ret, 0); + + len =3D write(self->ctrl_fd, rm_loopback_0, sizeof(rm_loopback_0)); + EXPECT_EQ(len, sizeof(rm_loopback_0)); + + ret =3D close(self->ctrl_fd); + EXPECT_EQ(ret, 0); +} + +TEST_F(proc_net_pktgen, wrong_ctrl_command) { + for (int i =3D 0; i <=3D sizeof(wrong_ctrl_command); i++) { + ssize_t len =3D write(self->ctrl_fd, wrong_ctrl_command, i); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + } +} + +TEST_F(proc_net_pktgen, legacy_ctrl_command) { + for (int i =3D 0; i <=3D sizeof(legacy_ctrl_command); i++) { + ssize_t len =3D write(self->ctrl_fd, legacy_ctrl_command, i); + if (i < (sizeof(legacy_ctrl_command) - 1)) { + // incomplete command string + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + } else { + // complete command string without/with trailing '\0' + EXPECT_EQ(len, i); + } + } +} + +TEST_F(proc_net_pktgen, wrong_device_command) { + for (int i =3D 0; i <=3D sizeof(wrong_device_command); i++) { + ssize_t len =3D write(self->device_fd, wrong_device_command, i); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + } +} + +TEST_F(proc_net_pktgen, device_command_min_pkt_size) { + ssize_t len; + + // with trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_0, sizeof(devi= ce_command_min_pkt_size_0)); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + + // without trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_0, sizeof(devi= ce_command_min_pkt_size_0) - 1); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + + // with trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_1, sizeof(devi= ce_command_min_pkt_size_1)); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + + // without trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_1, sizeof(devi= ce_command_min_pkt_size_1) - 1); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EINVAL); + + // with trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_2, sizeof(devi= ce_command_min_pkt_size_2)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_2)); + + // without trailing '\0' + len =3D write(self->device_fd, device_command_min_pkt_size_2, sizeof(devi= ce_command_min_pkt_size_2) - 1); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_2) - 1); + + len =3D write(self->device_fd, device_command_min_pkt_size_3, sizeof(devi= ce_command_min_pkt_size_3)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_3)); + + len =3D write(self->device_fd, device_command_min_pkt_size_4, sizeof(devi= ce_command_min_pkt_size_4)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_4)); + + len =3D write(self->device_fd, device_command_min_pkt_size_5, sizeof(devi= ce_command_min_pkt_size_5)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_5)); + + len =3D write(self->device_fd, device_command_min_pkt_size_6, sizeof(devi= ce_command_min_pkt_size_6)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_6)); + + len =3D write(self->device_fd, device_command_min_pkt_size_7, sizeof(devi= ce_command_min_pkt_size_7)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_7)); + + len =3D write(self->device_fd, device_command_min_pkt_size_8, sizeof(devi= ce_command_min_pkt_size_8)); + EXPECT_EQ(len, sizeof(device_command_min_pkt_size_8)); +} + +TEST_F(proc_net_pktgen, device_command_max_pkt_size) { + ssize_t len; + + len =3D write(self->device_fd, device_command_max_pkt_size_0, sizeof(devi= ce_command_max_pkt_size_0)); + EXPECT_EQ(len, sizeof(device_command_max_pkt_size_0)); +} + +TEST_F(proc_net_pktgen, device_command_pkt_size) { + ssize_t len; + + len =3D write(self->device_fd, device_command_pkt_size_0, sizeof(device_c= ommand_pkt_size_0)); + EXPECT_EQ(len, sizeof(device_command_pkt_size_0)); +} + +TEST_F(proc_net_pktgen, device_command_imix_weights) { + ssize_t len; + + len =3D write(self->device_fd, device_command_imix_weights_0, sizeof(devi= ce_command_imix_weights_0)); + EXPECT_EQ(len, sizeof(device_command_imix_weights_0)); + + len =3D write(self->device_fd, device_command_imix_weights_1, sizeof(devi= ce_command_imix_weights_1)); + EXPECT_EQ(len, sizeof(device_command_imix_weights_1)); + + len =3D write(self->device_fd, device_command_imix_weights_2, sizeof(devi= ce_command_imix_weights_2)); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, E2BIG); +} + +TEST_F(proc_net_pktgen, device_command_debug) { + ssize_t len; + + // debug on + len =3D write(self->device_fd, device_command_debug_0, sizeof(device_comm= and_debug_0)); + EXPECT_EQ(len, sizeof(device_command_debug_0)); + + // debug off + len =3D write(self->device_fd, device_command_debug_1, sizeof(device_comm= and_debug_1)); + EXPECT_EQ(len, sizeof(device_command_debug_1)); +} + +TEST_F(proc_net_pktgen, device_command_frags) { + ssize_t len; + + len =3D write(self->device_fd, device_command_frags_0, sizeof(device_comm= and_frags_0)); + EXPECT_EQ(len, sizeof(device_command_frags_0)); +} + +TEST_F(proc_net_pktgen, device_command_delay) { + ssize_t len; + + len =3D write(self->device_fd, device_command_delay_0, sizeof(device_comm= and_delay_0)); + EXPECT_EQ(len, sizeof(device_command_delay_0)); + + len =3D write(self->device_fd, device_command_delay_1, sizeof(device_comm= and_delay_1)); + EXPECT_EQ(len, sizeof(device_command_delay_1)); +} + +TEST_F(proc_net_pktgen, device_command_rate) { + ssize_t len; + + len =3D write(self->device_fd, device_command_rate_0, sizeof(device_comma= nd_rate_0)); + EXPECT_EQ(len, sizeof(device_command_rate_0)); +} + +TEST_F(proc_net_pktgen, device_command_ratep) { + ssize_t len; + + len =3D write(self->device_fd, device_command_ratep_0, sizeof(device_comm= and_ratep_0)); + EXPECT_EQ(len, sizeof(device_command_ratep_0)); +} + +TEST_F(proc_net_pktgen, device_command_udp_src_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_udp_src_min_0, sizeof(devic= e_command_udp_src_min_0)); + EXPECT_EQ(len, sizeof(device_command_udp_src_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_udp_dst_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_udp_dst_min_0, sizeof(devic= e_command_udp_dst_min_0)); + EXPECT_EQ(len, sizeof(device_command_udp_dst_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_udp_src_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_udp_src_max_0, sizeof(devic= e_command_udp_src_max_0)); + EXPECT_EQ(len, sizeof(device_command_udp_src_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_udp_dst_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_udp_dst_max_0, sizeof(devic= e_command_udp_dst_max_0)); + EXPECT_EQ(len, sizeof(device_command_udp_dst_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_clone_skb) { + ssize_t len; + + // clone_skb on (gives EOPNOTSUPP on lo device) + len =3D write(self->device_fd, device_command_clone_skb_0, sizeof(device_= command_clone_skb_0)); + EXPECT_EQ(len, -1); + EXPECT_EQ(errno, EOPNOTSUPP); + + // clone_skb off + len =3D write(self->device_fd, device_command_clone_skb_1, sizeof(device_= command_clone_skb_1)); + EXPECT_EQ(len, sizeof(device_command_clone_skb_1)); +} + +TEST_F(proc_net_pktgen, device_command_count) { + ssize_t len; + + len =3D write(self->device_fd, device_command_count_0, sizeof(device_comm= and_count_0)); + EXPECT_EQ(len, sizeof(device_command_count_0)); +} + +TEST_F(proc_net_pktgen, device_command_src_mac_count) { + ssize_t len; + + len =3D write(self->device_fd, device_command_src_mac_count_0, sizeof(dev= ice_command_src_mac_count_0)); + EXPECT_EQ(len, sizeof(device_command_src_mac_count_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst_mac_count) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst_mac_count_0, sizeof(dev= ice_command_dst_mac_count_0)); + EXPECT_EQ(len, sizeof(device_command_dst_mac_count_0)); +} + +TEST_F(proc_net_pktgen, device_command_burst) { + ssize_t len; + + // burst off + len =3D write(self->device_fd, device_command_burst_0, sizeof(device_comm= and_burst_0)); + EXPECT_EQ(len, sizeof(device_command_burst_0)); +} + +TEST_F(proc_net_pktgen, device_command_node) { + ssize_t len; + + len =3D write(self->device_fd, device_command_node_0, sizeof(device_comma= nd_node_0)); + EXPECT_EQ(len, sizeof(device_command_node_0)); +} + +TEST_F(proc_net_pktgen, device_command_xmit_mode) { + ssize_t len; + + len =3D write(self->device_fd, device_command_xmit_mode_0, sizeof(device_= command_xmit_mode_0)); + EXPECT_EQ(len, sizeof(device_command_xmit_mode_0)); + + len =3D write(self->device_fd, device_command_xmit_mode_1, sizeof(device_= command_xmit_mode_1)); + EXPECT_EQ(len, sizeof(device_command_xmit_mode_1)); + + len =3D write(self->device_fd, device_command_xmit_mode_2, sizeof(device_= command_xmit_mode_2)); + EXPECT_EQ(len, sizeof(device_command_xmit_mode_2)); + + len =3D write(self->device_fd, device_command_xmit_mode_3, sizeof(device_= command_xmit_mode_3)); + EXPECT_EQ(len, sizeof(device_command_xmit_mode_3)); +} + +TEST_F(proc_net_pktgen, device_command_flag) { + ssize_t len; + + // flag UDPCSUM on + len =3D write(self->device_fd, device_command_flag_0, sizeof(device_comma= nd_flag_0)); + EXPECT_EQ(len, sizeof(device_command_flag_0)); + + // flag UDPCSUM off + len =3D write(self->device_fd, device_command_flag_1, sizeof(device_comma= nd_flag_1)); + EXPECT_EQ(len, sizeof(device_command_flag_1)); + + // flag invalid + len =3D write(self->device_fd, device_command_flag_2, sizeof(device_comma= nd_flag_2)); + EXPECT_EQ(len, sizeof(device_command_flag_2)); +} + +TEST_F(proc_net_pktgen, device_command_dst_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst_min_0, sizeof(device_co= mmand_dst_min_0)); + EXPECT_EQ(len, sizeof(device_command_dst_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst_0, sizeof(device_comman= d_dst_0)); + EXPECT_EQ(len, sizeof(device_command_dst_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst_max_0, sizeof(device_co= mmand_dst_max_0)); + EXPECT_EQ(len, sizeof(device_command_dst_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst6) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst6_0, sizeof(device_comma= nd_dst6_0)); + EXPECT_EQ(len, sizeof(device_command_dst6_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst6_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst6_min_0, sizeof(device_c= ommand_dst6_min_0)); + EXPECT_EQ(len, sizeof(device_command_dst6_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst6_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst6_max_0, sizeof(device_c= ommand_dst6_max_0)); + EXPECT_EQ(len, sizeof(device_command_dst6_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_src6) { + ssize_t len; + + len =3D write(self->device_fd, device_command_src6_0, sizeof(device_comma= nd_src6_0)); + EXPECT_EQ(len, sizeof(device_command_src6_0)); +} + +TEST_F(proc_net_pktgen, device_command_src_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_src_min_0, sizeof(device_co= mmand_src_min_0)); + EXPECT_EQ(len, sizeof(device_command_src_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_src_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_src_max_0, sizeof(device_co= mmand_src_max_0)); + EXPECT_EQ(len, sizeof(device_command_src_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_dst_mac) { + ssize_t len; + + len =3D write(self->device_fd, device_command_dst_mac_0, sizeof(device_co= mmand_dst_mac_0)); + EXPECT_EQ(len, sizeof(device_command_dst_mac_0)); +} + +TEST_F(proc_net_pktgen, device_command_src_mac) { + ssize_t len; + + len =3D write(self->device_fd, device_command_src_mac_0, sizeof(device_co= mmand_src_mac_0)); + EXPECT_EQ(len, sizeof(device_command_src_mac_0)); +} + +TEST_F(proc_net_pktgen, device_command_clear_counters) { + ssize_t len; + + len =3D write(self->device_fd, device_command_clear_counters_0, sizeof(de= vice_command_clear_counters_0)); + EXPECT_EQ(len, sizeof(device_command_clear_counters_0)); +} + +TEST_F(proc_net_pktgen, device_command_flows) { + ssize_t len; + + len =3D write(self->device_fd, device_command_flows_0, sizeof(device_comm= and_flows_0)); + EXPECT_EQ(len, sizeof(device_command_flows_0)); +} + +#if 0 // needs CONFIG_XFRM +TEST_F(proc_net_pktgen, device_command_spi) { + ssize_t len; + + len =3D write(self->device_fd, device_command_spi_0, sizeof(device_comman= d_spi_0)); + EXPECT_EQ(len, sizeof(device_command_spi_0)); +} +#endif + +TEST_F(proc_net_pktgen, device_command_flowlen) { + ssize_t len; + + len =3D write(self->device_fd, device_command_flowlen_0, sizeof(device_co= mmand_flowlen_0)); + EXPECT_EQ(len, sizeof(device_command_flowlen_0)); +} + +TEST_F(proc_net_pktgen, device_command_queue_map_min) { + ssize_t len; + + len =3D write(self->device_fd, device_command_queue_map_min_0, sizeof(dev= ice_command_queue_map_min_0)); + EXPECT_EQ(len, sizeof(device_command_queue_map_min_0)); +} + +TEST_F(proc_net_pktgen, device_command_queue_map_max) { + ssize_t len; + + len =3D write(self->device_fd, device_command_queue_map_max_0, sizeof(dev= ice_command_queue_map_max_0)); + EXPECT_EQ(len, sizeof(device_command_queue_map_max_0)); +} + +TEST_F(proc_net_pktgen, device_command_mpls) { + ssize_t len; + + len =3D write(self->device_fd, device_command_mpls_0, sizeof(device_comma= nd_mpls_0)); + EXPECT_EQ(len, sizeof(device_command_mpls_0)); +} + +TEST_F(proc_net_pktgen, device_command_vlan_id) { + ssize_t len; + + len =3D write(self->device_fd, device_command_vlan_id_0, sizeof(device_co= mmand_vlan_id_0)); + EXPECT_EQ(len, sizeof(device_command_vlan_id_0)); + + len =3D write(self->device_fd, device_command_vlan_p_0, sizeof(device_com= mand_vlan_p_0)); + EXPECT_EQ(len, sizeof(device_command_vlan_p_0)); + + len =3D write(self->device_fd, device_command_vlan_cfi_0, sizeof(device_c= ommand_vlan_cfi_0)); + EXPECT_EQ(len, sizeof(device_command_vlan_cfi_0)); + + len =3D write(self->device_fd, device_command_vlan_id_1, sizeof(device_co= mmand_vlan_id_1)); + EXPECT_EQ(len, sizeof(device_command_vlan_id_1)); +} + +TEST_F(proc_net_pktgen, device_command_svlan_id) { + ssize_t len; + + len =3D write(self->device_fd, device_command_svlan_id_0, sizeof(device_c= ommand_svlan_id_0)); + EXPECT_EQ(len, sizeof(device_command_svlan_id_0)); + + len =3D write(self->device_fd, device_command_svlan_p_0, sizeof(device_co= mmand_svlan_p_0)); + EXPECT_EQ(len, sizeof(device_command_svlan_p_0)); + + len =3D write(self->device_fd, device_command_svlan_cfi_0, sizeof(device_= command_svlan_cfi_0)); + EXPECT_EQ(len, sizeof(device_command_svlan_cfi_0)); + + len =3D write(self->device_fd, device_command_svlan_id_1, sizeof(device_c= ommand_svlan_id_1)); + EXPECT_EQ(len, sizeof(device_command_svlan_id_1)); +} + + +TEST_F(proc_net_pktgen, device_command_tos) { + ssize_t len; + + len =3D write(self->device_fd, device_command_tos_0, sizeof(device_comman= d_tos_0)); + EXPECT_EQ(len, sizeof(device_command_tos_0)); + + len =3D write(self->device_fd, device_command_tos_1, sizeof(device_comman= d_tos_1)); + EXPECT_EQ(len, sizeof(device_command_tos_1)); + + len =3D write(self->device_fd, device_command_tos_2, sizeof(device_comman= d_tos_2)); + EXPECT_EQ(len, sizeof(device_command_tos_2)); +} + + +TEST_F(proc_net_pktgen, device_command_traffic_class) { + ssize_t len; + + len =3D write(self->device_fd, device_command_traffic_class_0, sizeof(dev= ice_command_traffic_class_0)); + EXPECT_EQ(len, sizeof(device_command_traffic_class_0)); +} + +TEST_F(proc_net_pktgen, device_command_skb_priority) { + ssize_t len; + + len =3D write(self->device_fd, device_command_skb_priority_0, sizeof(devi= ce_command_skb_priority_0)); + EXPECT_EQ(len, sizeof(device_command_skb_priority_0)); +} + +TEST_HARNESS_MAIN --=20 2.48.0