From nobody Thu Sep 10 07:17:10 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 4hgTWw1xD5z6rXxl for ; Thu, 10 Sep 2026 07:17:16 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hgTWv6c0mz3Jb4 for ; Thu, 10 Sep 2026 07:17:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789024635; 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=9wfJiNXBpYah8XWcHSwfnSbFHHlwKSamzIMsmlH3u+c=; b=SwuTSKd4lNRcNWs+hmA/aE67d7tU3JXYXjlXhduYb+JonqBf7zSmIEGHO6oJ8/ehnmqFhA ZI5JF33SRbBVwiD6bqLLnNJDV9xH7OYZ0uCfQAoOpkud/a6vJQ3NvQZh6DdSQ402gV/r6f L4lUJfYJGV0H4sWryS7yAfFDdBETDBUqQgxRZJM7Q01DIn40BvIiX4el30HACYnr7hIEGj UZBipqx6IDQtJAwvSU4UVAQYTjISq4tNfOTrdnPZk3pp9An4gFzh2C9p4qJGrIVF41PdNg tY9VXAwjGfXOPGohF2JJwXukm8UHIbPJsFIv9TA2u4nda/OpcdEEGKfsfwYdDw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789024635; b=ve5ZbGtkGQpwwG8T3TVQACXQ3ls+g4/f7X6NAbfVsFH/8oSdiwHsGfqk2pHLfIGyli7ONd AK8kcpBVBxlW4NuBmvgeoW6dDeQPjgC5TghgtuhaQPj8PxrCOVK5fAtYDhbG4mckLjzyoE 4F7PGZdFQYKAyYKTcE+J4AL54krIzoLZwkQ37qVND9szdIoeTWdNg5bvhtiRD6bcNjCB5m IFBSFybeJT1foFAzplXVVUJ/6S3Fac/5jZEX8bvOa+nUIwEs3ZKvpQ1vnNSLGuVuh4nKKi 5Pp89KcMm7fb91ki7mT6Y1hBosdm3dFH0iDcXKxPnKMR+9VkXWrbJDPungEXKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789024635; 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=9wfJiNXBpYah8XWcHSwfnSbFHHlwKSamzIMsmlH3u+c=; b=VZ3VtPpoMxY2J8m2Sb5KgyXSsWCmfc1aPAK4FXk6lT4+2FAxh6zRmLErsDCYJYaprrVkAg L244YxSGdVQwa2S9zS963YyH9EguktRXJFGFFiIWoMTfYoCkd3aMIUqFHapcblFI6NfGb4 V9W4wVnEv6GCgz0FS26ZIls1lsUKVJPpJevOUqOyWcjRztVV8cwguFHu7omntBBciMHgDu YbgDisE1A0SBsEC4G2obPrTQ8VsAphsxlz6YRxUCrV6IatsPsnTB8Bt323Y+MOzsoYrRqL BJ0PcXVmYt/FzNVXMHhiqiGalTbeaW9f2AYeDVJoKJro0uXuRKXcQhF2aZhlwA== 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 4hgTWv5PzZzH8x for ; Thu, 10 Sep 2026 07:17:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 45716 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 10 Sep 2026 07:17:10 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 429fbc7c35a6 - main - rtnetlink: Allow VF priority reporting in trunk mode 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: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 429fbc7c35a6d860462db3109608b7f800f0e50b Auto-Submitted: auto-generated Date: Thu, 10 Sep 2026 07:17:10 +0000 Message-Id: <6aa25976.45716.a369266@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=429fbc7c35a6d860462db3109608b7f800f0e50b commit 429fbc7c35a6d860462db3109608b7f800f0e50b Author: Kevin Bowling AuthorDate: 2026-09-10 06:54:50 +0000 Commit: Kevin Bowling CommitDate: 2026-09-10 07:15:27 +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 --- 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 c1d560fb4d12..5474655a4ab1 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 e217b1190b4d..eacb9c5db54a 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 @@ -401,7 +401,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 @@ -460,17 +460,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 328314d25ebb..59101ee60e77 100644 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -491,8 +491,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 | @@ -514,6 +513,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) @@ -695,8 +699,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; @@ -712,6 +715,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 a1c5b8455b3b..fc115116261d 100644 --- a/tests/sys/netlink/test_snl.c +++ b/tests/sys/netlink/test_snl.c @@ -297,6 +297,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) { @@ -706,6 +762,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);