From: Willy Tarreau Date: Sat, 22 Apr 2023 15:39:30 +0000 (+0200) Subject: MINOR: protocol: add a function to check if some features are supported X-Git-Tag: v2.8-dev8~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a5e6f4cca2396c5c498d9ebbdc12f9624ac6a48;p=thirdparty%2Fhaproxy.git MINOR: protocol: add a function to check if some features are supported The new function protocol_supports_flag() checks the protocol flags to verify if some features are supported, but will support being extended to refine the tests. Let's use it to check for REUSEPORT. --- diff --git a/include/haproxy/protocol.h b/include/haproxy/protocol.h index 5c0871aec7..828093d982 100644 --- a/include/haproxy/protocol.h +++ b/include/haproxy/protocol.h @@ -44,6 +44,14 @@ void protocol_clrf_all(uint flag); /* sets flag on all protocols. */ void protocol_setf_all(uint flag); +/* Checks if protocol supports PROTO_F flag . Returns zero if not, + * non-zero if supported. It may return a cached value from a previous test, + * and may run live tests then update the proto's flags to cache a result. It's + * better to call it only if needed so that it doesn't result in modules being + * loaded in case of a live test. + */ +int protocol_supports_flag(struct protocol *proto, uint flag); + /* binds all listeners of all registered protocols. Returns a composition * of ERR_NONE, ERR_RETRYABLE, ERR_FATAL, ERR_ABORT. */ diff --git a/src/listener.c b/src/listener.c index 45595cc69e..994e97a348 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1669,7 +1669,7 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code) /* special values: -1 = "by-thread", -2 = "by-group" */ if (shards == -1) { - if (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) + if (protocol_supports_flag(li->rx.proto, PROTO_F_REUSEPORT_SUPPORTED)) shards = todo; else { if (fe != global.cli_fe) @@ -1680,14 +1680,14 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code) } } else if (shards == -2) - shards = (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) ? my_popcountl(bind_conf->thread_set.grps) : 1; + shards = protocol_supports_flag(li->rx.proto, PROTO_F_REUSEPORT_SUPPORTED) ? my_popcountl(bind_conf->thread_set.grps) : 1; /* no more shards than total threads */ if (shards > todo) shards = todo; /* We also need to check if an explicit shards count was set and cannot be honored */ - if (shards > 1 && !(li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED)) { + if (shards > 1 && !protocol_supports_flag(li->rx.proto, PROTO_F_REUSEPORT_SUPPORTED)) { ha_warning("[%s:%d]: Disabling sharding for listener in %s '%s' because SO_REUSEPORT is disabled\n", bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id); shards = 1; diff --git a/src/protocol.c b/src/protocol.c index 7cc9674368..c190a36642 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -83,6 +83,25 @@ void protocol_setf_all(uint flag) HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock); } +/* Checks if protocol supports PROTO_F flag . Returns zero if not, + * non-zero if supported. It may return a cached value from a previous test, + * and may run live tests then update the proto's flags to cache a result. It's + * better to call it only if needed so that it doesn't result in modules being + * loaded in case of a live test. It is only supposed to be used during boot. + */ +int protocol_supports_flag(struct protocol *proto, uint flag) +{ + if (flag == PROTO_F_REUSEPORT_SUPPORTED) { + /* check if the protocol supports SO_REUSEPORT */ + if (!(_HA_ATOMIC_LOAD(&proto->flags) & PROTO_F_REUSEPORT_SUPPORTED)) + return 0; + + /* OK it looks like it is supported */ + return 1; + } + return 0; +} + /* binds all listeners of all registered protocols. Returns a composition * of ERR_NONE, ERR_RETRYABLE, ERR_FATAL. */