]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: Allow to set device's receive queues and transmit queues
authorSusant Sahani <ssahani@vmware.com>
Mon, 4 Jan 2021 15:40:47 +0000 (16:40 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 5 Jan 2021 03:46:28 +0000 (12:46 +0900)
man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index 7baf1a9df01e08d115148ce4872859830ec9f09a..422268b0f7c9ae1cb07dea87d31fb47641dfd0a4 100644 (file)
           integer in the range 0—4294967294. Defaults to unset.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>TransmitQueues=</varname></term>
+        <listitem>
+          <para>Specifies the devices's number of transmit queues. An integer in the range 1...4096.
+          When unset, the kernel's default will be used.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>ReceiveQueues=</varname></term>
+        <listitem>
+          <para>Specifies the devices's number of receive queues. An integer in the range 1...4096.
+          When unset, the kernel's default will be used.</para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><varname>RequiredForOnline=</varname></term>
         <listitem>
index 56ae6939a3ea58babca7fa387ef45acefcf44de0..aa82576c17f6cb1eed584dd5405746150fe8bcce 100644 (file)
@@ -1487,6 +1487,61 @@ static int link_set_group(Link *link) {
         return 0;
 }
 
+static int link_tx_rx_queues_hadler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+        int r;
+
+        assert(link);
+
+        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+                return 1;
+
+        r = sd_netlink_message_get_errno(m);
+        if (r < 0)
+                log_link_message_warning_errno(link, m, r, "Could not set transmit / receive queues for the interface");
+
+        return 1;
+}
+
+static int link_set_tx_rx_queues(Link *link) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(link->network);
+        assert(link->manager);
+        assert(link->manager->rtnl);
+
+        if (link->network->txqueues == 0 && link->network->rxqueues == 0)
+                return 0;
+
+        log_link_debug(link, "Setting transmit / receive queues");
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+        if (link->network->txqueues > 0) {
+                r = sd_netlink_message_append_u32(req, IFLA_NUM_TX_QUEUES, link->network->txqueues);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not set link transmit queues: %m");
+        }
+
+        if (link->network->rxqueues > 0) {
+                r = sd_netlink_message_append_u32(req, IFLA_NUM_RX_QUEUES, link->network->rxqueues);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not set link receive queues: %m");
+        }
+
+        r = netlink_call_async(link->manager->rtnl, NULL, req, link_tx_rx_queues_hadler,
+                               link_netlink_destroy_callback, link);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+        link_ref(link);
+
+        return 0;
+}
+
 static int link_handle_bound_to_list(Link *link) {
         Link *l;
         int r;
@@ -2062,6 +2117,10 @@ int link_configure(Link *link) {
         if (r < 0)
                 return r;
 
+        r = link_set_tx_rx_queues(link);
+        if (r < 0)
+                return r;
+
         r = ipv4ll_configure(link);
         if (r < 0)
                 return r;
index 2a6cb6deaeb90dd4f8fc675f7b708f0c3a3266c0..444c6c78bc144432a8706204cf6d19c042b11784 100644 (file)
@@ -59,6 +59,8 @@ Match.Architecture,                          config_parse_net_condition,
 Link.MACAddress,                             config_parse_hwaddr,                                      0,                             offsetof(Network, mac)
 Link.MTUBytes,                               config_parse_mtu,                                         AF_UNSPEC,                     offsetof(Network, mtu)
 Link.Group,                                  config_parse_uint32,                                      0,                             offsetof(Network, group)
+Link.TransmitQueues,                         config_parse_rx_tx_queues,                                0,                             offsetof(Network, txqueues)
+Link.ReceiveQueues,                          config_parse_rx_tx_queues,                                0,                             offsetof(Network, rxqueues)
 Link.ARP,                                    config_parse_tristate,                                    0,                             offsetof(Network, arp)
 Link.Multicast,                              config_parse_tristate,                                    0,                             offsetof(Network, multicast)
 Link.AllMulticast,                           config_parse_tristate,                                    0,                             offsetof(Network, allmulticast)
index daece28dbbe6905dbc258aa03ac5bd8ac1f8cb2d..6f1afed091d2eb192b61b5b27b6b06e0f32a20d7 100644 (file)
@@ -1196,6 +1196,40 @@ int config_parse_required_for_online(
         return 0;
 }
 
+int config_parse_rx_tx_queues(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        uint32_t k, *v = data;
+        int r;
+
+        if (isempty(rvalue)) {
+                *v = 0;
+                return 0;
+        }
+
+        r = safe_atou32(rvalue, &k);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
+                return 0;
+        }
+        if (k > 4096) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
+                return 0;
+        }
+
+        *v = k;
+        return 0;
+}
+
 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
                          "Failed to parse KeepConfiguration= setting");
 
index 32f5ae8d72a84eae5ca164b3a56030de9107bfbf..762dc971dbb84b81a9000ccf05980ae3fd2d162a 100644 (file)
@@ -84,6 +84,8 @@ struct Network {
         struct ether_addr *mac;
         uint32_t mtu;
         uint32_t group;
+        uint32_t txqueues;
+        uint32_t rxqueues;
         int arp;
         int multicast;
         int allmulticast;
@@ -328,6 +330,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
 CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
 CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
 CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_rx_tx_queues);
 
 const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
index f57f0cd561138d81910fd445394bd0982cc9ca4a..e7860702c6a4a1d8ce35f75c4570a4378b72963c 100644 (file)
@@ -39,6 +39,8 @@ Multicast=
 MACAddress=
 Group=
 Promiscuous=
+TransmitQueues=
+ReceiveQueues=
 [SR-IOV]
 VirtualFunction=
 MACSpoofCheck=