diff --git a/config.h.meson b/config.h.meson index d364f76281..eb4ba9dbbb 100644 --- a/config.h.meson +++ b/config.h.meson @@ -283,3 +283,5 @@ /* Define to 1 if you have history support from -lreadline. */ #mesondefine HAVE_READLINE_HISTORY +/* Define to 1 if you are building with eBPF support */ +#mesondefine WITH_EBPF \ No newline at end of file diff --git a/configure.ac b/configure.ac index ee6bd9af79..7ab652e788 100644 --- a/configure.ac +++ b/configure.ac @@ -571,6 +571,11 @@ fi if test "$with_ebpf" = "yes" -a "$have_ebpf" = "no"; then AC_MSG_ERROR([--with-ebpf=yes requires eBPF kernel header]) fi +if test "$with_ebpf" = "yes"; then + AC_DEFINE(WITH_EBPF, 1, [Define to 1 if you are building with eBPF support]) +else + AC_DEFINE(WITH_EBPF, 0, [Define to 1 if you are building with eBPF support]) +fi AM_CONDITIONAL(WITH_EBPF, test "${have_ebpf}" = "yes") # SELinux support diff --git a/meson.build b/meson.build index af167892ae..177b0326b1 100644 --- a/meson.build +++ b/meson.build @@ -476,6 +476,7 @@ else enable_ebpf = false endif endif +config_h.set10('WITH_EBPF', enable_ebpf) # libaudit support libaudit = get_option('libaudit') diff --git a/src/core/platform/tests/test-common.c b/src/core/platform/tests/test-common.c index fde7dc0de7..da2aa46b88 100644 --- a/src/core/platform/tests/test-common.c +++ b/src/core/platform/tests/test-common.c @@ -13,6 +13,10 @@ #include #include #include +#include +#if WITH_EBPF +#include +#endif #include "n-acd/src/n-acd.h" #include "libnm-platform/nm-platform-utils.h" @@ -96,6 +100,46 @@ nmtstp_is_root_test(void) nm_linux_platform_setup_with_tc_cache); } +/* + * Check that eBPF is usable if needed. + * + * Since Linux 4.4, unprivileged users may create programs of type + * BPF_PROG_TYPE_SOCKET_FILTER and associated maps, with some limitations. + * However, most distributions disable unprivileged access by setting + * /proc/sys/kernel/unprivileged_bpf_disabled to 1 or 2. + */ +gboolean +nmtstp_check_ebpf(void) +{ +#if WITH_EBPF + { + static int cached = -1; + union bpf_attr attr; + int ret; + + if (cached != -1) + return cached; + + attr = (union bpf_attr){ + .map_type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(uint32_t), + .value_size = sizeof(uint8_t), + .max_entries = 1, + }; + + ret = (int) syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); + if (ret >= 0) { + nm_close(ret); + cached = TRUE; + } else { + cached = FALSE; + } + return cached; + } +#endif + return TRUE; +} + gboolean nmtstp_is_sysfs_writable(void) { diff --git a/src/core/platform/tests/test-common.h b/src/core/platform/tests/test-common.h index 12d6e7ce67..85ae245274 100644 --- a/src/core/platform/tests/test-common.h +++ b/src/core/platform/tests/test-common.h @@ -68,6 +68,7 @@ gboolean nmtstp_is_root_test(void); gboolean nmtstp_is_sysfs_writable(void); +gboolean nmtstp_check_ebpf(void); /*****************************************************************************/ diff --git a/src/core/tests/test-l3cfg.c b/src/core/tests/test-l3cfg.c index 6b82fe433e..f59710beab 100644 --- a/src/core/tests/test-l3cfg.c +++ b/src/core/tests/test-l3cfg.c @@ -669,6 +669,11 @@ test_l3_ipv4ll(gconstpointer test_data) nm_auto_remove_l3ipv4ll_registration NML3IPv4LLRegistration *l3ipv4ll_reg = NULL; char sbuf_addr[NM_INET_ADDRSTRLEN]; + if (!nmtstp_check_ebpf()) { + g_test_skip("eBPF is not usable. Try: echo 0 > /proc/sys/kernel/unprivileged_bpf_disabled"); + return; + } + _LOGD("test start (/l3-ipv4ll/%d)", TEST_IDX); if (nmtst_test_quick()) {