]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #31444 from bluca/semaphore
authorFrantisek Sumsal <frantisek@sumsal.cz>
Wed, 28 Feb 2024 14:03:11 +0000 (15:03 +0100)
committerGitHub <noreply@github.com>
Wed, 28 Feb 2024 14:03:11 +0000 (15:03 +0100)
semaphore: set upstream build profile and set default branch to debian/master

64 files changed:
.github/workflows/differential-shellcheck.yml
TODO
man/systemd.link.xml
man/systemd.network.xml
shell-completion/bash/bootctl
shell-completion/bash/busctl
shell-completion/bash/coredumpctl
shell-completion/bash/homectl
shell-completion/bash/hostnamectl
shell-completion/bash/journalctl
shell-completion/bash/kernel-install
shell-completion/bash/localectl
shell-completion/bash/loginctl
shell-completion/bash/machinectl
shell-completion/bash/networkctl
shell-completion/bash/oomctl
shell-completion/bash/portablectl
shell-completion/bash/resolvectl
shell-completion/bash/systemctl.in
shell-completion/bash/systemd-analyze
shell-completion/bash/systemd-cat
shell-completion/bash/systemd-cgls
shell-completion/bash/systemd-cgtop
shell-completion/bash/systemd-confext
shell-completion/bash/systemd-cryptenroll
shell-completion/bash/systemd-delta
shell-completion/bash/systemd-detect-virt
shell-completion/bash/systemd-dissect
shell-completion/bash/systemd-id128
shell-completion/bash/systemd-nspawn
shell-completion/bash/systemd-path
shell-completion/bash/systemd-resolve
shell-completion/bash/systemd-run
shell-completion/bash/systemd-sysext
shell-completion/bash/timedatectl
shell-completion/bash/udevadm
src/libsystemd-network/ndisc-router-internal.h
src/libsystemd-network/sd-ndisc-router.c
src/network/networkd-ndisc.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/nspawn/nspawn-register.c
src/resolve/resolved-varlink.c
src/shared/cgroup-setup.c
src/shared/cpu-set-util.c
src/shared/cpu-set-util.h
src/systemd/sd-ndisc-router.h
src/test/test-cpu-set-util.c
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
src/userdb/userdbd-manager.c
test/test-network/conf/24-rps-cpu-disable.link [new file with mode: 0644]
test/test-network/conf/24-rps-cpu-empty.link [new file with mode: 0644]
test/test-network/conf/24-rps-cpu-invalid.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-0-1.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-0-empty.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-0-invalid.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-0.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-1.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-all.link [new file with mode: 0644]
test/test-network/conf/25-rps-cpu-multi.link [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py

index b04aabb14a046458fd83b07e072ee543bbb9cb92..89811edb9514f8766f3b495332ebfe1596600ca0 100644 (file)
@@ -31,5 +31,10 @@ jobs:
         uses: redhat-plumbers-in-action/differential-shellcheck@91e2582e40236f831458392d905578d680baa138
         with:
           # exclude all `.in` files because they may contain unsupported syntax, and they have to be preprocessed first
-          exclude-path: '**/*.in'
+          # TEMPORARY: exclude bash completion files, they would generate too many defects in Code scanning dashboard (600+)
+          # exclude zsh completion files, zsh is not supported by ShellCheck
+          exclude-path: |
+            '**/*.in'
+            'shell-completion/bash/*'
+            'shell-completion/zsh/*'
           token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/TODO b/TODO
index b213586530bd260162608a08be809029936099b5..80a2cd60b228e9028e632bb0252f6d70468e3b19 100644 (file)
--- a/TODO
+++ b/TODO
@@ -131,7 +131,7 @@ Deprecations and removals:
 Features:
 
 * add a new specifier to unit files that figures out the DDI the unit file is
-  from, tracing trough overlayfs, DM, loopback block device.
+  from, tracing through overlayfs, DM, loopback block device.
 
 * in os-release define a field that can be initialized at build time from
   SOURCE_DATE_EPOCH (maybe even under that name?). Would then be used to
index 3e98e4ddba0f202fb23fbeb1ced39d47e01b7af0..7c0a84dff87a8b08f59a5ba00db39c8c7e184542 100644 (file)
           <xi:include href="version-info.xml" xpointer="v232"/>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>ReceivePacketSteeringCPUMask=</varname></term>
+        <listitem>
+          <para>Configures Receive Packet Steering (RPS) list of CPUs to which RPS may forward traffic.
+          Takes a list of CPU indices or ranges separated by either whitespace or commas. Alternatively,
+          takes the special value <literal>all</literal> in which will include all available CPUs in the mask.
+          CPU ranges are specified by the lower and upper CPU indices separated by a dash (e.g. <literal>2-6</literal>).
+          This option may be specified more than once, in which case the specified CPU affinity masks are merged.
+          If an empty string is assigned, the mask is reset, all assignments prior to this will have no effect.
+          Defaults to unset and RPS CPU list is unchanged. To disable RPS when it was previously enabled, use the
+          special value <literal>disable</literal>.</para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><varname>ReceiveVLANCTAGHardwareAcceleration=</varname></term>
         <listitem>
index 96228fc1985d800d1e6ced7d41c174b9def92e5a..9be90e17c5e42e1d59e6d263eab097f77e00d2fa 100644 (file)
@@ -3394,16 +3394,6 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
-      <varlistentry>
-        <term><varname>UseICMP6RateLimit=</varname></term>
-        <listitem>
-          <para>Takes a boolean. When true, the ICMP6 rate limit received in the Router Advertisement will be set to ICMP6
-          rate limit based on the advertisement. Defaults to true.</para>
-
-          <xi:include href="version-info.xml" xpointer="v255"/>
-        </listitem>
-      </varlistentry>
-
       <varlistentry>
         <term><varname>UseGateway=</varname></term>
         <listitem>
index 8d8b507ea95131b3a651537a9ea702457d3ba664..45fcd502dee9f532c22b13929a6da25ac6d32c7f 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # bootctl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 5464225b15e2643eeb90d4d1ae181d5d66647f42..bb80c1768302d0f56afb5182cffbc258d3b3d4e6 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # busctl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b5719905f9a4c823a3013b5a68add5f1cc731ffb..ebab3607e41a2bd2c00d5dc1d11756ef58b80c12 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # coredumpctl(1) completion                       -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 3bb84fedb26803e80eb38749ce1720c337a57120..527dd81c458ee1b65b8debe9f95e781419af7dc9 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # homectl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 27a2fe63d2fb018d85dd1762bd71819a4183df72..d8256a9fed48d3a594966c7f4d2ac8d2538f0583 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # hostnamectl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index c7f6a05a6efa8c7c1ded1d56213a6c132789f8e2..c79a38c3527a975f343746ddd6b3345eb6e0c469 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # journalctl(1) completion                                -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 4708777507b56d541bd38d5720bcfb1899a5a111..d3a9d9bbd8480cd1634ad6f295be6592ce9bd3e7 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # kernel-install(8) completion                                   -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b601343a6b6e59bbdea3f449c20a2f105181d864..1717842648b9fd08317c798219d4bfb4aa0de8ac 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # localectl(1) completion                                 -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index e6c476742b38dd4c3f783e9928e8c702af7f9622..7dbd9c04eab1ece1f82404e37653923419b534f0 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # loginctl(1) completion                                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b28769b0b64d9ea287e23e596132a9d6fc4adf20..f4d46c95112d71fdad31088eb1dacc6bb91b5212 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # machinectl(1) completion                      -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index db59a9ce34748fce2af05ae9f1571b525e573396..6126984ef8663e64b7af4e0777d5b7c48d09f06c 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # networkctl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index dc45ba58c0383b37de3fd216bce3cf75ad2e7e24..e1ad197bf5e38190146d59558629806551093dd6 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # oomctl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 30e5da4aa28e06a023bd4d13a9a983b385496513..b22bbd95d6b3cabeb49a345059c3c00b0a024e94 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # portablectl(1) completion                             -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index bd3e8bf939308bfbf0da2b68b573192ceb4823d6..1a5febe1e3eb1053396f427af4d5009740137d6f 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # resolvectl(1) completion                                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 5c444b7fa4a7eebfa4280b136435579b5e6f449f..7f85e70d40fc56e2cb50cee6c858310e4bbc588c 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemctl(1) completion                                 -*- shell-script -*-
 # vi: ft=sh
 # SPDX-License-Identifier: LGPL-2.1-or-later
index 00cb478688d2ffcba22a853a9dae223118432b4f..eb1061f7875244061668cfa628cfc3b347208b2c 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-analyze(1) completion                      -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index e1e600217289877c5c87550f8002b690793b3135..6ccc7bf000f19c45617861a9bb8b3f19535cd844 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-cat(1) completion                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index f80bea73532fb5fed50ddf31690fb5ee5944413a..49739bd0c645f7ea09185a0464f0629466bbeffe 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-cgls(1) completion                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 731d9c924b178f526fba1224924377534d866f7e..6a33cb227fdf8ac77736864a3435cec3bc3f576d 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-cgtop(1) completion                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 09d114611c52bb55ece785d8f0090258a22283eb..d36f70fa094df2d791046551b508cd05072e26cd 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-confext(8) completion                        -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index f40a33bee6f268a3f8f0f34a8d1806295d538d01..6b13e58789d492da2305e8b9a928d258de8b8921 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-cryptenroll(1) completion                   -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b148755d0875440349e53d645521d8866ff014d3..ac7f5e970933fb20a1694d0cb4fc2bc6de0e20b3 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-delta(1) completion                      -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 9ade2af220fcf0da969f7754a518d2c7b3c6d508..edc861b20bab323ee8a4e628cc22e29a8251cfbc 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-detect-virt(1) completion             -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 17fb6420dea6d7bb189f0bfb7fc82179c68a7d2e..8d2b43423cbc8d19009cdb7c0aabf1701a02d824 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-dissect(1) completion                       -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 74ea1016a9332f2f5778bb79e196f1f7da5eeef3..54d4ec8f7a554c9773aba96ed98d0b3d92f9e6e8 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-id128(1) completion                         -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b12711be80485304fa05b793289381e8d58f8fa2..085e6a4d18785c5c147f547a607b16ce768229e0 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-nspawn(1) completion                  -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 40e2f7ec486b5c5ad6b005a5ad054991f64a7942..59d6597d06b147b3f39c1bd81e711d9e94deaa98 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-path(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 20d904aedfc3de702333557cab29379f7bf07c19..17890a9a0941138eb5217f1a7065590aa37a58e4 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-resolve(1) completion                             -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index c18228d00f059f5f9a8935bc0360f171d500d885..3a26a65d4e35b73a982d3c6c1c32bb87b284bde1 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-run(1) completion                       -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index b3f9f32fd507ced61feb6d31e9739d5cbbd868fe..5c15f076a878fec43252803d92a9c19f4e7c7a8c 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # systemd-sysext(8) completion                        -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 768b4a5e8206009946c26bb3aca1c552bd011122..f22cde282b925dd6ec068971d3d6648753da3521 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # timedatectl(1) completion                               -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 0606160c66b7f1c4aab4183cf13956c471d54498..fbbaed001c35edace8bfdf8afe56769146e09a19 100644 (file)
@@ -1,3 +1,4 @@
+# shellcheck shell=bash
 # udevadm(8) completion                                   -*- shell-script -*-
 # SPDX-License-Identifier: LGPL-2.1-or-later
 #
index 5bd9a65dd227948639dfc308861a493a9271689f..e39b4db3c48614218dd68fcc4192537f47faec08 100644 (file)
@@ -29,7 +29,6 @@ struct sd_ndisc_router {
 
         uint8_t hop_limit;
         uint32_t mtu;
-        uint64_t icmp6_ratelimit_usec;
 };
 
 static inline void* NDISC_ROUTER_RAW(const sd_ndisc_router *rt) {
index b90fb77cd82792f46f68717301b6a59ca7892eee..b1eb957dfe7e2295d963c8591972ae9288d387cd 100644 (file)
@@ -144,7 +144,6 @@ int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt) {
         rt->hop_limit = a->nd_ra_curhoplimit;
         rt->flags = a->nd_ra_flags_reserved; /* the first 8 bits */
         rt->lifetime_usec = be16_sec_to_usec(a->nd_ra_router_lifetime, /* max_as_infinity = */ false);
-        rt->icmp6_ratelimit_usec = be32_msec_to_usec(a->nd_ra_retransmit, /* max_as_infinity = */ false);
         rt->reachable_time_usec = be32_msec_to_usec(a->nd_ra_reachable, /* mas_as_infinity = */ false);
         rt->retransmission_time_usec = be32_msec_to_usec(a->nd_ra_retransmit, /* max_as_infinity = */ false);
 
@@ -294,14 +293,6 @@ int sd_ndisc_router_get_retransmission_time(sd_ndisc_router *rt, uint64_t *ret)
         return 0;
 }
 
-int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint64_t *ret) {
-        assert_return(rt, -EINVAL);
-        assert_return(ret, -EINVAL);
-
-        *ret = rt->icmp6_ratelimit_usec;
-        return 0;
-}
-
 int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret) {
         assert_return(rt, -EINVAL);
         assert_return(ret, -EINVAL);
index 24808413c185b1f4489aab742b487b669afd3463..33bd7335a18a28acecab701377f163757bf496f2 100644 (file)
@@ -512,43 +512,6 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         return 0;
 }
 
