summaryrefslogtreecommitdiffstats
path: root/src/core/bpf/restrict_ifaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/bpf/restrict_ifaces')
-rw-r--r--src/core/bpf/restrict_ifaces/meson.build24
-rw-r--r--src/core/bpf/restrict_ifaces/restrict-ifaces-skel.h14
-rw-r--r--src/core/bpf/restrict_ifaces/restrict-ifaces.bpf.c52
3 files changed, 90 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 0000000..5f36178
--- /dev/null
+++ b/src/core/bpf/restrict_ifaces/meson.build
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if conf.get('BPF_FRAMEWORK') != 1
+ subdir_done()
+endif
+
+restrict_ifaces_bpf_o_unstripped = custom_target(
+ 'restrict-ifaces.bpf.unstripped.o',
+ input : 'restrict-ifaces.bpf.c',
+ output : 'restrict-ifaces.bpf.unstripped.o',
+ command : bpf_o_unstripped_cmd)
+
+restrict_ifaces_bpf_o = custom_target(
+ 'restrict-ifaces.bpf.o',
+ input : restrict_ifaces_bpf_o_unstripped,
+ output : 'restrict-ifaces.bpf.o',
+ command : bpf_o_cmd)
+
+restrict_ifaces_skel_h = custom_target(
+ 'restrict-ifaces.skel.h',
+ input : restrict_ifaces_bpf_o,
+ output : 'restrict-ifaces.skel.h',
+ command : skel_h_cmd,
+ capture : true)
diff --git a/src/core/bpf/restrict_ifaces/restrict-ifaces-skel.h b/src/core/bpf/restrict_ifaces/restrict-ifaces-skel.h
new file mode 100644
index 0000000..f937490
--- /dev/null
+++ b/src/core/bpf/restrict_ifaces/restrict-ifaces-skel.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/* The SPDX header above is actually correct in claiming this was
+ * LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
+ * compatible with GPL we will claim this to be GPL however, which should be
+ * fine given that LGPL-2.1-or-later downgrades to GPL if needed.
+ */
+
+/* libbpf is used via dlopen(), so rename symbols */
+#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
+#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
+#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
+
+#include "bpf/restrict_ifaces/restrict-ifaces.skel.h"
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 0000000..32cde5c
--- /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 __always_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";