From nobody Sat Oct 31 18:58:44 2026 X-Original-To: dev-commits-src-branches@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 4jH6gm4SH3z6x5tq for ; Sat, 31 Oct 2026 18:58: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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jH6gm33F6z3J3j for ; Sat, 31 Oct 2026 18:58:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473124; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8TjVvzit7T0HuMgENlLf1AIOnGd9+JTblPFJrinPLLk=; b=qw5ryZjlK1xLTdkZg4Whbbb9CIZjlUc3Km2BdZpM5hmoSM/cqey1QgRoYKEAX5y8aJuneI A/CKxCRtQd8MNJaQLRDLD/q4DYYX5Of4ar2TOhm7mNRW4Nsn9dI6lT/MIShC/jBZuxOz0U a9HUmOcWJX8nyIN3hl5c3Op8PMWZwO5xKTC1nUDaPgJl5/vJs510cY68kPsSuYGg/QbUGZ pANP+Zb48vJGrZuf25snBbXMVRdKTFyChro/ir/ze6sqWg9Ew3dkqX38beqiNh8qs7zD/t YS995WXQDgr8SDaCBjWk7416aG2k3uSliLkSL7NZeccXtaVa3TupYHYHdDf63g== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793473124; b=Gd3NtRp+kX9AJ5wJcg8zZwGbWsX9Q+906GkbMSp28rzf6VMqOwdwVMGThKpWA878zsgpQM +yGp2fv79ln8Hl/fvyv4vLH/vbJrCWmZTDISwNaV8+wAqutYwGrHZMx0P1EYTcMDbEAjkm b2bb2HpQS7xCEoyXE/BRe4uDNBCHREMXY9w/r48W6aRTu+EfdEmbIFM8H5hBKhEMgI7wT2 Ce9TBpSOeGHDHO4CvcgFEc+P2tokScGWbcEP2r41LzJgr/IXeM8IvKRpp0jXdi7X++kk5Z 6mP94uzqYNfM1LAp1Y2H8ww2ow5L9//Ifhd0O6KgJ/08VJNKdiADsRRW+BZzXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793473124; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8TjVvzit7T0HuMgENlLf1AIOnGd9+JTblPFJrinPLLk=; b=a4PEs6qM0hAhWRQVjcPD/mQ0xnZTouCZBl4bxQHrLq/yHVmrR6otgHlgeY7bbWYKY0FX/W 0qTP20Ay2jDX7EsS3fdIpTlcxherMD/YzslyHvtKI7S4n3noT2KxYHb13Aq1Dz+/ujm1t7 8WCNF3tX08Dr6B0K9izBvTU7dwZEUU3rejNh1lPpmY0w1yAzoBFO+gGzoI+ptPIJcDErz+ D/g7IEtuApvG43PAX11aoi4aUPlt5TX6damMbyiu1sILJzZawPW9X5jIa6lHJxWAiRWL+J UGCAFa6NYTrLc/pH+LSCw+3B22PPlB25ZDPKFobC27/IongzZyt1+ZrAqpbM+w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jH6gm2kBkzPCP for ; Sat, 31 Oct 2026 18:58:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22c41 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 31 Oct 2026 18:58:44 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 6a98111eab80 - stable/15 - rtnetlink: Allow VF priority reporting in trunk mode List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 6a98111eab803df454233c146f5d9e09b5b3e1ad Auto-Submitted: auto-generated Date: Sat, 31 Oct 2026 18:58:44 +0000 Message-Id: <6ae63a64.22c41.355a4677@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=6a98111eab803df454233c146f5d9e09b5b3e1ad commit 6a98111eab803df454233c146f5d9e09b5b3e1ad Author: Kevin Bowling AuthorDate: 2026-09-10 06:54:50 +0000 Commit: Kevin Bowling CommitDate: 2026-10-31 18:57:04 +0000 rtnetlink: Allow VF priority reporting in trunk mode PF-administered priority need not impose an access VLAN. Permit the existing VLAN PCP attribute in either access or trunk mode, while keeping VLAN identifier and protocol access only. Display trunk PCP in ifconfig and document the broader meaning in the kernel snapshot, libifconfig, and rtnetlink contracts. This changes no attribute numbers, wire encoding, or structure layout. Reported by: kib Sponsored by: BBOX.io (cherry picked from commit 429fbc7c35a6d860462db3109608b7f800f0e50b) --- lib/libifconfig/libifconfig.h | 6 +++-- sbin/ifconfig/ifconfig.8 | 8 ++++-- sbin/ifconfig/ifvfstatus.c | 3 ++- share/man/man4/rtnetlink.4 | 22 ++++++++++------- sys/net/if_vf_status.h | 13 ++++++---- sys/netlink/route/iface.c | 16 +++++++++--- tests/sys/netlink/test_snl.c | 57 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 102 insertions(+), 23 deletions(-) diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h index dd2fd16dba92..bf9039f80c8d 100644 --- a/lib/libifconfig/libifconfig.h +++ b/lib/libifconfig/libifconfig.h @@ -214,8 +214,10 @@ int ifconfig_get_ifstatus(ifconfig_handle_t *h, const char *name, * the returned status object and is released by ifconfig_free_vf_status(). * VF records are returned through a pointer vector so append-only growth of * struct ifconfig_vf_info does not change the array stride seen by existing - * consumers. VLAN PCP and protocol describe the PF-administered access VLAN; - * they do not describe trunk-filter entries. + * consumers. VLAN identifier and protocol describe the PF-administered + * access VLAN. VLAN PCP describes PF-administered priority in access or + * trunk mode, including priority-only tagging with VID 0. These fields do + * not describe individual trunk filters or VF-selected priorities. */ enum ifconfig_vf_vlan_mode { diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index d8f20b93d0bb..f551d93a4596 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 6, 2026 +.Dd September 10, 2026 .Dt IFCONFIG 8 .Os .Sh NAME @@ -359,8 +359,12 @@ A zero minimum is displayed as .It Cm vlan An access VLAN is imposed by the PF; trunk mode means that no access VLAN is imposed and does not promise unlimited filter capacity. -Access mode may also report the priority code point and VLAN protocol. +Access mode may also report the VLAN protocol. The VLAN identifier can be zero when the PF imposes priority tagging only. +The PF-administered priority code point may be reported in access or trunk +mode. +An omitted priority is distinct from +.Cm pcp=0 . The filter count includes explicit filters recorded by the PF and excludes implicit untagged and priority-tag membership. .It Cm policy diff --git a/sbin/ifconfig/ifvfstatus.c b/sbin/ifconfig/ifvfstatus.c index 82cf0c5400d7..70cac1d1e8cc 100644 --- a/sbin/ifconfig/ifvfstatus.c +++ b/sbin/ifconfig/ifvfstatus.c @@ -241,7 +241,8 @@ vf_status(if_ctx *ctx) if (vf->vlan_mode == IFCONFIG_VF_VLAN_ACCESS && (vf->fields & (1ULL << IFLAF_VF_VLAN)) != 0) printf(" vid=%u", vf->vlan); - if (vf->vlan_mode == IFCONFIG_VF_VLAN_ACCESS && + if ((vf->vlan_mode == IFCONFIG_VF_VLAN_ACCESS || + vf->vlan_mode == IFCONFIG_VF_VLAN_TRUNK) && (vf->fields & (1ULL << IFLAF_VF_VLAN_PCP)) != 0) printf(" pcp=%u", vf->vlan_pcp); if (vf->vlan_mode == IFCONFIG_VF_VLAN_ACCESS && diff --git a/share/man/man4/rtnetlink.4 b/share/man/man4/rtnetlink.4 index 59b219b9e6e5..ba9d2bfb4c1a 100644 --- a/share/man/man4/rtnetlink.4 +++ b/share/man/man4/rtnetlink.4 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 6, 2026 +.Dd September 9, 2026 .Dt RTNETLINK 4 .Os .Sh NAME @@ -394,7 +394,7 @@ IFLAF_VF_INITIALIZED (bool) VF handshake completed IFLAF_VF_MAC (binary) PF-known primary MAC address IFLAF_VF_VLAN_MODE (uint8_t) IFLAF_VF_VLAN_* IFLAF_VF_VLAN (uint16_t) access VLAN identifier -IFLAF_VF_VLAN_PCP (uint8_t) access VLAN priority code point +IFLAF_VF_VLAN_PCP (uint8_t) PF-administered priority code point IFLAF_VF_VLAN_PROTO (uint16_t) host-order access VLAN EtherType IFLAF_VF_VLAN_COUNT (uint32_t) explicit VLAN filters IFLAF_VF_VLAN_LIMIT (uint32_t) explicit VLAN-filter limit @@ -453,17 +453,21 @@ When both are present and the maximum is nonzero, the minimum does not exceed the maximum. Access VLAN mode means that the PF imposes a single port VLAN policy. The optional -.Dv IFLAF_VF_VLAN , -.Dv IFLAF_VF_VLAN_PCP , +.Dv IFLAF_VF_VLAN and .Dv IFLAF_VF_VLAN_PROTO -attributes describe its VLAN identifier, IEEE 802.1p priority code point, and -host-order tag EtherType, respectively. -A present zero VLAN identifier can represent a priority-only access tag, and a -present zero priority is distinct from an omitted priority. -These attributes do not describe the VF's trunk filters. +attributes describe its VLAN identifier and host-order tag EtherType, +respectively, and are present only in access mode. +A present zero VLAN identifier can represent a priority-only access tag. Trunk mode means that no access VLAN is imposed and does not promise unlimited filter capacity. +.Dv IFLAF_VF_VLAN_PCP +describes the PF-administered IEEE 802.1p priority code point (0 through 7). +It may be present in access or trunk mode, including priority-only tagging +with VID 0. +A present zero priority is distinct from an omitted priority. +These attributes do not describe individual trunk filters or priorities +selected by the VF. .Dv IFLAF_VF_VLAN_COUNT counts explicit filters recorded by the PF. It excludes untagged or priority-tag membership installed implicitly by the diff --git a/sys/net/if_vf_status.h b/sys/net/if_vf_status.h index 57c625ff530c..4c24a4a8b615 100644 --- a/sys/net/if_vf_status.h +++ b/sys/net/if_vf_status.h @@ -19,11 +19,14 @@ * identifying which other members contain valid data. This distinguishes a * missing value from a value of false or zero. Drivers set bits only for * information they can report, and each transport converts the snapshot to - * its own ABI. VLAN PCP and protocol describe the PF-administered access - * VLAN, not the VF's trunk filters. Transmit rates describe an aggregate VF - * policy. When both are present and the maximum is nonzero, the minimum must - * not exceed it. A successful snapshot may contain zero VFs, allowing a - * provider to report that SR-IOV is available but is not currently configured. + * its own ABI. VLAN identifier and protocol describe the PF-administered + * access VLAN. VLAN PCP describes PF-administered priority in access or + * trunk mode, including priority-only tagging with VID 0. These fields do + * not describe individual trunk filters or VF-selected priorities. + * Transmit rates describe an aggregate VF policy. When both are present and + * the maximum is nonzero, the minimum must not exceed it. A successful + * snapshot may contain zero VFs, allowing a provider to report that SR-IOV is + * available but is not currently configured. */ #define IFVF_MAX_VFS UINT16_MAX #define IFVF_MAX_EXTENSIONS 16 diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c index f957e2d55785..68252019b520 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -489,8 +489,7 @@ validate_vf_extension(const struct if_vf_extension *extension, static int validate_vf_entry(const struct if_vf_info *vf, size_t *encoded_size) { - const uint64_t access_fields = IFVF_F_VLAN | IFVF_F_VLAN_PCP | - IFVF_F_VLAN_PROTO; + const uint64_t access_fields = IFVF_F_VLAN | IFVF_F_VLAN_PROTO; const uint64_t rate_fields = IFVF_F_MIN_TX_RATE | IFVF_F_MAX_TX_RATE; const uint64_t bool_fields = IFVF_F_CONFIGURED | IFVF_F_INITIALIZED | @@ -512,6 +511,11 @@ validate_vf_entry(const struct if_vf_info *vf, size_t *encoded_size) ((vf->fields & IFVF_F_VLAN_MODE) == 0 || vf->vlan_mode != IFVF_VLAN_ACCESS)) return (EINVAL); + if ((vf->fields & IFVF_F_VLAN_PCP) != 0 && + ((vf->fields & IFVF_F_VLAN_MODE) == 0 || + (vf->vlan_mode != IFVF_VLAN_ACCESS && + vf->vlan_mode != IFVF_VLAN_TRUNK))) + return (EINVAL); if ((vf->fields & rate_fields) == rate_fields && vf->max_tx_rate_bps != 0 && vf->min_tx_rate_bps > vf->max_tx_rate_bps) @@ -693,8 +697,7 @@ dump_vf_extensions(struct nl_writer *nw, const struct if_vf_info *vf) static int dump_vf_entry(struct nl_writer *nw, const struct if_vf_info *vf) { - const uint64_t access_fields = IFVF_F_VLAN | IFVF_F_VLAN_PCP | - IFVF_F_VLAN_PROTO; + const uint64_t access_fields = IFVF_F_VLAN | IFVF_F_VLAN_PROTO; const uint64_t rate_fields = IFVF_F_MIN_TX_RATE | IFVF_F_MAX_TX_RATE; int error, off; @@ -710,6 +713,11 @@ dump_vf_entry(struct nl_writer *nw, const struct if_vf_info *vf) ((vf->fields & IFVF_F_VLAN_MODE) == 0 || vf->vlan_mode != IFVF_VLAN_ACCESS)) return (EINVAL); + if ((vf->fields & IFVF_F_VLAN_PCP) != 0 && + ((vf->fields & IFVF_F_VLAN_MODE) == 0 || + (vf->vlan_mode != IFVF_VLAN_ACCESS && + vf->vlan_mode != IFVF_VLAN_TRUNK))) + return (EINVAL); if ((vf->fields & rate_fields) == rate_fields && vf->max_tx_rate_bps != 0 && vf->min_tx_rate_bps > vf->max_tx_rate_bps) diff --git a/tests/sys/netlink/test_snl.c b/tests/sys/netlink/test_snl.c index 2a81cc61412b..161e3615327e 100644 --- a/tests/sys/netlink/test_snl.c +++ b/tests/sys/netlink/test_snl.c @@ -304,6 +304,62 @@ ATF_TC_BODY(snl_parse_vf_status, tc) ATF_CHECK_EQ(vf->index, 15); } +ATF_TC(snl_parse_vf_trunk_pcp); +ATF_TC_HEAD(snl_parse_vf_trunk_pcp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests snl(3) parsing trunk PCP values and omitted priority"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} + +ATF_TC_BODY(snl_parse_vf_trunk_pcp, tc) +{ + struct snl_parsed_link link = {}; + struct snl_parsed_vf *vf; + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr; + uint32_t i; + int entry_off; + + ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE)); + snl_init_writer(&ss, &nw); + hdr = snl_create_msg_request(&nw, RTM_NEWLINK); + ATF_REQUIRE(hdr != NULL); + ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL); + ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLA_NUM_VF, 9)); + for (i = 0; i < 9; i++) { + entry_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD_VF); + ATF_REQUIRE(entry_off != 0); + ATF_REQUIRE(snl_add_msg_attr_u32(&nw, IFLAF_VF_INDEX, i)); + ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_MODE, + IFLAF_VF_VLAN_TRUNK)); + /* Cover PCP 0..7 and absence, without an imposed VLAN. */ + if (i < 8) + ATF_REQUIRE(snl_add_msg_attr_u8(&nw, IFLAF_VF_VLAN_PCP, + i)); + snl_end_attr_nested(&nw, entry_off); + } + hdr = snl_finalize_msg(&nw); + ATF_REQUIRE(hdr != NULL); + ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link)); + ATF_CHECK_EQ(link.ifla_num_vf, 9); + ATF_REQUIRE_EQ(link.iflaf_vf_status.vfs.count, 9); + for (i = 0; i < 9; i++) { + vf = link.iflaf_vf_status.vfs.items[i]; + ATF_CHECK_EQ(vf->index, i); + ATF_CHECK((vf->attrs & (1ULL << IFLAF_VF_VLAN_MODE)) != 0); + ATF_CHECK_EQ(vf->vlan_mode, IFLAF_VF_VLAN_TRUNK); + ATF_CHECK((vf->attrs & ((1ULL << IFLAF_VF_VLAN) | + (1ULL << IFLAF_VF_VLAN_PROTO))) == 0); + ATF_CHECK_EQ((vf->attrs & (1ULL << IFLAF_VF_VLAN_PCP)) != 0, + i < 8); + if (i < 8) + ATF_CHECK_EQ(vf->vlan_pcp, i); + } + snl_free(&ss); +} + ATF_TC(snl_parse_large_vf_status); ATF_TC_HEAD(snl_parse_large_vf_status, tc) { @@ -717,6 +773,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, snl_parse_bitset_array); ATF_TP_ADD_TC(tp, snl_verify_route_parsers); ATF_TP_ADD_TC(tp, snl_parse_vf_status); + ATF_TP_ADD_TC(tp, snl_parse_vf_trunk_pcp); ATF_TP_ADD_TC(tp, snl_parse_large_vf_status); ATF_TP_ADD_TC(tp, snl_parse_empty_vf_status); ATF_TP_ADD_TC(tp, snl_parse_vf_status_error);