From 58e9c34da63777eb632f07edc4c36003a83ce9d9 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 1 May 2022 10:49:09 +0100 Subject: [PATCH 1/3] 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. --- sapi/fpm/config.m4 | 18 ++++++++++++++++ sapi/fpm/fpm/fpm_conf.c | 6 ++++++ sapi/fpm/fpm/fpm_conf.h | 3 +++ sapi/fpm/fpm/fpm_sockets.c | 43 ++++++++++++++++++++++++++++++++++++++ sapi/fpm/fpm/fpm_sockets.h | 3 +++ sapi/fpm/php-fpm.conf.in | 4 ++++ 6 files changed, 77 insertions(+) diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index da09511a0deb1..706209ad32f88 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -396,6 +396,23 @@ AC_DEFUN([AC_FPM_TIMES], ]) ]) +AC_DEFUN([AC_FPM_SOCKETROUTE], +[ + have_socketroute=no + AC_MSG_CHECKING([for SO_SETFIB]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int x = SO_SETFIB;]])], [ + have_socketroute=yes + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) + + if test $have_socketroute = "yes"; then + AC_DEFINE([HAVE_SOCKETROUTE], 1, [do we have socket route capabilities]) + fi +]) + AC_DEFUN([AC_FPM_KQUEUE], [ AC_MSG_CHECKING([for kqueue]) @@ -539,6 +556,7 @@ if test "$PHP_FPM" != "no"; then AC_FPM_LQ AC_FPM_SYSCONF AC_FPM_TIMES + AC_FPM_SOCKETROUTE AC_FPM_KQUEUE AC_FPM_PORT AC_FPM_DEVPOLL diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 197c5b1c2b26e..9f56a32a9223a 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -70,6 +70,9 @@ struct fpm_global_config_s fpm_global_config = { #ifdef HAVE_SYSTEMD .systemd_watchdog = 0, .systemd_interval = -1, /* -1 means not set */ +#endif +#ifdef HAVE_SOCKETROUTE + .socketroute = -1, /* -1 means not set */ #endif .log_buffering = ZLOG_DEFAULT_BUFFERING, .log_limit = ZLOG_DEFAULT_LIMIT @@ -104,6 +107,9 @@ static struct ini_value_parser_s ini_fpm_global_options[] = { { "events.mechanism", &fpm_conf_set_string, GO(events_mechanism) }, #ifdef HAVE_SYSTEMD { "systemd_interval", &fpm_conf_set_time, GO(systemd_interval) }, +#endif +#ifdef HAVE_SOCKETROUTE + { "socket.route", &fpm_conf_set_integer, GO(socketroute) }, #endif { 0, 0, 0 } }; diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h index 4c0addc2a950f..21e2e2e4b2851 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -44,6 +44,9 @@ struct fpm_global_config_s { int systemd_watchdog; int systemd_interval; #endif +#ifdef HAVE_SOCKETROUTE + int socketroute; +#endif }; extern struct fpm_global_config_s fpm_global_config; diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 5b4bdc7f430a8..0bb77742a8a58 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,22 @@ static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct return -1; } +#ifdef HAVE_SOCKETROUTE + if (-1 < fpm_global_config.socketroute) { +#ifdef SO_SETFIB + if (routemax < fpm_global_config.socketroute) { + zlog(ZLOG_ERROR, "Invalid routing table id %d, max is %d", fpm_global_config.socketroute, routemax); + close(sock); + return -1; + } + + if (0 > setsockopt(sock, SOL_SOCKET, SO_SETFIB, &fpm_global_config.socketroute, sizeof(fpm_global_config.socketroute))) { + zlog(ZLOG_WARNING, "failed to change socket attribute"); + } +#endif + } +#endif + return sock; } /* }}} */ @@ -386,6 +406,23 @@ static int fpm_socket_af_unix_listening_socket(struct fpm_worker_pool_s *wp) /* } /* }}} */ +#ifdef HAVE_SOCKETROUTE +static zend_result fpm_socket_setroute_init(void) /* {{{ */ +{ +#ifdef SO_SETFIB + /* 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 +} +/* }}} */ +#endif + int fpm_sockets_init_main() /* {{{ */ { unsigned i, lq_len; @@ -399,6 +436,12 @@ int fpm_sockets_init_main() /* {{{ */ return -1; } +#ifdef HAVE_SOCKETROUTE + if (fpm_socket_setroute_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 c4c4fdbfdd07c..94d903ca45564 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/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in index 4818f20b436e9..ed2207f473592 100644 --- a/sapi/fpm/php-fpm.conf.in +++ b/sapi/fpm/php-fpm.conf.in @@ -125,6 +125,10 @@ ; Default value: 10 ;systemd_interval = 10 +; Sets the routing table for the sockets created within FPM +; - FreeBSD from 0 up to 65536 +;socket.route = -1 + ;;;;;;;;;;;;;;;;;;;; ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; From b3429d77f734fdf0009dfa2b468e4c1de1544838 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 2 Jul 2022 23:40:37 +0100 Subject: [PATCH 2/3] changes from feedback --- sapi/fpm/config.m4 | 18 ------------------ sapi/fpm/fpm/fpm_conf.c | 12 ++++++------ sapi/fpm/fpm/fpm_conf.h | 6 +++--- sapi/fpm/fpm/fpm_sockets.c | 23 +++++++++-------------- sapi/fpm/php-fpm.conf.in | 4 ---- 5 files changed, 18 insertions(+), 45 deletions(-) diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 706209ad32f88..da09511a0deb1 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -396,23 +396,6 @@ AC_DEFUN([AC_FPM_TIMES], ]) ]) -AC_DEFUN([AC_FPM_SOCKETROUTE], -[ - have_socketroute=no - AC_MSG_CHECKING([for SO_SETFIB]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int x = SO_SETFIB;]])], [ - have_socketroute=yes - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - ]) - - if test $have_socketroute = "yes"; then - AC_DEFINE([HAVE_SOCKETROUTE], 1, [do we have socket route capabilities]) - fi -]) - AC_DEFUN([AC_FPM_KQUEUE], [ AC_MSG_CHECKING([for kqueue]) @@ -556,7 +539,6 @@ if test "$PHP_FPM" != "no"; then AC_FPM_LQ AC_FPM_SYSCONF AC_FPM_TIMES - AC_FPM_SOCKETROUTE AC_FPM_KQUEUE AC_FPM_PORT AC_FPM_DEVPOLL diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 9f56a32a9223a..73be32b21ffd4 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -70,9 +70,6 @@ struct fpm_global_config_s fpm_global_config = { #ifdef HAVE_SYSTEMD .systemd_watchdog = 0, .systemd_interval = -1, /* -1 means not set */ -#endif -#ifdef HAVE_SOCKETROUTE - .socketroute = -1, /* -1 means not set */ #endif .log_buffering = ZLOG_DEFAULT_BUFFERING, .log_limit = ZLOG_DEFAULT_LIMIT @@ -107,9 +104,6 @@ static struct ini_value_parser_s ini_fpm_global_options[] = { { "events.mechanism", &fpm_conf_set_string, GO(events_mechanism) }, #ifdef HAVE_SYSTEMD { "systemd_interval", &fpm_conf_set_time, GO(systemd_interval) }, -#endif -#ifdef HAVE_SOCKETROUTE - { "socket.route", &fpm_conf_set_integer, GO(socketroute) }, #endif { 0, 0, 0 } }; @@ -131,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) }, @@ -1721,6 +1718,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 HAVE_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 21e2e2e4b2851..73657cd3a5a22 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -44,9 +44,6 @@ struct fpm_global_config_s { int systemd_watchdog; int systemd_interval; #endif -#ifdef HAVE_SOCKETROUTE - int socketroute; -#endif }; extern struct fpm_global_config_s fpm_global_config; @@ -106,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 0bb77742a8a58..84fb25e234359 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -254,19 +254,17 @@ static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct return -1; } -#ifdef HAVE_SOCKETROUTE - if (-1 < fpm_global_config.socketroute) { #ifdef SO_SETFIB - if (routemax < fpm_global_config.socketroute) { - zlog(ZLOG_ERROR, "Invalid routing table id %d, max is %d", fpm_global_config.socketroute, routemax); + 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, &fpm_global_config.socketroute, sizeof(fpm_global_config.socketroute))) { - zlog(ZLOG_WARNING, "failed to change socket attribute"); + 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 } #endif @@ -406,10 +404,9 @@ static int fpm_socket_af_unix_listening_socket(struct fpm_worker_pool_s *wp) /* } /* }}} */ -#ifdef HAVE_SOCKETROUTE -static zend_result fpm_socket_setroute_init(void) /* {{{ */ -{ #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) { @@ -418,9 +415,7 @@ static zend_result fpm_socket_setroute_init(void) /* {{{ */ } return SUCCESS; -#endif } -/* }}} */ #endif int fpm_sockets_init_main() /* {{{ */ @@ -436,8 +431,8 @@ int fpm_sockets_init_main() /* {{{ */ return -1; } -#ifdef HAVE_SOCKETROUTE - if (fpm_socket_setroute_init() == FAILURE) { +#ifdef SO_SETFIB + if (fpm_socket_setfib_init() == FAILURE) { return -1; } #endif diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in index ed2207f473592..4818f20b436e9 100644 --- a/sapi/fpm/php-fpm.conf.in +++ b/sapi/fpm/php-fpm.conf.in @@ -125,10 +125,6 @@ ; Default value: 10 ;systemd_interval = 10 -; Sets the routing table for the sockets created within FPM -; - FreeBSD from 0 up to 65536 -;socket.route = -1 - ;;;;;;;;;;;;;;;;;;;; ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; From 77311d34b1aa165edecf37a702c25f1cac932880 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sun, 3 Jul 2022 23:30:41 +0100 Subject: [PATCH 3/3] adding test, by default the kernel has one FIB unless we change the value for boot time. --- sapi/fpm/tests/setsofib.phpt | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 sapi/fpm/tests/setsofib.phpt diff --git a/sapi/fpm/tests/setsofib.phpt b/sapi/fpm/tests/setsofib.phpt new file mode 100644 index 0000000000000..ba6502e14acb6 --- /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-- +