mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
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>
This commit is contained in:
parent
0d341eccef
commit
dc83b840d3
14
src/core/bpf/restrict_ifaces/meson.build
Normal file
14
src/core/bpf/restrict_ifaces/meson.build
Normal file
@ -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
|
52
src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c
Normal file
52
src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c
Normal file
@ -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";
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user