Index: head/usr.sbin/Makefile =================================================================== --- head/usr.sbin/Makefile (revision 279460) +++ head/usr.sbin/Makefile (revision 279461) @@ -1,355 +1,356 @@ # From: @(#)Makefile 5.20 (Berkeley) 6/12/93 # $FreeBSD$ .include SUBDIR= adduser \ arp \ binmiscctl \ bsdconfig \ cdcontrol \ chkgrp \ chown \ chroot \ ckdist \ clear_locks \ crashinfo \ cron \ ctladm \ ctld \ daemon \ dconschat \ devctl \ devinfo \ digictl \ diskinfo \ dumpcis \ extattr \ extattrctl \ fifolog \ fstyp \ fwcontrol \ getfmac \ getpmac \ gstat \ i2c \ ifmcstat \ iostat \ + iovctl \ kldxref \ mailwrapper \ makefs \ memcontrol \ mergemaster \ mfiutil \ mixer \ mlxcontrol \ mountd \ mptutil \ mtest \ ${_mtree} \ newsyslog \ nfscbd \ nfsd \ nfsdumpstate \ nfsrevoke \ nfsuserd \ nmtree \ nologin \ ${_pc_sysinstall} \ pciconf \ periodic \ powerd \ procctl \ pstat \ pw \ pwd_mkdb \ quot \ rarpd \ rmt \ rpcbind \ rpc.lockd \ rpc.statd \ rpc.umntall \ rtprio \ service \ services_mkdb \ setfib \ setfmac \ setpmac \ smbmsg \ snapinfo \ spray \ syslogd \ sysrc \ tcpdrop \ tcpdump \ traceroute \ trpt \ tzsetup \ uefisign \ ugidfw \ vigr \ vipw \ wake \ watch \ watchdogd \ zic # NB: keep these sorted by MK_* knobs .if ${MK_ACCT} != "no" SUBDIR+= accton SUBDIR+= sa .endif .if ${MK_AMD} != "no" SUBDIR+= amd .endif .if ${MK_AUDIT} != "no" SUBDIR+= audit SUBDIR+= auditd .if ${MK_OPENSSL} != "no" SUBDIR+= auditdistd .endif SUBDIR+= auditreduce SUBDIR+= praudit .endif .if ${MK_AUTHPF} != "no" SUBDIR+= authpf .endif .if ${MK_AUTOFS} != "no" SUBDIR+= autofs .endif .if ${MK_BLUETOOTH} != "no" SUBDIR+= bluetooth .endif .if ${MK_BOOTPARAMD} != "no" SUBDIR+= bootparamd .endif .if ${MK_BSDINSTALL} != "no" SUBDIR+= bsdinstall .endif .if ${MK_BSNMP} != "no" SUBDIR+= bsnmpd .endif .if ${MK_CTM} != "no" SUBDIR+= ctm .endif .if ${MK_FLOPPY} != "no" SUBDIR+= fdcontrol SUBDIR+= fdformat SUBDIR+= fdread SUBDIR+= fdwrite .endif .if ${MK_FMTREE} != "no" SUBDIR+= mtree .endif .if ${MK_FREEBSD_UPDATE} != "no" SUBDIR+= freebsd-update .endif .if ${MK_GSSAPI} != "no" SUBDIR+= gssd .endif .if ${MK_GPIO} != "no" SUBDIR+= gpioctl .endif .if ${MK_INET6} != "no" SUBDIR+= ip6addrctl SUBDIR+= mld6query SUBDIR+= ndp SUBDIR+= rip6query SUBDIR+= route6d SUBDIR+= rrenumd SUBDIR+= rtadvctl SUBDIR+= rtadvd SUBDIR+= rtsold SUBDIR+= traceroute6 .endif .if ${MK_INETD} != "no" SUBDIR+= inetd .endif .if ${MK_IPFW} != "no" SUBDIR+= ipfwpcap .endif .if ${MK_ISCSI} != "no" SUBDIR+= iscsid .endif .if ${MK_JAIL} != "no" SUBDIR+= jail SUBDIR+= jexec SUBDIR+= jls .endif # XXX MK_SYSCONS .if ${MK_LEGACY_CONSOLE} != "no" SUBDIR+= kbdcontrol SUBDIR+= kbdmap SUBDIR+= moused SUBDIR+= vidcontrol .endif .if ${MK_LIBTHR} != "no" || ${MK_LIBPTHREAD} != "no" .if ${MK_PPP} != "no" SUBDIR+= pppctl .endif .if ${MK_NS_CACHING} != "no" SUBDIR+= nscd .endif .endif .if ${MK_LPR} != "no" SUBDIR+= lpr .endif .if ${MK_MAN_UTILS} != "no" SUBDIR+= manctl .endif .if ${MK_NAND} != "no" SUBDIR+= nandsim SUBDIR+= nandtool .endif .if ${MK_NETGRAPH} != "no" SUBDIR+= flowctl SUBDIR+= lmcconfig SUBDIR+= ngctl SUBDIR+= nghook .endif .if ${MK_NIS} != "no" SUBDIR+= rpc.yppasswdd SUBDIR+= rpc.ypupdated SUBDIR+= rpc.ypxfrd SUBDIR+= ypbind SUBDIR+= yp_mkdb SUBDIR+= yppoll SUBDIR+= yppush SUBDIR+= ypserv SUBDIR+= ypset .endif .if ${MK_NTP} != "no" SUBDIR+= ntp .endif .if ${MK_OPENSSL} != "no" SUBDIR+= keyserv .endif .if ${MK_PC_SYSINSTALL} != "no" _pc_sysinstall= pc-sysinstall .endif .if ${MK_PF} != "no" SUBDIR+= ftp-proxy .endif .if ${MK_PKGBOOTSTRAP} != "no" SUBDIR+= pkg .endif # XXX MK_TOOLCHAIN? .if ${MK_PMC} != "no" SUBDIR+= pmcannotate SUBDIR+= pmccontrol SUBDIR+= pmcstat SUBDIR+= pmcstudy .endif .if ${MK_PORTSNAP} != "no" SUBDIR+= portsnap .endif .if ${MK_PPP} != "no" SUBDIR+= ppp .endif .if ${MK_QUOTAS} != "no" SUBDIR+= edquota SUBDIR+= quotaon SUBDIR+= repquota .endif .if ${MK_RCMDS} != "no" SUBDIR+= rwhod .endif .if ${MK_RCS} != "no" SUBDIR+= etcupdate .endif .if ${MK_SENDMAIL} != "no" SUBDIR+= editmap SUBDIR+= mailstats SUBDIR+= makemap SUBDIR+= praliases SUBDIR+= sendmail .endif .if ${MK_TCP_WRAPPERS} != "no" SUBDIR+= tcpdchk SUBDIR+= tcpdmatch .endif .if ${MK_TESTS} != "no" SUBDIR+= tests .endif .if ${MK_TIMED} != "no" SUBDIR+= timed .endif .if ${MK_TOOLCHAIN} != "no" SUBDIR+= config SUBDIR+= crunch .endif .if ${MK_UNBOUND} != "no" SUBDIR+= unbound .endif .if ${MK_USB} != "no" SUBDIR+= uathload SUBDIR+= uhsoctl SUBDIR+= usbconfig SUBDIR+= usbdump .endif .if ${MK_UTMPX} != "no" SUBDIR+= ac SUBDIR+= lastlogin SUBDIR+= utx .endif .if ${MK_WIRELESS} != "no" SUBDIR+= ancontrol SUBDIR+= wlandebug SUBDIR+= wpa .endif .include SUBDIR:= ${SUBDIR:O} SUBDIR_PARALLEL= .include Index: head/usr.sbin/iovctl/Makefile =================================================================== --- head/usr.sbin/iovctl/Makefile (nonexistent) +++ head/usr.sbin/iovctl/Makefile (revision 279461) @@ -0,0 +1,17 @@ +# $FreeBSD$ + +PROG= iovctl +SRCS= iovctl.c parse.c validate.c +LIBADD= nv ucl m + +CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include + +WARNS?=6 + +MAN= \ + iovctl.8 \ + iovctl.conf.5 \ + +.include +.include + Property changes on: head/usr.sbin/iovctl/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/usr.sbin/iovctl/iovctl.c =================================================================== --- head/usr.sbin/iovctl/iovctl.c (nonexistent) +++ head/usr.sbin/iovctl/iovctl.c (revision 279461) @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved. + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iovctl.h" + +static void config_action(const char *filename, int dryrun); +static void delete_action(const char *device, int dryrun); +static void print_schema(const char *device); + +/* + * Fetch the config schema from the kernel via ioctl. This function has to + * call the ioctl twice: the first returns the amount of memory that we need + * to allocate for the schema, and the second actually fetches the schema. + */ +static nvlist_t * +get_schema(int fd) +{ + struct pci_iov_schema arg; + nvlist_t *schema; + int error; + + /* Do the ioctl() once to fetch the size of the schema. */ + arg.schema = NULL; + arg.len = 0; + arg.error = 0; + error = ioctl(fd, IOV_GET_SCHEMA, &arg); + if (error != 0) + err(1, "Could not fetch size of config schema"); + + arg.schema = malloc(arg.len); + if (arg.schema == NULL) + err(1, "Could not allocate %zu bytes for schema", + arg.len); + + /* Now do the ioctl() for real to get the schema. */ + error = ioctl(fd, IOV_GET_SCHEMA, &arg); + if (error != 0 || arg.error != 0) { + if (arg.error != 0) + errno = arg.error; + err(1, "Could not fetch config schema"); + } + + schema = nvlist_unpack(arg.schema, arg.len); + if (schema == NULL) + err(1, "Could not unpack schema"); + + free(arg.schema); + return (schema); +} + +/* + * Call the ioctl that activates SR-IOV and creates the VFs. + */ +static void +config_iov(int fd, const char *dev_name, const nvlist_t *config, int dryrun) +{ + struct pci_iov_arg arg; + int error; + + arg.config = nvlist_pack(config, &arg.len); + if (arg.config == NULL) + err(1, "Could not pack configuration"); + + if (dryrun) { + printf("Would enable SR-IOV on device '%s'.\n", dev_name); + printf( + "The following configuration parameters would be used:\n"); + nvlist_fdump(config, stdout); + printf( + "The configuration parameters consume %zu bytes when packed.\n", + arg.len); + } else { + error = ioctl(fd, IOV_CONFIG, &arg); + if (error != 0) + err(1, "Failed to configure SR-IOV"); + } + + free(arg.config); +} + +static int +open_device(const char *dev_name) +{ + char *dev; + int fd; + size_t copied, size; + long path_max; + + path_max = pathconf("/dev", _PC_PATH_MAX); + if (path_max < 0) + err(1, "Could not get maximum path length"); + + size = path_max; + dev = malloc(size); + if (dev == NULL) + err(1, "Could not allocate memory for device path"); + + if (dev_name[0] == '/') + copied = strlcpy(dev, dev_name, size); + else + copied = snprintf(dev, size, "/dev/iov/%s", dev_name); + + /* >= to account for null terminator. */ + if (copied >= size) + errx(1, "Provided file name too long"); + + fd = open(dev, O_RDWR); + if (fd < 0) + err(1, "Could not open device '%s'", dev); + + free(dev); + return (fd); +} + +static void +usage(void) +{ + + warnx("Usage: iovctl -C -f [-n]"); + warnx(" iovctl -D [-d | -f ] [-n]"); + warnx(" iovctl -S [-d | -f ]"); + exit(1); + +} + +enum main_action { + NONE, + CONFIG, + DELETE, + PRINT_SCHEMA, +}; + +int +main(int argc, char **argv) +{ + char *device; + const char *filename; + int ch, dryrun; + enum main_action action; + + device = NULL; + filename = NULL; + dryrun = 0; + action = NONE; + + while ((ch = getopt(argc, argv, "Cd:Df:nS")) != -1) { + switch (ch) { + case 'C': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = CONFIG; + break; + case 'd': + device = strdup(optarg); + break; + case 'D': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = DELETE; + break; + case 'f': + filename = optarg; + break; + case 'n': + dryrun = 1; + break; + case 'S': + if (action != NONE) { + warnx( + "Only one of -C, -D or -S may be specified"); + usage(); + } + action = PRINT_SCHEMA; + break; + case '?': + warnx("Unrecognized argument '-%c'\n", optopt); + usage(); + break; + } + } + + if (device != NULL && filename != NULL) { + warnx("Only one of the -d and -f flags may be specified"); + usage(); + } + + if (device == NULL && filename == NULL) { + warnx("Either the -d or -f flag must be specified"); + usage(); + } + + switch (action) { + case CONFIG: + if (filename == NULL) { + warnx("-d flag cannot be used with the -C flag"); + usage(); + } + config_action(filename, dryrun); + break; + case DELETE: + if (device == NULL) + device = find_device(filename); + delete_action(device, dryrun); + free(device); + break; + case PRINT_SCHEMA: + if (dryrun) { + warnx("-n flag cannot be used with the -S flag"); + usage(); + } + if (device == NULL) + device = find_device(filename); + print_schema(device); + free(device); + break; + default: + usage(); + break; + } + + exit(0); +} + +static void +config_action(const char *filename, int dryrun) +{ + char *dev; + nvlist_t *schema, *config; + int fd; + + dev = find_device(filename); + fd = open(dev, O_RDWR); + if (fd < 0) + err(1, "Could not open device '%s'", dev); + + schema = get_schema(fd); + config = parse_config_file(filename, schema); + if (config == NULL) + errx(1, "Could not parse config"); + + config_iov(fd, dev, config, dryrun); + + nvlist_destroy(config); + nvlist_destroy(schema); + free(dev); + close(fd); +} + +static void +delete_action(const char *dev_name, int dryrun) +{ + int fd, error; + + fd = open_device(dev_name); + + if (dryrun) + printf("Would attempt to delete all VF children of '%s'\n", + dev_name); + else { + error = ioctl(fd, IOV_DELETE); + if (error != 0) + err(1, "Failed to delete VFs"); + } + + close(fd); +} + +static void +print_default_value(const nvlist_t *parameter, const char *type) +{ + const uint8_t *mac; + size_t size; + + if (strcasecmp(type, "bool") == 0) + printf(" (default = %s)", + nvlist_get_bool(parameter, DEFAULT_SCHEMA_NAME) ? "true" : + "false"); + else if (strcasecmp(type, "string") == 0) + printf(" (default = %s)", + nvlist_get_string(parameter, DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint8_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint16_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint32_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "uint64_t") == 0) + printf(" (default = %ju)", + (uintmax_t)nvlist_get_number(parameter, + DEFAULT_SCHEMA_NAME)); + else if (strcasecmp(type, "unicast-mac") == 0) { + mac = nvlist_get_binary(parameter, DEFAULT_SCHEMA_NAME, &size); + printf(" (default = %02x:%02x:%02x:%02x:%02x:%02x)", mac[0], + mac[1], mac[2], mac[3], mac[4], mac[5]); + } else + errx(1, "Unexpected type in schema: '%s'", type); +} + +static void +print_subsystem_schema(const nvlist_t * subsystem_schema) +{ + const char *name, *type; + const nvlist_t *parameter; + void *it; + int nvtype; + + it = NULL; + while ((name = nvlist_next(subsystem_schema, &nvtype, &it)) != NULL) { + parameter = nvlist_get_nvlist(subsystem_schema, name); + type = nvlist_get_string(parameter, TYPE_SCHEMA_NAME); + + printf("\t%s : %s", name, type); + if (dnvlist_get_bool(parameter, REQUIRED_SCHEMA_NAME, false)) + printf(" (required)"); + else if (nvlist_exists(parameter, DEFAULT_SCHEMA_NAME)) + print_default_value(parameter, type); + else + printf(" (optional)"); + printf("\n"); + } +} + +static void +print_schema(const char *dev_name) +{ + nvlist_t *schema; + const nvlist_t *iov_schema, *driver_schema, *pf_schema, *vf_schema; + int fd; + + fd = open_device(dev_name); + schema = get_schema(fd); + + pf_schema = nvlist_get_nvlist(schema, PF_CONFIG_NAME); + iov_schema = nvlist_get_nvlist(pf_schema, IOV_CONFIG_NAME); + driver_schema = nvlist_get_nvlist(pf_schema, DRIVER_CONFIG_NAME); + printf( +"The following configuration parameters may be configured on the PF:\n"); + print_subsystem_schema(iov_schema); + print_subsystem_schema(driver_schema); + + vf_schema = nvlist_get_nvlist(schema, VF_SCHEMA_NAME); + iov_schema = nvlist_get_nvlist(vf_schema, IOV_CONFIG_NAME); + driver_schema = nvlist_get_nvlist(vf_schema, DRIVER_CONFIG_NAME); + printf( +"\nThe following configuration parameters may be configured on a VF:\n"); + print_subsystem_schema(iov_schema); + print_subsystem_schema(driver_schema); + + nvlist_destroy(schema); + close(fd); +} Property changes on: head/usr.sbin/iovctl/iovctl.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/usr.sbin/iovctl/iovctl.h =================================================================== --- head/usr.sbin/iovctl/iovctl.h (nonexistent) +++ head/usr.sbin/iovctl/iovctl.h (revision 279461) @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013-2015 Sandvine Inc. All rights reserved. + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef IOVCTL_H +#define IOVCTL_H + +char * find_device(const char *); +nvlist_t * parse_config_file(const char *, const nvlist_t *); +void validate_config(nvlist_t *, const nvlist_t *, const regex_t *); + +#endif + Property changes on: head/usr.sbin/iovctl/iovctl.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property