mirror of
https://github.com/systemd/systemd
synced 2026-03-25 16:25:04 +01:00
Compare commits
No commits in common. "dc131951b5f903b698f624a0234560d7a822ff21" and "468d9bc9011bc2278c4c2cf68052a55744918c96" have entirely different histories.
dc131951b5
...
468d9bc901
4
README
4
README
@ -40,7 +40,6 @@ REQUIREMENTS:
|
||||
Linux kernel >= 4.17 for cgroup-bpf socket address hooks
|
||||
Linux kernel >= 5.3 for bounded-loops in BPF program
|
||||
Linux kernel >= 5.4 for signed Verity images support
|
||||
Linux kernel >= 5.7 for BPF links
|
||||
|
||||
Kernel Config Options:
|
||||
CONFIG_DEVTMPFS
|
||||
@ -109,8 +108,7 @@ REQUIREMENTS:
|
||||
CONFIG_HAVE_EBPF_JIT
|
||||
CONFIG_CGROUP_BPF
|
||||
|
||||
Required for SocketBind{Allow|Deny}=, RestrictNetworkInterfaces= in
|
||||
resource control unit settings
|
||||
Required for SocketBind{Allow|Deny}= in resource control unit settings
|
||||
CONFIG_BPF
|
||||
CONFIG_BPF_SYSCALL
|
||||
CONFIG_BPF_JIT
|
||||
|
||||
@ -2528,8 +2528,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly as Environment = ['...', ...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -3072,8 +3070,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--property EnvironmentFiles is not documented!-->
|
||||
|
||||
<!--property PassEnvironment is not documented!-->
|
||||
@ -3642,8 +3638,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
|
||||
@ -4346,8 +4340,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly as Environment = ['...', ...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -4918,8 +4910,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--property EnvironmentFiles is not documented!-->
|
||||
|
||||
<!--property PassEnvironment is not documented!-->
|
||||
@ -5486,8 +5476,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
|
||||
@ -6087,8 +6075,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly as Environment = ['...', ...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -6587,8 +6573,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--property EnvironmentFiles is not documented!-->
|
||||
|
||||
<!--property PassEnvironment is not documented!-->
|
||||
@ -7073,8 +7057,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
|
||||
@ -7795,8 +7777,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly as Environment = ['...', ...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -8281,8 +8261,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--property EnvironmentFiles is not documented!-->
|
||||
|
||||
<!--property PassEnvironment is not documented!-->
|
||||
@ -8753,8 +8731,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
|
||||
@ -9328,8 +9304,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
};
|
||||
interface org.freedesktop.DBus.Peer { ... };
|
||||
interface org.freedesktop.DBus.Introspectable { ... };
|
||||
@ -9474,8 +9448,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--Autogenerated cross-references for systemd.directives, do not edit-->
|
||||
|
||||
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
|
||||
@ -9626,8 +9598,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<!--End of Autogenerated section-->
|
||||
|
||||
<refsect2>
|
||||
@ -9797,8 +9767,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
readonly a(iiqq) SocketBindAllow = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiqq) SocketBindDeny = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly (bas) RestrictNetworkInterfaces = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s KillMode = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -9959,8 +9927,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<!--property SocketBindDeny is not documented!-->
|
||||
|
||||
<!--property RestrictNetworkInterfaces is not documented!-->
|
||||
|
||||
<!--property KillMode is not documented!-->
|
||||
|
||||
<!--property KillSignal is not documented!-->
|
||||
@ -10137,8 +10103,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="SocketBindDeny"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="KillMode"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="KillSignal"/>
|
||||
|
||||
@ -773,77 +773,6 @@
|
||||
accept. An unsigned integer in the range 1…65535. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>UseAdaptiveRxCoalesce=</varname></term>
|
||||
<term><varname>UseAdaptiveTxCoalesce=</varname></term>
|
||||
<listitem>
|
||||
<para>Boolean properties that, when set, enable/disable adaptive Rx/Tx coalescing if the hardware
|
||||
supports it. When unset, the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>RxCoalesceSec=</varname></term>
|
||||
<term><varname>RxCoalesceIrqSec=</varname></term>
|
||||
<term><varname>RxCoalesceLowSec=</varname></term>
|
||||
<term><varname>RxCoalesceHighSec=</varname></term>
|
||||
<term><varname>TxCoalesceSec=</varname></term>
|
||||
<term><varname>TxCoalesceIrqSec=</varname></term>
|
||||
<term><varname>TxCoalesceLowSec=</varname></term>
|
||||
<term><varname>TxCoalesceHighSec=</varname></term>
|
||||
<listitem>
|
||||
<para>These properties configure the delay before Rx/Tx interrupts are generated after a packet is
|
||||
sent/received. The <literal>Irq</literal> properties come into effect when the host is servicing an
|
||||
IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into effect when the
|
||||
packet rate drops below the low packet rate threshold or exceeds the high packet rate threshold
|
||||
respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's defaults will be
|
||||
used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>RxMaxCoalescedFrames=</varname></term>
|
||||
<term><varname>RxMaxCoalescedIrqFrames=</varname></term>
|
||||
<term><varname>RxMaxCoalescedLowFrames=</varname></term>
|
||||
<term><varname>RxMaxCoalescedHighFrames=</varname></term>
|
||||
<term><varname>TxMaxCoalescedFrames=</varname></term>
|
||||
<term><varname>TxMaxCoalescedIrqFrames=</varname></term>
|
||||
<term><varname>TxMaxCoalescedLowFrames=</varname></term>
|
||||
<term><varname>TxMaxCoalescedHighFrames=</varname></term>
|
||||
<listitem>
|
||||
<para>These properties configure the maximum number of frames that are sent/received before a Rx/Tx
|
||||
interrupt is generated. The <literal>Irq</literal> properties come into effect when the host is
|
||||
servicing an IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into
|
||||
effect when the packet rate drops below the low packet rate threshold or exceeds the high packet
|
||||
rate threshold respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's
|
||||
defaults will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>CoalescePacketRateLow=</varname></term>
|
||||
<term><varname>CoalescePacketRateHigh=</varname></term>
|
||||
<listitem>
|
||||
<para>These properties configure the low and high packet rate (expressed in packets per second)
|
||||
threshold respectively and are used to determine when the corresponding coalescing settings for low
|
||||
and high packet rates come into effect if adaptive Rx/Tx coalescing is enabled. If unset, the
|
||||
kernel's defaults will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>CoalescePacketRateSampleIntervalSec=</varname></term>
|
||||
<listitem>
|
||||
<para>Configures how often to sample the packet rate used for adaptive Rx/Tx coalescing. This
|
||||
property cannot be zero. This lowest time granularity supported by this property is seconds.
|
||||
Partial seconds will be rounded up before being passed to the kernel. If unset, the kernel's
|
||||
default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>StatisticsBlockCoalesceSec=</varname></term>
|
||||
<listitem>
|
||||
<para>How long to delay driver in-memory statistics block updates. If the driver does not have an
|
||||
in-memory statistic block, this property is ignored. This property cannot be zero. If unset, the
|
||||
kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@ -855,52 +855,6 @@ SocketBindDeny=any
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>RestrictNetworkInterfaces=</varname></term>
|
||||
|
||||
<listitem>
|
||||
<para>Takes a list of space-separated network interface names. This option restricts the network
|
||||
interfaces that processes of this unit can use. By default processes can only use the network interfaces
|
||||
listed (allow-list). If the first character of the rule is <literal>~</literal>, the effect is inverted:
|
||||
the processes can only use network interfaces not listed (deny-list).
|
||||
</para>
|
||||
|
||||
<para>This option can appear multiple times, in which case the network interface names are merged. If the
|
||||
empty string is assigned the set is reset, all prior assigments will have not effect.
|
||||
</para>
|
||||
|
||||
<para>If you specify both types of this option (i.e. allow-listing and deny-listing), the first encountered
|
||||
will take precedence and will dictate the default action (allow vs deny). Then the next occurrences of this
|
||||
option will add or delete the listed network interface names from the set, depending of its type and the
|
||||
default action.
|
||||
</para>
|
||||
|
||||
<para>The loopback interface ("lo") is not treated in any special way, you have to configure it explicitly
|
||||
in the unit file.
|
||||
</para>
|
||||
<para>Example 1: allow-list
|
||||
<programlisting>
|
||||
RestrictNetworkInterfaces=eth1
|
||||
RestrictNetworkInterfaces=eth2</programlisting>
|
||||
Programs in the unit will be only able to use the eth1 and eth2 network
|
||||
interfaces.
|
||||
</para>
|
||||
|
||||
<para>Example 2: deny-list
|
||||
<programlisting>
|
||||
RestrictNetworkInterfaces=~eth1 eth2</programlisting>
|
||||
Programs in the unit will be able to use any network interface but eth1 and eth2.
|
||||
</para>
|
||||
|
||||
<para>Example 3: mixed
|
||||
<programlisting>
|
||||
RestrictNetworkInterfaces=eth1 eth2
|
||||
RestrictNetworkInterfaces=~eth1</programlisting>
|
||||
Programs in the unit will be only able to use the eth2 network interface.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DeviceAllow=</varname></term>
|
||||
|
||||
|
||||
@ -2214,7 +2214,6 @@ static const char *const cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
|
||||
[CGROUP_CONTROLLER_BPF_DEVICES] = "bpf-devices",
|
||||
[CGROUP_CONTROLLER_BPF_FOREIGN] = "bpf-foreign",
|
||||
[CGROUP_CONTROLLER_BPF_SOCKET_BIND] = "bpf-socket-bind",
|
||||
[CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES] = "bpf-restrict-network-interfaces",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);
|
||||
|
||||
@ -32,7 +32,6 @@ typedef enum CGroupController {
|
||||
CGROUP_CONTROLLER_BPF_DEVICES,
|
||||
CGROUP_CONTROLLER_BPF_FOREIGN,
|
||||
CGROUP_CONTROLLER_BPF_SOCKET_BIND,
|
||||
CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES,
|
||||
|
||||
_CGROUP_CONTROLLER_MAX,
|
||||
_CGROUP_CONTROLLER_INVALID = -EINVAL,
|
||||
@ -54,7 +53,6 @@ typedef enum CGroupMask {
|
||||
CGROUP_MASK_BPF_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_DEVICES),
|
||||
CGROUP_MASK_BPF_FOREIGN = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FOREIGN),
|
||||
CGROUP_MASK_BPF_SOCKET_BIND = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_SOCKET_BIND),
|
||||
CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES),
|
||||
|
||||
/* All real cgroup v1 controllers */
|
||||
CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS,
|
||||
@ -63,7 +61,7 @@ typedef enum CGroupMask {
|
||||
CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS,
|
||||
|
||||
/* All cgroup v2 BPF pseudo-controllers */
|
||||
CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES,
|
||||
CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND,
|
||||
|
||||
_CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1
|
||||
} CGroupMask;
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
restrict_ifaces_skel_h = custom_target(
|
||||
'restrict-ifaces.skel.h',
|
||||
input : 'restrict-ifaces.bpf.c',
|
||||
output : 'restrict-ifaces.skel.h',
|
||||
command : [build_bpf_skel_py,
|
||||
'--clang_exec', clang.path(),
|
||||
'--llvm_strip_exec', llvm_strip.path(),
|
||||
'--bpftool_exec', bpftool.path(),
|
||||
'--arch', host_machine.cpu_family(),
|
||||
'@INPUT@', '@OUTPUT@'])
|
||||
endif
|
||||
@ -1,52 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
/* <linux/bpf.h> must precede <bpf/bpf_helpers.h> due to integer types
|
||||
* in bpf helpers signatures.
|
||||
*/
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
const volatile __u8 is_allow_list = 0;
|
||||
|
||||
/* Map containing the network interfaces indexes.
|
||||
* The interpretation of the map depends on the value of is_allow_list.
|
||||
*/
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, __u32);
|
||||
__type(value, __u8);
|
||||
} sd_restrictif SEC(".maps");
|
||||
|
||||
#define DROP 0
|
||||
#define PASS 1
|
||||
|
||||
static inline int restrict_network_interfaces_impl(const struct __sk_buff *sk) {
|
||||
__u32 zero = 0, ifindex;
|
||||
__u8 *lookup_result;
|
||||
|
||||
ifindex = sk->ifindex;
|
||||
lookup_result = bpf_map_lookup_elem(&sd_restrictif, &ifindex);
|
||||
if (is_allow_list) {
|
||||
/* allow-list: let the packet pass if iface in the list */
|
||||
if (lookup_result)
|
||||
return PASS;
|
||||
} else {
|
||||
/* deny-list: let the packet pass if iface *not* in the list */
|
||||
if (!lookup_result)
|
||||
return PASS;
|
||||
}
|
||||
|
||||
return DROP;
|
||||
}
|
||||
|
||||
SEC("cgroup_skb/egress")
|
||||
int sd_restrictif_e(const struct __sk_buff *sk) {
|
||||
return restrict_network_interfaces_impl(sk);
|
||||
}
|
||||
|
||||
SEC("cgroup_skb/ingress")
|
||||
int sd_restrictif_i(const struct __sk_buff *sk) {
|
||||
return restrict_network_interfaces_impl(sk);
|
||||
}
|
||||
|
||||
static const char _license[] SEC("license") = "LGPL-2.1-or-later";
|
||||
@ -28,7 +28,6 @@
|
||||
#include "percent-util.h"
|
||||
#include "process-util.h"
|
||||
#include "procfs-util.h"
|
||||
#include "restrict-ifaces.h"
|
||||
#include "special.h"
|
||||
#include "stat-util.h"
|
||||
#include "stdio-util.h"
|
||||
@ -247,8 +246,6 @@ void cgroup_context_done(CGroupContext *c) {
|
||||
while (c->bpf_foreign_programs)
|
||||
cgroup_context_remove_bpf_foreign_program(c, c->bpf_foreign_programs);
|
||||
|
||||
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
|
||||
|
||||
cpu_set_reset(&c->cpuset_cpus);
|
||||
cpu_set_reset(&c->cpuset_mems);
|
||||
}
|
||||
@ -586,12 +583,6 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
cgroup_context_dump_socket_bind_item(bi, f);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
if (c->restrict_network_interfaces) {
|
||||
char *iface;
|
||||
SET_FOREACH(iface, c->restrict_network_interfaces)
|
||||
fprintf(f, "%sRestrictNetworkInterfaces: %s\n", prefix, iface);
|
||||
}
|
||||
}
|
||||
|
||||
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f) {
|
||||
@ -1106,12 +1097,6 @@ static void cgroup_apply_socket_bind(Unit *u) {
|
||||
(void) bpf_socket_bind_install(u);
|
||||
}
|
||||
|
||||
static void cgroup_apply_restrict_network_interfaces(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
(void) restrict_network_interfaces_install(u);
|
||||
}
|
||||
|
||||
static int cgroup_apply_devices(Unit *u) {
|
||||
_cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
|
||||
const char *path;
|
||||
@ -1542,9 +1527,6 @@ static void cgroup_context_apply(
|
||||
|
||||
if (apply_mask & CGROUP_MASK_BPF_SOCKET_BIND)
|
||||
cgroup_apply_socket_bind(u);
|
||||
|
||||
if (apply_mask & CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES)
|
||||
cgroup_apply_restrict_network_interfaces(u);
|
||||
}
|
||||
|
||||
static bool unit_get_needs_bpf_firewall(Unit *u) {
|
||||
@ -1598,17 +1580,6 @@ static bool unit_get_needs_socket_bind(Unit *u) {
|
||||
return c->socket_bind_allow || c->socket_bind_deny;
|
||||
}
|
||||
|
||||
static bool unit_get_needs_restrict_network_interfaces(Unit *u) {
|
||||
CGroupContext *c;
|
||||
assert(u);
|
||||
|
||||
c = unit_get_cgroup_context(u);
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
return !set_isempty(c->restrict_network_interfaces);
|
||||
}
|
||||
|
||||
static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||||
CGroupMask mask = 0;
|
||||
CGroupContext *c;
|
||||
@ -1664,9 +1635,6 @@ static CGroupMask unit_get_bpf_mask(Unit *u) {
|
||||
if (unit_get_needs_socket_bind(u))
|
||||
mask |= CGROUP_MASK_BPF_SOCKET_BIND;
|
||||
|
||||
if (unit_get_needs_restrict_network_interfaces(u))
|
||||
mask |= CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -3164,11 +3132,6 @@ static int cg_bpf_mask_supported(CGroupMask *ret) {
|
||||
if (r > 0)
|
||||
mask |= CGROUP_MASK_BPF_SOCKET_BIND;
|
||||
|
||||
/* BPF-based cgroup_skb/{egress|ingress} hooks */
|
||||
r = restrict_network_interfaces_supported();
|
||||
if (r > 0)
|
||||
mask |= CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES;
|
||||
|
||||
*ret = mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -160,9 +160,6 @@ struct CGroupContext {
|
||||
char **ip_filters_egress;
|
||||
LIST_HEAD(CGroupBPFForeignProgram, bpf_foreign_programs);
|
||||
|
||||
Set *restrict_network_interfaces;
|
||||
bool restrict_network_interfaces_is_allow_list;
|
||||
|
||||
/* For legacy hierarchies */
|
||||
uint64_t cpu_shares;
|
||||
uint64_t startup_cpu_shares;
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "percent-util.h"
|
||||
#include "socket-util.h"
|
||||
|
||||
BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max, "t", TasksMax, tasks_max_resolve);
|
||||
|
||||
@ -404,47 +403,6 @@ static int property_get_socket_bind(
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int property_get_restrict_network_interfaces(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
int r;
|
||||
CGroupContext *c = userdata;
|
||||
char *iface;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'r', "bas");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(reply, "b", c->restrict_network_interfaces_is_allow_list);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "s");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(iface, c->restrict_network_interfaces) {
|
||||
r = sd_bus_message_append(reply, "s", iface);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0),
|
||||
@ -499,7 +457,6 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("BPFProgram", "a(ss)", property_get_bpf_foreign_program, 0, 0),
|
||||
SD_BUS_PROPERTY("SocketBindAllow", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_allow), 0),
|
||||
SD_BUS_PROPERTY("SocketBindDeny", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_deny), 0),
|
||||
SD_BUS_PROPERTY("RestrictNetworkInterfaces", "(bas)", property_get_restrict_network_interfaces, 0, 0),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
@ -2006,64 +1963,6 @@ int bus_cgroup_set_property(
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (streq(name, "RestrictNetworkInterfaces")) {
|
||||
int is_allow_list;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'r', "bas");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &is_allow_list);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read_strv(message, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
char **s;
|
||||
|
||||
if (strv_isempty(l)) {
|
||||
c->restrict_network_interfaces_is_allow_list = false;
|
||||
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (set_isempty(c->restrict_network_interfaces))
|
||||
c->restrict_network_interfaces_is_allow_list = is_allow_list;
|
||||
|
||||
STRV_FOREACH(s, l) {
|
||||
if (!ifname_valid(*s)) {
|
||||
log_full(LOG_WARNING, "Invalid interface name, ignoring: %s", *s);
|
||||
continue;
|
||||
}
|
||||
if (c->restrict_network_interfaces_is_allow_list != (bool) is_allow_list)
|
||||
free(set_remove(c->restrict_network_interfaces, *s));
|
||||
else {
|
||||
r = set_put_strdup(&c->restrict_network_interfaces, *s);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
joined = strv_join(l, " ");
|
||||
if (!joined)
|
||||
return -ENOMEM;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s%s", name, is_allow_list ? "" : "~", joined);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (streq(name, "DisableControllers") || (u->transient && u->load_state == UNIT_STUB))
|
||||
return bus_cgroup_set_transient_property(u, c, name, message, flags, error);
|
||||
|
||||
@ -233,7 +233,6 @@
|
||||
{{type}}.BPFProgram, config_parse_bpf_foreign_program, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.SocketBindAllow, config_parse_cgroup_socket_bind, 0, offsetof({{type}}, cgroup_context.socket_bind_allow)
|
||||
{{type}}.SocketBindDeny, config_parse_cgroup_socket_bind, 0, offsetof({{type}}, cgroup_context.socket_bind_deny)
|
||||
{{type}}.RestrictNetworkInterfaces, config_parse_restrict_network_interfaces, 0, offsetof({{type}}, cgroup_context)
|
||||
{%- endmacro -%}
|
||||
|
||||
%{
|
||||
|
||||
@ -5711,72 +5711,6 @@ int config_parse_cgroup_socket_bind(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_restrict_network_interfaces(
|
||||
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) {
|
||||
CGroupContext *c = data;
|
||||
bool is_allow_rule = true;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
/* Empty assignment resets the list */
|
||||
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rvalue[0] == '~') {
|
||||
is_allow_rule = false;
|
||||
rvalue++;
|
||||
}
|
||||
|
||||
if (set_isempty(c->restrict_network_interfaces))
|
||||
/* Only initialize this when creating the set */
|
||||
c->restrict_network_interfaces_is_allow_list = is_allow_rule;
|
||||
|
||||
for (const char *p = rvalue;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Trailing garbage in %s, ignoring: %s", lvalue, rvalue);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ifname_valid(word)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid interface name, ignoring: %s", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c->restrict_network_interfaces_is_allow_list != is_allow_rule)
|
||||
free(set_remove(c->restrict_network_interfaces, word));
|
||||
else {
|
||||
r = set_put_strdup(&c->restrict_network_interfaces, word);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int merge_by_names(Unit **u, Set *names, const char *id) {
|
||||
char *k;
|
||||
int r;
|
||||
|
||||
@ -141,7 +141,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_socket_timestamping);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_extension_images);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_bpf_foreign_program);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_cgroup_socket_bind);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_restrict_network_interfaces);
|
||||
|
||||
/* gperf prototypes */
|
||||
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
||||
|
||||
@ -97,8 +97,6 @@ libcore_sources = '''
|
||||
namespace.h
|
||||
path.c
|
||||
path.h
|
||||
restrict-ifaces.c
|
||||
restrict-ifaces.h
|
||||
scope.c
|
||||
scope.h
|
||||
selinux-access.c
|
||||
@ -138,11 +136,6 @@ if conf.get('BPF_FRAMEWORK') == 1
|
||||
libcore_sources += [socket_bind_skel_h]
|
||||
endif
|
||||
|
||||
subdir('bpf/restrict_ifaces')
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
libcore_sources += [restrict_ifaces_skel_h]
|
||||
endif
|
||||
|
||||
load_fragment_gperf_gperf = custom_target(
|
||||
'load-fragment-gperf.gperf',
|
||||
input : 'load-fragment-gperf.gperf.in',
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include "fd-util.h"
|
||||
#include "restrict-ifaces.h"
|
||||
#include "netlink-util.h"
|
||||
|
||||
#if BPF_FRAMEWORK
|
||||
/* libbpf, clang and llc compile time dependencies are satisfied */
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-link.h"
|
||||
|
||||
#include "bpf/restrict_ifaces/restrict-ifaces.skel.h"
|
||||
|
||||
static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) {
|
||||
restrict_ifaces_bpf__destroy(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct restrict_ifaces_bpf *, restrict_ifaces_bpf_free);
|
||||
|
||||
static int prepare_restrict_ifaces_bpf(Unit* u, bool is_allow_list,
|
||||
const Set *restrict_network_interfaces,
|
||||
struct restrict_ifaces_bpf **ret_object) {
|
||||
_cleanup_(restrict_ifaces_bpf_freep) struct restrict_ifaces_bpf *obj = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
char *iface;
|
||||
int r, map_fd;
|
||||
|
||||
assert(ret_object);
|
||||
|
||||
obj = restrict_ifaces_bpf__open();
|
||||
if (!obj)
|
||||
return log_unit_error_errno(u, SYNTHETIC_ERRNO(ENOMEM), "Failed to open BPF object");
|
||||
|
||||
r = sym_bpf_map__resize(obj->maps.sd_restrictif, MAX(set_size(restrict_network_interfaces), 1u));
|
||||
if (r != 0)
|
||||
return log_unit_error_errno(u, r,
|
||||
"Failed to resize BPF map '%s': %m",
|
||||
sym_bpf_map__name(obj->maps.sd_restrictif));
|
||||
|
||||
obj->rodata->is_allow_list = is_allow_list;
|
||||
|
||||
r = restrict_ifaces_bpf__load(obj);
|
||||
if (r != 0)
|
||||
return log_unit_error_errno(u, r, "Failed to load BPF object: %m");
|
||||
|
||||
map_fd = sym_bpf_map__fd(obj->maps.sd_restrictif);
|
||||
|
||||
SET_FOREACH(iface, restrict_network_interfaces) {
|
||||
uint8_t dummy = 0;
|
||||
int ifindex;
|
||||
ifindex = rtnl_resolve_interface(&rtnl, iface);
|
||||
if (ifindex < 0) {
|
||||
log_unit_warning_errno(u, ifindex, "Couldn't find index of network interface: %m. Ignoring '%s'", iface);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sym_bpf_map_update_elem(map_fd, &ifindex, &dummy, BPF_ANY))
|
||||
return log_unit_error_errno(u, errno, "Failed to update BPF map '%s' fd: %m", sym_bpf_map__name(obj->maps.sd_restrictif));
|
||||
}
|
||||
|
||||
*ret_object = TAKE_PTR(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restrict_network_interfaces_supported(void) {
|
||||
_cleanup_(restrict_ifaces_bpf_freep) struct restrict_ifaces_bpf *obj = NULL;
|
||||
int r;
|
||||
static int supported = -1;
|
||||
|
||||
if (supported >= 0)
|
||||
return supported;
|
||||
|
||||
r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Can't determine whether the unified hierarchy is used: %m");
|
||||
supported = 0;
|
||||
return supported;
|
||||
}
|
||||
if (r == 0) {
|
||||
log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Not running with unified cgroup hierarchy, BPF is not supported");
|
||||
supported = 0;
|
||||
return supported;
|
||||
}
|
||||
|
||||
if (dlopen_bpf() < 0)
|
||||
return false;
|
||||
|
||||
if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SKB, /*ifindex=*/0)) {
|
||||
log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"BPF program type cgroup_skb is not supported");
|
||||
supported = 0;
|
||||
return supported;
|
||||
}
|
||||
|
||||
r = prepare_restrict_ifaces_bpf(NULL, true, NULL, &obj);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to load BPF object: %m");
|
||||
|
||||
supported = bpf_can_link_program(obj->progs.sd_restrictif_i);
|
||||
return supported;
|
||||
}
|
||||
|
||||
static int restrict_network_interfaces_install_impl(Unit *u) {
|
||||
_cleanup_(bpf_link_freep) struct bpf_link *egress_link = NULL, *ingress_link = NULL;
|
||||
_cleanup_(restrict_ifaces_bpf_freep) struct restrict_ifaces_bpf *obj = NULL;
|
||||
_cleanup_free_ char *cgroup_path = NULL;
|
||||
_cleanup_close_ int cgroup_fd = -1;
|
||||
CGroupContext *cc;
|
||||
int r;
|
||||
|
||||
cc = unit_get_cgroup_context(u);
|
||||
if (!cc)
|
||||
return 0;
|
||||
|
||||
r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &cgroup_path);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(u, r, "Failed to get cgroup path: %m");
|
||||
|
||||
if (!cc->restrict_network_interfaces)
|
||||
return 0;
|
||||
|
||||
r = prepare_restrict_ifaces_bpf(u,
|
||||
cc->restrict_network_interfaces_is_allow_list,
|
||||
cc->restrict_network_interfaces,
|
||||
&obj);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
cgroup_fd = open(cgroup_path, O_RDONLY | O_CLOEXEC | O_DIRECTORY, 0);
|
||||
if (cgroup_fd < 0)
|
||||
return -errno;
|
||||
|
||||
ingress_link = sym_bpf_program__attach_cgroup(obj->progs.sd_restrictif_i, cgroup_fd);
|
||||
r = sym_libbpf_get_error(ingress_link);
|
||||
if (r != 0)
|
||||
return log_unit_error_errno(u, r, "Failed to create ingress cgroup link: %m");
|
||||
|
||||
egress_link = sym_bpf_program__attach_cgroup(obj->progs.sd_restrictif_e, cgroup_fd);
|
||||
r = sym_libbpf_get_error(egress_link);
|
||||
if (r != 0)
|
||||
return log_unit_error_errno(u, r, "Failed to create egress cgroup link: %m");
|
||||
|
||||
u->restrict_ifaces_ingress_bpf_link = TAKE_PTR(ingress_link);
|
||||
u->restrict_ifaces_egress_bpf_link = TAKE_PTR(egress_link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restrict_network_interfaces_install(Unit *u) {
|
||||
int r = restrict_network_interfaces_install_impl(u);
|
||||
fdset_close(u->initial_restric_ifaces_link_fds);
|
||||
return r;
|
||||
}
|
||||
|
||||
int serialize_restrict_network_interfaces(Unit *u, FILE *f, FDSet *fds) {
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
r = bpf_serialize_link(f, fds, "restrict-ifaces-bpf-fd", u->restrict_ifaces_ingress_bpf_link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return bpf_serialize_link(f, fds, "restrict-ifaces-bpf-fd", u->restrict_ifaces_egress_bpf_link);
|
||||
}
|
||||
|
||||
int restrict_network_interfaces_add_initial_link_fd(Unit *u, int fd) {
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
if (!u->initial_restric_ifaces_link_fds) {
|
||||
u->initial_restric_ifaces_link_fds = fdset_new();
|
||||
if (!u->initial_restric_ifaces_link_fds)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = fdset_put(u->initial_restric_ifaces_link_fds, fd);
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(u, r, "Failed to put restrict-ifaces-bpf-fd %d to restored fdset: %m", fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! BPF_FRAMEWORK */
|
||||
int restrict_network_interfaces_supported(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restrict_network_interfaces_install(Unit *u) {
|
||||
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Failed to install RestrictInterfaces: BPF programs built from source code are not supported: %m");
|
||||
}
|
||||
|
||||
int serialize_restrict_network_interfaces(Unit *u, FILE *f, FDSet *fds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restrict_network_interfaces_add_initial_link_fd(Unit *u, int fd) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -1,16 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "fdset.h"
|
||||
#include "unit.h"
|
||||
|
||||
typedef struct Unit Unit;
|
||||
|
||||
int restrict_network_interfaces_supported(void);
|
||||
int restrict_network_interfaces_install(Unit *u);
|
||||
|
||||
int serialize_restrict_network_interfaces(Unit *u, FILE *f, FDSet *fds);
|
||||
|
||||
/* Add BPF link fd created before daemon-reload or daemon-reexec.
|
||||
* FDs will be closed at the end of restrict_network_interfaces_install. */
|
||||
int restrict_network_interfaces_add_initial_link_fd(Unit *u, int fd);
|
||||
@ -7,7 +7,6 @@
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "restrict-ifaces.h"
|
||||
#include "serialize.h"
|
||||
#include "string-table.h"
|
||||
#include "unit-serialize.h"
|
||||
@ -174,8 +173,6 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
|
||||
(void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-ingress-installed", u->ip_bpf_custom_ingress_installed);
|
||||
(void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-egress-installed", u->ip_bpf_custom_egress_installed);
|
||||
|
||||
(void) serialize_restrict_network_interfaces(u, f, fds);
|
||||
|
||||
if (uid_is_valid(u->ref_uid))
|
||||
(void) serialize_item_format(f, "ref-uid", UID_FMT, u->ref_uid);
|
||||
if (gid_is_valid(u->ref_gid))
|
||||
@ -416,21 +413,6 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
(void) bpf_program_deserialize_attachment_set(v, fds, &u->ip_bpf_custom_egress_installed);
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "restrict-ifaces-bpf-fd")) {
|
||||
int fd;
|
||||
|
||||
if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) {
|
||||
log_unit_debug(u, "Failed to parse restrict-ifaces-bpf-fd value: %s", v);
|
||||
continue;
|
||||
}
|
||||
if (fdset_remove(fds, fd) < 0) {
|
||||
log_unit_debug(u, "Failed to remove restrict-ifaces-bpf-fd %d from fdset", fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
(void) restrict_network_interfaces_add_initial_link_fd(u, fd);
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "ref-uid")) {
|
||||
uid_t uid;
|
||||
|
||||
|
||||
@ -766,12 +766,6 @@ Unit* unit_free(Unit *u) {
|
||||
|
||||
bpf_program_unref(u->bpf_device_control_installed);
|
||||
|
||||
#if BPF_FRAMEWORK
|
||||
bpf_link_free(u->restrict_ifaces_ingress_bpf_link);
|
||||
bpf_link_free(u->restrict_ifaces_egress_bpf_link);
|
||||
#endif
|
||||
fdset_free(u->initial_restric_ifaces_link_fds);
|
||||
|
||||
condition_free_list(u->conditions);
|
||||
condition_free_list(u->asserts);
|
||||
|
||||
|
||||
@ -335,12 +335,6 @@ typedef struct Unit {
|
||||
struct bpf_link *ipv6_socket_bind_link;
|
||||
#endif
|
||||
|
||||
FDSet *initial_restric_ifaces_link_fds;
|
||||
#if BPF_FRAMEWORK
|
||||
struct bpf_link *restrict_ifaces_ingress_bpf_link;
|
||||
struct bpf_link *restrict_ifaces_egress_bpf_link;
|
||||
#endif
|
||||
|
||||
/* Low-priority event source which is used to remove watched PIDs that have gone away, and subscribe to any new
|
||||
* ones which might have appeared. */
|
||||
sd_event_source *rewatch_pids_event_source;
|
||||
|
||||
@ -75,7 +75,8 @@ int bus_container_connect_socket(sd_bus *b) {
|
||||
r = wait_for_terminate_and_check("(sd-buscntrns)", child, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
bool nonzero_exit_status = r != EXIT_SUCCESS;
|
||||
if (r != EXIT_SUCCESS)
|
||||
return -EPROTO;
|
||||
|
||||
n = read(pair[0], &error_buf, sizeof(error_buf));
|
||||
if (n < 0)
|
||||
@ -94,11 +95,8 @@ int bus_container_connect_socket(sd_bus *b) {
|
||||
return 1;
|
||||
|
||||
if (error_buf > 0)
|
||||
return log_debug_errno(error_buf, "(sd-buscntr) failed to connect to D-Bus socket: %m");
|
||||
return log_debug_errno(error_buf, "Got error from (sd-buscntr): %m");
|
||||
}
|
||||
|
||||
if (nonzero_exit_status)
|
||||
return -EPROTO;
|
||||
|
||||
return bus_socket_start_auth(b);
|
||||
}
|
||||
|
||||
@ -1384,8 +1384,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||
|
||||
if (STR_IN_SET(field, "RestrictAddressFamilies",
|
||||
"SystemCallFilter",
|
||||
"SystemCallLog",
|
||||
"RestrictNetworkInterfaces")) {
|
||||
"SystemCallLog")) {
|
||||
int allow_list = 1;
|
||||
const char *p = eq;
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "memory-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "strxcpyx.h"
|
||||
|
||||
static const char* const duplex_table[_DUP_MAX] = {
|
||||
@ -1102,207 +1101,3 @@ int config_parse_wol(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_coalesce_u32(
|
||||
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) {
|
||||
u32_opt *dst = data;
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
dst->value = 0;
|
||||
dst->set = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse %s=, ignoring: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dst->value = k;
|
||||
dst->set = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_coalesce_sec(
|
||||
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) {
|
||||
u32_opt *dst = data;
|
||||
usec_t usec;
|
||||
int r;
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
dst->value = 0;
|
||||
dst->set = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_sec(rvalue, &usec);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse coalesce setting value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (usec > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Too large %s= value, ignoring: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(lvalue, "StatisticsBlockCoalesceSec", "CoalescePacketRateSampleIntervalSec") && usec < 1) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s= value, ignoring: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dst->value = (uint32_t) usec;
|
||||
dst->set = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce) {
|
||||
struct ethtool_coalesce ecmd = {
|
||||
.cmd = ETHTOOL_GCOALESCE,
|
||||
};
|
||||
struct ifreq ifr = {
|
||||
.ifr_data = (void*) &ecmd,
|
||||
};
|
||||
bool need_update = false;
|
||||
int r;
|
||||
|
||||
assert(ethtool_fd);
|
||||
assert(ifname);
|
||||
assert(coalesce);
|
||||
|
||||
if (coalesce->use_adaptive_rx_coalesce < 0 &&
|
||||
coalesce->use_adaptive_tx_coalesce < 0 &&
|
||||
!coalesce->rx_coalesce_usecs.set &&
|
||||
!coalesce->rx_max_coalesced_frames.set &&
|
||||
!coalesce->rx_coalesce_usecs_irq.set &&
|
||||
!coalesce->rx_max_coalesced_frames_irq.set &&
|
||||
!coalesce->tx_coalesce_usecs.set &&
|
||||
!coalesce->tx_max_coalesced_frames.set &&
|
||||
!coalesce->tx_coalesce_usecs_irq.set &&
|
||||
!coalesce->tx_max_coalesced_frames_irq.set &&
|
||||
!coalesce->stats_block_coalesce_usecs.set &&
|
||||
!coalesce->pkt_rate_low.set &&
|
||||
!coalesce->rx_coalesce_usecs_low.set &&
|
||||
!coalesce->rx_max_coalesced_frames_low.set &&
|
||||
!coalesce->tx_coalesce_usecs_low.set &&
|
||||
!coalesce->tx_max_coalesced_frames_low.set &&
|
||||
!coalesce->pkt_rate_high.set &&
|
||||
!coalesce->rx_coalesce_usecs_high.set &&
|
||||
!coalesce->rx_max_coalesced_frames_high.set &&
|
||||
!coalesce->tx_coalesce_usecs_high.set &&
|
||||
!coalesce->tx_max_coalesced_frames_high.set &&
|
||||
!coalesce->rate_sample_interval.set)
|
||||
return 0;
|
||||
|
||||
r = ethtool_connect(ethtool_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
|
||||
|
||||
r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (coalesce->use_adaptive_rx_coalesce >= 0)
|
||||
UPDATE(ecmd.use_adaptive_rx_coalesce, (uint32_t) coalesce->use_adaptive_rx_coalesce, need_update);
|
||||
|
||||
if (coalesce->use_adaptive_tx_coalesce >= 0)
|
||||
UPDATE(ecmd.use_adaptive_tx_coalesce, (uint32_t) coalesce->use_adaptive_tx_coalesce, need_update);
|
||||
|
||||
if (coalesce->rx_coalesce_usecs.set)
|
||||
UPDATE(ecmd.rx_coalesce_usecs, coalesce->rx_coalesce_usecs.value, need_update);
|
||||
|
||||
if (coalesce->rx_max_coalesced_frames.set)
|
||||
UPDATE(ecmd.rx_max_coalesced_frames, coalesce->rx_max_coalesced_frames.value, need_update);
|
||||
|
||||
if (coalesce->rx_coalesce_usecs_irq.set)
|
||||
UPDATE(ecmd.rx_coalesce_usecs_irq, coalesce->rx_coalesce_usecs_irq.value, need_update);
|
||||
|
||||
if (coalesce->rx_max_coalesced_frames_irq.set)
|
||||
UPDATE(ecmd.rx_max_coalesced_frames_irq, coalesce->rx_max_coalesced_frames_irq.value, need_update);
|
||||
|
||||
if (coalesce->tx_coalesce_usecs.set)
|
||||
UPDATE(ecmd.tx_coalesce_usecs, coalesce->tx_coalesce_usecs.value, need_update);
|
||||
|
||||
if (coalesce->tx_max_coalesced_frames.set)
|
||||
UPDATE(ecmd.tx_max_coalesced_frames, coalesce->tx_max_coalesced_frames.value, need_update);
|
||||
|
||||
if (coalesce->tx_coalesce_usecs_irq.set)
|
||||
UPDATE(ecmd.tx_coalesce_usecs_irq, coalesce->tx_coalesce_usecs_irq.value, need_update);
|
||||
|
||||
if (coalesce->tx_max_coalesced_frames_irq.set)
|
||||
UPDATE(ecmd.tx_max_coalesced_frames_irq, coalesce->tx_max_coalesced_frames_irq.value, need_update);
|
||||
|
||||
if (coalesce->stats_block_coalesce_usecs.set)
|
||||
UPDATE(ecmd.stats_block_coalesce_usecs, coalesce->stats_block_coalesce_usecs.value, need_update);
|
||||
|
||||
if (coalesce->pkt_rate_low.set)
|
||||
UPDATE(ecmd.pkt_rate_low, coalesce->pkt_rate_low.value, need_update);
|
||||
|
||||
if (coalesce->rx_coalesce_usecs_low.set)
|
||||
UPDATE(ecmd.rx_coalesce_usecs_low, coalesce->rx_coalesce_usecs_low.value, need_update);
|
||||
|
||||
if (coalesce->rx_max_coalesced_frames_low.set)
|
||||
UPDATE(ecmd.rx_max_coalesced_frames_low, coalesce->rx_max_coalesced_frames_low.value, need_update);
|
||||
|
||||
if (coalesce->tx_coalesce_usecs_low.set)
|
||||
UPDATE(ecmd.tx_coalesce_usecs_low, coalesce->tx_coalesce_usecs_low.value, need_update);
|
||||
|
||||
if (coalesce->tx_max_coalesced_frames_low.set)
|
||||
UPDATE(ecmd.tx_max_coalesced_frames_low, coalesce->tx_max_coalesced_frames_low.value, need_update);
|
||||
|
||||
if (coalesce->pkt_rate_high.set)
|
||||
UPDATE(ecmd.pkt_rate_high, coalesce->pkt_rate_high.value, need_update);
|
||||
|
||||
if (coalesce->rx_coalesce_usecs_high.set)
|
||||
UPDATE(ecmd.rx_coalesce_usecs_high, coalesce->rx_coalesce_usecs_high.value, need_update);
|
||||
|
||||
if (coalesce->rx_max_coalesced_frames_high.set)
|
||||
UPDATE(ecmd.rx_max_coalesced_frames_high, coalesce->rx_max_coalesced_frames_high.value, need_update);
|
||||
|
||||
if (coalesce->tx_coalesce_usecs_high.set)
|
||||
UPDATE(ecmd.tx_coalesce_usecs_high, coalesce->tx_coalesce_usecs_high.value, need_update);
|
||||
|
||||
if (coalesce->tx_max_coalesced_frames_high.set)
|
||||
UPDATE(ecmd.tx_max_coalesced_frames_high, coalesce->tx_max_coalesced_frames_high.value, need_update);
|
||||
|
||||
if (coalesce->rate_sample_interval.set)
|
||||
UPDATE(ecmd.rate_sample_interval, DIV_ROUND_UP(coalesce->rate_sample_interval.value, USEC_PER_SEC), need_update);
|
||||
|
||||
if (!need_update)
|
||||
return 0;
|
||||
|
||||
ecmd.cmd = ETHTOOL_SCOALESCE;
|
||||
r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -76,31 +76,6 @@ typedef struct netdev_ring_param {
|
||||
u32_opt tx;
|
||||
} netdev_ring_param;
|
||||
|
||||
typedef struct netdev_coalesce_param {
|
||||
u32_opt rx_coalesce_usecs;
|
||||
u32_opt rx_max_coalesced_frames;
|
||||
u32_opt rx_coalesce_usecs_irq;
|
||||
u32_opt rx_max_coalesced_frames_irq;
|
||||
u32_opt tx_coalesce_usecs;
|
||||
u32_opt tx_max_coalesced_frames;
|
||||
u32_opt tx_coalesce_usecs_irq;
|
||||
u32_opt tx_max_coalesced_frames_irq;
|
||||
u32_opt stats_block_coalesce_usecs;
|
||||
int use_adaptive_rx_coalesce;
|
||||
int use_adaptive_tx_coalesce;
|
||||
u32_opt pkt_rate_low;
|
||||
u32_opt rx_coalesce_usecs_low;
|
||||
u32_opt rx_max_coalesced_frames_low;
|
||||
u32_opt tx_coalesce_usecs_low;
|
||||
u32_opt tx_max_coalesced_frames_low;
|
||||
u32_opt pkt_rate_high;
|
||||
u32_opt rx_coalesce_usecs_high;
|
||||
u32_opt rx_max_coalesced_frames_high;
|
||||
u32_opt tx_coalesce_usecs_high;
|
||||
u32_opt tx_max_coalesced_frames_high;
|
||||
u32_opt rate_sample_interval;
|
||||
} netdev_coalesce_param;
|
||||
|
||||
int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret);
|
||||
int ethtool_get_link_info(int *ethtool_fd, const char *ifname,
|
||||
int *ret_autonegotiation, uint64_t *ret_speed,
|
||||
@ -114,7 +89,6 @@ int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname,
|
||||
uint64_t speed, Duplex duplex, NetDevPort port);
|
||||
int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels);
|
||||
int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg);
|
||||
int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce);
|
||||
|
||||
const char *duplex_to_string(Duplex d) _const_;
|
||||
Duplex duplex_from_string(const char *d) _pure_;
|
||||
@ -132,6 +106,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wol);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_port);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_advertise);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_u32);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_sec);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_nic_coalesce_setting);
|
||||
|
||||
@ -1023,7 +1023,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "SystemCallFilter", "SystemCallLog", "RestrictAddressFamilies", "RestrictNetworkInterfaces")) {
|
||||
} else if (STR_IN_SET(name, "SystemCallFilter", "SystemCallLog", "RestrictAddressFamilies")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
int allow_list;
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
|
||||
|
||||
static void test_cg_mask_to_string(void) {
|
||||
test_cg_mask_to_string_one(0, NULL);
|
||||
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces");
|
||||
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind");
|
||||
test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
|
||||
test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
|
||||
test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset");
|
||||
|
||||
@ -21,76 +21,54 @@ struct ConfigPerfItem;
|
||||
%struct-type
|
||||
%includes
|
||||
%%
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.permanent_mac)
|
||||
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
|
||||
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)
|
||||
Match.Type, config_parse_match_strv, 0, offsetof(LinkConfig, match.iftype)
|
||||
Match.Property, config_parse_match_property, 0, offsetof(LinkConfig, match.property)
|
||||
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(LinkConfig, conditions)
|
||||
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(LinkConfig, conditions)
|
||||
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
|
||||
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(LinkConfig, conditions)
|
||||
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
|
||||
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
|
||||
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
|
||||
Link.MACAddress, config_parse_hwaddr, 0, offsetof(LinkConfig, mac)
|
||||
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
|
||||
Link.Name, config_parse_ifname, 0, offsetof(LinkConfig, name)
|
||||
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(LinkConfig, alternative_names)
|
||||
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(LinkConfig, alternative_names_policy)
|
||||
Link.Alias, config_parse_ifalias, 0, offsetof(LinkConfig, alias)
|
||||
Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, txqueues)
|
||||
Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, rxqueues)
|
||||
Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(LinkConfig, txqueuelen)
|
||||
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(LinkConfig, mtu)
|
||||
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(LinkConfig, speed)
|
||||
Link.Duplex, config_parse_duplex, 0, offsetof(LinkConfig, duplex)
|
||||
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(LinkConfig, autonegotiation)
|
||||
Link.WakeOnLan, config_parse_wol, 0, offsetof(LinkConfig, wol)
|
||||
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
|
||||
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
|
||||
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
|
||||
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
|
||||
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
|
||||
Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
|
||||
Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
|
||||
Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
|
||||
Link.RxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.rx)
|
||||
Link.TxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.tx)
|
||||
Link.OtherChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.other)
|
||||
Link.CombinedChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.combined)
|
||||
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
|
||||
Link.RxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx)
|
||||
Link.RxMiniBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_mini)
|
||||
Link.RxJumboBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_jumbo)
|
||||
Link.TxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.tx)
|
||||
Link.RxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, rx_flow_control)
|
||||
Link.TxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, tx_flow_control)
|
||||
Link.AutoNegotiationFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, autoneg_flow_control)
|
||||
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
|
||||
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
|
||||
Link.RxCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
|
||||
Link.RxMaxCoalescedFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
|
||||
Link.RxCoalesceIrqSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
|
||||
Link.RxMaxCoalescedIrqFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_irq)
|
||||
Link.TxCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs)
|
||||
Link.TxMaxCoalescedFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames)
|
||||
Link.TxCoalesceIrqSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_irq)
|
||||
Link.TxMaxCoalescedIrqFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_irq)
|
||||
Link.StatisticsBlockCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.stats_block_coalesce_usecs)
|
||||
Link.UseAdaptiveRxCoalesce, config_parse_tristate, 0, offsetof(LinkConfig, coalesce.use_adaptive_rx_coalesce)
|
||||
Link.UseAdaptiveTxCoalesce, config_parse_tristate, 0, offsetof(LinkConfig, coalesce.use_adaptive_tx_coalesce)
|
||||
Link.CoalescePacketRateLow, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.pkt_rate_low)
|
||||
Link.RxCoalesceLowSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_low)
|
||||
Link.RxMaxCoalescedLowFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_low)
|
||||
Link.TxCoalesceLowSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_low)
|
||||
Link.TxMaxCoalescedLowFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_low)
|
||||
Link.CoalescePacketRateHigh, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.pkt_rate_high)
|
||||
Link.RxCoalesceHighSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_high)
|
||||
Link.RxMaxCoalescedHighFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_high)
|
||||
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)
|
||||
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.mac)
|
||||
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.permanent_mac)
|
||||
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
|
||||
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)
|
||||
Match.Type, config_parse_match_strv, 0, offsetof(LinkConfig, match.iftype)
|
||||
Match.Property, config_parse_match_property, 0, offsetof(LinkConfig, match.property)
|
||||
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(LinkConfig, conditions)
|
||||
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(LinkConfig, conditions)
|
||||
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
|
||||
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(LinkConfig, conditions)
|
||||
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
|
||||
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
|
||||
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
|
||||
Link.MACAddress, config_parse_hwaddr, 0, offsetof(LinkConfig, mac)
|
||||
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
|
||||
Link.Name, config_parse_ifname, 0, offsetof(LinkConfig, name)
|
||||
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(LinkConfig, alternative_names)
|
||||
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(LinkConfig, alternative_names_policy)
|
||||
Link.Alias, config_parse_ifalias, 0, offsetof(LinkConfig, alias)
|
||||
Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, txqueues)
|
||||
Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, rxqueues)
|
||||
Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(LinkConfig, txqueuelen)
|
||||
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(LinkConfig, mtu)
|
||||
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(LinkConfig, speed)
|
||||
Link.Duplex, config_parse_duplex, 0, offsetof(LinkConfig, duplex)
|
||||
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(LinkConfig, autonegotiation)
|
||||
Link.WakeOnLan, config_parse_wol, 0, offsetof(LinkConfig, wol)
|
||||
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
|
||||
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
|
||||
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
|
||||
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
|
||||
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
|
||||
Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
|
||||
Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
|
||||
Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
|
||||
Link.RxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.rx)
|
||||
Link.TxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.tx)
|
||||
Link.OtherChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.other)
|
||||
Link.CombinedChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.combined)
|
||||
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
|
||||
Link.RxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx)
|
||||
Link.RxMiniBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_mini)
|
||||
Link.RxJumboBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_jumbo)
|
||||
Link.TxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.tx)
|
||||
Link.RxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, rx_flow_control)
|
||||
Link.TxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, tx_flow_control)
|
||||
Link.AutoNegotiationFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, autoneg_flow_control)
|
||||
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
|
||||
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
|
||||
|
||||
@ -353,10 +353,6 @@ static int link_config_apply_ethtool_settings(int *ethtool_fd, const LinkConfig
|
||||
if (r < 0)
|
||||
log_device_warning_errno(device, r, "Could not set flow control, ignoring: %m");
|
||||
|
||||
r = ethtool_set_nic_coalesce_settings(ethtool_fd, name, &config->coalesce);
|
||||
if (r < 0)
|
||||
log_device_warning_errno(device, r, "Could not set coalesce settings, ignoring: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -64,7 +64,6 @@ struct LinkConfig {
|
||||
int rx_flow_control;
|
||||
int tx_flow_control;
|
||||
int autoneg_flow_control;
|
||||
netdev_coalesce_param coalesce;
|
||||
|
||||
LIST_FIELDS(LinkConfig, links);
|
||||
};
|
||||
|
||||
@ -1 +0,0 @@
|
||||
../TEST-01-BASIC/Makefile
|
||||
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TEST_NO_NSPAWN=1
|
||||
|
||||
set -e
|
||||
TEST_DESCRIPTION="test RestrictNetworkInterfaces="
|
||||
. $TEST_BASE_DIR/test-functions
|
||||
|
||||
do_test "$@" 62
|
||||
@ -51,25 +51,3 @@ TxFlowControl=
|
||||
AutoNegotiationFlowControl=
|
||||
GenericSegmentOffloadMaxBytes=
|
||||
GenericSegmentOffloadMaxSegments=
|
||||
RxCoalesceSec=
|
||||
RxMaxCoalescedFrames=
|
||||
RxCoalesceIrqSec=
|
||||
RxMaxCoalescedIrqFrames=
|
||||
TxCoalesceSec=
|
||||
TxMaxCoalescedFrames=
|
||||
TxCoalesceIrqSec=
|
||||
TxMaxCoalescedIrqFrames=
|
||||
StatisticsBlockCoalesceSec=
|
||||
UseAdaptiveRxCoalesce=
|
||||
UseAdaptiveTxCoalesce=
|
||||
CoalescePacketRateLow=
|
||||
RxCoalesceLowSec=
|
||||
RxMaxCoalescedLowFrames=
|
||||
TxCoalesceLowSec=
|
||||
TxMaxCoalescedLowFrames=
|
||||
CoalescePacketRateHigh=
|
||||
RxCoalesceHighSec=
|
||||
RxMaxCoalescedHighFrames=
|
||||
TxCoalesceHighSec=
|
||||
TxMaxCoalescedHighFrames=
|
||||
CoalescePacketRateSampleIntervalSec=
|
||||
|
||||
@ -886,7 +886,6 @@ RemoveIPC=
|
||||
ReserveVT=
|
||||
RestrictAddressFamilies=
|
||||
RestrictNamespaces=
|
||||
RestrictNetworkInterfaces=
|
||||
RestrictRealtime=
|
||||
RestrictSUIDSGID=
|
||||
RuntimeDirectory=
|
||||
|
||||
@ -144,7 +144,6 @@ RemoveIPC=
|
||||
RestartKillSignal=
|
||||
RestrictAddressFamilies=
|
||||
RestrictNamespaces=
|
||||
RestrictNetworkInterfaces=
|
||||
RestrictRealtime=
|
||||
RestrictSUIDSGID=
|
||||
RootDirectory=
|
||||
|
||||
@ -48,7 +48,6 @@ MemoryMin=
|
||||
MemorySwapMax=
|
||||
NetClass=
|
||||
RestartKillSignal=
|
||||
RestrictNetworkInterfaces=
|
||||
RuntimeMaxSec=
|
||||
SendSIGHUP=
|
||||
SendSIGKILL=
|
||||
|
||||
@ -275,7 +275,6 @@ RestartPreventExitStatus=
|
||||
RestartSec=
|
||||
RestrictAddressFamilies=
|
||||
RestrictNamespaces=
|
||||
RestrictNetworkInterfaces=
|
||||
RestrictRealtime=
|
||||
RestrictSUIDSGID=
|
||||
RootDirectory=
|
||||
|
||||
@ -44,7 +44,6 @@ MemoryMax=
|
||||
MemoryMin=
|
||||
MemorySwapMax=
|
||||
NetClass=
|
||||
RestrictNetworkInterfaces=
|
||||
Slice=
|
||||
SocketBindAllow=
|
||||
SocketBindDeny=
|
||||
|
||||
@ -180,7 +180,6 @@ RemoveOnStop=
|
||||
RestartKillSignal=
|
||||
RestrictAddressFamilies=
|
||||
RestrictNamespaces=
|
||||
RestrictNetworkInterfaces=
|
||||
RestrictRealtime=
|
||||
RestrictSUIDSGID=
|
||||
ReusePort=
|
||||
|
||||
@ -141,7 +141,6 @@ RemoveIPC=
|
||||
RestartKillSignal=
|
||||
RestrictAddressFamilies=
|
||||
RestrictNamespaces=
|
||||
RestrictNetworkInterfaces=
|
||||
RestrictRealtime=
|
||||
RestrictSUIDSGID=
|
||||
RootDirectory=
|
||||
|
||||
@ -672,7 +672,6 @@ setup_basic_environment() {
|
||||
has_user_dbus_socket && install_user_dbus
|
||||
setup_selinux
|
||||
strip_binaries
|
||||
instmods veth
|
||||
install_depmod_files
|
||||
generate_module_dependencies
|
||||
if get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
[Unit]
|
||||
Description=TEST-62-RESTRICT-IFACES-all-pings-work
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.1'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.5'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.9'
|
||||
RestrictNetworkInterfaces=
|
||||
Type=oneshot
|
||||
@ -1,9 +0,0 @@
|
||||
[Unit]
|
||||
Description=TEST-62-RESTRICT-IFACES-allow-list
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.1'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.5'
|
||||
ExecStart=/bin/sh -c '! ping -c 1 -W 0.2 192.168.113.9'
|
||||
RestrictNetworkInterfaces=veth0
|
||||
RestrictNetworkInterfaces=veth1
|
||||
Type=oneshot
|
||||
@ -1,9 +0,0 @@
|
||||
[Unit]
|
||||
Description=TEST-62-RESTRICT-IFACES-deny-list
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c '! ping -c 1 -W 0.2 192.168.113.1'
|
||||
ExecStart=/bin/sh -c '! ping -c 1 -W 0.2 192.168.113.5'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.9'
|
||||
RestrictNetworkInterfaces=~veth0
|
||||
RestrictNetworkInterfaces=~veth1
|
||||
Type=oneshot
|
||||
@ -1,9 +0,0 @@
|
||||
[Unit]
|
||||
Description=TEST-62-RESTRICT-IFACES-empty-assigment
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.1'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.5'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.9'
|
||||
RestrictNetworkInterfaces=veth0
|
||||
RestrictNetworkInterfaces=
|
||||
Type=oneshot
|
||||
@ -1,10 +0,0 @@
|
||||
[Unit]
|
||||
Description=TEST-62-RESTRICT-IFACES-invert-assigment
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c '! ping -c 1 -W 0.2 192.168.113.1'
|
||||
ExecStart=/bin/sh -c 'ping -c 1 -W 0.2 192.168.113.5'
|
||||
ExecStart=/bin/sh -c '! ping -c 1 -W 0.2 192.168.113.9'
|
||||
RestrictNetworkInterfaces=veth0
|
||||
RestrictNetworkInterfaces=veth0 veth1
|
||||
RestrictNetworkInterfaces=~veth0
|
||||
Type=oneshot
|
||||
@ -1,6 +0,0 @@
|
||||
Description=TEST-62-RESTRICT-IFACES
|
||||
|
||||
[Service]
|
||||
ExecStartPre=rm -f /failed /testok
|
||||
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
|
||||
Type=oneshot
|
||||
@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
set -o pipefail
|
||||
|
||||
setup() {
|
||||
systemd-analyze log-level debug
|
||||
systemd-analyze log-target console
|
||||
|
||||
for i in `seq 0 3`;
|
||||
do
|
||||
ip netns del ns${i} || true
|
||||
ip link del veth${i} || true
|
||||
ip netns add ns${i}
|
||||
ip link add veth${i} type veth peer name veth${i}_
|
||||
ip link set veth${i}_ netns ns${i}
|
||||
ip -n ns${i} link set dev veth${i}_ up
|
||||
ip -n ns${i} link set dev lo up
|
||||
ip -n ns${i} addr add "192.168.113."$((4*i+1))/30 dev veth${i}_
|
||||
ip link set dev veth${i} up
|
||||
ip addr add "192.168.113."$((4*i+2))/30 dev veth${i}
|
||||
done
|
||||
}
|
||||
|
||||
teardown() {
|
||||
set +e
|
||||
|
||||
for i in `seq 0 3`;
|
||||
do
|
||||
ip netns del ns${i}
|
||||
ip link del veth${i}
|
||||
done
|
||||
|
||||
systemd-analyze log-level info
|
||||
}
|
||||
|
||||
KERNEL_VERSION="$(uname -r)"
|
||||
KERNEL_MAJOR="${KERNEL_VERSION%%.*}"
|
||||
KERNEL_MINOR="${KERNEL_VERSION#$KERNEL_MAJOR.}"
|
||||
KERNEL_MINOR="${KERNEL_MINOR%%.*}"
|
||||
|
||||
MAJOR_REQUIRED=5
|
||||
MINOR_REQUIRED=7
|
||||
|
||||
if [[ "$KERNEL_MAJOR" -lt $MAJOR_REQUIRED || ("$KERNEL_MAJOR" -eq $MAJOR_REQUIRED && "$KERNEL_MINOR" -lt $MINOR_REQUIRED) ]]; then
|
||||
echo "kernel is not 5.7+" >>/skipped
|
||||
exit 0
|
||||
fi
|
||||
|
||||
trap teardown EXIT
|
||||
setup
|
||||
|
||||
systemctl start --wait testsuite-62-1.service
|
||||
systemctl start --wait testsuite-62-2.service
|
||||
systemctl start --wait testsuite-62-3.service
|
||||
systemctl start --wait testsuite-62-4.service
|
||||
systemctl start --wait testsuite-62-5.service
|
||||
|
||||
echo OK > /testok
|
||||
|
||||
exit 0
|
||||
Loading…
x
Reference in New Issue
Block a user