]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev/net: also support [SR-IOV] section in .link files
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 14 Jan 2022 08:24:49 +0000 (17:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 19 Jan 2022 06:00:49 +0000 (15:00 +0900)
The same section is already supported by .network files. But such
low-level inteerface setting should be done by udevd, instead of
networkd. Let's also support the same semantics by .link files.

Prompted by https://github.com/systemd/systemd/issues/20474#issuecomment-901901360.

man/systemd.link.xml
man/systemd.network.xml
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
test/fuzz/fuzz-link-parser/directives.link

index 45cabbccf70c1c0d5aa8a2843a500ca2cb5edfbd..60d2c11e3cd7043d2919e93d6888c813699e204d 100644 (file)
     </variablelist>
   </refsect1>
 
+  <refsect1 id='sr-iov'>
+    <title>[SR-IOV] Section Options</title>
+    <para>The [SR-IOV] section accepts the following keys. Specify several [SR-IOV] sections to
+    configure several SR-IOVs. SR-IOV provides the ability to partition a single physical PCI resource
+    into virtual PCI functions which can then be injected into a VM. In the case of network VFs, SR-IOV
+    improves north-south network performance (that is, traffic with endpoints outside the host machine)
+    by allowing traffic to bypass the host machine’s network stack.</para>
+
+    <variablelist class='network-directives'>
+      <varlistentry>
+        <term><varname>VirtualFunction=</varname></term>
+        <listitem>
+          <para>Specifies a Virtual Function (VF), lightweight PCIe function designed solely to move
+          data in and out. Takes an integer in the range 0…2147483646. This option is compulsory.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>VLANId=</varname></term>
+        <listitem>
+          <para>Specifies VLAN ID of the virtual function. Takes an integer in the range 1…4095.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>QualityOfService=</varname></term>
+        <listitem>
+          <para>Specifies quality of service of the virtual function. Takes an integer in the range
+          1…4294967294.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>VLANProtocol=</varname></term>
+        <listitem>
+          <para>Specifies VLAN protocol of the virtual function. Takes <literal>802.1Q</literal> or
+          <literal>802.1ad</literal>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>MACSpoofCheck=</varname></term>
+        <listitem>
+          <para>Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will
+          be used.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>QueryReceiveSideScaling=</varname></term>
+        <listitem>
+          <para>Takes a boolean. Toggle the ability of querying the receive side scaling (RSS)
+          configuration of the virtual function (VF). The VF RSS information like RSS hash key may be
+          considered sensitive on some devices where this information is shared between VF and the
+          physical function (PF). When unset, the kernel's default will be used.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>Trust=</varname></term>
+        <listitem>
+          <para>Takes a boolean. Allows one to set trust mode of the virtual function (VF). When set,
+          VF users can set a specific feature which may impact security and/or performance. When unset,
+          the kernel's default will be used.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>LinkState=</varname></term>
+        <listitem>
+          <para>Allows one to set the link state of the virtual function (VF). Takes a boolean or a
+          special value <literal>auto</literal>. Setting to <literal>auto</literal> means a
+          reflection of the physical function (PF) link state, <literal>yes</literal> lets the VF to
+          communicate with other VFs on this host even if the PF link state is down,
+          <literal>no</literal> causes the hardware to drop any packets sent by the VF. When unset,
+          the kernel's default will be used.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>MACAddress=</varname></term>
+        <listitem>
+          <para>Specifies the MAC address for the virtual function.</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
   <refsect1>
     <title>Examples</title>
 
index 574cf599ec8f59385a8e70a1cfd44ba4a79caaed..4f413946828827bb0a8e26a235f4015886b61acf 100644 (file)
     </variablelist>
   </refsect1>
 
-  <refsect1>
-    <title>[SR-IOV] Section Options</title>
-    <para>The [SR-IOV] section accepts the following keys. Specify several [SR-IOV] sections to
-    configure several SR-IOVs. SR-IOV provides the ability to partition a single physical PCI resource
-    into virtual PCI functions which can then be injected into a VM. In the case of network VFs, SR-IOV
-    improves north-south network performance (that is, traffic with endpoints outside the host machine)
-    by allowing traffic to bypass the host machine’s network stack.</para>
-
-    <variablelist class='network-directives'>
-      <varlistentry>
-        <term><varname>VirtualFunction=</varname></term>
-        <listitem>
-          <para>Specifies a Virtual Function (VF), lightweight PCIe function designed solely to move
-          data in and out. Takes an integer in the range 0…2147483646. This option is compulsory.
-          </para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>VLANId=</varname></term>
-        <listitem>
-          <para>Specifies VLAN ID of the virtual function. Takes an integer in the range 1…4095.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>QualityOfService=</varname></term>
-        <listitem>
-          <para>Specifies quality of service of the virtual function. Takes an integer in the range
-          1…4294967294.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>VLANProtocol=</varname></term>
-        <listitem>
-          <para>Specifies VLAN protocol of the virtual function. Takes <literal>802.1Q</literal> or
-          <literal>802.1ad</literal>.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>MACSpoofCheck=</varname></term>
-        <listitem>
-          <para>Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will
-          be used.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>QueryReceiveSideScaling=</varname></term>
-        <listitem>
-          <para>Takes a boolean. Toggle the ability of querying the receive side scaling (RSS)
-          configuration of the virtual function (VF). The VF RSS information like RSS hash key may be
-          considered sensitive on some devices where this information is shared between VF and the
-          physical function (PF). When unset, the kernel's default will be used.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>Trust=</varname></term>
-        <listitem>
-          <para>Takes a boolean. Allows one to set trust mode of the virtual function (VF). When set, VF
-          users can set a specific feature which may impact security and/or performance. When unset,
-          the kernel's default will be used.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>LinkState=</varname></term>
-        <listitem>
-          <para>Allows one to set the link state of the virtual function (VF). Takes a boolean or a
-          special value <literal>auto</literal>. Setting to <literal>auto</literal> means a
-          reflection of the physical function (PF) link state, <literal>yes</literal> lets the VF to
-          communicate with other VFs on this host even if the PF link state is down,
-          <literal>no</literal> causes the hardware to drop any packets sent by the VF. When unset,
-          the kernel's default will be used.</para>
-        </listitem>
-      </varlistentry>
-
-      <varlistentry>
-        <term><varname>MACAddress=</varname></term>
-        <listitem>
-          <para>Specifies the MAC address for the virtual function.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
+  <xi:include href="systemd.link.xml" xpointer="sr-iov" />
 
   <refsect1>
     <title>[Network] Section Options</title>
index ac7825b00f27978fd3d3c5715a5eda40ce12be4e..3732fd53ef2feeb0359611697a42728c8bc4f0a2 100644 (file)
@@ -8,6 +8,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #include "ethtool-util.h"
 #include "link-config.h"
 #include "net-condition.h"
+#include "netif-sriov.h"
 #include "socket-util.h"
 %}
 struct ConfigPerfItem;
