mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
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
This commit is contained in:
1 parent
b2a270da9f
commit
429fbc7c35
7 files changed
+102
-23
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user