-static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt) {
-        usec_t icmp6_ratelimit, msec;
-        int r;
-
-        assert(link);
-        assert(link->network);
-        assert(rt);
-
-        if (!link->network->ndisc_use_icmp6_ratelimit)
-                return 0;
-
-        /* Ignore the icmp6 ratelimit field of the RA header if the lifetime is zero. */
-        r = sd_ndisc_router_get_lifetime(rt, NULL);
-        if (r <= 0)
-                return r;
-
-        r = sd_ndisc_router_get_icmp6_ratelimit(rt, &icmp6_ratelimit);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get ICMP6 ratelimit from RA: %m");
-
-        /* We do not allow 0 here. */
-        if (!timestamp_is_set(icmp6_ratelimit))
-                return 0;
-
-        msec = DIV_ROUND_UP(icmp6_ratelimit, USEC_PER_MSEC);
-        if (msec <= 0 || msec > INT_MAX)
-                return 0;
-
-        /* Limit the maximal rates for sending ICMPv6 packets. 0 to disable any limiting, otherwise the
-         * minimal space between responses in milliseconds. Default: 1000. */
-        r = sysctl_write_ip_property_int(AF_INET6, NULL, "icmp/ratelimit", (int) msec);
-        if (r < 0)
-                log_link_warning_errno(link, r, "Failed to apply ICMP6 ratelimit, ignoring: %m");
-
-        return 0;
-}
-
 static int ndisc_router_process_reachable_time(Link *link, sd_ndisc_router *rt) {
         usec_t reachable_time, msec;
         int r;
@@ -1699,10 +1662,6 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return r;
 
-        r = ndisc_router_process_icmp6_ratelimit(link, rt);
-        if (r < 0)
-                return r;
-
         r = ndisc_router_process_reachable_time(link, rt);
         if (r < 0)
                 return r;
index 9171056156328e58385265befb99e96435fda185..dffc40308c7966f84fa8f501859a457a12a7f647 100644 (file)
@@ -303,7 +303,6 @@ IPv6AcceptRA.UseMTU,                         config_parse_bool,
 IPv6AcceptRA.UseHopLimit,                    config_parse_bool,                                        0,                             offsetof(Network, ndisc_use_hop_limit)
 IPv6AcceptRA.UseReachableTime,               config_parse_bool,                                        0,                             offsetof(Network, ndisc_use_reachable_time)
 IPv6AcceptRA.UseRetransmissionTime,          config_parse_bool,                                        0,                             offsetof(Network, ndisc_use_retransmission_time)
-IPv6AcceptRA.UseICMP6RateLimit,              config_parse_bool,                                        0,                             offsetof(Network, ndisc_use_icmp6_ratelimit)
 IPv6AcceptRA.DHCPv6Client,                   config_parse_ndisc_start_dhcp6_client,                    0,                             offsetof(Network, ndisc_start_dhcp6_client)
 IPv6AcceptRA.RouteTable,                     config_parse_dhcp_or_ra_route_table,                      AF_INET6,                      0
 IPv6AcceptRA.RouteMetric,                    config_parse_ndisc_route_metric,                          0,                             0
@@ -621,6 +620,7 @@ DHCPv6PrefixDelegation.Token,                config_parse_address_generation_typ
 DHCPv6PrefixDelegation.RouteMetric,          config_parse_uint32,                                      0,                             offsetof(Network, dhcp_pd_route_metric)
 IPv6AcceptRA.DenyList,                       config_parse_in_addr_prefixes,                            AF_INET6,                      offsetof(Network, ndisc_deny_listed_prefix)
 IPv6AcceptRA.BlackList,                      config_parse_in_addr_prefixes,                            AF_INET6,                      offsetof(Network, ndisc_deny_listed_prefix)
+IPv6AcceptRA.UseICMP6RateLimit,              config_parse_warn_compat,                                 DISABLED_LEGACY,               0
 TrafficControlQueueingDiscipline.Parent,                        config_parse_qdisc_parent,             _QDISC_KIND_INVALID,           0
 TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec,       config_parse_network_emulator_delay,   0,                             0
 TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_network_emulator_delay,   0,                             0
index 601820b1232cf9504fabff7ff552309789f728cd..3d418006d671c78474b1770cad4e10dd492103a8 100644 (file)
@@ -483,7 +483,6 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .ndisc_use_hop_limit = true,
                 .ndisc_use_reachable_time = true,
                 .ndisc_use_retransmission_time = true,
-                .ndisc_use_icmp6_ratelimit = true,
                 .ndisc_route_table = RT_TABLE_MAIN,
                 .ndisc_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
                 .ndisc_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,
index b30e3b22098ff38cb9b513e78f906c329fa143e4..467789bd68ac845135af0747c9a8ece274726967 100644 (file)
@@ -345,7 +345,6 @@ struct Network {
         bool ndisc_use_hop_limit;
         bool ndisc_use_reachable_time;
         bool ndisc_use_retransmission_time;
-        bool ndisc_use_icmp6_ratelimit;
         bool ndisc_quickack;
         bool ndisc_use_captive_portal;
         bool ndisc_use_pref64;
index 27400aa4a21fba72faaea081b34b279d4b75c069..358958b82b3d6f1b9d8e692591915e014edc2366 100644 (file)
@@ -305,7 +305,7 @@ int allocate_scope(
 
                 r = bus_append_scope_pidref(m, &pidref);
         } else
-                r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
+                r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) pid);
         if (r < 0)
                 return bus_log_create_error(r);
 
