From 8ef6844a34cd6765bfa09d2fdaf4f0609d6c59cb Mon Sep 17 00:00:00 2001 From: jim-p Date: Wed, 28 Aug 2019 16:17:01 -0400 Subject: [PATCH] Make NTP minpoll and maxpoll user-configurable. Implements #6787 --- src/etc/inc/system.inc | 59 +++++++++++++++++++++++-- src/usr/local/www/services_ntpd.php | 33 ++++++++++++++ src/usr/local/www/services_ntpd_gps.php | 35 +++++++++++++++ src/usr/local/www/services_ntpd_pps.php | 34 +++++++++++++- 4 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 017b34bea5..2ffb1a653f 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -1857,6 +1857,49 @@ function system_timezone_configure() { } } +/* Generate list of possible NTP poll values + * https://redmine.pfsense.org/issues/9439 */ +global $ntp_poll_min_value, $ntp_poll_max_value; +global $ntp_poll_min_default_gps, $ntp_poll_max_default_gps; +global $ntp_poll_min_default_pps, $ntp_poll_max_default_pps; +global $ntp_poll_min_default, $ntp_poll_max_default; +$ntp_poll_min_value = 4; +$ntp_poll_max_value = 17; +$ntp_poll_min_default_gps = 4; +$ntp_poll_max_default_gps = 4; +$ntp_poll_min_default_pps = 4; +$ntp_poll_max_default_pps = 4; +$ntp_poll_min_default = 'omit'; +$ntp_poll_max_default = 9; + +function system_ntp_poll_values() { + global $ntp_poll_min_value, $ntp_poll_max_value; + $poll_values = array("" => gettext('Default')); + + for ($i = $ntp_poll_min_value; $i <= $ntp_poll_max_value; $i++) { + $sec = 2 ** $i; + $poll_values[$i] = $i . ': ' . number_format($sec) . ' ' . gettext('seconds') . + ' (' . convert_seconds_to_dhms($sec) . ')'; + } + + $poll_values['omit'] = gettext('Omit (Do not set)'); + return $poll_values; +} + +function system_ntp_fixup_poll_value($type, $configvalue, $default) { + $pollstring = ""; + + if (empty($configvalue)) { + $configvalue = $default; + } + + if ($configvalue != 'omit') { + $pollstring = " {$type} {$configvalue}"; + } + + return $pollstring; +} + function system_ntp_setup_gps($serialport) { global $config, $g; $gps_device = '/dev/gps0'; @@ -1935,6 +1978,9 @@ function system_ntp_setup_pps($serialport) { function system_ntp_configure() { global $config, $g; + global $ntp_poll_min_default_gps, $ntp_poll_max_default_gps; + global $ntp_poll_min_default_pps, $ntp_poll_max_default_pps; + global $ntp_poll_min_default, $ntp_poll_max_default; $driftfile = "/var/db/ntpd.drift"; $statsdir = "/var/log/ntp"; @@ -1968,7 +2014,8 @@ function system_ntp_configure() { $ntpcfg .= "\n"; $ntpcfg .= "# PPS Setup\n"; $ntpcfg .= 'server 127.127.22.0'; - $ntpcfg .= ' minpoll 4 maxpoll 4'; + $ntpcfg .= system_ntp_fixup_poll_value('minpoll', $config['ntpd']['pps']['ppsminpoll'], $ntp_poll_min_default_pps); + $ntpcfg .= system_ntp_fixup_poll_value('maxpoll', $config['ntpd']['pps']['ppsmaxpoll'], $ntp_poll_max_default_pps); if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */ $ntpcfg .= ' prefer'; } @@ -2024,7 +2071,9 @@ function system_ntp_configure() { } else { $ntpcfg .= '0'; } - $ntpcfg .= ' minpoll 4 maxpoll 4'; + $ntpcfg .= system_ntp_fixup_poll_value('minpoll', $config['ntpd']['gps']['gpsminpoll'], $ntp_poll_min_default_gps); + $ntpcfg .= system_ntp_fixup_poll_value('maxpoll', $config['ntpd']['gps']['gpsmaxpoll'], $ntp_poll_max_default_gps); + if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */ $ntpcfg .= ' prefer'; } @@ -2091,7 +2140,11 @@ function system_ntp_configure() { $ntpcfg .= 'server '; } - $ntpcfg .= "{$ts} iburst maxpoll 9"; + $ntpcfg .= "{$ts} iburst"; + + $ntpcfg .= system_ntp_fixup_poll_value('minpoll', $config['ntpd']['ntpminpoll'], $ntp_poll_min_default); + $ntpcfg .= system_ntp_fixup_poll_value('maxpoll', $config['ntpd']['ntpmaxpoll'], $ntp_poll_max_default); + if (substr_count($config['ntpd']['prefer'], $ts)) { $ntpcfg .= ' prefer'; } diff --git a/src/usr/local/www/services_ntpd.php b/src/usr/local/www/services_ntpd.php index d8afb939c7..2b64e14769 100644 --- a/src/usr/local/www/services_ntpd.php +++ b/src/usr/local/www/services_ntpd.php @@ -34,6 +34,9 @@ require_once("guiconfig.inc"); require_once('rrd.inc'); require_once("shaper.inc"); +global $ntp_poll_min_default, $ntp_poll_max_default; +$ntp_poll_values = system_ntp_poll_values(); + if (!is_array($config['ntpd'])) { $config['ntpd'] = array(); } @@ -59,6 +62,20 @@ if ($_POST) { $input_errors[] = gettext("The supplied value for NTP Orphan Mode is invalid."); } + if (!array_key_exists($pconfig['ntpminpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is invalid."); + } + + if (!array_key_exists($pconfig['ntpmaxpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Maximum Poll Interval is invalid."); + } + + if (is_numericint($pconfig['ntpminpoll']) && + is_numericint($pconfig['ntpmaxpoll']) && + ($pconfig['ntpmaxpoll'] < $pconfig['ntpminpoll'])) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is higher than NTP Maximum Poll Interval."); + } + if (!$input_errors) { if (is_array($_POST['interface'])) { $config['ntpd']['interface'] = implode(",", $_POST['interface']); @@ -98,6 +115,8 @@ if ($_POST) { $config['system']['timeservers'] = trim($timeservers); $config['ntpd']['orphan'] = trim($pconfig['ntporphan']); + $config['ntpd']['ntpminpoll'] = $pconfig['ntpminpoll']; + $config['ntpd']['ntpmaxpoll'] = $pconfig['ntpmaxpoll']; if (!empty($_POST['logpeer'])) { $config['ntpd']['logpeer'] = $_POST['logpeer']; @@ -308,6 +327,20 @@ $section->addInput(new Form_Input( 'The number here specifies the stratum reported during orphan mode and should normally be set to a number high enough ' . 'to insure that any other servers available to clients are preferred over this server (default: 12).'); +$section->addInput(new Form_Select( + 'ntpminpoll', + 'Minimum Poll Interval', + $pconfig['ntpminpoll'], + $ntp_poll_values, +))->setHelp('Minimum poll interval for NTP messages. If set, must be less than or equal to Maximum Poll Interval.'); + +$section->addInput(new Form_Select( + 'ntpmaxpoll', + 'Maximum Poll Interval', + $pconfig['ntpmaxpoll'], + $ntp_poll_values, +))->setHelp('Maximum poll interval for NTP messages. If set, must be greater than or equal to Minimum Poll Interval.'); + $section->addInput(new Form_Checkbox( 'statsgraph', 'NTP Graphs', diff --git a/src/usr/local/www/services_ntpd_gps.php b/src/usr/local/www/services_ntpd_gps.php index 2ef457afcb..0fe5df42eb 100644 --- a/src/usr/local/www/services_ntpd_gps.php +++ b/src/usr/local/www/services_ntpd_gps.php @@ -33,6 +33,9 @@ require_once("guiconfig.inc"); $gpstypes = array(gettext('Custom'), gettext('Default'), 'Generic', 'Garmin', 'MediaTek', 'SiRF', 'U-Blox', 'SureGPS'); +global $ntp_poll_min_default_gps, $ntp_poll_max_default_gps; +$ntp_poll_values = system_ntp_poll_values(); + function set_default_gps() { global $config; @@ -155,6 +158,21 @@ if ($_POST) { if (!in_array($_POST['gpstype'], $gpstypes)) { $input_errors[] = gettext("The submitted GPS type is invalid."); } + + if (!array_key_exists($pconfig['gpsminpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is invalid."); + } + + if (!array_key_exists($pconfig['gpsmaxpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Maximum Poll Interval is invalid."); + } + + if (is_numericint($pconfig['gpsminpoll']) && + is_numericint($pconfig['gpsmaxpoll']) || + ($pconfig['gpsmaxpoll'] < $pconfig['gpsminpoll'])) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is higher than Maximum Poll Interval."); + } + } else { /* set defaults if they do not already exist */ if (!is_array($config['ntpd']) || !is_array($config['ntpd']['gps']) || empty($config['ntpd']['gps']['type'])) { @@ -286,6 +304,9 @@ if ($_POST && empty($input_errors)) { unset($config['ntpd']['gps']['nmeaset']); } + $config['ntpd']['gps']['gpsminpoll'] = $_POST['gpsminpoll']; + $config['ntpd']['gps']['gpsmaxpoll'] = $_POST['gpsmaxpoll']; + write_config(gettext("Updated NTP GPS Settings")); $changes_applied = true; @@ -425,6 +446,20 @@ $section->addInput(new Form_Input( $pconfig['stratum'] ))->setHelp('This may be used to change the GPS Clock stratum (default: 0). This may be useful to, for some reason, have ntpd prefer a different clock.'); +$section->addInput(new Form_Select( + 'gpsminpoll', + 'Minimum Poll Interval', + $pconfig['gpsminpoll'], + $ntp_poll_values, +))->setHelp('Minimum poll interval for NTP messages. If set, must be less than or equal to Maximum Poll Interval.'); + +$section->addInput(new Form_Select( + 'gpsmaxpoll', + 'Maximum Poll Interval', + $pconfig['gpsmaxpoll'], + $ntp_poll_values, +))->setHelp('Maximum poll interval for NTP messages. If set, must be greater than or equal to Minimum Poll Interval.'); + $section->addInput(new Form_Checkbox( 'gpsprefer', 'Flags', diff --git a/src/usr/local/www/services_ntpd_pps.php b/src/usr/local/www/services_ntpd_pps.php index d86601eacc..6783c564f0 100644 --- a/src/usr/local/www/services_ntpd_pps.php +++ b/src/usr/local/www/services_ntpd_pps.php @@ -31,6 +31,9 @@ require_once("guiconfig.inc"); +global $ntp_poll_min_default_pps, $ntp_poll_max_default_pps; +$ntp_poll_values = system_ntp_poll_values(); + if (!is_array($config['ntpd'])) { $config['ntpd'] = array(); } @@ -41,6 +44,20 @@ if (!is_array($config['ntpd']['pps'])) { if ($_POST) { unset($input_errors); + if (!array_key_exists($pconfig['ppsminpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is invalid."); + } + + if (!array_key_exists($pconfig['ppsmaxpoll'], $ntp_poll_values)) { + $input_errors[] = gettext("The supplied value for Maximum Poll Interval is invalid."); + } + + if (is_numericint($pconfig['ppsminpoll']) && + is_numericint($pconfig['ppsmaxpoll']) || + ($pconfig['ppsmaxpoll'] < $pconfig['ppsminpoll'])) { + $input_errors[] = gettext("The supplied value for Minimum Poll Interval is higher than Maximum Poll Interval."); + } + if (!$input_errors) { if (!empty($_POST['ppsport']) && file_exists('/dev/'.$_POST['ppsport'])) { $config['ntpd']['pps']['port'] = $_POST['ppsport']; @@ -90,6 +107,8 @@ if ($_POST) { } elseif (isset($config['ntpd']['pps']['refid'])) { unset($config['ntpd']['pps']['refid']); } + $config['ntpd']['pps']['ppsminpoll'] = $_POST['ppsminpoll']; + $config['ntpd']['pps']['ppsmaxpoll'] = $_POST['ppsmaxpoll']; write_config("Updated NTP PPS Settings"); @@ -101,7 +120,6 @@ if ($_POST) { init_config_arr(array('ntpd', 'pps')); $pconfig = &$config['ntpd']['pps']; - $pgtitle = array(gettext("Services"), gettext("NTP"), gettext("PPS")); $pglinks = array("", "services_ntpd.php", "@self"); $shortcut_section = "ntp"; @@ -167,6 +185,20 @@ $section->addInput(new Form_Input( $pconfig['stratum'] ))->setHelp('This may be used to change the PPS Clock stratum (default: 0). This may be useful to, for some reason, have ntpd prefer a different clock and just monitor this source.'); +$section->addInput(new Form_Select( + 'ppsminpoll', + 'Minimum Poll Interval', + $pconfig['ppsminpoll'], + $ntp_poll_values, +))->setHelp('Minimum poll interval for NTP messages. If set, must be less than or equal to Maximum Poll Interval.'); + +$section->addInput(new Form_Select( + 'ppsmaxpoll', + 'Maximum Poll Interval', + $pconfig['ppsmaxpoll'], + $ntp_poll_values, +))->setHelp('Maximum poll interval for NTP messages. If set, must be greater than or equal to Minimum Poll Interval.'); + $section->addInput(new Form_Checkbox( 'ppsflag2', 'Flags',