Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 09 Aug 2026 06:47:43 +0000
From:      Kevin Bowling <kbowling@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Eric Joyner <erj@FreeBSD.org>
Subject:   git: 1ccf543b21ef - main - ifconfig: Add SR-IOV VF status output
Message-ID:  <6a78228f.3fa89.2de83f53@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=1ccf543b21eff6e0828142e5c1d09519247143f4

commit 1ccf543b21eff6e0828142e5c1d09519247143f4
Author:     Eric Joyner <erj@FreeBSD.org>
AuthorDate: 2019-03-18 18:30:00 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-09 06:46:29 +0000

    ifconfig: Add SR-IOV VF status output
    
    - Adds SR-IOV VF status to the existing ifconfig "-v" output
    - Adds ioctl command for reporting VF status info from drivers
    - Adds support to iflib for drivers to handle this new ioctl
    - Add support for ioctl in ixl(4)
    
    Signed-off-by: Eric Joyner <erj@freebsd.org>
    
    Relnotes:       yes
    Differential Revision:  https://reviews.freebsd.org/D19647
---
 sbin/ifconfig/Makefile           |  1 +
 sbin/ifconfig/ifconfig.c         |  2 ++
 sbin/ifconfig/ifconfig.h         |  1 +
 sbin/ifconfig/ifconfig_netlink.c |  3 +-
 sbin/ifconfig/ifvfstatus.c       | 78 ++++++++++++++++++++++++++++++++++++++++
 sys/dev/ixl/if_ixl.c             | 35 +++++++++++++++++-
 sys/net/if.h                     | 15 ++++++++
 sys/net/ifdi_if.m                | 12 +++++++
 sys/net/iflib.c                  | 12 +++++++
 sys/sys/sockio.h                 |  2 ++
 10 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/sbin/ifconfig/Makefile b/sbin/ifconfig/Makefile
index 26391023d54a..759b5d6f1438 100644
--- a/sbin/ifconfig/Makefile
+++ b/sbin/ifconfig/Makefile
@@ -35,6 +35,7 @@ SRCS+=	ifgif.c			# GIF reversed header workaround
 SRCS+=	ifipsec.c		# IPsec VTI
 
 SRCS+=	sfp.c			# SFP/SFP+ information
+SRCS+=	ifvfstatus.c		# VF status information
 LIBADD+=	ifconfig m util
 CFLAGS+=	-I${SRCTOP}/lib/libifconfig -I${OBJTOP}/lib/libifconfig
 
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 0e839eeafc5b..52aa5696804e 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1891,6 +1891,8 @@ status(if_ctx *ctx, const struct sockaddr_dl *sdl __unused, struct ifaddrs *ifa)
 		args->afp->af_other_status(ctx);
 
 	print_ifstatus(ctx);
+	if (args->verbose > 0)
+		vf_status(ctx);
 	if (args->verbose > 0)
 		sfp_status(ctx);
 
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 672020443b8c..75778e27a340 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -281,6 +281,7 @@ void	clone_setdefcallback_prefix(const char *, clone_callback_func *);
 void	clone_setdefcallback_filter(clone_match_func *, clone_callback_func *);
 
 void	sfp_status(if_ctx *ctx);
+void	vf_status(if_ctx *ctx);
 
 struct sockaddr_dl;
 bool	match_ether(const struct sockaddr_dl *sdl);
diff --git a/sbin/ifconfig/ifconfig_netlink.c b/sbin/ifconfig/ifconfig_netlink.c
index b1467fde4c93..565a1ac91e20 100644
--- a/sbin/ifconfig/ifconfig_netlink.c
+++ b/sbin/ifconfig/ifconfig_netlink.c
@@ -414,6 +414,8 @@ status_nl(if_ctx *ctx, struct iface *iface)
 		args->afp->af_other_status(ctx);
 
 	print_ifstatus(ctx);
