diff options
author | Mauricio Vásquez <mauricio@kinvolk.io> | 2021-01-21 10:45:38 -0500 |
---|---|---|
committer | Mauricio Vásquez <mauricio@kinvolk.io> | 2021-08-18 15:55:53 -0500 |
commit | dc83b840d33e30fcd4363e26b933fa5cce410c4a (patch) | |
tree | b015f890daa1e81473e14991982c4b079799408e /src/core | |
parent | 0d341eccef06cb27bb79064b92264a45e859192d (diff) | |
download | systemd-dc83b840d33e30fcd4363e26b933fa5cce410c4a.tar.gz |
core: add RestrictNetworkInterfaces= BPF program source code
The code is composed by two BPF_PROG_TYPE_CGROUP_SKB programs that
are loaded in the cgroup inet ingress and egress hooks
(BPF_CGROUP_INET_{INGRESS|EGRESS}).
The decision to let a packet pass or not is based on a map that contains
the indexes of the interfaces.
Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/bpf/restrict_ifaces/meson.build | 14 | ||||
-rw-r--r-- | src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c | 52 | ||||
-rw-r--r-- | src/core/meson.build | 5 |
3 files changed, 71 insertions, 0 deletions
diff --git a/src/core/bpf/restrict_ifaces/meson.build b/src/core/bpf/restrict_ifaces/meson.build new file mode 100644 index 0000000000..5bf024d42d --- /dev/null +++ b/src/core/bpf/restrict_ifaces/meson.build @@ -0,0 +1,14 @@ +# 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 diff --git a/src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c b/src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c new file mode 100644 index 0000000000..347a3a8d21 --- /dev/null +++ b/src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c @@ -0,0 +1,52 @@ +/* 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"; diff --git a/src/core/meson.build b/src/core/meson.build index 1941081972..df773b6675 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -136,6 +136,11 @@ 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', |