@@ -368,7 +368,11 @@ int allocate_scope(
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        r = bus_wait_for_jobs_one(w, object, BUS_WAIT_JOBS_LOG_ERROR, NULL);
+        r = bus_wait_for_jobs_one(
+                        w,
+                        object,
+                        BUS_WAIT_JOBS_LOG_ERROR,
+                        /* extra_args= */ NULL);
         if (r < 0)
                 return r;
 
index a85a27867629d5865edaf3f4bc0aec9eb477fb0b..6e6e973f94a066a921fe80aa3fbabf653e0407c3 100644 (file)
@@ -1016,7 +1016,7 @@ static int vl_method_resolve_service(Varlink* link, JsonVariant* parameters, Var
                 return -EINVAL;
 
         r = varlink_dispatch(link, parameters, dispatch_table, &p);
-        if (r < 0)
+        if (r != 0)
                 return r;
 
         if (p.ifindex < 0)
index a528d4292d03691671d0eff9018bca5b4c54097f..d753fd933678ca7aa0550664adbaa7c0ea007580 100644 (file)
@@ -106,7 +106,7 @@ bool cg_is_unified_wanted(void) {
                 return (wanted = true);
 
         /* If any controller is in use as v1, don't use unified. */
-        return (wanted = cg_any_controller_used_for_v1() <= 0);
+        return (wanted = (cg_any_controller_used_for_v1() <= 0));
 }
 
 bool cg_is_legacy_wanted(void) {
index d096576cd6c37c214c1d2fb2e1de951c6f5bb358..1112de1333d42f934311a0c22ee6f6ff684def2e 100644 (file)
@@ -11,6 +11,7 @@
 #include "errno-util.h"
 #include "extract-word.h"
 #include "fd-util.h"
+#include "hexdecoct.h"
 #include "log.h"
 #include "macro.h"
 #include "memory-util.h"
@@ -82,6 +83,63 @@ char *cpu_set_to_range_string(const CPUSet *set) {
         return TAKE_PTR(str) ?: strdup("");
 }
 
+char* cpu_set_to_mask_string(const CPUSet *a) {
+        _cleanup_free_ char *str = NULL;
+        size_t len = 0;
+        bool found_nonzero = false;
+
+        assert(a);
+
+        /* Return CPU set in hexadecimal bitmap mask, e.g.
+         *   CPU   0 ->  "1"
+         *   CPU   1 ->  "2"
+         *   CPU 0,1 ->  "3"
+         *   CPU 0-3 ->  "f"
+         *   CPU 0-7 -> "ff"
+         *   CPU 4-7 -> "f0"
+         *   CPU   7 -> "80"
+         *   None    ->  "0"
+         *
+         * When there are more than 32 CPUs, separate every 32 CPUs by comma, e.g.
+         *  CPU 0-47 -> "ffff,ffffffff"
+         *  CPU 0-63 -> "ffffffff,ffffffff"
+         *  CPU 0-71 -> "ff,ffffffff,ffffffff" */
+
+        for (ssize_t i = a->allocated * 8; i >= 0; i -= 4) {
+                uint8_t m = 0;
+
+                for (size_t j = 0; j < 4; j++)
+                        if (CPU_ISSET_S(i + j, a->allocated, a->set))
+                                m |= 1U << j;
+
+                if (!found_nonzero)
+                        found_nonzero = m > 0;
+
+                if (!found_nonzero && m == 0)
+                        /* Skip leading zeros */
+                        continue;
+
+                if (!GREEDY_REALLOC(str, len + 3))
+                        return NULL;
+
+                str[len++] = hexchar(m);
+                if (i >= 4 && i % 32 == 0)
+                        /* Separate by comma for each 32 CPUs. */
+                        str[len++] = ',';
+                str[len] = 0;
+        }
+
+        return TAKE_PTR(str) ?: strdup("0");
+}
+
+CPUSet* cpu_set_free(CPUSet *c) {
+        if (!c)
+                return c;
+
+        cpu_set_reset(c);
+        return mfree(c);
+}
+
 int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
         size_t need;
 
@@ -290,3 +348,22 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
         *set = TAKE_STRUCT(s);
         return 0;
 }
+
+int cpu_mask_add_all(CPUSet *mask) {
+        long m;
+        int r;
+
+        assert(mask);
+
+        m = sysconf(_SC_NPROCESSORS_ONLN);
+        if (m < 0)
+                return -errno;
+
+        for (unsigned i = 0; i < (unsigned) m; i++) {
+                r = cpu_set_add(mask, i);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
index 3c63a5882616fe2d571ab981d644325344a9320f..618fe1b0a3b27803f92c429909a7c8003949ed02 100644 (file)
@@ -19,11 +19,15 @@ static inline void cpu_set_reset(CPUSet *a) {
         *a = (CPUSet) {};
 }
 
+CPUSet* cpu_set_free(CPUSet *c);
+DEFINE_TRIVIAL_CLEANUP_FUNC(CPUSet*, cpu_set_free);
+
 int cpu_set_add_all(CPUSet *a, const CPUSet *b);
 int cpu_set_add(CPUSet *a, unsigned cpu);
 
 char* cpu_set_to_string(const CPUSet *a);
 char *cpu_set_to_range_string(const CPUSet *a);
+char* cpu_set_to_mask_string(const CPUSet *a);
 int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
 
 int parse_cpu_set_full(
@@ -50,3 +54,4 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
 int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
 
 int cpus_in_affinity_mask(void);
+int cpu_mask_add_all(CPUSet *mask);
index 7cde2979ac7e36f26575e35c5efe775eed92b379..bfdaeb468948cb95d63bf20944915bf8651a3819 100644 (file)
@@ -37,7 +37,6 @@ int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t
 int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size);
 
 int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret);
-int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint64_t *ret);
 int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret);
 int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret);
 int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
