From 5174ee23537d82d5ea20ef84ce40cf274c74c5ed Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 1 May 2022 10:49:09 +0100 Subject: [PATCH] FPM add routing view global option (for FreeBSD for now). set the route table FIB id to the sockets created within FPM up to the max set by the system, avoiding having to use setfib command line. Closes #8470. --- NEWS | 3 +++ sapi/fpm/fpm/fpm_conf.c | 9 ++++++++ sapi/fpm/fpm/fpm_conf.h | 3 +++ sapi/fpm/fpm/fpm_sockets.c | 38 +++++++++++++++++++++++++++++++ sapi/fpm/fpm/fpm_sockets.h | 3 +++ sapi/fpm/tests/setsofib.phpt | 44 ++++++++++++++++++++++++++++++++++++ sapi/fpm/www.conf.in | 4 ++++ 7 files changed, 104 insertions(+) create mode 100644 sapi/fpm/tests/setsofib.phpt diff --git a/NEWS b/NEWS index 33912e60b50..15161b0df66 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.0beta1 +- FPM: + - Added listen.setfib pool option to set route FIB on FreeBSD. (David Carlier) + 07 Jul 2022, PHP 8.2.0alpha3 - Core: diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 197c5b1c2b2..fb414231a63 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -125,6 +125,9 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = { { "listen.group", &fpm_conf_set_string, WPO(listen_group) }, { "listen.mode", &fpm_conf_set_string, WPO(listen_mode) }, { "listen.allowed_clients", &fpm_conf_set_string, WPO(listen_allowed_clients) }, +#ifdef SO_SETFIB + { "listen.setfib", &fpm_conf_set_integer, WPO(listen_setfib) }, +#endif { "process.priority", &fpm_conf_set_integer, WPO(process_priority) }, { "process.dumpable", &fpm_conf_set_boolean, WPO(process_dumpable) }, { "pm", &fpm_conf_set_pm, WPO(pm) }, @@ -618,6 +621,9 @@ static void *fpm_worker_pool_config_alloc(void) /* {{{ */ wp->config->process_dumpable = 0; wp->config->clear_env = 1; wp->config->decorate_workers_output = 1; +#ifdef SO_SETFIB + wp->config->listen_setfib = -1; +#endif if (!fpm_worker_all_pools) { fpm_worker_all_pools = wp; @@ -1715,6 +1721,9 @@ static void fpm_conf_dump(void) /* {{{ */ zlog(ZLOG_NOTICE, "\tlisten.group = %s", STR2STR(wp->config->listen_group)); zlog(ZLOG_NOTICE, "\tlisten.mode = %s", STR2STR(wp->config->listen_mode)); zlog(ZLOG_NOTICE, "\tlisten.allowed_clients = %s", STR2STR(wp->config->listen_allowed_clients)); +#ifdef SO_SETFIB + zlog(ZLOG_NOTICE, "\tlisten.setfib = %d", wp->config->listen_setfib); +#endif if (wp->config->process_priority == 64) { zlog(ZLOG_NOTICE, "\tprocess.priority = undefined"); } else { diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h index 4c0addc2a95..73657cd3a5a 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -103,6 +103,9 @@ struct fpm_worker_pool_config_s { char *listen_acl_users; char *listen_acl_groups; #endif +#ifdef SO_SETFIB + int listen_setfib; +#endif }; struct ini_value_parser_s { diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 5b4bdc7f430..84fb25e2343 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -39,6 +39,10 @@ static struct fpm_array_s sockets_list; enum { FPM_GET_USE_SOCKET = 1, FPM_STORE_SOCKET = 2, FPM_STORE_USE_SOCKET = 3 }; +#ifdef SO_SETFIB +static int routemax = -1; +#endif + static inline void fpm_sockets_get_env_name(char *envname, unsigned idx) /* {{{ */ { if (!idx) { @@ -250,6 +254,20 @@ static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct return -1; } +#ifdef SO_SETFIB + if (-1 < wp->config->listen_setfib) { + if (routemax < wp->config->listen_setfib) { + zlog(ZLOG_ERROR, "Invalid routing table id %d, max is %d", wp->config->listen_setfib, routemax); + close(sock); + return -1; + } + + if (0 > setsockopt(sock, SOL_SOCKET, SO_SETFIB, &wp->config->listen_setfib, sizeof(wp->config->listen_setfib))) { + zlog(ZLOG_WARNING, "failed to change socket SO_SETFIB attribute"); + } + } +#endif + return sock; } /* }}} */ @@ -386,6 +404,20 @@ static int fpm_socket_af_unix_listening_socket(struct fpm_worker_pool_s *wp) /* } /* }}} */ +#ifdef SO_SETFIB +static zend_result fpm_socket_setfib_init(void) +{ + /* potentially up to 65536 but needs to check the actual cap beforehand */ + size_t len = sizeof(routemax); + if (sysctlbyname("net.fibs", &routemax, &len, NULL, 0) < 0) { + zlog(ZLOG_ERROR, "failed to get max routing table"); + return FAILURE; + } + + return SUCCESS; +} +#endif + int fpm_sockets_init_main() /* {{{ */ { unsigned i, lq_len; @@ -399,6 +431,12 @@ int fpm_sockets_init_main() /* {{{ */ return -1; } +#ifdef SO_SETFIB + if (fpm_socket_setfib_init() == FAILURE) { + return -1; + } +#endif + /* import inherited sockets */ for (i = 0; i < FPM_ENV_SOCKET_SET_MAX; i++) { fpm_sockets_get_env_name(envname, i); diff --git a/sapi/fpm/fpm/fpm_sockets.h b/sapi/fpm/fpm/fpm_sockets.h index c4c4fdbfdd0..94d903ca455 100644 --- a/sapi/fpm/fpm/fpm_sockets.h +++ b/sapi/fpm/fpm/fpm_sockets.h @@ -5,6 +5,9 @@ #include #include +#if defined(__FreeBSD__) +#include +#endif #include #include #include diff --git a/sapi/fpm/tests/setsofib.phpt b/sapi/fpm/tests/setsofib.phpt new file mode 100644 index 00000000000..ba6502e14ac --- /dev/null +++ b/sapi/fpm/tests/setsofib.phpt @@ -0,0 +1,44 @@ +--TEST-- +FPM: listen.setfib` +--SKIPIF-- + +--FILE-- +start(); +$tester->expectLogError('Invalid routing table id 68000, max is 1'); +$tester->terminate(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- + diff --git a/sapi/fpm/www.conf.in b/sapi/fpm/www.conf.in index 32705b9f3d3..f1220355d6c 100644 --- a/sapi/fpm/www.conf.in +++ b/sapi/fpm/www.conf.in @@ -62,6 +62,10 @@ listen = 127.0.0.1:9000 ; Default Value: any ;listen.allowed_clients = 127.0.0.1 +; Set the associated the route table (FIB). FreeBSD only +; Default Value: -1 +;listen.setfib = 1 + ; Specify the nice(2) priority to apply to the pool processes (only if set) ; The value can vary from -19 (highest priority) to 20 (lower priority) ; Note: - It will only work if the FPM master process is launched as root