From nobody Tue May 19 07:27:39 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gKR8c5JP1z6dkCP for ; Tue, 19 May 2026 07:27:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gKR8c3BTCz3ntK for ; Tue, 19 May 2026 07:27:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779175664; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Z31WAuPXhcY9Fpse7Q3M5lwtggORfCb5LFCiBKIVTEk=; b=V7QwP0eDx9cj4Mi6T6EDWYtQhud4IByvR8DGnpzY0fELHCYKZ6NQNqdc8qeXuQV6BVKW8d neDwWakYRAF3xxH0QQiu2dVy7eAjC1Ikag4V/X8IaOJa9gSXSK2wj5yvtcPxLQHlbOiK+n UnzXCFQCSYglLdeJfOKGP1GecrcEnYsPS6B4pQ79/uFvaZW1qvoV5HKck2l//yIsb7IXxl FSGNi4zZsrpsjisrW28ZEYtZZD+pDqtRGtaCT7tGXkRbwbNIJPDFB2jg27xAWxk/dgxzUo WLOmP8A1JGH5Mk9ZR2Z3WQFo5L/Y77Ez/6hsnGvOGf9oOufOGrULQh+F7uNhVQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1779175664; a=rsa-sha256; cv=none; b=Q6WHOYMlddZVydMtviu18gnbinleGY9sLsKfM5BnYd4WL9mfVdjWlxR8C7rDhmZQIwsvg1 uRJ4bSDBuH++Bvs3iSRQjjU+8AmHgjbMX9RIlKpL24yVfqOpU6P2+pTCgBRPPvDYNEqg+z hYtcrio4DczaGMaH84q2papgiYKZG6UwLbkyRnrIJInDv1/vbNh1bRg1/BwMKNsrbIUhnC 0m9ibUcTlNZH6+Kx9zAr32Z2IStcGRHg1Or+nPKUSCm250f6toEynEwg5lC8ervohKGhEW uZ+WgH8+hSkqQi6P1tIV+zZFkfIhGGtpIXy950DFQntOT5rXERVGBn+uwO0LjQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779175664; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Z31WAuPXhcY9Fpse7Q3M5lwtggORfCb5LFCiBKIVTEk=; b=ZNBVOeTGb7MQBF+/LuykF7DK6ahthrtRk7d6cWHIb+5nVxbmYdmBMhwWB/K/xSPh/eryHc O38l2ynZGOyM66IMeRO/L2zNP5xQbziOrwu4Ytna6e39uxy+vIKm6JqEBFoVP0d/01udDg rrRwyRd+U/Q/jk0zgcSH8LZ1NRTVlASDtJ3+OAOgNZkXPdpRoIQLPvcwDEyHvGPo7ZXH9o FfyfBLl1c8AlhUFMFUWjMQrTqLa839fGqGhb8lPMINL74zsJ3y/9/4WBf7CqIe9AysnMkg OAPC5Io0b69IzL+s+FyPoO0cZmFm2lfdrwDknTJw0GjfcSL1kJOzUAU3mLVzJg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gKR8c2X82z13xP for ; Tue, 19 May 2026 07:27:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 27aff by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 19 May 2026 07:27:39 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Boris Lytochkin From: Andrey V. Elsukov Subject: git: 8b10555b6b70 - stable/15 - ipfw: fix IPv6 flow label matching List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ae X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 8b10555b6b709a32ed4e625a45a1cbea3a977985 Auto-Submitted: auto-generated Date: Tue, 19 May 2026 07:27:39 +0000 Message-Id: <6a0c10eb.27aff.24abd64a@gitrepo.freebsd.org> The branch stable/15 has been updated by ae: URL: https://cgit.FreeBSD.org/src/commit/?id=8b10555b6b709a32ed4e625a45a1cbea3a977985 commit 8b10555b6b709a32ed4e625a45a1cbea3a977985 Author: Boris Lytochkin AuthorDate: 2026-05-12 07:44:10 +0000 Commit: Andrey V. Elsukov CommitDate: 2026-05-19 07:25:45 +0000 ipfw: fix IPv6 flow label matching * do not require just only ip6 proto for flow-id opcode in ipfw(8). ipv6-icmp, tcp, udp should be fine too. * fix off-by-one bug leading to out-of-bounds read. * apply IPV6_FLOWLABEL_MASK before comparison in flow6id_match(), so flow-id opcode will match a specified flow label. No need to take protocol version and traffic class into account. * add the test to verify that opcode is working correctly. Reviewed by: pouria Obtained from: Yandex LLC Differential Revision: https://reviews.freebsd.org/D56869 (cherry picked from commit 3d39eadcdeb301e95abdc94b1ad5d1255fa0f446) --- sbin/ipfw/ipfw2.c | 5 +-- sys/netpfil/ipfw/ip_fw2.c | 4 +- tests/sys/netpfil/common/pft_ping.py | 13 +++++- tests/sys/netpfil/ipfw/Makefile | 1 + tests/sys/netpfil/ipfw/ipv6-flow-id.sh | 78 ++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 6 deletions(-) diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 9e8171a65d62..a2bfd63c6002 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -5514,10 +5514,7 @@ read_options: break; case TOK_FLOWID: - if (proto != IPPROTO_IPV6 ) - errx( EX_USAGE, "flow-id filter is active " - "only for ipv6 protocol\n"); - fill_flow6( (ipfw_insn_u32 *) cmd, *av, cblen); + fill_flow6(insntod(cmd, u32), *av, cblen); av++; break; diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index 59b35f93103a..8c0a5c16831a 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -780,7 +780,9 @@ static int flow6id_match(int curr_flow, ipfw_insn_u32 *cmd) { int i; - for (i=0; i <= cmd->o.arg1; ++i) + /* Mask proto version and traffic class out before comparing flow-id */ + curr_flow &= ntohl(IPV6_FLOWLABEL_MASK); + for (i=0; i < cmd->o.arg1; ++i) if (curr_flow == cmd->d[i]) return 1; return 0; diff --git a/tests/sys/netpfil/common/pft_ping.py b/tests/sys/netpfil/common/pft_ping.py index a2a1d9c7f4ec..ada4f8607ab0 100644 --- a/tests/sys/netpfil/common/pft_ping.py +++ b/tests/sys/netpfil/common/pft_ping.py @@ -63,6 +63,7 @@ def prepare_ipv6(send_params): dst_address = send_params.get('dst_address') hlim = send_params.get('hlim') tc = send_params.get('tc') + fl = send_params.get('fl') ip6 = sp.IPv6(dst=dst_address) if src_address: ip6.src = src_address @@ -70,6 +71,8 @@ def prepare_ipv6(send_params): ip6.hlim = hlim if tc: ip6.tc = tc + if fl: + ip6.fl = fl return ip6 @@ -224,6 +227,7 @@ def check_ipv6(expect_params, packet): flags = expect_params.get('flags') hlim = expect_params.get('hlim') tc = expect_params.get('tc') + fl = expect_params.get('fl') ip6 = packet.getlayer(sp.IPv6) if not ip6: LOGGER.debug('Packet is not IPv6!') @@ -245,6 +249,9 @@ def check_ipv6(expect_params, packet): if tc and ip6.tc != tc: LOGGER.debug(f'Wrong TC value {ip6.tc}, expected {tc}') return False + if fl and ip6.fl != fl: + LOGGER.debug(f'Wrong Flow Label value {ip6.fl}, expected {fl}') + return False return True @@ -635,6 +642,8 @@ def parse_args(): help='ICMP Echo Request payload size') parser_send.add_argument('--send-tc', type=int, help='IPv6 Traffic Class or IPv4 DiffServ / ToS') + parser_send.add_argument('--send-fl', type=int, + help='IPv6 Flow label') parser_send.add_argument('--send-tcpopt-unaligned', action='store_true', help='Include unaligned TCP options') parser_send.add_argument('--send-nop', action='store_true', @@ -652,6 +661,8 @@ def parse_args(): help='TCP sequence number') parser_expect.add_argument('--expect-tc', type=int, help='IPv6 Traffic Class or IPv4 DiffServ / ToS') + parser_expect.add_argument('--expect-fl', type=int, + help='IPv6 Flow Label') parser.add_argument('-v', '--verbose', action='store_true', help=('Enable verbose logging. Apart of potentially useful information ' @@ -673,7 +684,7 @@ def main(): send_params = {} expect_params = {} for param_name in ( - 'flags', 'hlim', 'length', 'mss', 'seq', 'tc', 'frag_length', + 'flags', 'hlim', 'length', 'mss', 'seq', 'tc', 'fl', 'frag_length', 'sport', 'dport', ): param_arg = vars(args).get(f'send_{param_name}') diff --git a/tests/sys/netpfil/ipfw/Makefile b/tests/sys/netpfil/ipfw/Makefile index 873ef43ba917..3bbbc3c996e3 100644 --- a/tests/sys/netpfil/ipfw/Makefile +++ b/tests/sys/netpfil/ipfw/Makefile @@ -4,6 +4,7 @@ TESTSDIR= ${TESTSBASE}/sys/netpfil/ipfw ATF_TESTS_SH+= fwd \ divert \ + ipv6-flow-id \ lookup ${PACKAGE}FILES+= fwd_inetd.conf \ diff --git a/tests/sys/netpfil/ipfw/ipv6-flow-id.sh b/tests/sys/netpfil/ipfw/ipv6-flow-id.sh new file mode 100644 index 000000000000..fd3ef2f6cd81 --- /dev/null +++ b/tests/sys/netpfil/ipfw/ipv6-flow-id.sh @@ -0,0 +1,78 @@ +# +# Copyright (c) 2026 Boris Lytochkin +# +# SPDX-License-Identifier: BSD-2-Clause +# + +common_dir="$(atf_get_srcdir)/../common" +. ${common_dir}/utils.subr + +NC="nc -w 1 -dnN" + +setup_network_v6() +{ + epair="$1" + + ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad -ifdisabled + + vnet_mkjail alcatraz ${epair}b + + ifconfig -j alcatraz ${epair}b inet6 2001:db8:42::2/64 up no_dad -ifdisabled + + jexec alcatraz /usr/sbin/inetd -p /dev/null $(atf_get_srcdir)/lookup_inetd.conf + + # Sanity checks + atf_check -s exit:0 -o ignore ping6 -i .1 -c 3 -s 1200 2001:db8:42::2 + atf_check -o "inline:GOOD 82\n" ${NC} 2001:db8:42::2 82 +} + +atf_test_case "ipv6fl" "cleanup" + +ipv6fl_head() +{ + atf_set descr 'flow-id test' + atf_set require.user root + atf_set require.progs python3 scapy +} + +ipv6fl_body() +{ + + firewall_init "ipfw" + + epair=$(vnet_mkepair) + + setup_network_v6 ${epair} + + # Check if the firewall is able to match exact IPv6 flow label + firewall_config "alcatraz" ipfw ipfw \ + "ipfw -q add 100 allow ip6 from any to any flow-id 0xbaad" \ + "ipfw -q add 200 deny ipv6-icmp from any to any icmp6types 128 in" + + # Check Flow Label matches + atf_check -s exit:0 ${common_dir}/pft_ping.py \ + --sendif ${epair}a \ + --fromaddr 2001:db8:42::1 \ + --to 2001:db8:42::2 \ + --send-fl $((0xbaad)) \ + --replyif ${epair}a + + # Check Flow Label mismatch + atf_check -s exit:1 ${common_dir}/pft_ping.py \ + --sendif ${epair}a \ + --fromaddr 2001:db8:42::1 \ + --to 2001:db8:42::2 \ + --send-fl $((0xf001)) \ + --replyif ${epair}a + +} + +ipv6fl_cleanup() +{ + firewall_cleanup $1 +} + +atf_init_test_cases() +{ + atf_add_test_case "ipv6fl" +}