index a0660f579ed72c0628b9a48813665499fd2f7be3..0c2304e2c09610d517e6a7d9b9bcb787670db426 100644 (file)
@@ -25,6 +25,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "1"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Simple range (from CPUAffinity example) */
@@ -43,6 +47,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "1-2 4"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "16"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* A more interesting range */
@@ -61,6 +69,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0-3 8-11"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "f0f"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Quoted strings */
@@ -76,6 +88,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "8-11"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "f00"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Use commas as separators */
@@ -106,6 +122,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0-7 63"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "80000000,000000ff"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Ranges */
@@ -120,6 +140,28 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_string: %s", str);
         str = mfree(str);
         cpu_set_reset(&c);
+        assert_se(parse_cpu_set_full("36-39,44-47", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+        for (cpu = 36; cpu < 40; cpu++)
+                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+        for (cpu = 44; cpu < 48; cpu++)
+                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "f0f0,00000000"));
+        str = mfree(str);
+        cpu_set_reset(&c);
+        assert_se(parse_cpu_set_full("64-71", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+        for (cpu = 64; cpu < 72; cpu++)
+                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "ff,00000000,00000000"));
+        str = mfree(str);
+        cpu_set_reset(&c);
 
         /* Ranges with trailing comma, space */
         assert_se(parse_cpu_set_full("0-3  8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
@@ -136,12 +178,20 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0-3 8-11"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "f0f"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Negative range (returns empty cpu_set) */
         assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
         assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
         assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "0"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Overlapping ranges */
@@ -157,6 +207,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0-11"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "fff"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Mix ranges and individual CPUs */
@@ -174,6 +228,10 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "0 2 4-11"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "ff5"));
+        str = mfree(str);
         cpu_set_reset(&c);
 
         /* Garbage */
