diff --git a/gennghttpxfun.py b/gennghttpxfun.py index 329df86c..abc74025 100755 --- a/gennghttpxfun.py +++ b/gennghttpxfun.py @@ -177,6 +177,8 @@ OPTIONS = [ "tls13-ciphers", "tls13-client-ciphers", "no-strip-incoming-early-data", + "bpf-program-file", + "no-bpf", ] LOGVARS = [ diff --git a/src/Makefile.am b/src/Makefile.am index c3630271..15b1d402 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,6 +35,7 @@ AM_CFLAGS = $(WARNCFLAGS) AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS) AM_CPPFLAGS = \ -DPKGDATADIR='"$(pkgdatadir)"' \ + -DPKGLIBDIR='"$(pkglibdir)"' \ -I$(top_srcdir)/lib/includes \ -I$(top_builddir)/lib/includes \ -I$(top_srcdir)/lib \ diff --git a/src/shrpx.cc b/src/shrpx.cc index 23260d32..78ef768e 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -1561,6 +1561,9 @@ void fill_default_config(Config *config) { LOG(FATAL) << "Unable to generate stateless reset secret"; exit(EXIT_FAILURE); } + + auto &bpfconf = quicconf.bpf; + bpfconf.prog_file = StringRef::from_lit(PKGLIBDIR "/reuseport_kern.o"); } #endif // ENABLE_HTTP3 @@ -2870,7 +2873,21 @@ Scripting: Ignore mruby compile error for per-pattern mruby script file. If error occurred, it is treated as if no mruby file were specified for the pattern. +)"; +#ifdef ENABLE_HTTP3 + out << R"( +QUIC: + --bpf-program-file= + Specify a path to eBPF program file reuseport_kern.o to + steer an incoming QUIC UDP datagram to a correct socket. + Default: )" + << config->quic.bpf.prog_file << R"( + --no-bpf Disable eBPF. +)"; +#endif // ENABLE_HTTP3 + + out << R"( Misc: --conf= Load configuration from . Please note that @@ -3560,6 +3577,8 @@ int main(int argc, char **argv) { {SHRPX_OPT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument, &flag, 167}, {SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument, &flag, 168}, + {SHRPX_OPT_BPF_PROGRAM_FILE.c_str(), required_argument, &flag, 169}, + {SHRPX_OPT_NO_BPF.c_str(), no_argument, &flag, 170}, {nullptr, 0, nullptr, 0}}; int option_index = 0; @@ -4363,6 +4382,14 @@ int main(int argc, char **argv) { cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST, StringRef::from_lit("yes")); break; + case 169: + // --bpf-program-file + cmdcfgs.emplace_back(SHRPX_OPT_BPF_PROGRAM_FILE, StringRef{optarg}); + break; + case 170: + // --no-bpf + cmdcfgs.emplace_back(SHRPX_OPT_NO_BPF, StringRef::from_lit("yes")); + break; default: break; } diff --git a/src/shrpx_config.cc b/src/shrpx_config.cc index aadbe916..b4ad3e6f 100644 --- a/src/shrpx_config.cc +++ b/src/shrpx_config.cc @@ -1689,6 +1689,11 @@ int option_lookup_token(const char *name, size_t namelen) { return SHRPX_OPTID_ALTSVC; } break; + case 'f': + if (util::strieq_l("no-bp", name, 5)) { + return SHRPX_OPTID_NO_BPF; + } + break; case 'n': if (util::strieq_l("daemo", name, 5)) { return SHRPX_OPTID_DAEMON; @@ -1981,6 +1986,9 @@ int option_lookup_token(const char *name, size_t namelen) { case 16: switch (name[15]) { case 'e': + if (util::strieq_l("bpf-program-fil", name, 15)) { + return SHRPX_OPTID_BPF_PROGRAM_FILE; + } if (util::strieq_l("certificate-fil", name, 15)) { return SHRPX_OPTID_CERTIFICATE_FILE; } @@ -3815,6 +3823,18 @@ int parse_config(Config *config, int optid, const StringRef &opt, case SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA: config->http.early_data.strip_incoming = !util::strieq_l("yes", optarg); + return 0; + case SHRPX_OPTID_BPF_PROGRAM_FILE: +#ifdef ENABLE_HTTP3 + config->quic.bpf.prog_file = make_string_ref(config->balloc, optarg); +#endif // ENABLE_HTTP3 + + return 0; + case SHRPX_OPTID_NO_BPF: +#ifdef ENABLE_HTTP3 + config->quic.bpf.disabled = util::strieq_l("yes", optarg); +#endif // ENABLE_HTTP3 + return 0; case SHRPX_OPTID_CONF: LOG(WARN) << "conf: ignored"; diff --git a/src/shrpx_config.h b/src/shrpx_config.h index 16a6dbce..789b9582 100644 --- a/src/shrpx_config.h +++ b/src/shrpx_config.h @@ -360,6 +360,9 @@ constexpr auto SHRPX_OPT_TLS13_CLIENT_CIPHERS = StringRef::from_lit("tls13-client-ciphers"); constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA = StringRef::from_lit("no-strip-incoming-early-data"); +constexpr auto SHRPX_OPT_BPF_PROGRAM_FILE = + StringRef::from_lit("bpf-program-file"); +constexpr auto SHRPX_OPT_NO_BPF = StringRef::from_lit("no-bpf"); constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8; @@ -717,6 +720,10 @@ struct QUICConfig { struct { bool log; } debug; + struct { + StringRef prog_file; + bool disabled; + } bpf; }; #endif // ENABLE_HTTP3 @@ -1098,6 +1105,7 @@ enum { SHRPX_OPTID_BACKEND_TLS_SNI_FIELD, SHRPX_OPTID_BACKEND_WRITE_TIMEOUT, SHRPX_OPTID_BACKLOG, + SHRPX_OPTID_BPF_PROGRAM_FILE, SHRPX_OPTID_CACERT, SHRPX_OPTID_CERTIFICATE_FILE, SHRPX_OPTID_CIPHERS, @@ -1159,6 +1167,7 @@ enum { SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS, SHRPX_OPTID_MRUBY_FILE, SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO, + SHRPX_OPTID_NO_BPF, SHRPX_OPTID_NO_HOST_REWRITE, SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST, SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST, diff --git a/src/shrpx_worker.cc b/src/shrpx_worker.cc index 1cf293d9..02989ea7 100644 --- a/src/shrpx_worker.cc +++ b/src/shrpx_worker.cc @@ -644,9 +644,11 @@ DNSTracker *Worker::get_dns_tracker() { return &dns_tracker_; } # ifdef HAVE_LIBBPF bool Worker::should_attach_bpf() const { auto config = get_config(); + auto &quicconf = config->quic; auto &apiconf = config->api; - if (config->single_thread || config->num_worker == 1) { + if (quicconf.bpf.disabled || config->single_thread || + config->num_worker == 1) { return false; } @@ -659,8 +661,10 @@ bool Worker::should_attach_bpf() const { bool Worker::should_update_bpf_map() const { auto config = get_config(); + auto &quicconf = config->quic; - return !config->single_thread && config->num_worker > 1; + return !quicconf.bpf.disabled && !config->single_thread && + config->num_worker > 1; } uint32_t Worker::compute_sk_index() const { @@ -819,11 +823,15 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) { } # ifdef HAVE_LIBBPF + auto config = get_config(); + auto &quic_bpf_refs = conn_handler_->get_quic_bpf_refs(); int err; if (should_attach_bpf()) { - auto obj = bpf_object__open_file("bpf/reuseport_kern.o", nullptr); + auto &bpfconf = config->quic.bpf; + + auto obj = bpf_object__open_file(bpfconf.prog_file.c_str(), nullptr); err = libbpf_get_error(obj); if (err) { LOG(FATAL) << "Failed to open bpf object file: " @@ -883,7 +891,6 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) { } constexpr uint32_t zero = 0; - auto config = get_config(); uint32_t num_socks = config->num_worker; if (bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks,