The branch main has been updated by kp:

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

commit c57c26179033f64c2011a2d2a904ee3fa62e826a
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2024-05-29 17:29:35 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2024-06-17 08:50:15 +0000

    iovctl: allow vlan restrictions to be passed to the driver
    
    Allow iovctl to create VFs that are restricted to specific VLAN IDs.
    
    Reviewed by:    kib, np
    MFC after:      2 weeks
    Sponsored by:   Orange Business Services
    Differential Revision:  https://reviews.freebsd.org/D45402
---
 sys/dev/pci/pci_iov_schema.c  | 61 +++++++++++++++++++++++++++++++++++++++++++
 sys/sys/iov.h                 |  2 ++
 sys/sys/iov_schema.h          |  3 ++-
 usr.sbin/iovctl/iovctl.c      |  6 +++++
 usr.sbin/iovctl/iovctl.conf.5 |  5 +++-
 usr.sbin/iovctl/parse.c       | 25 ++++++++++++++++++
 6 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/sys/dev/pci/pci_iov_schema.c b/sys/dev/pci/pci_iov_schema.c
index 3cec329d77a1..804a8b1c0a8f 100644
--- a/sys/dev/pci/pci_iov_schema.c
+++ b/sys/dev/pci/pci_iov_schema.c
@@ -54,11 +54,13 @@ static validate_func pci_iov_schema_validate_bool;
 static validate_func pci_iov_schema_validate_string;
 static validate_func pci_iov_schema_validate_uint;
 static validate_func pci_iov_schema_validate_unicast_mac;
+static validate_func pci_iov_schema_validate_vlan;
 
 static default_validate_t pci_iov_validate_bool_default;
 static default_validate_t pci_iov_validate_string_default;
 static default_validate_t pci_iov_validate_uint_default;
 static default_validate_t pci_iov_validate_unicast_mac_default;
+static default_validate_t pci_iov_validate_vlan_default;
 
 struct config_type_validator {
        const char *type_name;
@@ -107,6 +109,11 @@ static struct config_type_validator 
pci_iov_schema_validators[] = {
                .validate = pci_iov_schema_validate_unicast_mac,
                .default_validate = pci_iov_validate_unicast_mac_default,
        },
+       {
+               .type_name = "vlan",
+               .validate = pci_iov_schema_validate_vlan,
+               .default_validate = pci_iov_validate_vlan_default,
+       },
 };
 
 static const struct config_type_validator *
@@ -261,6 +268,26 @@ pci_iov_schema_add_unicast_mac(nvlist_t *schema, const 
char *name,
        nvlist_move_nvlist(schema, name, entry);
 }
 
+void
+pci_iov_schema_add_vlan(nvlist_t *schema, const char *name,
+    uint32_t flags, const uint16_t defaultVal)
+{
+       nvlist_t *entry;
+
+       entry = nvlist_create(NV_FLAG_IGNORE_CASE);
+       if (entry == NULL) {
+               nvlist_set_error(schema, ENOMEM);
+               return;
+       }
+
+       pci_iov_schema_add_type(entry, "vlan");
+       if (flags & IOV_SCHEMA_HASDEFAULT)
+               nvlist_add_number(entry, "default", defaultVal);
+       pci_iov_schema_add_required(entry, flags);
+
+       nvlist_move_nvlist(schema, name, entry);
+}
+
 static int
 pci_iov_schema_validate_bool(const struct config_type_validator * validator,
    const nvlist_t *config, const char *name)
@@ -320,6 +347,24 @@ pci_iov_schema_validate_unicast_mac(
        return (0);
 }
 
+static int
+pci_iov_schema_validate_vlan(
+    const struct config_type_validator * validator,
+    const nvlist_t *config, const char *name)
+{
+       uint16_t vlan;
+
+       if (!nvlist_exists_number(config, name))
+               return (EINVAL);
+
+       vlan = nvlist_get_number(config, name);
+
+       if (vlan > 4095 && vlan != VF_VLAN_TRUNK)
+               return (EINVAL);
+
+       return (0);
+}
+
 static void
 pci_iov_config_add_default(const nvlist_t *param_schema, const char *name,
     nvlist_t *config)
@@ -400,6 +445,22 @@ pci_iov_validate_unicast_mac_default(
        return (0);
 }
 