@@ -190,6 +248,10 @@ TEST(parse_cpu_set) {
         assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
         assert_se(!c.set);                /* empty string returns NULL */
         assert_se(c.allocated == 0);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        assert_se(streq(str, "0"));
+        str = mfree(str);
 
         /* Runaway quoted string */
         assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
@@ -206,6 +268,23 @@ TEST(parse_cpu_set) {
         log_info("cpu_set_to_range_string: %s", str);
         assert_se(streq(str, "8000-8191"));
         str = mfree(str);
+        assert_se(str = cpu_set_to_mask_string(&c));
+        log_info("cpu_set_to_mask_string: %s", str);
+        for (size_t i = 0; i < strlen(str); i++) {
+                if (i < 54) {
+                        if (i >= 8 && (i + 1) % 9 == 0)
+                                assert_se(str[i] == ',');
+                        else
+                                assert_se(str[i] == 'f');
+                }
+                else {
+                        if (i >= 8 && (i + 1) % 9 == 0)
+                                assert_se(str[i] == ',');
+                        else
+                                assert_se(str[i] == '0');
+                }
+        }
+        str = mfree(str);
         cpu_set_reset(&c);
 }
 
index 42d7cc7ee21a721b1439e00d8c158300cb811b44..b77759d09446fcc7a47b7eff3dd35a0a32f36ab7 100644 (file)
@@ -108,6 +108,7 @@ 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)
+Link.ReceivePacketSteeringCPUMask,         config_parse_rps_cpu_mask,             0,                             offsetof(LinkConfig, rps_cpu_mask)
 Link.MDI,                                  config_parse_mdi,                      0,                             offsetof(LinkConfig, mdi)
 Link.SR-IOVVirtualFunctions,               config_parse_sr_iov_num_vfs,           0,                             offsetof(LinkConfig, sr_iov_num_vfs)
 SR-IOV.VirtualFunction,                    config_parse_sr_iov_uint32,            0,                             offsetof(LinkConfig, sr_iov_by_section)
