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