diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index b2e5b09ad0..f3ee29e37a 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -868,7 +868,7 @@ function interface_reset($interface, $ifacecfg = false, $suspend = false) case 'slaac': case 'dhcp6': interface_dhcpv6_prepare($interface, $ifcfg, true); - killbypid('/var/run/dhcp6c.pid', 'HUP'); + killbypid("/var/run/dhcp6c.{$device}.pid", 'HUP'); break; case 'idassoc6': case 'track6': @@ -2609,7 +2609,7 @@ function interface_track6_configure($interface, $lancfg, $reload = false) case 'dhcp6': if ($reload || !isset($lancfg['enable'])) { interface_dhcpv6_prepare($lancfg['track6-interface'], $trackcfg); - killbypid('/var/run/dhcp6c.pid', 'HUP'); + killbypid("/var/run/dhcp6c.{$trackcfg['if']}.pid", 'HUP'); } break; } @@ -2893,15 +2893,16 @@ function interface_dhcpv6_configure($interface, $wancfg) } /* always kill rtsold in case of reconfigure */ - killbypid('/var/run/rtsold.pid'); + killbypid("/var/run/rtsold.{$wancfg['if']}.pid"); @unlink("/tmp/rtsold.{$wancfg['if']}.done"); - $rtsold_frmt = ['/usr/sbin/rtsold -%s -aiu -p %s -A %s -R %s']; + $rtsold_frmt = ['/usr/sbin/rtsold -%s -iu -p %s -A %s -R %s %s']; $rtsold_args = [ $settings->dhcp6_debug->isEmpty() ? 'd' : 'D', - '/var/run/rtsold.pid', + "/var/run/rtsold.{$wancfg['if']}.pid", '/usr/local/opnsense/scripts/interfaces/rtsold_script.sh', '/usr/local/opnsense/scripts/interfaces/rtsold_resolvconf.sh', + $wancfg['if'], ]; /* fire up rtsold for IPv6 RAs first */ @@ -2917,28 +2918,6 @@ function interface_dhcpv6_configure($interface, $wancfg) } } -function interface_dhcpv6_id($interface) -{ - global $config; - - /* configuration default */ - $id = 0; - - if (empty($config['interfaces'])) { - return $id; - } - - /* detect unique index */ - foreach (array_keys($config['interfaces']) as $key) { - if ($key == $interface) { - break; - } - $id += 1; - } - - return $id; -} - function interface_dhcpv6_prepare($interface, $wancfg, $cleanup = false) { if (!is_array($wancfg)) { @@ -2946,7 +2925,6 @@ function interface_dhcpv6_prepare($interface, $wancfg, $cleanup = false) } $settings = new OPNsense\Interfaces\Settings(); - $id = interface_dhcpv6_id($interface); $device = $wancfg['if']; $dhcp6cconf = "# generated for {$interface} in {$wancfg['ipaddrv6']} mode\n"; @@ -2968,9 +2946,9 @@ function interface_dhcpv6_prepare($interface, $wancfg, $cleanup = false) log_msg("DHCP6 config file override does not exist: '{$dhcp6cfile}'", LOG_ERR); } } elseif (!empty($wancfg['adv_dhcp6_config_advanced'])) { - $dhcp6cconf .= DHCP6_Config_File_Advanced($interface, $wancfg, $device, $id); + $dhcp6cconf .= DHCP6_Config_File_Advanced($interface, $wancfg, $device); } else { - $dhcp6cconf .= DHCP6_Config_File_Basic($interface, $wancfg, $device, $id); + $dhcp6cconf .= DHCP6_Config_File_Basic($interface, $wancfg, $device); } if (!$cleanup) { @@ -2978,24 +2956,9 @@ function interface_dhcpv6_prepare($interface, $wancfg, $cleanup = false) } else { @unlink("/var/etc/dhcp6c.{$device}.conf"); } - - $dhcp6cconf = ''; - - /* merge configs and prepare single instance of dhcp6c for startup */ - foreach (legacy_config_get_interfaces(['enable' => true, 'virtual' => false]) as $_interface => $_wancfg) { - if (empty($_wancfg['ipaddrv6']) || ($_wancfg['ipaddrv6'] != 'dhcp6' && $_wancfg['ipaddrv6'] != 'slaac')) { - continue; - } - - if (file_exists("/var/etc/dhcp6c.{$_wancfg['if']}.conf")) { - $dhcp6cconf .= file_get_contents("/var/etc/dhcp6c.{$_wancfg['if']}.conf"); - } - } - - @file_put_contents('/var/etc/dhcp6c.conf', $dhcp6cconf); } -function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0) +function DHCP6_Config_File_Basic($interface, $wancfg, $wanif) { $dhcp6cconf = ''; @@ -3020,7 +2983,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0) } $pd_conf .= " };\n"; - /* XXX $id from dhcp6_assoc_pd */ + $id = strlen($wancfg['dhcp6_assoc_pd'] ?? '') ? $wancfg['dhcp6_assoc_pd'] : '0'; $assoc_pd[$id] = ($assoc_pd[$id] ?? '') . $pd_conf; } @@ -3035,25 +2998,26 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0) } $pd_conf .= " };\n"; - /* XXX $id from track6_assoc_pd */ + $id = strlen($lancfg['track6_assoc_pd'] ?? '') ? $lancfg['track6_assoc_pd'] : '0'; $assoc_pd[$id] = ($assoc_pd[$id] ?? '') . $pd_conf; } } + + if (!count($assoc_pd)) { + /* for backwards compatibility always emit a default PD request */ + $assoc_pd[0] = ''; + } } ksort($assoc_pd, SORT_NUMERIC); - /* for backwards compatibility always emit this PD request */ - if (!isset($assoc_pd[$id])) { - $assoc_pd[$id] = ''; - } - $dhcp6cconf .= "interface {$wanif} {\n"; if (!isset($wancfg['dhcp6prefixonly'])) { /* request non-temporary address */ - $dhcp6cconf .= " send ia-na {$id};\n"; + $dhcp6cconf .= " send ia-na 0;\n"; } + if (is_numeric($wancfg['dhcp6-ia-pd-len'])) { /* request prefix delegation */ foreach (array_keys($assoc_pd) as $id) { @@ -3074,7 +3038,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0) $dhcp6cconf .= "};\n"; if (!isset($wancfg['dhcp6prefixonly'])) { - $dhcp6cconf .= "id-assoc na {$id} { };\n"; + $dhcp6cconf .= "id-assoc na 0 { };\n"; } foreach ($assoc_pd as $i => $pd_conf) { @@ -3091,7 +3055,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0) return $dhcp6cconf; } -function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0) +function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif) { $send_options = ""; @@ -3133,7 +3097,7 @@ function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0) if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_address_id'])) { $id_assoc_statement_address .= "{$wancfg['adv_dhcp6_id_assoc_statement_address_id']}"; } else { - $id_assoc_statement_address .= $id; + $id_assoc_statement_address .= 0; /* only as a fallback */ } $id_assoc_statement_address .= " {\n"; @@ -3163,7 +3127,7 @@ function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0) if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_prefix_id'])) { $id_assoc_statement_prefix .= "{$wancfg['adv_dhcp6_id_assoc_statement_prefix_id']}"; } else { - $id_assoc_statement_prefix .= $id; + $id_assoc_statement_prefix .= 0; /* only as a fallback */ } $id_assoc_statement_prefix .= " {\n"; diff --git a/src/opnsense/scripts/interfaces/rtsold_script.sh b/src/opnsense/scripts/interfaces/rtsold_script.sh index f9e09a89ac..d87ac0f2e1 100755 --- a/src/opnsense/scripts/interfaces/rtsold_script.sh +++ b/src/opnsense/scripts/interfaces/rtsold_script.sh @@ -33,17 +33,17 @@ if [ -z "${IFNAME}" ]; then fi if grep -q "^interface ${IFNAME} " /var/etc/radvd.conf; then - /usr/bin/logger -t dhcp6c "rtsold_script: rejecting dhcp6c" + /usr/bin/logger -t dhcp6c "rtsold_script: rejecting dhcp6c on ${IFNAME}" echo "Rejecting own configuration." exit 0 fi +CONFFILE="/var/etc/dhcp6c.${IFNAME}.conf" +PIDFILE="/var/run/dhcp6c.${IFNAME}.pid" DONEFILE="/tmp/rtsold.${IFNAME}.done" -CONFFILE="/var/etc/dhcp6c.conf" -PIDFILE="/var/run/dhcp6c.pid" if [ ! -f "${CONFFILE}" ]; then - /usr/bin/logger -t dhcp6c "rtsold_script: skipping dhcp6c" + /usr/bin/logger -t dhcp6c "rtsold_script: skipping dhcp6c on ${IFNAME}" exit 0 fi @@ -74,10 +74,10 @@ if [ -f "${PIDFILE}" ]; then fi if [ -f "${PIDFILE}" ]; then - /usr/bin/logger -t dhcp6c "rtsold_script: reloading dhcp6c" + /usr/bin/logger -t dhcp6c "rtsold_script: reloading dhcp6c on ${IFNAME}" /bin/pkill -HUP -F "${PIDFILE}" else - /usr/bin/logger -t dhcp6c "rtsold_script: starting dhcp6c" + /usr/bin/logger -t dhcp6c "rtsold_script: starting dhcp6c on ${IFNAME}" /usr/local/sbin/dhcp6c $(get_var EXTRAOPTS) -c "${CONFFILE}" -p "${PIDFILE}" fi diff --git a/src/www/interfaces.php b/src/www/interfaces.php index 4bd4e3027b..7b83bf11ac 100644 --- a/src/www/interfaces.php +++ b/src/www/interfaces.php @@ -251,20 +251,31 @@ function validate_track6_idassoc6(&$pconfig, $if) if ($track6_prefix_id < 0 || $track6_prefix_id >= $ipv6_num_prefix_ids) { $input_errors[] = gettext("You specified an IPv6 prefix ID that is out of range."); } + $assoc_pd_ref = '0'; + if (!empty($pconfig["{$pconfig['type6']}_assoc_pd"]) && ctype_digit($pconfig["{$pconfig['type6']}_assoc_pd"])) { + $assoc_pd_ref = $pconfig["{$pconfig['type6']}_assoc_pd"]; + } foreach (link_interface_to_track6($pconfig["{$pconfig['type6']}-interface"]) as $trackif => $trackcfg) { - if ($trackif != $if && $trackcfg['track6-prefix-id'] == $track6_prefix_id) { + $assoc_pd_link = !empty($trackcfg['track6_assoc_pd']) ? $trackcfg['track6_assoc_pd'] : '0'; + if ($trackif != $if && $assoc_pd_ref == $assoc_pd_ref && $trackcfg['track6-prefix-id'] == $track6_prefix_id) { $input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.'); break; } } if (isset($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'])) { - if ($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'] == $track6_prefix_id) { + $assoc_pd_parent = !empty($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6_assoc_pd']) ? + $config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6_assoc_pd'] : '0'; + if ($assoc_pd_ref == $assoc_pd_parent && $config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'] == $track6_prefix_id) { $input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.'); } } } } + if (!empty($pconfig["{$pconfig['type6']}_assoc_pd"]) && !ctype_digit($pconfig["{$pconfig['type6']}_assoc_pd"])) { + $input_errors[] = gettext('You must enter a valid number for the IPv6 prefix association identity.'); + } + if (isset($pconfig["{$pconfig['type6']}_ifid--hex"]) && $pconfig["{$pconfig['type6']}_ifid--hex"] != '') { if (!ctype_xdigit($pconfig["{$pconfig['type6']}_ifid--hex"])) { $input_errors[] = gettext('You must enter a valid hexadecimal number for the IPv6 interface ID.'); @@ -298,6 +309,9 @@ function store_track6_idassoc6(&$new_config, &$pconfig) if (isset($pconfig["{$pconfig['type6']}_ifid--hex"]) && ctype_xdigit($pconfig["{$pconfig['type6']}_ifid--hex"])) { $new_config['track6_ifid'] = intval($pconfig["{$pconfig['type6']}_ifid--hex"], 16); } + if (!empty($pconfig["{$pconfig['type6']}_assoc_pd"])) { + $new_config['track6_assoc_pd'] = $pconfig["{$pconfig['type6']}_assoc_pd"]; + } if ($pconfig['type6'] == 'track6') { /* this is not needed in the new world */ $new_config['dhcpd6track6allowoverride'] = !empty($pconfig['dhcpd6track6allowoverride']); @@ -464,6 +478,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { 'dhcp6_ifid', 'dhcp6_norequest_dns', 'dhcp6_rapid_commit', + 'dhcp6_assoc_pd', 'dhcp6vlanprio', 'dhcphostname', 'dhcprejectfrom', @@ -491,6 +506,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { 'subnetv6', 'track6-interface', 'track6-prefix-id', + 'track6_assoc_pd', 'track6_ifid', ]; foreach ($std_copy_fieldnames as $fieldname) { @@ -512,7 +528,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $pconfig['dhcpd6track6allowoverride'] = isset($a_interfaces[$if]['dhcpd6track6allowoverride']); $pconfig['dhcp6_request_dns'] = empty($pconfig['dhcp6_norequest_dns']); - foreach(['-interface', '-prefix-id', '-prefix-id--hex', '_ifid', '_ifid--hex'] as $fieldname) { + foreach(['-interface', '-prefix-id', '-prefix-id--hex', '_assoc_pd', '_ifid', '_ifid--hex'] as $fieldname) { /* only for form consistency */ $pconfig["idassoc6{$fieldname}"] = $pconfig["track6{$fieldname}"]; } @@ -750,14 +766,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $input_errors[] = gettext("You specified an IPv6 prefix ID that is out of range."); } } + $assoc_pd_ref = '0'; + if (!empty($pconfig['dhcp6_assoc_pd']) && ctype_digit($pconfig['dhcp6_assoc_pd'])) { + $assoc_pd_ref = $pconfig['dhcp6_assoc_pd']; + } foreach (link_interface_to_track6($pconfig['track6-interface']) as $trackif => $trackcfg) { - if ($trackcfg['track6-prefix-id'] == $dhcp6_prefix_id) { + $assoc_pd_link = !empty($trackcfg['track6_assoc_pd']) ? $trackcfg['track6_assoc_pd'] : '0'; + if ($assoc_pd_ref == $assoc_pd_link && $trackcfg['track6-prefix-id'] == $dhcp6_prefix_id) { $input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.'); break; } } } } + if (!empty($pconfig['dhcp6_assoc_pd']) && !ctype_digit($pconfig['dhcp6_assoc_pd'])) { + $input_errors[] = gettext('You must enter a valid number for the IPv6 prefix association identity.'); + } if (isset($pconfig['dhcp6_ifid--hex']) && $pconfig['dhcp6_ifid--hex'] != '') { if (!ctype_xdigit($pconfig['dhcp6_ifid--hex'])) { $input_errors[] = gettext('You must enter a valid hexadecimal number for the IPv6 interface ID.'); @@ -1123,6 +1147,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (!empty($pconfig['dhcp6_rapid_commit'])) { $new_config['dhcp6_rapid_commit'] = true; } + if (!empty($pconfig['dhcp6_assoc_pd'])) { + $new_config['dhcp6_assoc_pd'] = $pconfig['dhcp6_assoc_pd']; + } $new_config['adv_dhcp6_interface_statement_send_options'] = $pconfig['adv_dhcp6_interface_statement_send_options']; $new_config['adv_dhcp6_interface_statement_request_options'] = $pconfig['adv_dhcp6_interface_statement_request_options']; $new_config['adv_dhcp6_interface_statement_information_only_enable'] = $pconfig['adv_dhcp6_interface_statement_information_only_enable']; @@ -2390,6 +2417,15 @@ include("head.inc"); + + + + + + + @@ -2619,6 +2655,15 @@ include("head.inc"); + + + + + + + @@ -2675,6 +2720,15 @@ include("head.inc"); + + + + + + +