index a8b2cc23a2c57747030de4f73c63b636c59f14c8..8eee527bbff5880b2f91db5423b7e250a28c7ba7 100644 (file)
@@ -73,6 +73,7 @@ static LinkConfig* link_config_free(LinkConfig *config) {
         free(config->alias);
         free(config->wol_password_file);
         erase_and_free(config->wol_password);
+        cpu_set_free(config->rps_cpu_mask);
 
         ordered_hashmap_free_with_destructor(config->sr_iov_by_section, sr_iov_free);
 
@@ -937,6 +938,49 @@ static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) {
         return 0;
 }
 
+static int link_apply_rps_cpu_mask(Link *link) {
+        _cleanup_free_ char *mask_str = NULL;
+        LinkConfig *config;
+        int r;
+
+        assert(link);
+        config = ASSERT_PTR(link->config);
+
+        /* Skip if the config is not specified. */
+        if (!config->rps_cpu_mask)
+                return 0;
+
+        mask_str = cpu_set_to_mask_string(config->rps_cpu_mask);
+        if (!mask_str)
+                return log_oom();
+
+        log_link_debug(link, "Applying RPS CPU mask: %s", mask_str);
+
+        /* Currently, this will set CPU mask to all rx queue of matched device. */
+        FOREACH_DEVICE_SYSATTR(link->device, attr) {
+                const char *c;
+
+                c = path_startswith(attr, "queues/");
+                if (!c)
+                        continue;
+
+                c = startswith(c, "rx-");
+                if (!c)
+                        continue;
+
+                c += strcspn(c, "/");
+
+                if (!path_equal(c, "/rps_cpus"))
+                        continue;
+
+                r = sd_device_set_sysattr_value(link->device, attr, mask_str);
+                if (r < 0)
+                        log_link_warning_errno(link, r, "Failed to write %s sysfs attribute, ignoring: %m", attr);
+        }
+
+        return 0;
+}
+
 static int link_apply_udev_properties(Link *link, bool test) {
         LinkConfig *config;
         sd_device *device;
@@ -1024,6 +1068,10 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link, boo
         if (r < 0)
                 return r;
 
+        r = link_apply_rps_cpu_mask(link);
+        if (r < 0)
+                return r;
+
         return 0;
 }
 
