mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
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 <[email protected]> Relnotes: yes Differential Revision: https://reviews.freebsd.org/D19647
This commit is contained in:
1 parent
75538a0f32
commit
1ccf543b21
10 files changed
+159
-2
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+34
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ */
|
||||
Reference in new issue
Block a user