summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorMauricio Vásquez <mauricio@kinvolk.io>2021-01-21 10:45:38 -0500
committerMauricio Vásquez <mauricio@kinvolk.io>2021-08-18 15:55:53 -0500
commitdc83b840d33e30fcd4363e26b933fa5cce410c4a (patch)
treeb015f890daa1e81473e14991982c4b079799408e /src/core
parent0d341eccef06cb27bb79064b92264a45e859192d (diff)
downloadsystemd-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.build14
-rw-r--r--src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c52
-rw-r--r--src/core/meson.build5
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',