@@ -1314,6 +1362,65 @@ int config_parse_wol_password(
         return 0;
 }
 
+int config_parse_rps_cpu_mask(
+                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) {
+
+        _cleanup_(cpu_set_freep) CPUSet *allocated = NULL;
+        CPUSet *mask, **rps_cpu_mask = ASSERT_PTR(data);
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                *rps_cpu_mask = cpu_set_free(*rps_cpu_mask);
+                return 0;
+        }
+
+        if (*rps_cpu_mask)
+                mask = *rps_cpu_mask;
+        else {
+                allocated = new0(CPUSet, 1);
+                if (!allocated)
+                        return log_oom();
+
+                mask = allocated;
+        }
+
+        if (streq(rvalue, "disable")) {
+                cpu_set_reset(mask);
+                return 0;
+        }
+
+        if (streq(rvalue, "all")) {
+                r = cpu_mask_add_all(mask);
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Failed to create CPU affinity mask representing \"all\" cpus, ignoring: %m");
+                        return 0;
+                }
+        } else {
+                r = parse_cpu_set_extend(rvalue, mask, /* warn= */ true, unit, filename, line, lvalue);
+                if (r < 0)
+                        return 0;
+        }
+
+        if (allocated)
+                *rps_cpu_mask = TAKE_PTR(allocated);
+
+        return 0;
+}
+
 static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = {
         [MAC_ADDRESS_POLICY_PERSISTENT] = "persistent",
         [MAC_ADDRESS_POLICY_RANDOM] = "random",
index 98cadc212e1fe9fe8380843eda3ba5ccc595a386..f6abff89e8b3bc8a9fc65ffc84b19d7c45f4936f 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "condition.h"
 #include "conf-parser.h"
+#include "cpu-set-util.h"
 #include "ethtool-util.h"
 #include "hashmap.h"
 #include "list.h"
@@ -84,6 +85,7 @@ struct LinkConfig {
         int autoneg_flow_control;
         netdev_coalesce_param coalesce;
         uint8_t mdi;
+        CPUSet *rps_cpu_mask;
 
         uint32_t sr_iov_num_vfs;
         OrderedHashmap *sr_iov_by_section;
@@ -121,3 +123,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wol_password);
 CONFIG_PARSER_PROTOTYPE(config_parse_mac_address_policy);
 CONFIG_PARSER_PROTOTYPE(config_parse_name_policy);
 CONFIG_PARSER_PROTOTYPE(config_parse_alternative_names_policy);
+CONFIG_PARSER_PROTOTYPE(config_parse_rps_cpu_mask);
index 8720721f43cd31f17b30f1ea557247cc99b9f5a5..5925602e43369e8a46061632e8462f300e3526f2 100644 (file)
@@ -192,6 +192,12 @@ static int start_one_worker(Manager *m) {
                         _exit(EXIT_FAILURE);
                 }
 
+                r = setenv_systemd_log_level();
+                if (r < 0) {
+                        log_error_errno(r, "Failed to set $SYSTEMD_LOG_LEVEL: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
                 r = invoke_callout_binary(SYSTEMD_USERWORK_PATH, STRV_MAKE(SYSTEMD_USERWORK_PATH, "xxxxxxxxxxxxxxxx")); /* With some extra space rename_process() can make use of */
                 log_error_errno(r, "Failed start worker process: %m");
                 _exit(EXIT_FAILURE);
diff --git a/test/test-network/conf/24-rps-cpu-disable.link b/test/test-network/conf/24-rps-cpu-disable.link
new file mode 100644 (file)
index 0000000..fb3451a
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=disable
diff --git a/test/test-network/conf/24-rps-cpu-empty.link b/test/test-network/conf/24-rps-cpu-empty.link
new file mode 100644 (file)
index 0000000..fc1342b
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=
diff --git a/test/test-network/conf/24-rps-cpu-invalid.link b/test/test-network/conf/24-rps-cpu-invalid.link
new file mode 100644 (file)
index 0000000..76d6713
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0 3 8-invalid
diff --git a/test/test-network/conf/25-rps-cpu-0-1.link b/test/test-network/conf/25-rps-cpu-0-1.link
new file mode 100644 (file)
index 0000000..d026248
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0 1
diff --git a/test/test-network/conf/25-rps-cpu-0-empty.link b/test/test-network/conf/25-rps-cpu-0-empty.link
new file mode 100644 (file)
index 0000000..b25b417
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0
+ReceivePacketSteeringCPUMask=
diff --git a/test/test-network/conf/25-rps-cpu-0-invalid.link b/test/test-network/conf/25-rps-cpu-0-invalid.link
new file mode 100644 (file)
index 0000000..26147a0
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0
+ReceivePacketSteeringCPUMask=invalid
diff --git a/test/test-network/conf/25-rps-cpu-0.link b/test/test-network/conf/25-rps-cpu-0.link
new file mode 100644 (file)
index 0000000..b1f4bc2
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0
diff --git a/test/test-network/conf/25-rps-cpu-1.link b/test/test-network/conf/25-rps-cpu-1.link
new file mode 100644 (file)
index 0000000..d24d713
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=1
diff --git a/test/test-network/conf/25-rps-cpu-all.link b/test/test-network/conf/25-rps-cpu-all.link
new file mode 100644 (file)
index 0000000..b7a8eda
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=all
diff --git a/test/test-network/conf/25-rps-cpu-multi.link b/test/test-network/conf/25-rps-cpu-multi.link
new file mode 100644 (file)
index 0000000..d7d4d04
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Match]
+OriginalName=dummy98
+
+[Link]
+ReceivePacketSteeringCPUMask=0 1
+ReceivePacketSteeringCPUMask=2,3
index aa7bd1e87aa7cf576d0927cc42f7ccdd4077c477..e194f212ee15f44f2729f4ee21aaf1f0d3e8c9b2 100755 (executable)
@@ -2459,6 +2459,131 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
 
         self.wait_online('ifb99:degraded')
 
+    def test_rps_cpu_0(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 1)
+
+    @unittest.skipUnless(os.cpu_count() >= 2, reason="CPU count should be >= 2 to pass this test")
+    def test_rps_cpu_1(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-1.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 2)
+
+    @unittest.skipUnless(os.cpu_count() >= 2, reason="CPU count should be >= 2 to pass this test")
+    def test_rps_cpu_0_1(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0-1.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 3)
+
+    @unittest.skipUnless(os.cpu_count() >= 4, reason="CPU count should be >= 4 to pass this test")
+    def test_rps_cpu_multi(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-multi.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 15)
+
+    def test_rps_cpu_all(self):
+        cpu_count = os.cpu_count()
+
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-all.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(f"{int(output.replace(',', ''), base=16):x}", f'{(1 << cpu_count) - 1:x}')
+
+    def test_rps_cpu_disable(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-all.link', '24-rps-cpu-disable.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
+    def test_rps_cpu_empty(self):
+        copy_network_unit('12-dummy.netdev', '24-rps-cpu-empty.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
+    def test_rps_cpu_0_empty(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0-empty.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
+    def test_rps_cpu_0_and_empty(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0.link', '24-rps-cpu-empty.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
+    def test_rps_cpu_invalid(self):
+        copy_network_unit('12-dummy.netdev', '24-rps-cpu-invalid.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
+    def test_rps_cpu_0_invalid(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0-invalid.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 1)
+
+    def test_rps_cpu_0_and_invalid(self):
+        copy_network_unit('12-dummy.netdev', '25-rps-cpu-0.link', '24-rps-cpu-invalid.link')
+        start_networkd()
+
+        self.wait_links('dummy98')
+
+        output = check_output('cat /sys/class/net/dummy98/queues/rx-0/rps_cpus')
+        print(output)
+        self.assertEqual(int(output.replace(',', ''), base=16), 0)
+
 class NetworkdL2TPTests(unittest.TestCase, Utilities):
 
     def setUp(self):
@@ -5577,7 +5702,7 @@ class NetworkdDHCPServerRelayAgentTests(unittest.TestCase, Utilities):
         print(output)
         self.assertRegex(output, r'Address: 192.168.5.150 \(DHCP4 via 192.168.5.1\)')
 
-    def test_replay_agent_on_bridge(self):
+    def test_relay_agent_on_bridge(self):
         copy_network_unit('25-agent-bridge.netdev',
                           '25-agent-veth-client.netdev',
                           '25-agent-bridge.network',