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 5c0871a..828093d 100644
--- a/include/haproxy/protocol.h
+++ b/include/haproxy/protocol.h
@@ -44,6 +44,14 @@
/* sets flag <flag> on all protocols. */
void protocol_setf_all(uint flag);
+/* Checks if protocol <proto> supports PROTO_F flag <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 45595cc..994e97a 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -1669,7 +1669,7 @@
/* 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 @@
}
}
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 7cc9674..c190a36 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -83,6 +83,25 @@
HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
}
+/* Checks if protocol <proto> supports PROTO_F flag <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.
*/