+static int
+pci_iov_validate_vlan_default(
+    const struct config_type_validator * validator, const nvlist_t *param)
+{
+       uint16_t vlan;
+
+       if (! nvlist_exists_number(param, DEFAULT_SCHEMA_NAME))
+               return (EINVAL);
+
+       vlan = nvlist_get_number(param, DEFAULT_SCHEMA_NAME);
+       if (vlan > 4095 && vlan != VF_VLAN_TRUNK)
+               return (EINVAL);
+
+       return (0);
+}
+
 static int
 pci_iov_validate_param_schema(const nvlist_t *schema)
 {
diff --git a/sys/sys/iov.h b/sys/sys/iov.h
index 0171fc5a98cf..2ae7e5ac6767 100644
--- a/sys/sys/iov.h
+++ b/sys/sys/iov.h
@@ -46,6 +46,8 @@
 #define        DEFAULT_SCHEMA_NAME     "DEFAULT"
 #define        REQUIRED_SCHEMA_NAME    "REQUIRED"
 
+#define        VF_VLAN_TRUNK           4096
+
 /*
  * Because each PF device is expected to expose a unique set of possible
  * configurations, the SR-IOV infrastructure dynamically queries the PF
diff --git a/sys/sys/iov_schema.h b/sys/sys/iov_schema.h
index cb50f7796d30..66c883540563 100644
--- a/sys/sys/iov_schema.h
+++ b/sys/sys/iov_schema.h
@@ -48,5 +48,6 @@ void  pci_iov_schema_add_uint64(nvlist_t *schema, const char 
*name,
            uint32_t flags, uint64_t defaultVal);
 void   pci_iov_schema_add_unicast_mac(nvlist_t *schema, const char *name,
            uint32_t flags, const uint8_t * defaultVal);
-
+void   pci_iov_schema_add_vlan(nvlist_t *schema, const char *name,
+           uint32_t flags, const uint16_t defaultVal);
 #endif
diff --git a/usr.sbin/iovctl/iovctl.c b/usr.sbin/iovctl/iovctl.c
index 0110751082ec..28d2e0a93504 100644
--- a/usr.sbin/iovctl/iovctl.c
+++ b/usr.sbin/iovctl/iovctl.c
@@ -345,6 +345,12 @@ print_default_value(const nvlist_t *parameter, const char 
*type)
                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 if (strcasecmp(type, "vlan") == 0) {
+               uint16_t vlan = nvlist_get_number(parameter, 
DEFAULT_SCHEMA_NAME);
+               if (vlan == VF_VLAN_TRUNK)
+                       printf(" (default = trunk)");
+               else
+                       printf(" (default = %d)", vlan);
        } else
                errx(1, "Unexpected type in schema: '%s'", type);
 }
diff --git a/usr.sbin/iovctl/iovctl.conf.5 b/usr.sbin/iovctl/iovctl.conf.5
index a7eb6c2077ee..1bae96e150ba 100644
--- a/usr.sbin/iovctl/iovctl.conf.5
+++ b/usr.sbin/iovctl/iovctl.conf.5
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd May 29, 2020
+.Dd May 30, 2024
 .Dt IOVCTL.CONF 5
 .Os
 .Sh NAME
@@ -95,6 +95,8 @@ The following option types are supported:
 .Bl -tag -width indent
 .It boolean
 Accepts a boolean value of true or false.
+.It vlan
+Accepts a VLAN ID, or "trunk" to allow any VLAN ID.
 .It mac-addr
 Accepts a unicast MAC address specified as a string of the form
 xx:xx:xx:xx:xx:xx, where xx is one or two hexadecimal digits.
@@ -159,6 +161,7 @@ DEFAULT {
 VF-0 {
        mac-addr : "02:56:48:7e:d9:f7";
        passthrough : false;
+       vlan: 1;
 }
 .Ed
 .Sh SEE ALSO
diff --git a/usr.sbin/iovctl/parse.c b/usr.sbin/iovctl/parse.c
index b1aad7d7ddd6..6b7645f341cc 100644
--- a/usr.sbin/iovctl/parse.c
+++ b/usr.sbin/iovctl/parse.c
@@ -160,6 +160,29 @@ add_unicast_mac_config(const char *key, const ucl_object_t 
*obj, nvlist_t *confi
        nvlist_add_binary(config, key, mac, ETHER_ADDR_LEN);
 }
 
+static void
+add_vlan_config(const char *key, const ucl_object_t *obj, nvlist_t *config)
+{
+       int64_t val;
+       const char *strVal = "";
+
+       if(ucl_object_tostring_safe(obj, &strVal)) {
+               if (strcasecmp(strVal, "trunk") == 0) {
+                       nvlist_add_number(config, key, VF_VLAN_TRUNK);
+                       return;
+               }
+               report_config_error(key, obj, "vlan");
+       }
+
+       if (!ucl_object_toint_safe(obj, &val))
+               report_config_error(key, obj, "vlan");
+
+       if (val < 0 || val > 4095)
+               report_config_error(key, obj, "vlan");
+
+       nvlist_add_number(config, key, val);
+}
+
 /*
  * Validates that the given configuration value has the right type as specified
  * in the schema, and then adds the value to the configuration node.
@@ -186,6 +209,8 @@ add_config(const char *key, const ucl_object_t *obj, 
nvlist_t *config,
                add_uint_config(key, obj, config, type, UINT64_MAX);
        else if (strcasecmp(type, "unicast-mac") == 0)
                add_unicast_mac_config(key, obj, config);
+       else if (strcasecmp(type, "vlan") == 0)
+               add_vlan_config(key, obj, config);
        else
                errx(1, "Unexpected type '%s' in schema", type);
 }

Reply via email to