From bd29dfef8ba1799bb07f8d5e20710c68beb8fe30 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 14 Jan 2022 17:24:49 +0900 Subject: [PATCH] udev/net: also support [SR-IOV] section in .link files 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 | 89 ++++++++++++++++++++++ man/systemd.network.xml | 89 +--------------------- src/udev/net/link-config-gperf.gperf | 10 +++ src/udev/net/link-config.c | 62 ++++++++++++++- src/udev/net/link-config.h | 3 + test/fuzz/fuzz-link-parser/directives.link | 10 +++ 6 files changed, 174 insertions(+), 89 deletions(-) diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 45cabbccf7..60d2c11e3c 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -949,6 +949,95 @@ + + [SR-IOV] Section Options + 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. + + + + VirtualFunction= + + 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. + + + + + + VLANId= + + Specifies VLAN ID of the virtual function. Takes an integer in the range 1…4095. + + + + + QualityOfService= + + Specifies quality of service of the virtual function. Takes an integer in the range + 1…4294967294. + + + + + VLANProtocol= + + Specifies VLAN protocol of the virtual function. Takes 802.1Q or + 802.1ad. + + + + + MACSpoofCheck= + + Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will + be used. + + + + + QueryReceiveSideScaling= + + 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. + + + + + Trust= + + 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. + + + + + LinkState= + + Allows one to set the link state of the virtual function (VF). Takes a boolean or a + special value auto. Setting to auto means a + reflection of the physical function (PF) link state, yes lets the VF to + communicate with other VFs on this host even if the PF link state is down, + no causes the hardware to drop any packets sent by the VF. When unset, + the kernel's default will be used. + + + + + MACAddress= + + Specifies the MAC address for the virtual function. + + + + + Examples diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 574cf599ec..4f41394682 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -300,94 +300,7 @@ - - [SR-IOV] Section Options - 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. - - - - VirtualFunction= - - 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. - - - - - - VLANId= - - Specifies VLAN ID of the virtual function. Takes an integer in the range 1…4095. - - - - - QualityOfService= - - Specifies quality of service of the virtual function. Takes an integer in the range - 1…4294967294. - - - - - VLANProtocol= - - Specifies VLAN protocol of the virtual function. Takes 802.1Q or - 802.1ad. - - - - - MACSpoofCheck= - - Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will - be used. - - - - - QueryReceiveSideScaling= - - 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. - - - - - Trust= - - 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. - - - - - LinkState= - - Allows one to set the link state of the virtual function (VF). Takes a boolean or a - special value auto. Setting to auto means a - reflection of the physical function (PF) link state, yes lets the VF to - communicate with other VFs on this host even if the PF link state is down, - no causes the hardware to drop any packets sent by the VF. When unset, - the kernel's default will be used. - - - - - MACAddress= - - Specifies the MAC address for the virtual function. - - - - + [Network] Section Options diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf index ac7825b00f..3732fd53ef 100644 --- a/src/udev/net/link-config-gperf.gperf +++ b/src/udev/net/link-config-gperf.gperf @@ -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) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 05f0f2e0a6..3e8b6aaaf2 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -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; } diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index 3b2cd69620..e71738cfbf 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -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); }; diff --git a/test/fuzz/fuzz-link-parser/directives.link b/test/fuzz/fuzz-link-parser/directives.link index 7586e35b49..87b435c745 100644 --- a/test/fuzz/fuzz-link-parser/directives.link +++ b/test/fuzz/fuzz-link-parser/directives.link @@ -80,3 +80,13 @@ RxMaxCoalescedHighFrames= TxCoalesceHighSec= TxMaxCoalescedHighFrames= CoalescePacketRateSampleIntervalSec= +[SR-IOV] +VirtualFunction= +MACSpoofCheck= +VLANId= +VLANProtocol= +QualityOfService= +QueryReceiveSideScaling= +Trust= +LinkState= +MACAddress=