+	if (args->verbose > 0)
+		vf_status(ctx);
 	if (args->drivername || args->verbose) {
 		if (ifconfig_get_orig_name(lifh, link->ifla_ifname,
 		    &drivername) != 0) {
@@ -492,4 +494,3 @@ list_interfaces_nl(struct ifconfig_args *args)
 	close(ctx->io_s);
 	snl_free(&ss);
 }
-
diff --git a/sbin/ifconfig/ifvfstatus.c b/sbin/ifconfig/ifvfstatus.c
new file mode 100644
index 000000000000..0c90d667855c
--- /dev/null
+++ b/sbin/ifconfig/ifvfstatus.c
@@ -0,0 +1,78 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ifconfig.h"
+
+void
+vf_status(if_ctx *ctx)
+{
+	struct ifvfstatus_entry *entries;
+	struct ifvfstatus ifvfs;
+
+	memset(&ifvfs, 0, sizeof(ifvfs));
+	strlcpy(ifvfs.ifvfs_name, ctx->ifname, sizeof(ifvfs.ifvfs_name));
+	if (ioctl_ctx(ctx, SIOCGIFVFSTATUS, &ifvfs) < 0)
+		return;
+	if (ifvfs.ifvfs_count == 0)
+		return;
+
+	entries = calloc(ifvfs.ifvfs_count, sizeof(*entries));
+	if (entries == NULL)
+		err(1, "calloc");
+	ifvfs.ifvfs_list = entries;
+	if (ioctl_ctx(ctx, SIOCGIFVFSTATUS, &ifvfs) < 0) {
+		free(entries);
+		warn("SIOCGIFVFSTATUS");
+		return;
+	}
+
+	printf("\tvirtual functions: %d\n", ifvfs.ifvfs_count);
+	for (int i = 0; i < ifvfs.ifvfs_count; i++) {
+		printf("\t\tvf %3d: mac %s", i,
+		    ether_ntoa((const struct ether_addr *)entries[i].mac_addr));
+		if (entries[i].vlan > -1)
+			printf(" vlan %d", entries[i].vlan);
+		if (entries[i].active)
+			printf(" active");
+		putchar('\n');
+	}
+
+	free(entries);
+}
diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c
index bfaf6cd69e58..439b93f0b80a 100644
--- a/sys/dev/ixl/if_ixl.c
+++ b/sys/dev/ixl/if_ixl.c
@@ -122,6 +122,7 @@ static uint64_t	 ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt);
 static int	 ixl_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req);
 static int	 ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data);
 static bool	 ixl_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event);
+static int	 ixl_if_vfstat_ioctl(if_ctx_t ctx, struct ifvfstatus *ifvfs);
 #ifdef PCI_IOV
 static void	 ixl_if_vflr_handle(if_ctx_t ctx);
 #endif
@@ -193,6 +194,7 @@ static device_method_t ixl_if_methods[] = {
 	DEVMETHOD(ifdi_i2c_req, ixl_if_i2c_req),
 	DEVMETHOD(ifdi_priv_ioctl, ixl_if_priv_ioctl),
 	DEVMETHOD(ifdi_needs_restart, ixl_if_needs_restart),
+	DEVMETHOD(ifdi_vfstat_ioctl, ixl_if_vfstat_ioctl),
 #ifdef PCI_IOV
 	DEVMETHOD(ifdi_iov_init, ixl_if_iov_init),
 	DEVMETHOD(ifdi_iov_uninit, ixl_if_iov_uninit),
@@ -1908,6 +1910,38 @@ ixl_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event)
 	}
 }
 
