Bump libbpf to v0.7.0 and turn on all strict features

This commit is contained in:
Tatsuhiro Tsujikawa 2022-02-21 21:18:52 +09:00
parent a22f2cfcc8
commit 830cf1e294
6 changed files with 69 additions and 58 deletions

View File

@ -85,7 +85,7 @@ jobs:
- name: Build libbpf - name: Build libbpf
if: matrix.http3 == 'http3' && matrix.compiler == 'clang' && runner.os == 'Linux' if: matrix.http3 == 'http3' && matrix.compiler == 'clang' && runner.os == 'Linux'
run: | run: |
git clone -b v0.6.1 https://github.com/libbpf/libbpf git clone -b v0.7.0 https://github.com/libbpf/libbpf
cd libbpf cd libbpf
PREFIX=$PWD/build make -C src install PREFIX=$PWD/build make -C src install

View File

@ -164,13 +164,13 @@ In order to build optional eBPF program to direct an incoming QUIC UDP
datagram to a correct socket for nghttpx, the following libraries are datagram to a correct socket for nghttpx, the following libraries are
required: required:
* libbpf-dev >= 0.4.0 * libbpf-dev >= 0.7.0
Use ``--with-libbpf`` configure option to build eBPF program. Use ``--with-libbpf`` configure option to build eBPF program.
libelf-dev is needed to build libbpf. libelf-dev is needed to build libbpf.
For Ubuntu 20.04, you can build libbpf from `the source code For Ubuntu 20.04, you can build libbpf from `the source code
<https://github.com/libbpf/libbpf/releases/tag/v0.6.1>`_. nghttpx <https://github.com/libbpf/libbpf/releases/tag/v0.7.0>`_. nghttpx
requires eBPF program for reloading its configuration and hot swapping requires eBPF program for reloading its configuration and hot swapping
its executable. its executable.
@ -387,12 +387,12 @@ Build ngtcp2:
$ make install $ make install
$ cd .. $ cd ..
If your Linux distribution does not have libbpf-dev >= 0.4.0, build If your Linux distribution does not have libbpf-dev >= 0.7.0, build
from source: from source:
.. code-block:: text .. code-block:: text
$ git clone --depth 1 -b v0.6.1 https://github.com/libbpf/libbpf $ git clone --depth 1 -b v0.7.0 https://github.com/libbpf/libbpf
$ cd libbpf $ cd libbpf
$ PREFIX=$PWD/build make -C src install $ PREFIX=$PWD/build make -C src install
$ cd .. $ cd ..

View File

