mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 00:07:26 +00:00
Services: ISC DHCPv6 - show "tracking" interfaces when enabled and offer an explicit disable (#8576)
* Services: ISC DHCPv6 - show "tracking" interfaces when enabled an offer an explicit disable option for the service in question so someone could use dnsmasq or kea instead. To avoid large changes, we opt for a minimal set here. In services_dhcpv6.php, we add a separate form and handler in case tracking (without dhcpd6track6allowoverride) is set, which either flushes the unused isc-dhcpv6 server configuration when enabled (default) or writes a small section only including ['enabled' => -1]. For visibility, we show the calculated range as would be set by dhcpd_dhcp6_configure() when tracking is used. The backend code then double checks the services which er explicitly disabled (-1) and skip processing for these (not enabled). In order to make people aware of the fact that an isc-dhcpv6 server could be running, make sure the menu system also reflects reality. Since router advertisements are stored within the same container and will need a toggle as well, keep the value of ramode so we have a way to intervene in a similar way as for dhcpv6. One small side affect of this commit is that it will show "Services: Router Advertisements" for the tracking interface, which we need to implement later. One of the building blocks for: https://github.com/opnsense/core/issues/8528 * Update src/www/services_dhcpv6.php Co-authored-by: Franco Fichtner <franco@opnsense.org> * Services: Router Advertisements: show "tracking" interfaces when enabled an offer an explicit disable option for the service in question so someone could use dnsmasq instead. More or less the same construction as added for dhcpv6, using the ramode field to switch between types (disabled or assisted). While here, also bugfix fieldname in services_dhcpv6.php also for https://github.com/opnsense/core/issues/8528 --------- Co-authored-by: Franco Fichtner <franco@opnsense.org>
This commit is contained in:
parent
3280916191
commit
727967ed6d
@ -47,16 +47,23 @@ function dhcpd_run()
|
||||
function dhcpd_dhcpv6_enabled()
|
||||
{
|
||||
global $config;
|
||||
$explicit_off = [];
|
||||
|
||||
/* handle manually configured DHCP6 server settings first */
|
||||
foreach (config_read_array('dhcpdv6') as $dhcpv6if => $dhcpv6ifconf) {
|
||||
if (isset($config['interfaces'][$dhcpv6if]['enable']) && isset($dhcpv6ifconf['enable'])) {
|
||||
return true;
|
||||
if ($dhcpv6ifconf['enable'] == '-1') {
|
||||
$explicit_off[] = $dhcpv6if;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifcfg) {
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifnm => $ifcfg) {
|
||||
if (in_array($ifnm, $explicit_off)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface']) && !isset($ifcfg['dhcpd6track6allowoverride'])) {
|
||||
return true;
|
||||
}
|
||||
@ -864,8 +871,12 @@ function dhcpd_dhcp6_configure($verbose = false, $blacklist = [])
|
||||
|
||||
if (!isset($config['interfaces'][$ifname]['dhcpd6track6allowoverride'])) {
|
||||
/* mock a real server */
|
||||
$dhcpdv6cfg[$ifname] = array();
|
||||
$dhcpdv6cfg[$ifname]['enable'] = true;
|
||||
if (!empty($dhcpdv6cfg[$ifname]) && $dhcpdv6cfg[$ifname]['enable'] == '-1') {
|
||||
/* tracking, but dhcpv6 disabled */
|
||||
$dhcpdv6cfg[$ifname] = [];
|
||||
} else {
|
||||
$dhcpdv6cfg[$ifname] = ['enable' => true];
|
||||
}
|
||||
|
||||
/* fixed range */
|
||||
$ifcfgipv6arr[7] = '1000';
|
||||
|
||||
@ -40,16 +40,21 @@ function radvd_configure()
|
||||
function radvd_enabled()
|
||||
{
|
||||
global $config;
|
||||
$explicit_off = [];
|
||||
|
||||
/* handle manually configured DHCP6 server settings first */
|
||||
foreach (config_read_array('dhcpdv6') as $dhcpv6if => $dhcpv6ifconf) {
|
||||
if (isset($config['interfaces'][$dhcpv6if]['enable']) && isset($dhcpv6ifconf['ramode']) && $dhcpv6ifconf['ramode'] != 'disabled') {
|
||||
return true;
|
||||
} elseif (isset($dhcpv6ifconf['ramode']) && $dhcpv6ifconf['ramode'] == 'disabled') {
|
||||
$explicit_off[] = $dhcpv6if;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifcfg) {
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifnm => $ifcfg) {
|
||||
if (in_array($ifnm, $explicit_off)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface']) && !isset($ifcfg['dhcpd6track6allowoverride'])) {
|
||||
return true;
|
||||
}
|
||||
@ -349,6 +354,9 @@ function radvd_configure_do($verbose = false, $blacklist = [])
|
||||
} elseif (isset($blacklist[$if])) {
|
||||
$radvdconf .= "# Skipping blacklisted interface {$if}\n";
|
||||
continue;
|
||||
} elseif (!empty($config['dhcpdv6'][$if]) && !empty($config['dhcpdv6'][$if]['ramode']) && $config['dhcpdv6'][$if]['ramode'] == 'disabled') {
|
||||
$radvdconf .= "# Skipping explicit disabled interface {$if}\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$trackif = $config['interfaces'][$if]['track6-interface'];
|
||||
|
||||
@ -265,7 +265,7 @@ class MenuSystem
|
||||
) {
|
||||
$iftargets['dhcp4'][$key] = !empty($node->descr) ? (string)$node->descr : strtoupper($key);
|
||||
}
|
||||
if (!empty(filter_var($node->ipaddrv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) || !empty($node->dhcpd6track6allowoverride)) {
|
||||
if (!empty(filter_var($node->ipaddrv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) || !empty($node->{'track6-interface'})) {
|
||||
$iftargets['dhcp6'][$key] = !empty($node->descr) ? (string)$node->descr : strtoupper($key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2022 Deciso B.V.
|
||||
* Copyright (C) 2014-2025 Deciso B.V.
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* Copyright (C) 2010 Seth Mos <seth.mos@dds.nl>
|
||||
* All rights reserved.
|
||||
@ -34,6 +34,104 @@ require_once("system.inc");
|
||||
require_once("interfaces.inc");
|
||||
require_once("plugins.inc.d/dhcpd.inc");
|
||||
|
||||
|
||||
function show_track6_form($if)
|
||||
{
|
||||
global $config;
|
||||
$service_hook = 'dhcpd6';
|
||||
include("head.inc");
|
||||
include("fbegin.inc");
|
||||
$enable_label = gettext("Enable");
|
||||
$range_label = gettext("Range");
|
||||
$enable_descr = sprintf(gettext("Enable DHCPv6 server on " . "%s " ."interface"),!empty($config['interfaces'][$if]['descr']) ? htmlspecialchars($config['interfaces'][$if]['descr']) : strtoupper($if));
|
||||
$enable_input = 'checked="checked"';
|
||||
$save_btn_text = html_safe(gettext('Save'));
|
||||
/* calculated "fixed" range */
|
||||
list ($ifcfgipv6) = interfaces_primary_address6($if, legacy_interfaces_details());
|
||||
$range = ['from' => '?', 'to' => '?'];
|
||||
if (is_ipaddrv6($ifcfgipv6)) {
|
||||
$ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64);
|
||||
$ifcfgipv6arr = explode(':', $ifcfgipv6);
|
||||
$ifcfgipv6arr[7] = '1000';
|
||||
$range['from'] = Net_IPv6::compress(implode(':', $ifcfgipv6arr));
|
||||
$ifcfgipv6arr[7] = '2000';
|
||||
$range['to'] = Net_IPv6::compress(implode(':', $ifcfgipv6arr));
|
||||
}
|
||||
|
||||
if (!empty($config['dhcpdv6']) && !empty($config['dhcpdv6'][$if]) && isset($config['dhcpdv6'][$if]['enable']) && $config['dhcpdv6'][$if]['enable'] == '-1') {
|
||||
/* disabled */
|
||||
$enable_input = '';
|
||||
}
|
||||
|
||||
$range_tr = <<<EOD
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> $range_label</td>
|
||||
<td>{$range['from']} - {$range['to']}</td>
|
||||
</tr>
|
||||
EOD;
|
||||
|
||||
|
||||
echo <<<EOD
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped opnsense_standard_table_form">
|
||||
<tr>
|
||||
<td style="width:22%"></td>
|
||||
<td style="width:78%; text-align:right">
|
||||
<div style='height: 15px;'></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> $enable_label</td>
|
||||
<td>
|
||||
<input name="enable" type="checkbox" value="yes" $enable_input/>
|
||||
<strong>$enable_descr</strong>
|
||||
</td>
|
||||
$range_tr
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input name="if" type="hidden" value="$if" />
|
||||
<input name="submit" type="submit" class="formbtn btn btn-primary" value="$save_btn_text"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
EOD;
|
||||
include("foot.inc");
|
||||
}
|
||||
|
||||
function process_track6_form($if)
|
||||
{
|
||||
$dhcpdv6cfg = &config_read_array('dhcpdv6');
|
||||
$this_server = [];
|
||||
if (isset($dhcpdv6cfg[$if]) && isset($dhcpdv6cfg[$if]['ramode'])) {
|
||||
/* keep ramode for router advertisements so we can use this field to disable the service when in tracking mode */
|
||||
$this_server['ramode'] = $dhcpdv6cfg[$if]['ramode'];
|
||||
}
|
||||
if (empty($_POST['enable'])) {
|
||||
$this_server['enable'] = '-1';
|
||||
}
|
||||
$dhcpdv6cfg[$if] = $this_server;
|
||||
write_config();
|
||||
reconfigure_dhcpd();
|
||||
filter_configure();
|
||||
header(url_safe('Location: /services_dhcpv6.php?if=%s', array($if)));
|
||||
}
|
||||
|
||||
|
||||
function reconfigure_dhcpd()
|
||||
{
|
||||
system_resolver_configure();
|
||||
@ -41,17 +139,15 @@ function reconfigure_dhcpd()
|
||||
clear_subsystem_dirty('staticmapsv6');
|
||||
}
|
||||
|
||||
$if = null;
|
||||
$act = null;
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// handle identifiers and action
|
||||
if (!empty($_GET['if']) && !empty($config['interfaces'][$_GET['if']]) &&
|
||||
isset($config['interfaces'][$_GET['if']]['enable']) &&
|
||||
(is_ipaddr($config['interfaces'][$_GET['if']]['ipaddrv6']) ||
|
||||
!empty($config['interfaces'][$_GET['if']]['dhcpd6track6allowoverride']))) {
|
||||
!empty($config['interfaces'][$_GET['if']]['track6-interface']))) {
|
||||
$if = $_GET['if'];
|
||||
} else {
|
||||
/* if no interface is provided this invoke is invalid */
|
||||
header(url_safe('Location: /index.php'));
|
||||
exit;
|
||||
}
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// handle identifiers and actions
|
||||
@ -60,11 +156,28 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
if (!empty($_POST['act'])) {
|
||||
$act = $_POST['act'];
|
||||
} else {
|
||||
$act = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX: In case of tracking, show different form and only handle on/off options.
|
||||
* this code injection is intended to keep changes as minimal as possible and avoid regressions on existing isc-dhcp6 installs,
|
||||
* while showing current state for tracking interfaces.
|
||||
**/
|
||||
if ($if === null) {
|
||||
/* if no interface is provided this invoke is invalid */
|
||||
header(url_safe('Location: /index.php'));
|
||||
exit;
|
||||
} elseif (!empty($config['interfaces'][$if]['track6-interface']) && !isset($config['interfaces'][$if]['dhcpd6track6allowoverride'])) {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
show_track6_form($if);
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
process_track6_form($if);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
/* default form processing */
|
||||
|
||||
$ifcfgip = $config['interfaces'][$if]['ipaddrv6'];
|
||||
$ifcfgsn = $config['interfaces'][$if]['subnetv6'];
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2022 Franco Fichtner <franco@opnsense.org>
|
||||
* Copyright (C) 2014-2016 Deciso B.V.
|
||||
* Copyright (C) 2014-2025 Deciso B.V.
|
||||
* Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>
|
||||
* Copyright (C) 2010 Seth Mos <seth.mos@dds.nl>
|
||||
* All rights reserved.
|
||||
@ -37,6 +37,108 @@ function val_int_in_range($value, $min, $max) {
|
||||
return (((string)(int)$value) == $value) && $value >= $min && $value <= $max;
|
||||
}
|
||||
|
||||
function show_track6_form($if)
|
||||
{
|
||||
global $config;
|
||||
$service_hook = 'radvd';
|
||||
include("head.inc");
|
||||
include("fbegin.inc");
|
||||
|
||||
$ra_label = gettext('Router Advertisements');
|
||||
$save_btn_text = html_safe(gettext('Save'));
|
||||
|
||||
if (!empty($config['dhcpdv6']) && !empty($config['dhcpdv6'][$if]) && isset($config['dhcpdv6'][$if]['ramode']) && $config['dhcpdv6'][$if]['ramode'] == 'disabled') {
|
||||
/* disabled */
|
||||
$options = "<option value=''>" . gettext('Assisted') . "</option>\n";
|
||||
$options .= "<option value='disabled' selected='selected'>" . gettext('Disabled') . "</option>";
|
||||
} else {
|
||||
$options = "<option value='' selected='selected'>" . gettext('Assisted') . "</option>\n";
|
||||
$options .= "<option value='disabled'>" . gettext('Disabled') . "</option>";
|
||||
}
|
||||
|
||||
echo <<<EOD
|
||||
<section class="page-content-main">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<section class="col-xs-12">
|
||||
<div class="tab-content content-box col-xs-12">
|
||||
<form method="post" name="iform" id="iform">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped opnsense_standard_table_form">
|
||||
<tr>
|
||||
<td style="width:22%"></td>
|
||||
<td style="width:78%; text-align:right">
|
||||
<div style='height: 15px;'></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-info-circle text-muted"></i> $ra_label</td>
|
||||
<td>
|
||||
<select name='ramode' class='selectpicker'>$options</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input name="if" type="hidden" value="$if" />
|
||||
<input name="submit" type="submit" class="formbtn btn btn-primary" value="$save_btn_text"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
EOD;
|
||||
|
||||
include("foot.inc");
|
||||
}
|
||||
|
||||
function process_track6_form($if)
|
||||
{
|
||||
$dhcpdv6cfg = &config_read_array('dhcpdv6');
|
||||
$this_server = [];
|
||||
if (isset($dhcpdv6cfg[$if]) && isset($dhcpdv6cfg[$if]['enable'])) {
|
||||
/* keep enable for dhcpv6 so we can use this field to disable the service when in tracking mode */
|
||||
$this_server['enable'] = $dhcpdv6cfg[$if]['enable'];
|
||||
}
|
||||
if (!empty($_POST['ramode'])) {
|
||||
$this_server['ramode'] = 'disabled';
|
||||
}
|
||||
$dhcpdv6cfg[$if] = $this_server;
|
||||
write_config();
|
||||
radvd_configure_do();
|
||||
header(url_safe('Location: /services_router_advertisements.php?if=%s', array($if)));
|
||||
}
|
||||
|
||||
$if = null;
|
||||
if (!empty($_REQUEST['if']) && !empty($config['interfaces'][$_REQUEST['if']])) {
|
||||
$if = $_REQUEST['if'];
|
||||
} else {
|
||||
/* if no interface is provided this invoke is invalid */
|
||||
header(url_safe('Location: /index.php'));
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX: In case of tracking, show different form and only handle on/off options.
|
||||
* this code injection is intended to keep changes as minimal as possible and avoid regressions on existing isc-dhcp6 installs,
|
||||
* while showing current state for tracking interfaces.
|
||||
**/
|
||||
if (!empty($config['interfaces'][$if]) && !empty($config['interfaces'][$if]['track6-interface']) && !isset($config['interfaces'][$if]['dhcpd6track6allowoverride'])) {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
show_track6_form($if);
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
process_track6_form($if);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
/* default form processing */
|
||||
|
||||
|
||||
$advanced_options = [
|
||||
'AdvDefaultLifetime',
|
||||
'AdvValidLifetime',
|
||||
@ -50,14 +152,6 @@ $advanced_options = [
|
||||
];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (!empty($_GET['if']) && !empty($config['interfaces'][$_GET['if']])) {
|
||||
$if = $_GET['if'];
|
||||
} else {
|
||||
/* if no interface is provided this invoke is invalid */
|
||||
header(url_safe('Location: /index.php'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$pconfig = array();
|
||||
$config_copy_fieldsnames = array('ramode', 'rapriority', 'rainterface', 'ramininterval', 'ramaxinterval', 'radomainsearchlist');
|
||||
$config_copy_fieldsnames = array_merge($advanced_options, $config_copy_fieldsnames);
|
||||
@ -93,10 +187,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$pconfig['raroutes'] = array();
|
||||
}
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!empty($_POST['if']) && !empty($config['interfaces'][$_POST['if']])) {
|
||||
$if = $_POST['if'];
|
||||
}
|
||||
|
||||
/* input validation */
|
||||
$input_errors = array();
|
||||
$pconfig = $_POST;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user