nghttpx: Add options to specify eBPF program file path and disable eBPF

This commit is contained in:
Tatsuhiro Tsujikawa 2021-08-26 14:13:14 +09:00
parent 8ac4bee3bc
commit 8563ec5a7a
6 changed files with 70 additions and 4 deletions

View File

@ -177,6 +177,8 @@ OPTIONS = [
"tls13-ciphers", "tls13-ciphers",
"tls13-client-ciphers", "tls13-client-ciphers",
"no-strip-incoming-early-data", "no-strip-incoming-early-data",
"bpf-program-file",
"no-bpf",
] ]
LOGVARS = [ LOGVARS = [

View File

@ -35,6 +35,7 @@ AM_CFLAGS = $(WARNCFLAGS)
AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS) AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS)
AM_CPPFLAGS = \ AM_CPPFLAGS = \
-DPKGDATADIR='"$(pkgdatadir)"' \ -DPKGDATADIR='"$(pkgdatadir)"' \
-DPKGLIBDIR='"$(pkglibdir)"' \
-I$(top_srcdir)/lib/includes \ -I$(top_srcdir)/lib/includes \
-I$(top_builddir)/lib/includes \ -I$(top_builddir)/lib/includes \
-I$(top_srcdir)/lib \ -I$(top_srcdir)/lib \

View File

@ -1561,6 +1561,9 @@ void fill_default_config(Config *config) {
LOG(FATAL) << "Unable to generate stateless reset secret"; LOG(FATAL) << "Unable to generate stateless reset secret";
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
auto &bpfconf = quicconf.bpf;
bpfconf.prog_file = StringRef::from_lit(PKGLIBDIR "/reuseport_kern.o");
} }
#endif // ENABLE_HTTP3 #endif // ENABLE_HTTP3
@ -2870,7 +2873,21 @@ Scripting:
Ignore mruby compile error for per-pattern mruby script Ignore mruby compile error for per-pattern mruby script
file. If error occurred, it is treated as if no mruby file. If error occurred, it is treated as if no mruby
file were specified for the pattern. file were specified for the pattern.
)";
#ifdef ENABLE_HTTP3
out << R"(
QUIC:
--bpf-program-file=<PATH>
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: Misc:
--conf=<PATH> --conf=<PATH>
Load configuration from <PATH>. Please note that Load configuration from <PATH>. 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_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument, &flag, 167},
{SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument, {SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST.c_str(), no_argument,
&flag, 168}, &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}}; {nullptr, 0, nullptr, 0}};
int option_index = 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, cmdcfgs.emplace_back(SHRPX_OPT_CLIENT_NO_HTTP2_CIPHER_BLOCK_LIST,
StringRef::from_lit("yes")); StringRef::from_lit("yes"));
break; 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: default:
break; break;
} }

View File

@ -1689,6 +1689,11 @@ int option_lookup_token(const char *name, size_t namelen) {
return SHRPX_OPTID_ALTSVC; return SHRPX_OPTID_ALTSVC;
} }
break; break;
case 'f':
if (util::strieq_l("no-bp", name, 5)) {
return SHRPX_OPTID_NO_BPF;
}
break;
case 'n': case 'n':
if (util::strieq_l("daemo", name, 5)) { if (util::strieq_l("daemo", name, 5)) {
return SHRPX_OPTID_DAEMON; return SHRPX_OPTID_DAEMON;
@ -1981,6 +1986,9 @@ int option_lookup_token(const char *name, size_t namelen) {
case 16: case 16:
switch (name[15]) { switch (name[15]) {
case 'e': 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)) { if (util::strieq_l("certificate-fil", name, 15)) {
return SHRPX_OPTID_CERTIFICATE_FILE; 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: case SHRPX_OPTID_NO_STRIP_INCOMING_EARLY_DATA:
config->http.early_data.strip_incoming = !util::strieq_l("yes", optarg); 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; return 0;
case SHRPX_OPTID_CONF: case SHRPX_OPTID_CONF:
LOG(WARN) << "conf: ignored"; LOG(WARN) << "conf: ignored";

View File

@ -360,6 +360,9 @@ constexpr auto SHRPX_OPT_TLS13_CLIENT_CIPHERS =
StringRef::from_lit("tls13-client-ciphers"); StringRef::from_lit("tls13-client-ciphers");
constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA = constexpr auto SHRPX_OPT_NO_STRIP_INCOMING_EARLY_DATA =
StringRef::from_lit("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; constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
@ -717,6 +720,10 @@ struct QUICConfig {
struct { struct {
bool log; bool log;
} debug; } debug;
struct {
StringRef prog_file;
bool disabled;
} bpf;
}; };
#endif // ENABLE_HTTP3 #endif // ENABLE_HTTP3
@ -1098,6 +1105,7 @@ enum {
SHRPX_OPTID_BACKEND_TLS_SNI_FIELD, SHRPX_OPTID_BACKEND_TLS_SNI_FIELD,
SHRPX_OPTID_BACKEND_WRITE_TIMEOUT, SHRPX_OPTID_BACKEND_WRITE_TIMEOUT,
SHRPX_OPTID_BACKLOG, SHRPX_OPTID_BACKLOG,
SHRPX_OPTID_BPF_PROGRAM_FILE,
SHRPX_OPTID_CACERT, SHRPX_OPTID_CACERT,
SHRPX_OPTID_CERTIFICATE_FILE, SHRPX_OPTID_CERTIFICATE_FILE,
SHRPX_OPTID_CIPHERS, SHRPX_OPTID_CIPHERS,
@ -1159,6 +1167,7 @@ enum {
SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS, SHRPX_OPTID_MAX_RESPONSE_HEADER_FIELDS,
SHRPX_OPTID_MRUBY_FILE, SHRPX_OPTID_MRUBY_FILE,
SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO, SHRPX_OPTID_NO_ADD_X_FORWARDED_PROTO,
SHRPX_OPTID_NO_BPF,
SHRPX_OPTID_NO_HOST_REWRITE, SHRPX_OPTID_NO_HOST_REWRITE,
SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST, SHRPX_OPTID_NO_HTTP2_CIPHER_BLACK_LIST,
SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST, SHRPX_OPTID_NO_HTTP2_CIPHER_BLOCK_LIST,

View File

@ -644,9 +644,11 @@ DNSTracker *Worker::get_dns_tracker() { return &dns_tracker_; }
# ifdef HAVE_LIBBPF # ifdef HAVE_LIBBPF
bool Worker::should_attach_bpf() const { bool Worker::should_attach_bpf() const {
auto config = get_config(); auto config = get_config();
auto &quicconf = config->quic;
auto &apiconf = config->api; 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; return false;
} }
@ -659,8 +661,10 @@ bool Worker::should_attach_bpf() const {
bool Worker::should_update_bpf_map() const { bool Worker::should_update_bpf_map() const {
auto config = get_config(); 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 { uint32_t Worker::compute_sk_index() const {
@ -819,11 +823,15 @@ int Worker::create_quic_server_socket(UpstreamAddr &faddr) {
} }
# ifdef HAVE_LIBBPF # ifdef HAVE_LIBBPF
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; int err;
if (should_attach_bpf()) { 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); err = libbpf_get_error(obj);
if (err) { if (err) {
LOG(FATAL) << "Failed to open bpf object file: " 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; constexpr uint32_t zero = 0;
auto config = get_config();
uint32_t num_socks = config->num_worker; uint32_t num_socks = config->num_worker;
if (bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks, if (bpf_map_update_elem(bpf_map__fd(sk_info), &zero, &num_socks,