@ -423,26 +423,26 @@ static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval) {
return __jhash_nwords(a, b, 0, initval + JHASH_INITVAL + (2 << 2)); return __jhash_nwords(a, b, 0, initval + JHASH_INITVAL + (2 << 2));
} }
struct bpf_map_def SEC("maps") cid_prefix_map = { struct {
.type = BPF_MAP_TYPE_HASH, __uint(type, BPF_MAP_TYPE_HASH);
.max_entries = 255, __uint(max_entries, 255);
.key_size = sizeof(__u64), __type(key, __u64);
.value_size = sizeof(__u32), __type(value, __u32);
}; } cid_prefix_map SEC(".maps");
struct bpf_map_def SEC("maps") reuseport_array = { struct {
.type = BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, __uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
.max_entries = 255, __uint(max_entries, 255);
.key_size = sizeof(__u32), __type(key, __u32);
.value_size = sizeof(__u32), __type(value, __u32);
}; } reuseport_array SEC(".maps");
struct bpf_map_def SEC("maps") sk_info = { struct {
.type = BPF_MAP_TYPE_ARRAY, __uint(type, BPF_MAP_TYPE_ARRAY);
.max_entries = 3, __uint(max_entries, 3);
.key_size = sizeof(__u32), __type(key, __u32);
.value_size = sizeof(__u64), __type(value, __u64);
}; } sk_info SEC(".maps");
typedef struct quic_hd { typedef struct quic_hd {
__u8 *dcid; __u8 *dcid;

View File

@ -599,7 +599,7 @@ fi
# libbpf (for src) # libbpf (for src)
have_libbpf=no have_libbpf=no
if test "x${request_libbpf}" != "xno"; then if test "x${request_libbpf}" != "xno"; then
PKG_CHECK_MODULES([LIBBPF], [libbpf >= 0.4.0], [have_libbpf=yes], PKG_CHECK_MODULES([LIBBPF], [libbpf >= 0.7.0], [have_libbpf=yes],
[have_libbpf=no]) [have_libbpf=no])
if test "x${have_libbpf}" = "xyes"; then if test "x${have_libbpf}" = "xyes"; then
AC_DEFINE([HAVE_LIBBPF], [1], [Define to 1 if you have `libbpf` library.]) AC_DEFINE([HAVE_LIBBPF], [1], [Define to 1 if you have `libbpf` library.])

View File

@ -59,6 +59,9 @@
#ifdef HAVE_LIBSYSTEMD #ifdef HAVE_LIBSYSTEMD
# include <systemd/sd-daemon.h> # include <systemd/sd-daemon.h>
#endif // HAVE_LIBSYSTEMD #endif // HAVE_LIBSYSTEMD
#ifdef HAVE_LIBBPF
# include <bpf/libbpf.h>
#endif // HAVE_LIBBPF
#include <cinttypes> #include <cinttypes>
#include <limits> #include <limits>
@ -3925,6 +3928,10 @@ int main(int argc, char **argv) {
nghttp2::tls::libssl_init(); nghttp2::tls::libssl_init();
#ifdef HAVE_LIBBPF
libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
#endif // HAVE_LIBBPF
#ifndef NOTHREADS #ifndef NOTHREADS
nghttp2::tls::LibsslGlobalLock lock; nghttp2::tls::LibsslGlobalLock lock;
#endif // NOTHREADS #endif // NOTHREADS

View File

@ -899,32 +899,32 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
auto config = get_config(); auto config = get_config();
auto &quic_bpf_refs = conn_handler_->get_quic_bpf_refs(); auto &quic_bpf_refs = conn_handler_->get_quic_bpf_refs();
int err;
if (should_attach_bpf()) { if (should_attach_bpf()) {
auto &bpfconf = config->quic.bpf; auto &bpfconf = config->quic.bpf;
auto obj = bpf_object__open_file(bpfconf.prog_file.c_str(), nullptr); auto obj = bpf_object__open_file(bpfconf.prog_file.c_str(), nullptr);
err = libbpf_get_error(obj); if (!obj) {
if (err) { auto error = errno;
LOG(FATAL) << "Failed to open bpf object file: " LOG(FATAL) << "Failed to open bpf object file: "
<< xsi_strerror(-err, errbuf.data(), errbuf.size()); << xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
if (bpf_object__load(obj)) { rv = bpf_object__load(obj);
if (rv != 0) {
LOG(FATAL) << "Failed to load bpf object file: " LOG(FATAL) << "Failed to load bpf object file: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
auto prog = bpf_object__find_program_by_name(obj, "select_reuseport"); auto prog = bpf_object__find_program_by_name(obj, "select_reuseport");
err = libbpf_get_error(prog); if (!prog) {
if (err) { auto error = errno;
LOG(FATAL) << "Failed to find sk_reuseport program: " LOG(FATAL) << "Failed to find sk_reuseport program: "
<< xsi_strerror(-err, errbuf.data(), errbuf.size()); << xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -935,10 +935,10 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
auto reuseport_array = auto reuseport_array =
bpf_object__find_map_by_name(obj, "reuseport_array"); bpf_object__find_map_by_name(obj, "reuseport_array");
err = libbpf_get_error(reuseport_array); if (!reuseport_array) {
if (err) { auto error = errno;
LOG(FATAL) << "Failed to get reuseport_array: " LOG(FATAL) << "Failed to get reuseport_array: "
<< xsi_strerror(-err, errbuf.data(), errbuf.size()); << xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -946,10 +946,10 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
ref.reuseport_array = bpf_map__fd(reuseport_array); ref.reuseport_array = bpf_map__fd(reuseport_array);
auto cid_prefix_map = bpf_object__find_map_by_name(obj, "cid_prefix_map"); auto cid_prefix_map = bpf_object__find_map_by_name(obj, "cid_prefix_map");
err = libbpf_get_error(cid_prefix_map); if (!cid_prefix_map) {
if (err) { auto error = errno;
LOG(FATAL) << "Failed to get cid_prefix_map: " LOG(FATAL) << "Failed to get cid_prefix_map: "
<< xsi_strerror(-err, errbuf.data(), errbuf.size()); << xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -957,10 +957,10 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
ref.cid_prefix_map = bpf_map__fd(cid_prefix_map); ref.cid_prefix_map = bpf_map__fd(cid_prefix_map);
auto sk_info = bpf_object__find_map_by_name(obj, "sk_info"); auto sk_info = bpf_object__find_map_by_name(obj, "sk_info");
err = libbpf_get_error(sk_info); if (!sk_info) {
if (err) { auto error = errno;
LOG(FATAL) << "Failed to get sk_info: " LOG(FATAL) << "Failed to get sk_info: "
<< xsi_strerror(-err, errbuf.data(), errbuf.size()); << xsi_strerror(error, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -968,10 +968,11 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
constexpr uint32_t zero = 0; constexpr uint32_t zero = 0;
uint64_t num_socks = config->num_worker; uint64_t num_socks = config->num_worker;
if (bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks, rv =
BPF_ANY) != 0) { bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks, BPF_ANY);
if (rv != 0) {
LOG(FATAL) << "Failed to update sk_info: " LOG(FATAL) << "Failed to update sk_info: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -982,19 +983,20 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
auto &qkms = conn_handler_->get_quic_keying_materials(); auto &qkms = conn_handler_->get_quic_keying_materials();
auto &qkm = qkms->keying_materials.front(); auto &qkm = qkms->keying_materials.front();
if (bpf_map_update_elem(bpf_map__fd(sk_info), &key_high_idx, rv = bpf_map_update_elem(bpf_map__fd(sk_info), &key_high_idx,
qkm.cid_encryption_key.data(), BPF_ANY) != 0) { qkm.cid_encryption_key.data(), BPF_ANY);
if (rv != 0) {
LOG(FATAL) << "Failed to update key_high_idx sk_info: " LOG(FATAL) << "Failed to update key_high_idx sk_info: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
if (bpf_map_update_elem(bpf_map__fd(sk_info), &key_low_idx, rv = bpf_map_update_elem(bpf_map__fd(sk_info), &key_low_idx,
qkm.cid_encryption_key.data() + 8, qkm.cid_encryption_key.data() + 8, BPF_ANY);
BPF_ANY) != 0) { if (rv != 0) {
LOG(FATAL) << "Failed to update key_low_idx sk_info: " LOG(FATAL) << "Failed to update key_low_idx sk_info: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
@ -1014,18 +1016,20 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
const auto &ref = quic_bpf_refs[faddr.index]; const auto &ref = quic_bpf_refs[faddr.index];
auto sk_index = compute_sk_index(); auto sk_index = compute_sk_index();
if (bpf_map_update_elem(ref.reuseport_array, &sk_index, &fd, rv =
BPF_NOEXIST) != 0) { bpf_map_update_elem(ref.reuseport_array, &sk_index, &fd, BPF_NOEXIST);
if (rv != 0) {
LOG(FATAL) << "Failed to update reuseport_array: " LOG(FATAL) << "Failed to update reuseport_array: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }
if (bpf_map_update_elem(ref.cid_prefix_map, cid_prefix_.data(), &sk_index, rv = bpf_map_update_elem(ref.cid_prefix_map, cid_prefix_.data(),
BPF_NOEXIST) != 0) { &sk_index, BPF_NOEXIST);
if (rv != 0) {
LOG(FATAL) << "Failed to update cid_prefix_map: " LOG(FATAL) << "Failed to update cid_prefix_map: "
<< xsi_strerror(errno, errbuf.data(), errbuf.size()); << xsi_strerror(-rv, errbuf.data(), errbuf.size());
close(fd); close(fd);
return -1; return -1;
} }