+static int
+ixl_if_vfstat_ioctl(if_ctx_t ctx, struct ifvfstatus *ifvfs)
+{
+	struct ixl_pf *pf;
+	struct ifvfstatus_entry ent;
+	struct ixl_vf *vf;
+	int error;
+
+	pf = iflib_get_softc(ctx);
+	if (pf->num_vfs < 1)
+		return (ENXIO);
+	if (ifvfs->ifvfs_count == 0) {
+		ifvfs->ifvfs_count = pf->num_vfs;
+		return (0);
+	}
+	if (ifvfs->ifvfs_count != pf->num_vfs)
+		return (EINVAL);
+
+	for (int i = 0; i < pf->num_vfs; i++) {
+		vf = &pf->vfs[i];
+		memset(&ent, 0, sizeof(ent));
+		ent.active = !!(vf->vf_flags & VF_FLAG_ENABLED);
+		memcpy(ent.mac_addr, vf->mac, sizeof(ent.mac_addr));
+		/* No host VLAN support. */
+		ent.vlan = -1;
+		error = copyout(&ent, &ifvfs->ifvfs_list[i], sizeof(ent));
+		if (error != 0)
+			return (error);
+	}
+	return (0);
+}
+
 /*
  * Sanity check and save off tunable values.
  */
@@ -1976,4 +2010,3 @@ ixl_save_pf_tunables(struct ixl_pf *pf)
 			pf->fc = ixl_flow_control;
 	}
 }
-
diff --git a/sys/net/if.h b/sys/net/if.h
index 4bb6a2659ce7..c5b7768f033d 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -662,6 +662,21 @@ struct ifdownreason {
 	char		ifdr_msg[IFDR_MSG_SIZE];
 };
 
+struct ifvfstatus_entry {
+	uint8_t		mac_addr[6];
+	int16_t		vlan;
+	uint8_t		active;
+	uint8_t		spare0;
+	uint16_t	spare1;
+	uint32_t	spare2;
+};
+
+struct ifvfstatus {
+	char		ifvfs_name[IFNAMSIZ];
+	int		ifvfs_count;
+	struct ifvfstatus_entry *ifvfs_list;
+};
+
 #endif /* __BSD_VISIBLE */
 
 /*
diff --git a/sys/net/ifdi_if.m b/sys/net/ifdi_if.m
index cb24ba36ee60..65a130d64ee4 100644
--- a/sys/net/ifdi_if.m
+++ b/sys/net/ifdi_if.m
@@ -112,6 +112,13 @@ CODE {
 		return (ENOTSUP);
 	}
 
+	static int
+	null_vfstat_ioctl(if_ctx_t _ctx __unused,
+	    struct ifvfstatus *_ifvfs __unused)
+	{
+		return (ENOTSUP);
+	}
+
 	static bool
 	null_needs_restart(if_ctx_t _ctx __unused, enum iflib_restart_event _event __unused)
 	{
@@ -375,3 +382,8 @@ METHOD int get_downreason {
 	if_ctx_t _ctx;
 	struct ifdownreason *_ifdr;
 } DEFAULT null_get_downreason;
+
+METHOD int vfstat_ioctl {
+	if_ctx_t _ctx;
+	struct ifvfstatus *_ifvfs;
+} DEFAULT null_vfstat_ioctl;
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index c56f15cc00bc..314e8e527628 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -4657,6 +4657,18 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data)
 		err = IFDI_GET_DOWNREASON(ctx, (struct ifdownreason *)data);
 		CTX_UNLOCK(ctx);
 		break;
+	case SIOCGIFVFSTATUS:
+	{
+		struct ifvfstatus *ifvfs;
+
+		ifvfs = (struct ifvfstatus *)data;
+		if (ifvfs->ifvfs_count < 0)
+			return (EINVAL);
+		CTX_LOCK(ctx);
+		err = IFDI_VFSTAT_IOCTL(ctx, ifvfs);
+		CTX_UNLOCK(ctx);
+		break;
+	}
 	default:
 		err = ether_ioctl(ifp, command, data);
 		break;
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 121acd5ba287..a3ce196c7959 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -152,4 +152,6 @@
 #define	SIOCSUMBPARAM	 _IOW('i', 158, struct ifreq)	/* set MBIM param */
 #define	SIOCGUMBPARAM	_IOWR('i', 159, struct ifreq)	/* get MBIM param */
 
+#define	SIOCGIFVFSTATUS	_IOWR('i', 163, struct ifvfstatus) /* get VF status */
+
 #endif /* !_SYS_SOCKIO_H_ */


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a78228f.3fa89.2de83f53>