@@ -101,3 +102,12 @@ Link.RxMaxCoalescedHighFrames,             config_parse_coalesce_u32,
 Link.TxCoalesceHighSec,                    config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
 Link.TxMaxCoalescedHighFrames,             config_parse_coalesce_u32,             0,                             offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
 Link.CoalescePacketRateSampleIntervalSec,  config_parse_coalesce_sec,             0,                             offsetof(LinkConfig, coalesce.rate_sample_interval)
+SR-IOV.VirtualFunction,                    config_parse_sr_iov_uint32,            0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.VLANId,                             config_parse_sr_iov_uint32,            0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.QualityOfService,                   config_parse_sr_iov_uint32,            0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.VLANProtocol,                       config_parse_sr_iov_vlan_proto,        0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.MACSpoofCheck,                      config_parse_sr_iov_boolean,           0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.QueryReceiveSideScaling,            config_parse_sr_iov_boolean,           0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.Trust,                              config_parse_sr_iov_boolean,           0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.LinkState,                          config_parse_sr_iov_link_state,        0,                             offsetof(LinkConfig, sr_iov_by_section)
+SR-IOV.MACAddress,                         config_parse_sr_iov_mac,               0,                             offsetof(LinkConfig, sr_iov_by_section)
index 05f0f2e0a61b029a0436300a8ff641b8d72df091..3e8b6aaaf29b7fcb8bb423c861d67963b0eaa808 100644 (file)
@@ -22,6 +22,7 @@
 #include "log-link.h"
 #include "memory-util.h"
 #include "net-condition.h"
