From nobody Wed Sep 30 13:54:56 2026 Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F3E345C6F7 for ; Fri, 7 Aug 2026 22:10:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140602; cv=none; b=P8CS4lp+pCUy+pJp9ZQeBkm+tXx7Lh07OJmi9xZAa5KrJKiQ4TINoUS6DE7PIPSvPdiPuizi4OLE1eXHVxtEFG3aQBecp1Eh99b4tMoWqgKibIV52RU9jgN27EsSqSTtHh5jBUbg7Y0Y3o4T+1Jg0c62+sL+GwgFEeRaGdvGZS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140602; c=relaxed/simple; bh=V5PT+zcfv5kwBc3zsPLyOemrZEyr7x51j1JNaZhSLI8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iEjXzJInQbh3vp8B7tQSI5V6mR70ZSDaPPYTQlTgYbY1lPV9TOSmyQEv6/enZHTGILK6j4puAbEwPmA+pZ+DtrRDorpT47XapKOmcxidwalF11SXQWD7zOZLqlJp4UE1Jme4HxQaawM0fcksNfCoJ1Kumgpan/fP45DRxdLnnNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=VXAqTPzL; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VXAqTPzL" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-2caed617615so858935ad.3 for ; Fri, 07 Aug 2026 15:10:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786140600; x=1786745400; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kZPO0FvOtEF8M9IFK2RY794kxXwOWSbOPIOTROMX56g=; b=VXAqTPzLDm4AnEFgYVxXKRuKSfYMxynzNJh5wMFTiE6JGFb9gYBebrPBoVsQRmnBtN Ls1LF0g2MSeM29/x3uSw7OVmtXcYvNxtBJ4wpNPYvjBJC7Ze5NJk5bmI0tpN4iHln2yM zPKSz7vnlSvd5gV05lKcQ1UoPsZuvGM2TfKLFRDk8wsuXR6oSMJYS/tQKYfqZG+IHzMX rBFx0+g2FovHppZS7RPTQ6Ewp60TxQ8B4zC119e5s/KNnS9loU/nxYHg/GxXfVgXVH12 7+I35LPx3u7NthrcwR/Tg1lcubbL/mHmpsD5weCBXNV6Zo4vqiPLEagv4eOvcocrvOTO QzBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786140600; x=1786745400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kZPO0FvOtEF8M9IFK2RY794kxXwOWSbOPIOTROMX56g=; b=sQl4m67or7DMmyNJfoEtkohRtBhgRvHZ6GI104Nc4x991pBEKgCob4CT/s8yN64HEm 5b0xYm7OMmSPeVbNAS877Mr+DO+ECy2lQIc0W2YHVjb3nSam18D/cA0iBjDF9PSwkGYo mpjkWv/YCXCNyLRVlm37ozyIZCjK0kD2wfyHOQ7gGL7NxLkkYxcKbTp2nYezuw+S3rov buhopmyeMy/Kn7aAzpavEdmsAXTNgzjSOHST9Xm0k/L6LDWRCh0mBiU/l3tdwXkC5pd7 /sLYZGmATD1cYUrWkMezl3FT5QApSu1UjapIWlrj5dMqH3s1ILHYfIRpzo1/j+jPdZVI +RRQ== X-Forwarded-Encrypted: i=1; AHgh+RpGp0ufWusXX/KWE7ee9S81M+tizO6fKQtj3Fds/T2ideHWW6A3M3AxPJKJXYgBZG7kHcB4aR6Mlszql8A=@vger.kernel.org X-Gm-Message-State: AOJu0Yz+er1ViPMkQpHuKoEFPVSR4bQyo05uBRzEIER8UY5c9QFgpVBs QmQ3c4YI0bHI8KC+o39jWPRZZ2PRe6FtIJRXMcoYm5+vQtKZdK9y/eG6 X-Gm-Gg: AR+sD12YceuKmZNNt6PRLlpJfYNsTf2bj7DdPJEJUyvmHNxMoosZc4UxyOn6yVSBte1 CGwHKce9YQscnpGIp562uMNr2l7gyf0yazOPIlZHoS58sBk8tYvE5uQyR47mP8gQXztfDGhxPSC I43WYkStUTKznM4C/+jBKQ4bNJ3HA0e58zrWzkqTFsRNYbPwPzlEbEKeWxtBYhRwWv0mCVIsu/y 00Y2BOpgfpT1vChPIgeUVAoSptB3oZ5tgiGEbqnjCi56n8JoijjXiCzUwBgBNTi26dQ6d4c5wha Wb2JeGDiuluR/BiZyfbctE7V2R8pxV/6DlIwyg7EkKlAtCggF8+acMLTZ9CJqavLQ0VaAQh/Wkw KEBZy9gaL6ri8YNL6k1ywz+DWNrOdYA4WAwrtOpXTCte6dnJ/+EcylnAQbwSbX9SaReEkrLaq/j z6G3+ynTh2QTix7kZcXQHVYIOgvFxkUSwe4oni7XLtktvDiU0WvA9sfUWBIv80bavUjw== X-Received: by 2002:a05:6a21:3390:b0:3c3:93ce:663 with SMTP id adf61e73a8af0-3cb85f4a26emr28784462637.26.1786140599730; Fri, 07 Aug 2026 15:09:59 -0700 (PDT) Received: from fedora ([2804:1b3:a8c3:8ee5:1c39:64d9:e257:73dc]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315be568bd3sm11182762eec.0.2026.08.07.15.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 15:09:59 -0700 (PDT) From: Marcelo Mendes Spessoto Junior To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Marcelo Mendes Spessoto Junior Subject: [PATCH net-next v3 1/5] selftests: net: test IPV6_FL_A_RENEW Date: Fri, 7 Aug 2026 19:09:38 -0300 Message-ID: <20260807220942.421382-2-marcelomspessoto@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807220942.421382-1-marcelomspessoto@gmail.com> References: <20260807220942.421382-1-marcelomspessoto@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RENEW was the only flow label action without selftests coverage. Assert renew returns no error on correct usage and fails for labels that do not exist. This test is based on the previously implemented EXCL share test, which demonstrates that a new flow label with the same value can be created after the linger period. Renew is used here to show that a flow label can last longer and block a new flow label creation after the previous linger time. This test, however, demands sleep during execution, and should be placed as a conditional test under the -l option. The addition of the expect_fail_errno helper is necessary to assert the corresponding error when a function can fail in multiple ways. Signed-off-by: Marcelo Mendes Spessoto Junior --- .../selftests/net/ipv6_flowlabel_mgr.c | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testi= ng/selftests/net/ipv6_flowlabel_mgr.c index af95b48acea9..ec187890a1ed 100644 --- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c +++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c @@ -42,6 +42,23 @@ #define expect_pass(x) __expect(x) #define expect_fail(x) __expect(!(x)) =20 +#define expect_fail_errno(x, e) \ + do { \ + int __exp =3D (e); \ + int __ret =3D (x); \ + int __err =3D errno; \ + if (__ret && __err =3D=3D __exp) \ + fprintf(stderr, "[OK] " #x "\n"); \ + else if (!__ret) \ + error(1, 0, "[ERR] " #x \ + " (line %d): unexpectedly succeeded", \ + __LINE__); \ + else \ + error(1, 0, "[ERR] " #x \ + " (line %d): expected errno %d, got %d", \ + __LINE__, __exp, __err); \ + } while (0) + static bool cfg_long_running; static bool cfg_verbose; =20 @@ -71,6 +88,19 @@ static int flowlabel_put(int fd, uint32_t label) return setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req)); } =20 +static int flowlabel_renew(int fd, uint32_t label, uint8_t share, + uint16_t linger) +{ + struct in6_flowlabel_req req =3D { + .flr_action =3D IPV6_FL_A_RENEW, + .flr_label =3D htonl(label), + .flr_share =3D share, + .flr_linger =3D linger, + }; + + return setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req)); +} + static void run_tests(int fd) { int wstatus; @@ -94,7 +124,7 @@ static void run_tests(int fd) expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE)); explain("cannot get it again with the exclusive (FL_FL_EXCL) flag"); expect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE | IPV6_FL_F_EXCL)); + IPV6_FL_F_CREATE | IPV6_FL_F_EXCL)); explain("can now put exactly three references"); expect_pass(flowlabel_put(fd, 1)); expect_pass(flowlabel_put(fd, 1)); @@ -160,6 +190,32 @@ static void run_tests(int fd) error(1, errno, "wait"); if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) !=3D 0) error(1, errno, "wait: unexpected child result"); + + explain("It is not possible to renew a label that does not exist"); + expect_fail_errno(flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1)), + ESRCH); + + explain("Create a label for basic renew validation"); + expect_pass(flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE)); + explain("renew does not error for an existing, valid label"); + expect_pass(flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1))); + + if (cfg_long_running) { + explain("create a new label with FL_MIN_LINGER linger time"); + expect_pass(flowlabel_get(fd, 6, IPV6_FL_S_EXCL, + IPV6_FL_F_CREATE)); + explain("renew the label to extend linger, then put it"); + expect_pass(flowlabel_renew(fd, 6, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1))); + expect_pass(flowlabel_put(fd, 6)); + sleep(FL_MIN_LINGER * 2 + 1); + explain("cannot create: new linger time not over yet"); + expect_fail_errno(flowlabel_get(fd, 6, IPV6_FL_S_ANY, + IPV6_FL_F_CREATE), + EPERM); + } } =20 static void parse_opts(int argc, char **argv) --=20 2.55.0 From nobody Wed Sep 30 13:54:56 2026 Received: from mail-pg1-f172.google.com (mail-pg1-f172.google.com [209.85.215.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E61B6459AF9 for ; Fri, 7 Aug 2026 22:10:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140605; cv=none; b=iAch49WgJ/0I2lwpoC0m4sy64jxCB5hEeoHqHVGka5tfX/EGgrPs/dUUKZllILZJI/8vQsE2V6RhYWi/EDfMzxNtThQAZ+kjgt2EqlZi3PZFJZzFvFPKDCmmGKlbiYAR6RFQ8urQlj0qoglq5fNamILaLL3/D0gWHLP+lh+uQzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140605; c=relaxed/simple; bh=HgtG2lJaDXD2Ez34y3RSHzeEVJH+VzPy71sbxtDt4GE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Fcwh7RyoG0okqbzcb4efUfw7OT1CQYAeXgnHx9eXnWTsTlfTUR1SfHlWYEGbxJj4LDzO7uNiAko7FSzO5oamDulr96+AH+5VWwNo7DM89iRr1Tijff7xfVAU/FU8qnOTEeegfjzHkVuycO/3H0Szwqugx+D7u6b6yJ3SOKfv6Gw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ETj5mQmy; arc=none smtp.client-ip=209.85.215.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ETj5mQmy" Received: by mail-pg1-f172.google.com with SMTP id 41be03b00d2f7-c99eaa1f020so4057786a12.2 for ; Fri, 07 Aug 2026 15:10:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786140603; x=1786745403; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=XE0UzVUXwsGoJ/wVoGB07+IWtuFU1IC6Kjeaw1YnJIU=; b=ETj5mQmygvBNvtapE4Iq86SAnuTSFr27de/vM2vm9oVbpDg421vXR+t0oQV1CD7ZKq wQmrE4+qPYQ8TQl1/7vteEyYM97SYLndzAyYTs5X5AjvNa2hKc0+LbzpiVx6jnOXWYvo Zd7E4NZsVrRSg6RuTA0t9xf3Bm9qYcEETAhfGuhn2u5f1rRu8VHVtGd8hlIzZMD0MJrG Q1vUrcg9mVBeSrzhdFC1TAlFxBSqI+D7lWRfTqQgYpRksrTMK8YYgV6+aMnbFfUzNmdf UHPVFvsa1L0c0cQ69ydFpkAy7Rc/+rF4QB1oBOHXjQxwwlBzdqVjIJj6BJEDwOpVOGEZ g4BQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786140603; x=1786745403; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=XE0UzVUXwsGoJ/wVoGB07+IWtuFU1IC6Kjeaw1YnJIU=; b=lFZxXkc7TsBf4H4vaT6uHESEK5Tt+zkiOl7StgYB0tkraauxSq9aNGQTGgTtyg4A4T KkUYY1PSr29LkNUMPA4lEK1zvdx5zjJDqMyLvylVdfOlogNgpPlgiNhUC/3MwJ4DTjsX eyi38w0OYXThkCqhUsYLRB1n0ZcsQ8VdXhovmo/vMI3qFrzpDpYzIkWtJ9uRexRCT7OE eu9aeh8Dm7xuCqG/kyHVqZUiOIEvc7dmgTcRZv075Co0mX5FI8fN0wCwdJgio83w2YVq hhHYHT6nRgazs1b6ESf6rnllVrP6n4YBJKW81khFRtV/ru/Pf6xbLbtcKyvCtH7cBDPf etMg== X-Forwarded-Encrypted: i=1; AHgh+RqqBNY7usGpBao/4p5bv/d3x+Lo3QTcnWx7VKGB4hsAg95AIjXesTmWqvupBvlfyPc0m7RjuYWbi3MTrOI=@vger.kernel.org X-Gm-Message-State: AOJu0YzPlIHRGUQFNdED0SgVNdj0xvtic465+QOAs8wabX9qr6Y6CWUS UL+O5bd4ka0ARHO7BqckcBWKeJd2YgPkyohKUKhji0Ue14PW1zJpI/WME65K+ktt X-Gm-Gg: AR+sD13TAaudxeh19T6xB6QMmoyl6YQTpJO4vHGvXIhFvfaBnGFSRsgHU+czHDi+mol 0x5vSwHpxdmFO84j7eUpHb9lOWZcHk9FeceUdS9a0StB+StJ4WgYii1ZPI82M9icSsXp5aiQzIe flmjX4H8Beo1OgBXdPoi5M6vB8RBsGNG0whKNFiChnTy6KQEKBs1FOoVX8Wx6B/vyKUBTPyHO0p i6cFTaSSog2G8N7rO2Gg7iqWtymXXb+CVag9Lc9XCg2QT1lKNjufAsFC9c8zLwviBHhcQnOKv4K 1TRJtjEttJ+y5a7VWbexiEwf1tx+iLe6iJT0+FFLuZlGBqmzKPMXtGElSr3U71tDNPAcljhkz3P hUBEJ2IwphxC2IuhAJiCvct9XW8qZoS98wipkRFg8DQmD+/cRssZzdqheaUGa9BnXn8zBONk8CU vBHnd8d7qdx4CO9C1dE2UCakkaY01Z7p/mwLEPZc65uArrJJ2cVGWWS8oAp8S+D+WSdQ== X-Received: by 2002:a05:6a20:728c:b0:3c0:b4f8:bbfb with SMTP id adf61e73a8af0-3cbc03b5531mr7505750637.22.1786140603049; Fri, 07 Aug 2026 15:10:03 -0700 (PDT) Received: from fedora ([2804:1b3:a8c3:8ee5:1c39:64d9:e257:73dc]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315be568bd3sm11182762eec.0.2026.08.07.15.10.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 15:10:02 -0700 (PDT) From: Marcelo Mendes Spessoto Junior To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Marcelo Mendes Spessoto Junior Subject: [PATCH net-next v3 2/5] selftests: net: test IPV6_FL_F_REMOTE Date: Fri, 7 Aug 2026 19:09:39 -0300 Message-ID: <20260807220942.421382-3-marcelomspessoto@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807220942.421382-1-marcelomspessoto@gmail.com> References: <20260807220942.421382-1-marcelomspessoto@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This flag retrieves the flow label seen by the socket at connection setup via a getsockopt query. Therefore, the validation of this flag requires a brief connection setup (source code for flow label shows it must be TCP). The simple TCP connection logic was wrapped inside two simple helpers, because there are other uncovered features of flow label mgr that could benefit from it (such as IPV6_FL_F_REFLECT). Signed-off-by: Marcelo Mendes Spessoto Junior --- .../selftests/net/ipv6_flowlabel_mgr.c | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testi= ng/selftests/net/ipv6_flowlabel_mgr.c index ec187890a1ed..51541e792257 100644 --- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c +++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c @@ -24,6 +24,9 @@ #ifndef IPV6_FLOWLABEL_MGR #define IPV6_FLOWLABEL_MGR 32 #endif +#ifndef IPV6_FLOWINFO_SEND +#define IPV6_FLOWINFO_SEND 33 +#endif =20 /* from net/ipv6/ip6_flowlabel.c */ #define FL_MIN_LINGER 6 @@ -101,6 +104,67 @@ static int flowlabel_renew(int fd, uint32_t label, uin= t8_t share, return setsockopt(fd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &req, sizeof(req)); } =20 +static struct sockaddr_in6 loopback_addr(void) +{ + struct sockaddr_in6 addr =3D { + .sin6_family =3D AF_INET6, + .sin6_addr =3D IN6ADDR_LOOPBACK_INIT, + .sin6_port =3D htons(8888), + }; + + return addr; +} + +static int tcp_listen(void) +{ + struct sockaddr_in6 addr =3D loopback_addr(); + const int one =3D 1; + int fd; + + fd =3D socket(PF_INET6, SOCK_STREAM, 0); + if (fd =3D=3D -1) + error(1, errno, "socket listener"); + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) + error(1, errno, "setsockopt SO_REUSEADDR"); + if (bind(fd, (void *)&addr, sizeof(addr))) + error(1, errno, "bind"); + if (listen(fd, 1)) + error(1, errno, "listen"); + + return fd; +} + +static void tcp_connect(int listener, uint32_t flowlabel, + int *client, int *accepted) +{ + struct sockaddr_in6 addr =3D loopback_addr(); + const int one =3D 1; + int cfd, afd; + + cfd =3D socket(PF_INET6, SOCK_STREAM, 0); + if (cfd =3D=3D -1) + error(1, errno, "socket client"); + + if (flowlabel_get(cfd, flowlabel, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE)) + error(1, errno, "flowlabel_get"); + if (setsockopt(cfd, SOL_IPV6, IPV6_FLOWINFO_SEND, &one, sizeof(one))) + error(1, errno, "setsockopt flowinfo_send"); + addr.sin6_flowinfo =3D htonl(flowlabel); + + if (connect(cfd, (void *)&addr, sizeof(addr))) + error(1, errno, "connect"); + + afd =3D accept(listener, NULL, NULL); + if (afd =3D=3D -1) + error(1, errno, "accept"); + + if (flowlabel_put(cfd, flowlabel)) + error(1, errno, "flowlabel_put"); + + *client =3D cfd; + *accepted =3D afd; +} + static void run_tests(int fd) { int wstatus; @@ -216,6 +280,30 @@ static void run_tests(int fd) IPV6_FL_F_CREATE), EPERM); } + + { + struct in6_flowlabel_req freq =3D { + .flr_action =3D IPV6_FL_A_GET, + .flr_flags =3D IPV6_FL_F_REMOTE, + }; + int remote_listener =3D tcp_listen(); + socklen_t freq_len =3D sizeof(freq); + int remote_cfd, remote_afd; + + explain("Prepare TCP SYN for REMOTE flag validation"); + tcp_connect(remote_listener, 7, &remote_cfd, &remote_afd); + + explain("Query for label sent by client with IPV6_FL_F_REMOTE"); + expect_pass(getsockopt(remote_afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, + &freq, &freq_len)); + if (ntohl(freq.flr_label) !=3D 7) + error(1, 0, "unexpected remote flowlabel %u", + ntohl(freq.flr_label)); + + close(remote_afd); + close(remote_cfd); + close(remote_listener); + } } =20 static void parse_opts(int argc, char **argv) --=20 2.55.0 From nobody Wed Sep 30 13:54:56 2026 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84FC9469826 for ; Fri, 7 Aug 2026 22:10:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140610; cv=none; b=I66Mlke2pZdUEI0lgu/BOEZmXwSyXjW0s7mQG9KhcFRDt2XbVGPb48VWEvjqMr7E5zASMxgo8FYR9tdhMB389gRy+Y8/sReEM0yhHqFufEaX4BAYFKVqCgPzGeHVq/Ty2xoKMDFU6hexw27Tx+2jILAIDaaR3Gvk7FmWJ2MnlYo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140610; c=relaxed/simple; bh=yrKxam1mAG3nYRnHckVi5zYwUOS6b+SZe0OPFHhASsc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nRVasDWJm0UIt0aDlNYKs9b4Nl3fA+XHzDN+hhunUBwslTjGxMiAAQ+R2APvNdJpn6I2jB9Nj1hGsZuQKM5JRjDb6VX0dwuIV1vOoYhMfFom6Hge6fclBUtKmO6IoULic7pk0fn/owrJDUk9mnUiazTALyam4gQZi0X/RbbbOXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=hOCrL47+; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hOCrL47+" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-2cc7ef7ec27so814515ad.1 for ; Fri, 07 Aug 2026 15:10:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786140606; x=1786745406; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VyWHUTu1TvU3eL62Q6jwzEcXDxMtIPq0Po9Uu+hdpt8=; b=hOCrL47+IIu1e36eWx3T+TwxitHvaTaSJAIbMMTcoZmkU50btaHR7FSFjNyjOvbVkw gtRck0M6kwES4P1S978uXxaYu4ZtPgVY7DLhSatFymjptZTb9Ayrbi9VddhF2DRAmzJN EN+KowU8zTkeASDREGB9KuH5Th2vloWC1gkOsloqdmz2NmYGGX5dQyp4vQVo7i0B7yF5 uK0plgyEv5AjZ7vTuu56O1z/tjTjnEYHZ/NhRkALGKE/mHlPpspOJiwfX2CILgmmhrIv Z9g/9YkIlv3mo6phdH/y4q+J8K6xfHKBOR5niA450kFmvql9vM7OLZ9eGLXDRm/Nbe3y 22OQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786140606; x=1786745406; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VyWHUTu1TvU3eL62Q6jwzEcXDxMtIPq0Po9Uu+hdpt8=; b=n56s7eByZ5YyDfvW/e6XdbmWaeMfptwD8DJ0W8BbF3LFbFBEoKUFFoNnQtbcd3WS2T FAR2U+j8eKfuP+981kXDuPHGGBQ5aBjNquCeawcB9eSngyx6QsRM7+kX7VTbPfaI+QW6 z0b2Nr+niRq0CgCxunjjJIl8lc8ryAdyWlZp5ViN1sSJdy6JE8CSgcRjtGvtDXGhXo0g ioy3jAMqIBdzRLrZhrnLnuxtPQ5L8YugH0Aapojrx8DIS/e4N/Z7/je5HSy1LSVyFS2D NnZK4ZmSDTjGnD2Yn3hQUcaANDszbl+/vcD9o82ZjUVKk+6+lqm+KyYczQWoGsuGhQ6f RMvw== X-Forwarded-Encrypted: i=1; AHgh+RopP3lww3J7z2lLXB5cL7xutGaEg9caTr+oNZl8ad4ed+Q1kcNUKif6W0FOkCasTd7kijz6jLRlXe0daO4=@vger.kernel.org X-Gm-Message-State: AOJu0YzNRaQ81Vt60tR97lfS6dJZMVeDkp6aq54vQf9CNZQo8OMgGCmZ n+v426ComoG62R3tDDgoQnZyKc576+KEaSlR9Ey6eRDAQ3feR2xxNgXZcjI37xK8 X-Gm-Gg: AR+sD13qJ/QoXM2LVOsKpWhfL7s7SPIxs+OQZEDlUjx3iICsyCGPWKRNBLuqrnd7F9h OZ7E0hUGWj/4BPmeYVh8UE0RRKSLbDoqgwMLe4PC0oq+grlcBPu+gs1Npokv8c3R9VjrVuznxKW MtoTFScUbw4C8Sj3yrPgmuH0SQsKOyixx623aMHvXTP1UWuMRMSxIy11zF9vccGZBK5nYlop8Nt vxckXBf+z+iT4YnKITWSjdpQZKRuJPTOn/WErDLvDRymAzjvKVxznDGvayVT/fbJnT2Iiym5q2Q 0+gffkquM2P2EK96K8csWLkGHQWZXX83crz5I+5sEMciYMR1hJAC9mBOVcuM1OJJLIjetey2UO+ QM9HuCVolpoyOGV/f49Yros0SE2668TwWLdgUjcIasplVqUb4Zu5GgDZhVyzRK+aByxURI74VYK Xh7lTKLxVk9gos4xCAW+UE5o6blJ2xq75X8y9KI7yqJpNT8kY3qfAvJYfoWlR1QNpfnA== X-Received: by 2002:a17:902:ced0:b0:2c9:cb1b:64d6 with SMTP id d9443c01a7336-2d2a8e9ded1mr49060655ad.19.1786140606491; Fri, 07 Aug 2026 15:10:06 -0700 (PDT) Received: from fedora ([2804:1b3:a8c3:8ee5:1c39:64d9:e257:73dc]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315be568bd3sm11182762eec.0.2026.08.07.15.10.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 15:10:06 -0700 (PDT) From: Marcelo Mendes Spessoto Junior To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Marcelo Mendes Spessoto Junior Subject: [PATCH net-next v3 3/5] selftests: net: create own netns in ipv6_flowlabel_mgr Date: Fri, 7 Aug 2026 19:09:40 -0300 Message-ID: <20260807220942.421382-4-marcelomspessoto@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807220942.421382-1-marcelomspessoto@gmail.com> References: <20260807220942.421382-1-marcelomspessoto@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Have ipv6_flowlabel_mgr create and configure its own network namespace (unshare(CLONE_NEWNET) + bring up lo), the same way ipv6_fragmentation.c and icmp_rfc4884.c already do, instead of relying on the in_netns.sh wrapper script. The setup can then be reused across tests through fixtures and provide isolated network environments for each test in the case of a future adoption of kselftest_harness. It also avoids the leak of modifications to the netns in case the user runs the test file directly, outside the wrapper and without the in_netns.sh file. Signed-off-by: Marcelo Mendes Spessoto Junior --- tools/testing/selftests/net/ipv6_flowlabel.sh | 2 +- .../selftests/net/ipv6_flowlabel_mgr.c | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/ipv6_flowlabel.sh b/tools/testing/= selftests/net/ipv6_flowlabel.sh index cee95e252bee..2eeda39bf64c 100755 --- a/tools/testing/selftests/net/ipv6_flowlabel.sh +++ b/tools/testing/selftests/net/ipv6_flowlabel.sh @@ -8,7 +8,7 @@ set -e =20 echo "TEST management" -./in_netns.sh ./ipv6_flowlabel_mgr +./ipv6_flowlabel_mgr =20 echo "TEST datapath" ./in_netns.sh \ diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testi= ng/selftests/net/ipv6_flowlabel_mgr.c index 51541e792257..f8d8b09b9d86 100644 --- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c +++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c @@ -8,11 +8,14 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -306,6 +309,30 @@ static void run_tests(int fd) } } =20 +static void setup(void) +{ + struct ifreq ifr =3D { + .ifr_name =3D "lo" + }; + int ctl; + + if (unshare(CLONE_NEWNET)) + error(1, errno, "unshare"); + + ctl =3D socket(AF_LOCAL, SOCK_STREAM, 0); + if (ctl =3D=3D -1) + error(1, errno, "socket"); + + if (ioctl(ctl, SIOCGIFFLAGS, &ifr)) + error(1, errno, "ioctl SIOCGIFFLAGS"); + ifr.ifr_flags |=3D IFF_UP; + if (ioctl(ctl, SIOCSIFFLAGS, &ifr)) + error(1, errno, "ioctl: bring lo up"); + + if (close(ctl)) + error(1, errno, "close"); +} + static void parse_opts(int argc, char **argv) { int c; @@ -329,6 +356,7 @@ int main(int argc, char **argv) int fd; =20 parse_opts(argc, argv); + setup(); =20 fd =3D socket(PF_INET6, SOCK_DGRAM, 0); if (fd =3D=3D -1) --=20 2.55.0 From nobody Wed Sep 30 13:54:56 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BA1C46C825 for ; Fri, 7 Aug 2026 22:10:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140612; cv=none; b=LUlNr6FXiseT0CU5qSlvqg3lFtFgj6CkbZE+isIoQIbemsOaSKLJDGW7kyFlet6KEtt996eN42AEO/+KHohhL9J/r1OKZyUquZDv1FwLOwzYsfI4FZIXe+vYX1Cgt+WRXHF0O5eDcNd31+ZE20tx0jB8JsCsWoyopCeB6xcE/FY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140612; c=relaxed/simple; bh=RRCXOWIG7wQhsKY6MWJcWH1ko4HQP18F7eGyDZKZ3Yg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p3aBU0oBCMzwxa1c2NBFKjBvkvLKMooOcfe9er/Fsx2BhBrFSjSrXJEjHEPU/1deN21SrKqtFWqWBt/haMclqeopoyv0A03KDIFXgy+czq9MD4Ceftr+f0M0xr29kc34dBqz58Wpax8MioTM52UevdiAiZC/v4D3mX8CY17ZTCQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Fvzuz4Cc; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Fvzuz4Cc" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2ceab75934dso943255ad.2 for ; Fri, 07 Aug 2026 15:10:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786140610; x=1786745410; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=eE6hvbuq5iFYO3P8zMcP762X8R9vSoVUqqxZJnu8QhQ=; b=Fvzuz4CcrUyf5sMX3FKYg9wpSuPskQsGjO9/j1j4N1kNV5Q/6cuqg7PK7iV/5Agm0S Bne+IXb9gjzISZrrezC7AiqF3cLCWDQHzmqGrrBtVvjHjxOnTxy3hKuAhB9yMEK+1/QB ELeFmeijBXD8QIoo96S1c6wAKLV+oJjcnjTtjLsCK5pdelzW/YOm5G6GqKE4e9h5vIzx BJ98MdHCPMw0L8XeNfdlKJDXaeIEdTBr8MfC7d6WznP253hEV2UHlGjMsMX1B+b4oHv8 LtEZvPu8PlqyzsKNIef9i27sB/ZQnEPj4m/Aa5iRk6lEwckN/DQO8QaVmnOTRHTgX2uB LYJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786140610; x=1786745410; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=eE6hvbuq5iFYO3P8zMcP762X8R9vSoVUqqxZJnu8QhQ=; b=kIsOBKw6kcPS5z+Xen5yZGj2dau1RVv+1NEhHq3TixP6AkiL8CXIY3FhJKWuDhpAr1 66CsaCiKCtwiccABO5CH+Y9B+CrIRVTEWeH4tI4GmecnkM2tEv8twyBbN/+hP7lokhDD kXPyQWN9hM6bgIUizzTQffCPLBTSkj0CtjsLfPPdUrAMLYiDSKasU3Xc5voNf5vBZelB VL4eKjzCF42qvRHgIOy1kg3asZg/75oHeg2Oe6pwRS4+S08H6mV/yFdnYCJfCDokLliO lHh2LS0tHelnC/2ZVPJcxYxPSueR9XI1lA1D7ybI9BRRLUv6wQJTjGSJHizu65DXx/MO VB9g== X-Forwarded-Encrypted: i=1; AHgh+RqGgDj0uv8tzT723YUb7RCwvH6soidAnkRJ52EppNag6iqgEhCw4G0hDNdjceSLbZWVu2LTCtJldvvdrFc=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2ID/TZykg30DwLottDi0muTbuOfE2UZwuy0x39Vm1a+x5C7lJ G6ZO5h5hgtmhdE9YP20UKvF4nkFy8s4ucSqYIQkzFRP2tR4IIpSy5KKn X-Gm-Gg: AR+sD130jIE1ajXggWRZMp6wPt7uaijI02asZvnNc+2xtcMMWoV+7bWwTeC7HH6iR1G UorzXjOhfJ09AQX0YD9na8FFPllH7n3T52VZl8fnk7snz/ckUn0VRQMQcDQeviRX45OJF6mp/8H 0tymknE07EEJQZ//ifAWQYBuOEQhqu15UpmOQvOiNCAhRaefJUsN/Dc7fYWLzhQiIS1FeUAnI/X Uft6/CwUdgNqM+Ma6rm3hYFq/InSTX5D35gZnkK5XU2muyPCuIiWy0OtTOJBMPgw1bVK8h3u1Lx GFKP+mROjvnJ8A2DmRlPGsM4ppz32g2/T9TIRugPvWAS4YKFDVaMf209VHKuyEDW4eSu9aAzqEL hppvOqLMUYg2NwS5rKNhzhKQVTIM2PiYqnRRMIS+fMxETaEYDuaIRYOb4sMS1f5GUvo+4KWRebT jj34oLnodaCS1qxy2Tp7rK5cOren+4Y0eklIMniApwtsh4TnXve5DrcpqnboyLufdWzQ== X-Received: by 2002:a17:90b:1d8d:b0:38f:5869:387b with SMTP id 98e67ed59e1d1-3903c56c2eamr23722431a91.9.1786140609850; Fri, 07 Aug 2026 15:10:09 -0700 (PDT) Received: from fedora ([2804:1b3:a8c3:8ee5:1c39:64d9:e257:73dc]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315be568bd3sm11182762eec.0.2026.08.07.15.10.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 15:10:09 -0700 (PDT) From: Marcelo Mendes Spessoto Junior To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Marcelo Mendes Spessoto Junior Subject: [PATCH net-next v3 4/5] selftests: net: test IPV6_FL_F_REFLECT Date: Fri, 7 Aug 2026 19:09:41 -0300 Message-ID: <20260807220942.421382-5-marcelomspessoto@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807220942.421382-1-marcelomspessoto@gmail.com> References: <20260807220942.421382-1-marcelomspessoto@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" According to the source code, flowlabel_consistency must be deactivated for the IPV6_FL_F_REFLECT flag to work. Since ipv6_flowlabel_mgr now runs in its own network namespace, do this directly from the test binary. Attempt to disable net.ipv6.flowlabel_consistency and skip the reflect test if that fails. A disabled flowlabel_consistency does not affect the remaining features being tested on the file, and failing to disable is not fatal and skips the reflect test only. The previously defined tcp_listen and tcp_connect helpers were reused, since the connection flow required for REFLECT validation is very similar to REMOTE. Signed-off-by: Marcelo Mendes Spessoto Junior --- .../selftests/net/ipv6_flowlabel_mgr.c | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testi= ng/selftests/net/ipv6_flowlabel_mgr.c index f8d8b09b9d86..d32150abd8ff 100644 --- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c +++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -168,6 +169,23 @@ static void tcp_connect(int listener, uint32_t flowlab= el, *accepted =3D afd; } =20 +static bool disable_flowlabel_consistency(void) +{ + int fd; + + fd =3D open("/proc/sys/net/ipv6/flowlabel_consistency", O_WRONLY); + if (fd =3D=3D -1) + return false; + + if (write(fd, "0", 1) !=3D 1) { + close(fd); + return false; + } + close(fd); + + return true; +} + static void run_tests(int fd) { int wstatus; @@ -307,6 +325,54 @@ static void run_tests(int fd) close(remote_cfd); close(remote_listener); } + + if (!disable_flowlabel_consistency()) { + fprintf(stderr, + "[INFO] skip REFLECT: cannot disable net.ipv6.flowlabel_consistency\n"); + } else { + struct in6_flowlabel_req reflect_query =3D { + .flr_action =3D IPV6_FL_A_GET, + }; + struct in6_flowlabel_req reflect_off =3D { + .flr_action =3D IPV6_FL_A_PUT, + .flr_flags =3D IPV6_FL_F_REFLECT, + }; + struct in6_flowlabel_req reflect_on =3D { + .flr_action =3D IPV6_FL_A_GET, + .flr_flags =3D IPV6_FL_F_REFLECT, + }; + socklen_t reflect_query_len =3D sizeof(reflect_query); + int reflect_listener =3D tcp_listen(); + int reflect_cfd, reflect_afd; + + explain("Enable REFLECT on listener before client connects"); + expect_pass(setsockopt(reflect_listener, SOL_IPV6, + IPV6_FLOWLABEL_MGR, &reflect_on, + sizeof(reflect_on))); + + tcp_connect(reflect_listener, 8, &reflect_cfd, &reflect_afd); + + explain("accepted socket's label should be reflected"); + expect_pass(getsockopt(reflect_afd, SOL_IPV6, + IPV6_FLOWLABEL_MGR, &reflect_query, + &reflect_query_len)); + if (ntohl(reflect_query.flr_label) !=3D 8) + error(1, 0, "unexpected reflected flowlabel %u", + ntohl(reflect_query.flr_label)); + + explain("PUT+REFLECT disables reflection on accepted socket"); + expect_pass(setsockopt(reflect_afd, SOL_IPV6, + IPV6_FLOWLABEL_MGR, &reflect_off, + sizeof(reflect_off))); + explain("cannot disable reflection twice"); + expect_fail(setsockopt(reflect_afd, SOL_IPV6, + IPV6_FLOWLABEL_MGR, &reflect_off, + sizeof(reflect_off))); + + close(reflect_afd); + close(reflect_cfd); + close(reflect_listener); + } } =20 static void setup(void) --=20 2.55.0 From nobody Wed Sep 30 13:54:56 2026 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 952A246D2C1 for ; Fri, 7 Aug 2026 22:10:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140618; cv=none; b=MD0pQNYu1J0UCyzJKgRY2/gFXc48sWn3Zrk5Gsnrs7OR2jk39vdsNH6wZEQmNTOsb6Vvjn4ZQspYDV3h8Eo246K3iBAoUO0Em2I0xtIl/XtV/i2Uu44TstgFglWW/NC8CoeAt0mRhnXt7wZcPkmuOKhWp7gBIH8VFsxMsm2rgSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786140618; c=relaxed/simple; bh=UdTLA46TnlBC54VM7lt50wf4vX5dZatdViC5SajQf0E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OWhGZmRDEs4Zch8GKpiWiiZ3ggHMarwvP7/MdvzjLuti1ZcLTmYYfx/E1KaaMqzR7YX/rOCZs5fBC9e1cdcn06V7jcT0CVfgMOwcuv3DREOT02mwyCPp4vE77aB5bXWmpyUyrgxqmjDFBjJJU8eW7ZexG7zzYwpTMksX2Yt+kjA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gDWOcqa5; arc=none smtp.client-ip=209.85.216.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gDWOcqa5" Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-38f620399a0so28868a91.2 for ; Fri, 07 Aug 2026 15:10:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786140613; x=1786745413; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cx5VGBsebkKX9AnlFkRAfLKtyddKfDmd3R9T8O1d6aU=; b=gDWOcqa5iSbre1dCR2kLCZEgtuHGD/U1rP1I1zqsaXjRr0JNGAMXHHvp3aAPqTcb/S 7LafHtcQMyBnjERSSy6+GKbUPH/FDVmt4+CXeS/H+N5+0nVDQa/Bpoz5PL5F8MBHYGLH ezS6myHSa4hcysIHUbRLRuuHcSzc7os1y4oHVoEERZ/NCBvifufyVfXLPpjoagJ3fNf4 XushGFM0kVhE9/dRrgMCgrc5+smkceTIMivGPJNHMAR78HNrqSIGx8AS1mfGOKyZrfsK tMWxjvZcN+XLnXSwxxFUYnH4k7Fe19JD33UR1qsHI4H/qGQ+cOK+Yw1IpkLdCjvzXfnt loBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786140613; x=1786745413; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=cx5VGBsebkKX9AnlFkRAfLKtyddKfDmd3R9T8O1d6aU=; b=COrEBZdMP7UtuRrTR23zxAWNuNVCSYMWq3vF0GixvAI3hvOw/E+tWaaKtZJOy9OuYp xzyDm7blCv9K6LrbttXaeVmhtpRhAI5p3Hsjwzc0Eqmw8HsiBiNevQYYztZCDYhY2aYi oZATrqGGqmXEssipaGuAmNdAWK3TgDb1DW5E6SHa9lbk4bdGLd+J5h+aPS0s81nmlTrh gFVkNbGZmD7UyTWutktVCU1+po+0GmQ/XFw2GZwqZOXqWbzHjfDhz1lTTgluqa40xMVo 3lOFJt1VEk/tJapowMbDHobpOlitDiHa6j9ljq1q2+u1XW16rXlxS9jmQD0nW3GJBKXl dwLw== X-Forwarded-Encrypted: i=1; AHgh+RpOlMCLYfLTW/1nCPfxfEN12tVzDrQf6V9OTYUuv5fwdZ+Tx1yS1+rdHpczk25ohO/a5IpO3zCq3GFmYTk=@vger.kernel.org X-Gm-Message-State: AOJu0YxW37E9pj6qqbmgaODqCKgkGSrNNrfOXRgS8kES2uLo9Br96SNb e5jbliCXBKiR00tJEBD+sEZI6ohFuoT4M1Rb0CgB0TRAbReE52w4a+MO X-Gm-Gg: AR+sD12tFDDUtJ75ypRpSrFyE2KDpku1D68yjI6iYGSlwRMdQ7Uz3qNT2B0jcQnWWct ympGh25JIpGxUQb/IdD1JcyRtFs209wUSspcq+stJyAdf6E8mv/k/aq931JpQmCn5b90YkwTHeq uZgPFbBEPiQcbONurw2UTvWDaC3LcQ0tfYWQj3pk8cVRlh6Cs4rpsbcYS35bp1/5JrcBrYm+biC gp2PHewIO6yF4Xb2aucHDtlHPEi0XxEGcSj1jgQYhueACN2yNkZpljkZRYYl6d9kKb8w9scQZ7H wkqtX7NBxENJDse1Rx4eZdSExQoqMYjhmDxk2lAyS6zkBb+bWCupbb31JZbH2A7Ku2TWlUi/xFA hnsLqBfS9T+wXuqKBc0J8wdQM+Um3x9wiCKUupr+Rbjii20a0gU9DWxmEUmANDTa4oCZFJW4ZIj 67X2EMcEAp3hinWBZ5vYm/YuX+8nR28CnAq31AvgGkkJeL1HPNS72Tyx1LFoOiAk2mhg== X-Received: by 2002:a17:90b:5244:b0:38e:9eb2:9d43 with SMTP id 98e67ed59e1d1-3903c5b685bmr25189638a91.16.1786140613400; Fri, 07 Aug 2026 15:10:13 -0700 (PDT) Received: from fedora ([2804:1b3:a8c3:8ee5:1c39:64d9:e257:73dc]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-315be568bd3sm11182762eec.0.2026.08.07.15.10.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Aug 2026 15:10:12 -0700 (PDT) From: Marcelo Mendes Spessoto Junior To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Shuah Khan Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Marcelo Mendes Spessoto Junior Subject: [PATCH net-next v3 5/5] selftests: net: adopt harness for flow label mgr Date: Fri, 7 Aug 2026 19:09:42 -0300 Message-ID: <20260807220942.421382-6-marcelomspessoto@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260807220942.421382-1-marcelomspessoto@gmail.com> References: <20260807220942.421382-1-marcelomspessoto@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The kselftest_harness.h file contains modern helpers to build tests for kselftest. Dropping the custom test helpers in ipv6_flowlabel_mgr in favor of the harness makes tests more legible and conforms to the structure of the latest selftests. It also enforces the TAP standard. Another change made to the structure of the ipv6_flowlabel_mgr test file was the removal of parse_opts. The supported opts were already unused: the binary is listed in TEST_GEN_FILES, and is driven solely by ipv6_flowlabel.sh via "./ipv6_flowlabel_mgr", which never passed -l or -v. Dropping the -l gate means the two checks it previously guarded (each with a 13-second sleep, ~26 seconds total) are now unconditionally enabled on every run instead of never running at all. The TH_LOG calls and code comments now cover the information that the removed, custom -v flag used to print. Finally, FIXTURE_SETUP(flowlabel) ensures each test gets its own isolated network namespace. The previously added setup() helper was dropped to conform to the netns setup pattern used in icmp_rfc4884.c. disable_flowlabel_consistency() was moved next to reflect_flag, the only test that calls it, and now uses SKIP() instead of an ad hoc [INFO] message when the sysctl cannot be disabled. Signed-off-by: Marcelo Mendes Spessoto Junior --- .../selftests/net/ipv6_flowlabel_mgr.c | 622 ++++++++++-------- 1 file changed, 365 insertions(+), 257 deletions(-) diff --git a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c b/tools/testi= ng/selftests/net/ipv6_flowlabel_mgr.c index d32150abd8ff..072fb3a9b121 100644 --- a/tools/testing/selftests/net/ipv6_flowlabel_mgr.c +++ b/tools/testing/selftests/net/ipv6_flowlabel_mgr.c @@ -23,6 +23,7 @@ #include #include #include +#include "kselftest_harness.h" =20 /* uapi/glibc weirdness may leave this undefined */ #ifndef IPV6_FLOWLABEL_MGR @@ -35,40 +36,6 @@ /* from net/ipv6/ip6_flowlabel.c */ #define FL_MIN_LINGER 6 =20 -#define explain(x) \ - do { if (cfg_verbose) fprintf(stderr, " " x "\n"); } while (0) - -#define __expect(x) \ - do { \ - if (!(x)) \ - fprintf(stderr, "[OK] " #x "\n"); \ - else \ - error(1, 0, "[ERR] " #x " (line %d)", __LINE__); \ - } while (0) - -#define expect_pass(x) __expect(x) -#define expect_fail(x) __expect(!(x)) - -#define expect_fail_errno(x, e) \ - do { \ - int __exp =3D (e); \ - int __ret =3D (x); \ - int __err =3D errno; \ - if (__ret && __err =3D=3D __exp) \ - fprintf(stderr, "[OK] " #x "\n"); \ - else if (!__ret) \ - error(1, 0, "[ERR] " #x \ - " (line %d): unexpectedly succeeded", \ - __LINE__); \ - else \ - error(1, 0, "[ERR] " #x \ - " (line %d): expected errno %d, got %d", \ - __LINE__, __exp, __err); \ - } while (0) - -static bool cfg_long_running; -static bool cfg_verbose; - static int flowlabel_get(int fd, uint32_t label, uint8_t share, uint16_t f= lags) { struct in6_flowlabel_req req =3D { @@ -169,269 +136,410 @@ static void tcp_connect(int listener, uint32_t flow= label, *accepted =3D afd; } =20 -static bool disable_flowlabel_consistency(void) +static int bringup_loopback(void) { + struct ifreq ifr =3D { + .ifr_name =3D "lo" + }; int fd; =20 - fd =3D open("/proc/sys/net/ipv6/flowlabel_consistency", O_WRONLY); - if (fd =3D=3D -1) - return false; + fd =3D socket(AF_LOCAL, SOCK_STREAM, 0); + if (fd < 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) + goto err; + + ifr.ifr_flags =3D ifr.ifr_flags | IFF_UP; + + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) + goto err; =20 - if (write(fd, "0", 1) !=3D 1) { - close(fd); - return false; - } close(fd); + return 0; =20 - return true; +err: + close(fd); + return -1; } =20 -static void run_tests(int fd) +FIXTURE(flowlabel) {}; + +FIXTURE_SETUP(flowlabel) { - int wstatus; - pid_t pid; + int ret; =20 - explain("cannot get non-existent label"); - expect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0)); - - explain("cannot put non-existent label"); - expect_fail(flowlabel_put(fd, 1)); - - explain("cannot create label greater than 20 bits"); - expect_fail(flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE)); - - explain("create a new label (FL_F_CREATE)"); - expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE)); - explain("can get the label (without FL_F_CREATE)"); - expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0)); - explain("can get it again with create flag set, too"); - expect_pass(flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE)); - explain("cannot get it again with the exclusive (FL_FL_EXCL) flag"); - expect_fail(flowlabel_get(fd, 1, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE | IPV6_FL_F_EXCL)); - explain("can now put exactly three references"); - expect_pass(flowlabel_put(fd, 1)); - expect_pass(flowlabel_put(fd, 1)); - expect_pass(flowlabel_put(fd, 1)); - expect_fail(flowlabel_put(fd, 1)); - - explain("create a new exclusive label (FL_S_EXCL)"); - expect_pass(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE)); - explain("cannot get it again in non-exclusive mode"); - expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE)); - explain("cannot get it again in exclusive mode either"); - expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE)); - expect_pass(flowlabel_put(fd, 2)); - - if (cfg_long_running) { - explain("cannot reuse the label, due to linger"); - expect_fail(flowlabel_get(fd, 2, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE)); - explain("after sleep, can reuse"); - sleep(FL_MIN_LINGER * 2 + 1); - expect_pass(flowlabel_get(fd, 2, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE)); + ret =3D unshare(CLONE_NEWNET); + ASSERT_EQ(ret, 0) { + TH_LOG("unshare(CLONE_NEWNET) failed: %s", strerror(errno)); } =20 - explain("create a new user-private label (FL_S_USER)"); - expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE)); - explain("cannot get it again in non-exclusive mode"); - expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0)); - explain("cannot get it again in exclusive mode"); - expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0)); - explain("can get it again in user mode"); - expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0)); - explain("child process can get it too, but not after setuid(nobody)"); + ret =3D bringup_loopback(); + ASSERT_EQ(ret, 0) TH_LOG("Failed to bring up loopback interface"); +} + +FIXTURE_TEARDOWN(flowlabel) +{ +} + +TEST_F(flowlabel, cannot_get_non_existent_label) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 9, IPV6_FL_S_ANY, 0); + EXPECT_TRUE(err) TH_LOG("expected get of a non-existent label to fail"); + EXPECT_EQ(ENOENT, errno) TH_LOG("expected ENOENT, got %d", errno); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, cannot_put_non_existent_label) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_put(fd, 10); + EXPECT_TRUE(err) TH_LOG("expected put of a non-existent label to fail"); + EXPECT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, cannot_create_label_greater_than_20_bits) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 0x1FFFFF, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(err) TH_LOG("expected label > 20 bits to be rejected"); + EXPECT_EQ(EINVAL, errno) TH_LOG("expected EINVAL, got %d", errno); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, can_create_and_get_and_put_labels) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) TH_LOG("failed to create label (FL_F_CREATE)"); + + err =3D flowlabel_get(fd, 1, IPV6_FL_S_ANY, 0); + EXPECT_TRUE(!err) TH_LOG("failed to get the label without FL_F_CREATE"); + + err =3D flowlabel_get(fd, 1, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to get it again with create flag set, too"); + + err =3D flowlabel_get(fd, 1, IPV6_FL_S_ANY, + IPV6_FL_F_CREATE | IPV6_FL_F_EXCL); + EXPECT_TRUE(err) + TH_LOG("expected FL_F_EXCL to reject existing label"); + EXPECT_EQ(EEXIST, errno) TH_LOG("expected EEXIST, got %d", errno); + + err =3D flowlabel_put(fd, 1); + EXPECT_TRUE(!err) TH_LOG("failed to put first reference"); + err =3D flowlabel_put(fd, 1); + EXPECT_TRUE(!err) TH_LOG("failed to put second reference"); + err =3D flowlabel_put(fd, 1); + EXPECT_TRUE(!err) TH_LOG("failed to put third reference"); + err =3D flowlabel_put(fd, 1); + EXPECT_TRUE(err) + TH_LOG("expected fourth put to fail, no references left"); + EXPECT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, exclusive_label_share) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to create a new exclusive label (FL_S_EXCL)"); + + err =3D flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(err) TH_LOG("expected reuse in non-exclusive mode to fail"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + err =3D flowlabel_get(fd, 2, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE); + EXPECT_TRUE(err) TH_LOG("expected reuse in exclusive mode to fail too"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + err =3D flowlabel_put(fd, 2); + EXPECT_TRUE(!err) TH_LOG("failed to put the exclusive label"); + + err =3D flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(err) TH_LOG("expected reuse to fail, due to linger"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + sleep(FL_MIN_LINGER * 2 + 1); + + err =3D flowlabel_get(fd, 2, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) TH_LOG("expected reuse to succeed after linger"); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, user_private_label_share) +{ + int fd, err, wstatus; + pid_t pid; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 3, IPV6_FL_S_USER, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to create a new user-private label (FL_S_USER)"); + + err =3D flowlabel_get(fd, 3, IPV6_FL_S_ANY, 0); + EXPECT_TRUE(err) TH_LOG("expected get in non-exclusive mode to fail"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + err =3D flowlabel_get(fd, 3, IPV6_FL_S_EXCL, 0); + EXPECT_TRUE(err) TH_LOG("expected get in exclusive mode to fail"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + err =3D flowlabel_get(fd, 3, IPV6_FL_S_USER, 0); + EXPECT_TRUE(!err) TH_LOG("failed to get it again in user mode"); + pid =3D fork(); - if (pid =3D=3D -1) - error(1, errno, "fork"); + ASSERT_NE(-1, pid) TH_LOG("fork failed"); if (!pid) { - expect_pass(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0)); + err =3D flowlabel_get(fd, 3, IPV6_FL_S_USER, 0); + EXPECT_TRUE(!err) + TH_LOG("child failed to get the user-private label"); + if (setuid(USHRT_MAX)) - fprintf(stderr, "[INFO] skip setuid child test\n"); - else - expect_fail(flowlabel_get(fd, 3, IPV6_FL_S_USER, 0)); + exit(KSFT_SKIP); + + err =3D flowlabel_get(fd, 3, IPV6_FL_S_USER, 0); + EXPECT_TRUE(err) + TH_LOG("child unexpectedly got label after setuid"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); exit(0); } - if (wait(&wstatus) =3D=3D -1) - error(1, errno, "wait"); - if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) !=3D 0) - error(1, errno, "wait: unexpected child result"); - - explain("create a new process-private label (FL_S_PROCESS)"); - expect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE)); - explain("can get it again"); - expect_pass(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0)); - explain("child process cannot can get it"); + ASSERT_EQ(pid, wait(&wstatus)) TH_LOG("wait failed"); + ASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG("child did not exit normally"); + if (WEXITSTATUS(wstatus) =3D=3D KSFT_SKIP) + SKIP(return, + "setuid(USHRT_MAX) unavailable (no CAP_SETUID or uid unmapped)"); + EXPECT_EQ(0, WEXITSTATUS(wstatus)) + TH_LOG("child reported unexpected result"); + + EXPECT_EQ(0, close(fd)); +} + +TEST_F(flowlabel, process_private_label_share) +{ + int fd, err, wstatus; + pid_t pid; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to create a new process-private label"); + + err =3D flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0); + EXPECT_TRUE(!err) TH_LOG("failed to get it again"); + pid =3D fork(); - if (pid =3D=3D -1) - error(1, errno, "fork"); + ASSERT_NE(-1, pid) TH_LOG("fork failed"); if (!pid) { - expect_fail(flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0)); + err =3D flowlabel_get(fd, 4, IPV6_FL_S_PROCESS, 0); + EXPECT_TRUE(err) + TH_LOG("child unexpectedly got process-private label"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); exit(0); } - if (wait(&wstatus) =3D=3D -1) - error(1, errno, "wait"); - if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) !=3D 0) - error(1, errno, "wait: unexpected child result"); - - explain("It is not possible to renew a label that does not exist"); - expect_fail_errno(flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, - 2 * (FL_MIN_LINGER * 2 + 1)), - ESRCH); - - explain("Create a label for basic renew validation"); - expect_pass(flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE)); - explain("renew does not error for an existing, valid label"); - expect_pass(flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, - 2 * (FL_MIN_LINGER * 2 + 1))); - - if (cfg_long_running) { - explain("create a new label with FL_MIN_LINGER linger time"); - expect_pass(flowlabel_get(fd, 6, IPV6_FL_S_EXCL, - IPV6_FL_F_CREATE)); - explain("renew the label to extend linger, then put it"); - expect_pass(flowlabel_renew(fd, 6, IPV6_FL_S_EXCL, - 2 * (FL_MIN_LINGER * 2 + 1))); - expect_pass(flowlabel_put(fd, 6)); - sleep(FL_MIN_LINGER * 2 + 1); - explain("cannot create: new linger time not over yet"); - expect_fail_errno(flowlabel_get(fd, 6, IPV6_FL_S_ANY, - IPV6_FL_F_CREATE), - EPERM); - } + ASSERT_EQ(pid, wait(&wstatus)) TH_LOG("wait failed"); + ASSERT_TRUE(WIFEXITED(wstatus)) TH_LOG("child did not exit normally"); + EXPECT_EQ(0, WEXITSTATUS(wstatus)) + TH_LOG("child reported unexpected result"); =20 - { - struct in6_flowlabel_req freq =3D { - .flr_action =3D IPV6_FL_A_GET, - .flr_flags =3D IPV6_FL_F_REMOTE, - }; - int remote_listener =3D tcp_listen(); - socklen_t freq_len =3D sizeof(freq); - int remote_cfd, remote_afd; - - explain("Prepare TCP SYN for REMOTE flag validation"); - tcp_connect(remote_listener, 7, &remote_cfd, &remote_afd); - - explain("Query for label sent by client with IPV6_FL_F_REMOTE"); - expect_pass(getsockopt(remote_afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, - &freq, &freq_len)); - if (ntohl(freq.flr_label) !=3D 7) - error(1, 0, "unexpected remote flowlabel %u", - ntohl(freq.flr_label)); - - close(remote_afd); - close(remote_cfd); - close(remote_listener); - } + EXPECT_EQ(0, close(fd)); +} =20 - if (!disable_flowlabel_consistency()) { - fprintf(stderr, - "[INFO] skip REFLECT: cannot disable net.ipv6.flowlabel_consistency\n"); - } else { - struct in6_flowlabel_req reflect_query =3D { - .flr_action =3D IPV6_FL_A_GET, - }; - struct in6_flowlabel_req reflect_off =3D { - .flr_action =3D IPV6_FL_A_PUT, - .flr_flags =3D IPV6_FL_F_REFLECT, - }; - struct in6_flowlabel_req reflect_on =3D { - .flr_action =3D IPV6_FL_A_GET, - .flr_flags =3D IPV6_FL_F_REFLECT, - }; - socklen_t reflect_query_len =3D sizeof(reflect_query); - int reflect_listener =3D tcp_listen(); - int reflect_cfd, reflect_afd; - - explain("Enable REFLECT on listener before client connects"); - expect_pass(setsockopt(reflect_listener, SOL_IPV6, - IPV6_FLOWLABEL_MGR, &reflect_on, - sizeof(reflect_on))); - - tcp_connect(reflect_listener, 8, &reflect_cfd, &reflect_afd); - - explain("accepted socket's label should be reflected"); - expect_pass(getsockopt(reflect_afd, SOL_IPV6, - IPV6_FLOWLABEL_MGR, &reflect_query, - &reflect_query_len)); - if (ntohl(reflect_query.flr_label) !=3D 8) - error(1, 0, "unexpected reflected flowlabel %u", - ntohl(reflect_query.flr_label)); - - explain("PUT+REFLECT disables reflection on accepted socket"); - expect_pass(setsockopt(reflect_afd, SOL_IPV6, - IPV6_FLOWLABEL_MGR, &reflect_off, - sizeof(reflect_off))); - explain("cannot disable reflection twice"); - expect_fail(setsockopt(reflect_afd, SOL_IPV6, - IPV6_FLOWLABEL_MGR, &reflect_off, - sizeof(reflect_off))); - - close(reflect_afd); - close(reflect_cfd); - close(reflect_listener); - } +TEST_F(flowlabel, cannot_renew_non_existent_label) +{ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1)); + EXPECT_TRUE(err) + TH_LOG("expected renew of a non-existent label to fail"); + EXPECT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno); + + EXPECT_EQ(0, close(fd)); } =20 -static void setup(void) +TEST_F(flowlabel, can_renew_existing_label) { - struct ifreq ifr =3D { - .ifr_name =3D "lo" - }; - int ctl; + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); =20 - if (unshare(CLONE_NEWNET)) - error(1, errno, "unshare"); + err =3D flowlabel_get(fd, 5, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to create a new label for renew validation"); =20 - ctl =3D socket(AF_LOCAL, SOCK_STREAM, 0); - if (ctl =3D=3D -1) - error(1, errno, "socket"); + err =3D flowlabel_renew(fd, 5, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1)); + EXPECT_TRUE(!err) TH_LOG("failed to renew an existing valid label"); =20 - if (ioctl(ctl, SIOCGIFFLAGS, &ifr)) - error(1, errno, "ioctl SIOCGIFFLAGS"); - ifr.ifr_flags |=3D IFF_UP; - if (ioctl(ctl, SIOCSIFFLAGS, &ifr)) - error(1, errno, "ioctl: bring lo up"); + err =3D flowlabel_put(fd, 5); + EXPECT_TRUE(!err) TH_LOG("failed to put the label"); =20 - if (close(ctl)) - error(1, errno, "close"); + EXPECT_EQ(0, close(fd)); } =20 -static void parse_opts(int argc, char **argv) +TEST_F(flowlabel, renew_label_linger) { - int c; - - while ((c =3D getopt(argc, argv, "lv")) !=3D -1) { - switch (c) { - case 'l': - cfg_long_running =3D true; - break; - case 'v': - cfg_verbose =3D true; - break; - default: - error(1, 0, "%s: parse error", argv[0]); - } - } + /* RENEW must extend a label's linger period: putting a renewed + * label and waiting out its original linger time must not be + * enough to allow the label to be recreated. + */ + int fd, err; + + fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + ASSERT_GE(fd, 0) TH_LOG("socket failed"); + + err =3D flowlabel_get(fd, 6, IPV6_FL_S_EXCL, IPV6_FL_F_CREATE); + EXPECT_TRUE(!err) + TH_LOG("failed to create label with FL_MIN_LINGER linger time"); + + err =3D flowlabel_renew(fd, 6, IPV6_FL_S_EXCL, + 2 * (FL_MIN_LINGER * 2 + 1)); + EXPECT_TRUE(!err) + TH_LOG("failed to renew the label to increase its linger time"); + + err =3D flowlabel_put(fd, 6); + EXPECT_TRUE(!err) TH_LOG("failed to put the label"); + + sleep(FL_MIN_LINGER * 2 + 1); + + err =3D flowlabel_get(fd, 6, IPV6_FL_S_ANY, IPV6_FL_F_CREATE); + EXPECT_TRUE(err) + TH_LOG("expected reuse to fail, new linger time not over yet"); + EXPECT_EQ(EPERM, errno) TH_LOG("expected EPERM, got %d", errno); + + EXPECT_EQ(0, close(fd)); } =20 -int main(int argc, char **argv) +TEST_F(flowlabel, remote_flag) { - int fd; + /* The REMOTE flag, used for getsockopt, is expected to retrieve the + * label from the latest received header. + */ + struct in6_flowlabel_req freq =3D { + .flr_action =3D IPV6_FL_A_GET, + .flr_flags =3D IPV6_FL_F_REMOTE, + }; + socklen_t freq_len =3D sizeof(freq); + int listener, cfd, afd, err; =20 - parse_opts(argc, argv); - setup(); + listener =3D tcp_listen(); + tcp_connect(listener, 7, &cfd, &afd); =20 - fd =3D socket(PF_INET6, SOCK_DGRAM, 0); + err =3D getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, &freq, &freq_len); + EXPECT_TRUE(!err) TH_LOG("getsockopt with IPV6_FL_F_REMOTE failed"); + EXPECT_EQ(7, ntohl(freq.flr_label)) + TH_LOG("unexpected remote flow label"); + + EXPECT_EQ(0, close(afd)); + EXPECT_EQ(0, close(cfd)); + EXPECT_EQ(0, close(listener)); +} + +static bool disable_flowlabel_consistency(void) +{ + int fd; + + fd =3D open("/proc/sys/net/ipv6/flowlabel_consistency", O_WRONLY); if (fd =3D=3D -1) - error(1, errno, "socket"); + return false; =20 - run_tests(fd); + if (write(fd, "0", 1) !=3D 1) { + close(fd); + return false; + } + close(fd); =20 - if (close(fd)) - error(1, errno, "close"); + return true; +} =20 - return 0; +TEST_F(flowlabel, reflect_flag) +{ + /* The REFLECT flag acts as a trigger to the REPFLOW bit. When REPFLOW + * is triggered for a socket, it adopts the label received from the + * connected socket. + */ + struct in6_flowlabel_req reflect_on =3D { + .flr_action =3D IPV6_FL_A_GET, + .flr_flags =3D IPV6_FL_F_REFLECT, + }; + struct in6_flowlabel_req reflect_query =3D { + .flr_action =3D IPV6_FL_A_GET, + }; + struct in6_flowlabel_req reflect_off =3D { + .flr_action =3D IPV6_FL_A_PUT, + .flr_flags =3D IPV6_FL_F_REFLECT, + }; + socklen_t reflect_query_len =3D sizeof(reflect_query); + int listener, cfd, afd, err; + + if (!disable_flowlabel_consistency()) + SKIP(return, + "cannot disable net.ipv6.flowlabel_consistency"); + + listener =3D tcp_listen(); + err =3D setsockopt(listener, SOL_IPV6, IPV6_FLOWLABEL_MGR, + &reflect_on, sizeof(reflect_on)); + EXPECT_TRUE(!err) TH_LOG("failed to enable REFLECT on the listener"); + + tcp_connect(listener, 8, &cfd, &afd); + + err =3D getsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, + &reflect_query, &reflect_query_len); + EXPECT_TRUE(!err) + TH_LOG("failed to query the accepted socket's outgoing label"); + EXPECT_EQ(8, ntohl(reflect_query.flr_label)) + TH_LOG("accepted socket did not reflect client's label"); + + err =3D setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, + &reflect_off, sizeof(reflect_off)); + EXPECT_TRUE(!err) + TH_LOG("failed to disable REFLECT on the accepted socket"); + + err =3D setsockopt(afd, SOL_IPV6, IPV6_FLOWLABEL_MGR, + &reflect_off, sizeof(reflect_off)); + EXPECT_TRUE(err) TH_LOG("expected disabling REFLECT twice to fail"); + EXPECT_EQ(ESRCH, errno) TH_LOG("expected ESRCH, got %d", errno); + + EXPECT_EQ(0, close(afd)); + EXPECT_EQ(0, close(cfd)); + EXPECT_EQ(0, close(listener)); } + +TEST_HARNESS_MAIN --=20 2.55.0