]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: define a helper function for basic bpf checks
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 1 Jun 2022 21:56:25 +0000 (23:56 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 2 Jun 2022 13:59:41 +0000 (15:59 +0200)
src/core/bpf-lsm.c
src/core/bpf-socket-bind.c
src/core/bpf-util.c [new file with mode: 0644]
src/core/bpf-util.h [new file with mode: 0644]
src/core/meson.build
src/core/restrict-ifaces.c

index 46fc8c8d3b6bc90cb9e8704f0ac376179ae7eb01..3ebc2fd1661b0a483135370b1beb94e4d620d45f 100644 (file)
@@ -26,6 +26,7 @@
 /* libbpf, clang and llc compile time dependencies are satisfied */
 #include "bpf-dlopen.h"
 #include "bpf-link.h"
+#include "bpf-util.h"
 #include "bpf/restrict_fs/restrict-fs-skel.h"
 
 #define CGROUP_HASH_SIZE_MAX 2048
@@ -135,23 +136,8 @@ bool lsm_bpf_supported(bool initialize) {
         if (!initialize)
                 return false;
 
-        r = dlopen_bpf();
-        if (r < 0) {
-                log_info_errno(r, "Failed to open libbpf, LSM BPF is not supported: %m");
-                return (supported = false);
-        }
-
-        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
-        if (r < 0) {
-                log_warning_errno(r, "Can't determine whether the unified hierarchy is used: %m");
+        if (!cgroup_bpf_supported())
                 return (supported = false);
-        }
-
-        if (r == 0) {
-                log_info_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                               "Not running with unified cgroup hierarchy, LSM BPF is not supported");
-                return (supported = false);
-        }
 
         r = mac_bpf_use();
         if (r < 0) {
index 09f83dc667f386d9f76bbc2f704d5a3a9ab22846..2000c5029bd83ef552d404ae5e6bc445058f8acc 100644 (file)
@@ -11,8 +11,9 @@
 /* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
 #include "bpf-dlopen.h"
 #include "bpf-link.h"
-#include "bpf/socket_bind/socket-bind-skel.h"
+#include "bpf-util.h"
 #include "bpf/socket_bind/socket-bind-api.bpf.h"
+#include "bpf/socket_bind/socket-bind-skel.h"
 
 static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) {
         /* socket_bind_bpf__destroy handles object == NULL case */
@@ -116,15 +117,7 @@ int bpf_socket_bind_supported(void) {
         _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
         int r;
 
-        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
-        if (r < 0)
-                return log_debug_errno(r, "Can't determine whether the unified hierarchy is used: %m");
-        if (r == 0) {
-                log_debug("Not running with unified cgroup hierarchy, BPF is not supported");
-                return false;
-        }
-
-        if (dlopen_bpf() < 0)
+        if (!cgroup_bpf_supported())
                 return false;
 
         if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*ifindex=*/0)) {
diff --git a/src/core/bpf-util.c b/src/core/bpf-util.c
new file mode 100644 (file)
index 0000000..9130aa3
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "bpf-dlopen.h"
+#include "bpf-util.h"
+#include "cgroup-util.h"
+#include "log.h"
+
+bool cgroup_bpf_supported(void) {
+        static int supported = -1;
+        int r;
+
+        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");
+                return (supported = false);
+        }
+
+        if (r == 0) {
+                log_info_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "Not running with unified cgroup hierarchy, disabling cgroup BPF features.");
+                return (supported = false);
+        }
+
+        r = dlopen_bpf();
+        if (r < 0) {
+                log_info_errno(r, "Failed to open libbpf, cgroup BPF features disabled: %m");
+                return (supported = false);
+        }
+
+        return (supported = true);
+}
diff --git a/src/core/bpf-util.h b/src/core/bpf-util.h
new file mode 100644 (file)
index 0000000..a6c55cd
--- /dev/null
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <stdbool.h>
+
+bool cgroup_bpf_supported(void);
index 052844c8bf34a270f9135febe6e47a7aae6e89b4..d7ac4e59a8e6778db3f96f2c2ad996f3790c0471 100644 (file)
@@ -135,6 +135,13 @@ libcore_sources = files(
         'unit.h',
 )
 
+if conf.get('BPF_FRAMEWORK') == 1
+        libcore_sources += files(
+                'bpf-util.c',
+                'bpf-util.h',
+        )
+endif
+
 subdir('bpf')
 
 subdir('bpf/socket_bind')
index efa5c8d85abcdbfd977b39b454b68d5d1dfb9e85..a3d99854182fcf507245aa86fe39490dfe20264a 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "bpf-dlopen.h"
 #include "bpf-link.h"
-
+#include "bpf-util.h"
 #include "bpf/restrict_ifaces/restrict-ifaces-skel.h"
 
 static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) {
@@ -78,29 +78,21 @@ int restrict_network_interfaces_supported(void) {
         if (supported >= 0)
                 return supported;
 
-        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
-        if (r < 0)
-                return log_error_errno(r, "Can't determine whether the unified hierarchy is used: %m");
-        if (r == 0) {
-                log_debug("Not running with unified cgroup hierarchy, BPF is not supported");
-                return supported = 0;
-        }
-
-        if (dlopen_bpf() < 0)
-                return false;
+        if (!cgroup_bpf_supported())
+                return (supported = false);
 
         if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SKB, /*ifindex=*/0)) {
                 log_debug("BPF program type cgroup_skb is not supported");
-                return supported = 0;
+                return (supported = false);
         }
 
         r = prepare_restrict_ifaces_bpf(NULL, true, NULL, &obj);
         if (r < 0) {
                 log_debug_errno(r, "Failed to load BPF object: %m");
-                return supported = 0;
+                return (supported = false);
         }
 
-        return supported = bpf_can_link_program(obj->progs.sd_restrictif_i);
+        return (supported = bpf_can_link_program(obj->progs.sd_restrictif_i));
 }
 
 static int restrict_network_interfaces_install_impl(Unit *u) {