+#include "netif-sriov.h"
 #include "netif-util.h"
 #include "netlink-util.h"
 #include "parse-util.h"
@@ -60,6 +61,8 @@ static LinkConfig* link_config_free(LinkConfig *config) {
         free(config->wol_password_file);
         erase_and_free(config->wol_password);
 
+        ordered_hashmap_free_with_destructor(config->sr_iov_by_section, sr_iov_free);
+
         return mfree(config);
 }
 
@@ -257,7 +260,9 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
                         STRV_MAKE_CONST(filename),
                         (const char* const*) CONF_PATHS_STRV("systemd/network"),
                         dropin_dirname,
-                        "Match\0Link\0",
+                        "Match\0"
+                        "Link\0"
+                        "SR-IOV\0",
                         config_item_perf_lookup, link_config_gperf_lookup,
                         CONFIG_PARSE_WARN, config, NULL);
         if (r < 0)
@@ -285,6 +290,10 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
         if (r < 0)
                 return r;
 
+        r = sr_iov_drop_invalid_sections(config->sr_iov_by_section);
+        if (r < 0)
+                return r;
+
         log_debug("Parsed configuration file %s", filename);
 
         LIST_PREPEND(configs, ctx->configs, TAKE_PTR(config));
@@ -830,6 +839,53 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
         return 0;
 }
 
+static int sr_iov_configure(Link *link, sd_netlink **rtnl, SRIOV *sr_iov) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(rtnl);
+        assert(link->ifindex > 0);
+
+        if (!*rtnl) {
+                r = sd_netlink_open(rtnl);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_link(*rtnl, &req, RTM_SETLINK, link->ifindex);
+        if (r < 0)
+                return r;
+
+        r = sr_iov_set_netlink_message(sr_iov, req);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_call(*rtnl, req, 0, NULL);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) {
+        SRIOV *sr_iov;
+        int r;
+
+        assert(link);
+        assert(link->config);
+
+        ORDERED_HASHMAP_FOREACH(sr_iov, link->config->sr_iov_by_section) {
+                r = sr_iov_configure(link, rtnl, sr_iov);
+                if (r < 0)
+                        log_link_warning_errno(link, r,
+                                               "Failed to configure SR-IOV virtual function %"PRIu32", ignoring: %m",
+                                               sr_iov->vf);
+        }
+
+        return 0;
+}
+
 int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
         int r;
 
@@ -861,6 +917,10 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
         if (r < 0)
                 return r;
 
+        r = link_apply_sr_iov_config(link, rtnl);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
index 3b2cd696201ffb80a3e5c3aa22e0dab93066b584..e71738cfbf0e72a4ec5b2e0101b05f794069907c 100644 (file)
@@ -7,6 +7,7 @@
 #include "condition.h"
 #include "conf-parser.h"
 #include "ethtool-util.h"
+#include "hashmap.h"
 #include "list.h"
 #include "net-condition.h"
 #include "netif-naming-scheme.h"
@@ -76,6 +77,8 @@ struct LinkConfig {
         int autoneg_flow_control;
         netdev_coalesce_param coalesce;
 
+        OrderedHashmap *sr_iov_by_section;
+
         LIST_FIELDS(LinkConfig, configs);
 };
 
index 7586e35b4930e8e90c9c5a1fabf7f75c121ad32f..87b435c745ab66eabf74fadcfdce38fe0057c72a 100644 (file)
@@ -80,3 +80,13 @@ RxMaxCoalescedHighFrames=
 TxCoalesceHighSec=
 TxMaxCoalescedHighFrames=
 CoalescePacketRateSampleIntervalSec=
+[SR-IOV]
+VirtualFunction=
+MACSpoofCheck=
+VLANId=
+VLANProtocol=
+QualityOfService=
+QueryReceiveSideScaling=
+Trust=
+LinkState=
+MACAddress=