Skip to content

Commit 91093f3

Browse files
committed
interfaces: IAID selection and prefix range reservation #7647
1 parent 76ed1ef commit 91093f3

2 files changed

Lines changed: 117 additions & 19 deletions

File tree

src/etc/inc/interfaces.inc

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,7 +2970,7 @@ function interface_dhcpv6_prepare($interface, $wancfg, $cleanup = false)
29702970
@file_put_contents('/var/etc/dhcp6c.conf', $dhcp6cconf);
29712971
}
29722972

2973-
function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0)
2973+
function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $default_id)
29742974
{
29752975
$dhcp6cconf = '';
29762976

@@ -2995,7 +2995,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0)
29952995
}
29962996
$pd_conf .= " };\n";
29972997

2998-
/* XXX $id from dhcp6_assoc_pd */
2998+
$id = strlen($wancfg['dhcp6_assoc_pd'] ?? '') ? $wancfg['dhcp6_assoc_pd'] : $default_id;
29992999
$assoc_pd[$id] = ($assoc_pd[$id] ?? '') . $pd_conf;
30003000
}
30013001

@@ -3010,25 +3010,26 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0)
30103010
}
30113011
$pd_conf .= " };\n";
30123012

3013-
/* XXX $id from track6_assoc_pd */
3013+
$id = strlen($lancfg['track6_assoc_pd'] ?? '') ? $lancfg['track6_assoc_pd'] : $default_id;
30143014
$assoc_pd[$id] = ($assoc_pd[$id] ?? '') . $pd_conf;
30153015
}
30163016
}
3017-
}
30183017

3019-
ksort($assoc_pd, SORT_NUMERIC);
3018+
if (!count($assoc_pd)) {
3019+
/* for backwards compatibility always emit a default PD request */
3020+
$assoc_pd[$default_id] = '';
3021+
}
30203022

3021-
/* for backwards compatibility always emit this PD request */
3022-
if (!isset($assoc_pd[$id])) {
3023-
$assoc_pd[$id] = '';
3023+
ksort($assoc_pd, SORT_NUMERIC);
30243024
}
30253025

30263026
$dhcp6cconf .= "interface {$wanif} {\n";
30273027

30283028
if (!isset($wancfg['dhcp6prefixonly'])) {
30293029
/* request non-temporary address */
3030-
$dhcp6cconf .= " send ia-na {$id};\n";
3030+
$dhcp6cconf .= " send ia-na {$default_id};\n";
30313031
}
3032+
30323033
if (is_numeric($wancfg['dhcp6-ia-pd-len'])) {
30333034
/* request prefix delegation */
30343035
foreach (array_keys($assoc_pd) as $id) {
@@ -3049,7 +3050,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0)
30493050
$dhcp6cconf .= "};\n";
30503051

30513052
if (!isset($wancfg['dhcp6prefixonly'])) {
3052-
$dhcp6cconf .= "id-assoc na {$id} { };\n";
3053+
$dhcp6cconf .= "id-assoc na {$default_id} { };\n";
30533054
}
30543055

30553056
foreach ($assoc_pd as $i => $pd_conf) {
@@ -3066,7 +3067,7 @@ function DHCP6_Config_File_Basic($interface, $wancfg, $wanif, $id = 0)
30663067
return $dhcp6cconf;
30673068
}
30683069

3069-
function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0)
3070+
function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $default_id)
30703071
{
30713072
$send_options = "";
30723073

@@ -3108,7 +3109,7 @@ function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0)
31083109
if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_address_id'])) {
31093110
$id_assoc_statement_address .= "{$wancfg['adv_dhcp6_id_assoc_statement_address_id']}";
31103111
} else {
3111-
$id_assoc_statement_address .= $id;
3112+
$id_assoc_statement_address .= $default_id;
31123113
}
31133114
$id_assoc_statement_address .= " {\n";
31143115

@@ -3138,7 +3139,7 @@ function DHCP6_Config_File_Advanced($interface, $wancfg, $wanif, $id = 0)
31383139
if (is_numeric($wancfg['adv_dhcp6_id_assoc_statement_prefix_id'])) {
31393140
$id_assoc_statement_prefix .= "{$wancfg['adv_dhcp6_id_assoc_statement_prefix_id']}";
31403141
} else {
3141-
$id_assoc_statement_prefix .= $id;
3142+
$id_assoc_statement_prefix .= $default_id;
31423143
}
31433144
$id_assoc_statement_prefix .= " {\n";
31443145

src/www/interfaces.php

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,23 +248,54 @@ function validate_track6_idassoc6(&$pconfig, $if)
248248
if ($ipv6_delegation_length >= 0) {
249249
$ipv6_num_prefix_ids = pow(2, $ipv6_delegation_length);
250250
$track6_prefix_id = intval($pconfig["{$pconfig['type6']}-prefix-id--hex"], 16);
251+
$track6_prefix_range = $pconfig["{$pconfig['type6']}_prefix_range"];
251252
if ($track6_prefix_id < 0 || $track6_prefix_id >= $ipv6_num_prefix_ids) {
252253
$input_errors[] = gettext("You specified an IPv6 prefix ID that is out of range.");
254+
} elseif (strlen($track6_prefix_range)) {
255+
if (!ctype_digit($track6_prefix_range)) {
256+
$input_errors[] = gettext("You specified an IPv6 prefix range that is not valid.");
257+
} elseif ($track6_prefix_range < 1 || $track6_prefix_id + $track6_prefix_range > $ipv6_num_prefix_ids) {
258+
$input_errors[] = gettext("You specified an IPv6 prefix range that is out of range.");
259+
}
253260
}
261+
$default_id = interface_dhcpv6_id($pconfig["{$pconfig['type6']}-interface"]);
262+
$assoc_pd_ref = !empty($pconfig["{$pconfig['type6']}_assoc_pd"]) && ctype_digit($pconfig["{$pconfig['type6']}_assoc_pd"]) ?
263+
$pconfig["{$pconfig['type6']}_assoc_pd"] : $default_id;
254264
foreach (link_interface_to_track6($pconfig["{$pconfig['type6']}-interface"]) as $trackif => $trackcfg) {
255-
if ($trackif != $if && $trackcfg['track6-prefix-id'] == $track6_prefix_id) {
265+
if ($trackif == $if) {
266+
continue;
267+
}
268+
$assoc_pd_link = !empty($trackcfg['track6_assoc_pd']) ? $trackcfg['track6_assoc_pd'] : $default_id;
269+
if ($assoc_pd_ref != $assoc_pd_ref) {
270+
continue;
271+
}
272+
/* the end of non-overlapping intervals needs to specify 0 ... n-1 */
273+
$track6_range_end = !empty($track6_prefix_range) ? $track6_prefix_range - 1 : 0;
274+
$track6_range_end += $track6_prefix_id;
275+
$range_end_link = !empty($trackcfg['track6_prefix_range']) ? $trackcfg['track6_prefix_range'] - 1 : 0;
276+
$range_end_link += $trackcfg['track6-prefix-id'];
277+
if ($trackcfg['track6-prefix-id'] == $track6_prefix_id) {
256278
$input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.');
257279
break;
280+
} elseif ($trackcfg['track6-prefix-id'] <= $track6_range_end && $track6_prefix_id <= $range_end_link) {
281+
$input_errors[] = gettext('You specified an IPv6 prefix range that is already in use.');
282+
break;
258283
}
259284
}
260285
if (isset($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'])) {
261-
if ($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'] == $track6_prefix_id) {
286+
$assoc_pd_parent = !empty($config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6_assoc_pd']) ?
287+
$config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6_assoc_pd'] : $default_id;
288+
if ($assoc_pd_ref == $assoc_pd_parent && $config['interfaces'][$pconfig["{$pconfig['type6']}-interface"]]['dhcp6-prefix-id'] == $track6_prefix_id) {
262289
$input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.');
263290
}
264291
}
265292
}
266293
}
267294

295+
if (!empty($pconfig["{$pconfig['type6']}_assoc_pd"]) && !ctype_digit($pconfig["{$pconfig['type6']}_assoc_pd"])) {
296+
$input_errors[] = gettext('You must enter a valid number for the IPv6 prefix association identity.');
297+
}
298+
268299
if (isset($pconfig["{$pconfig['type6']}_ifid--hex"]) && $pconfig["{$pconfig['type6']}_ifid--hex"] != '') {
269300
if (!ctype_xdigit($pconfig["{$pconfig['type6']}_ifid--hex"])) {
270301
$input_errors[] = gettext('You must enter a valid hexadecimal number for the IPv6 interface ID.');
@@ -298,6 +329,12 @@ function store_track6_idassoc6(&$new_config, &$pconfig)
298329
if (isset($pconfig["{$pconfig['type6']}_ifid--hex"]) && ctype_xdigit($pconfig["{$pconfig['type6']}_ifid--hex"])) {
299330
$new_config['track6_ifid'] = intval($pconfig["{$pconfig['type6']}_ifid--hex"], 16);
300331
}
332+
if (!empty($pconfig["{$pconfig['type6']}_prefix_range"])) {
333+
$new_config['track6_prefix_range'] = $pconfig["{$pconfig['type6']}_prefix_range"];
334+
}
335+
if (!empty($pconfig["{$pconfig['type6']}_assoc_pd"])) {
336+
$new_config['track6_assoc_pd'] = $pconfig["{$pconfig['type6']}_assoc_pd"];
337+
}
301338
if ($pconfig['type6'] == 'track6') {
302339
/* this is not needed in the new world */
303340
$new_config['dhcpd6track6allowoverride'] = !empty($pconfig['dhcpd6track6allowoverride']);
@@ -461,6 +498,7 @@ function get_wireless_channel_info($interface)
461498
'dhcp6_ifid',
462499
'dhcp6_norequest_dns',
463500
'dhcp6_rapid_commit',
501+
'dhcp6_assoc_pd',
464502
'dhcp6vlanprio',
465503
'dhcphostname',
466504
'dhcprejectfrom',
@@ -488,7 +526,9 @@ function get_wireless_channel_info($interface)
488526
'subnetv6',
489527
'track6-interface',
490528
'track6-prefix-id',
529+
'track6_assoc_pd',
491530
'track6_ifid',
531+
'track6_prefix_range',
492532
];
493533
foreach ($std_copy_fieldnames as $fieldname) {
494534
$pconfig[$fieldname] = isset($a_interfaces[$if][$fieldname]) ? $a_interfaces[$if][$fieldname] : null;
@@ -509,7 +549,7 @@ function get_wireless_channel_info($interface)
509549
$pconfig['dhcpd6track6allowoverride'] = isset($a_interfaces[$if]['dhcpd6track6allowoverride']);
510550
$pconfig['dhcp6_request_dns'] = empty($pconfig['dhcp6_norequest_dns']);
511551

512-
foreach(['-interface', '-prefix-id', '-prefix-id--hex', '_ifid', '_ifid--hex'] as $fieldname) {
552+
foreach(['-interface', '-prefix-id', '-prefix-id--hex', '_assoc_pd', '_ifid', '_ifid--hex', '_prefix_range'] as $fieldname) {
513553
/* only for form consistency */
514554
$pconfig["idassoc6{$fieldname}"] = $pconfig["track6{$fieldname}"];
515555
}
@@ -747,14 +787,21 @@ interface_sync_wireless_clones($a_interfaces[$if], false);
747787
$input_errors[] = gettext("You specified an IPv6 prefix ID that is out of range.");
748788
}
749789
}
790+
$default_id = interface_dhcpv6_id($if);
791+
$assoc_pd_ref = !empty($pconfig['dhcp6_assoc_pd']) && ctype_digit($pconfig['dhcp6_assoc_pd']) ?
792+
$pconfig['dhcp6_assoc_pd'] : $default_id;
750793
foreach (link_interface_to_track6($pconfig['track6-interface']) as $trackif => $trackcfg) {
751-
if ($trackcfg['track6-prefix-id'] == $dhcp6_prefix_id) {
794+
$assoc_pd_link = !empty($trackcfg['track6_assoc_pd']) ? $trackcfg['track6_assoc_pd'] : $default_id;
795+
if ($assoc_pd_ref == $assoc_pd_link && $trackcfg['track6-prefix-id'] == $dhcp6_prefix_id) {
752796
$input_errors[] = gettext('You specified an IPv6 prefix ID that is already in use.');
753797
break;
754798
}
755799
}
756800
}
757801
}
802+
if (!empty($pconfig['dhcp6_assoc_pd']) && !ctype_digit($pconfig['dhcp6_assoc_pd'])) {
803+
$input_errors[] = gettext('You must enter a valid number for the IPv6 prefix association identity.');
804+
}
758805
if (isset($pconfig['dhcp6_ifid--hex']) && $pconfig['dhcp6_ifid--hex'] != '') {
759806
if (!ctype_xdigit($pconfig['dhcp6_ifid--hex'])) {
760807
$input_errors[] = gettext('You must enter a valid hexadecimal number for the IPv6 interface ID.');
@@ -1123,6 +1170,9 @@ interface_sync_wireless_clones($a_interfaces[$if], false);
11231170
if (!empty($pconfig['dhcp6_rapid_commit'])) {
11241171
$new_config['dhcp6_rapid_commit'] = true;
11251172
}
1173+
if (!empty($pconfig['dhcp6_assoc_pd'])) {
1174+
$new_config['dhcp6_assoc_pd'] = $pconfig['dhcp6_assoc_pd'];
1175+
}
11261176
$new_config['adv_dhcp6_interface_statement_send_options'] = $pconfig['adv_dhcp6_interface_statement_send_options'];
11271177
$new_config['adv_dhcp6_interface_statement_request_options'] = $pconfig['adv_dhcp6_interface_statement_request_options'];
11281178
$new_config['adv_dhcp6_interface_statement_information_only_enable'] = $pconfig['adv_dhcp6_interface_statement_information_only_enable'];
@@ -1809,7 +1859,7 @@ function toggle_wirelesscfg() {
18091859
<option value=""><?=gettext('Default (no preference, typically autoselect)');?></option>
18101860
<?php
18111861
foreach($mediaopts_list as $mediaopt):?>
1812-
<option value="<?=$mediaopt;?>" <?=$mediaopt == trim($pconfig['media'] . " ". $pconfig['mediaopt']) ? "selected=\"selected\"" : "";?> >
1862+
<option value="<?=$mediaopt;?>" <?=!empty($pconfig['media']) && $mediaopt == trim($pconfig['media'] . " ". $pconfig['mediaopt']) ? "selected=\"selected\"" : "";?> >
18131863
<?=$mediaopt;?>
18141864
</option>
18151865
<?php
@@ -2390,6 +2440,15 @@ function toggle_wirelesscfg() {
23902440
</div>
23912441
</td>
23922442
</tr>
2443+
<tr class="dhcpv6_basic">
2444+
<td><a id="help_for_dhcp6_assoc_pd" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Optional prefix IAID') ?></td>
2445+
<td>
2446+
<input name="dhcp6_assoc_pd" type="text" id="dhcp6_assoc_pd" placeholder="<?= html_safe(interface_dhcpv6_id($if)) ?>" value="<?= html_safe($pconfig['dhcp6_assoc_pd']) ?>" />
2447+
<div class="hidden" data-for="help_for_dhcp6_assoc_pd">
2448+
<?= gettext('The ID to use for prefix request identity association if required to be non-standard.') ?>
2449+
</div>
2450+
</td>
2451+
</tr>
23932452
<tr class="dhcpv6_advanced">
23942453
<td><a id="help_for_dhcp6_intf_stmt" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Interface Statement");?></td>
23952454
<td>
@@ -2607,6 +2666,16 @@ function toggle_wirelesscfg() {
26072666
</div>
26082667
</td>
26092668
</tr>
2669+
<tr>
2670+
<td><a id="help_for_idassoc6_prefix_range" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Reserved prefix range') ?></td>
2671+
<td>
2672+
<input name="idassoc6_prefix_range" type="text" class="form-control" id="idassoc6_prefix_range" placeholder="1" value="<?= $pconfig['idassoc6_prefix_range'] ?>" />
2673+
</div>
2674+
<div class="hidden" data-for="help_for_idassoc6_prefix_range">
2675+
<?= gettext('The value in this field is the length of the reserved prefix range for downstream prefix delegation. The range starts at the given prefix ID. The default is to only reserve the given prefix ID.') ?>
2676+
</div>
2677+
</td>
2678+
</tr>
26102679
<tr>
26112680
<td><a id="help_for_idassoc6_ifid" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Optional interface ID') ?></td>
26122681
<td>
@@ -2619,6 +2688,15 @@ function toggle_wirelesscfg() {
26192688
</div>
26202689
</td>
26212690
</tr>
2691+
<tr>
2692+
<td><a id="help_for_idassoc6_assoc_pd" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Optional prefix IAID') ?></td>
2693+
<td>
2694+
<input name="idassoc6_assoc_pd" type="text" id="idassoc6_assoc_pd" placeholder="<?= html_safe(interface_dhcpv6_id($pconfig['idassoc6-interface'])) ?>" value="<?= html_safe($pconfig['idassoc6_assoc_pd']) ?>" />
2695+
<div class="hidden" data-for="help_for_idassoc6_assoc_pd">
2696+
<?= gettext('The ID to use for prefix request identity association if required to be non-standard.') ?>
2697+
</div>
2698+
</td>
2699+
</tr>
26222700
</tbody>
26232701
</table>
26242702
</div>
@@ -2663,6 +2741,16 @@ function toggle_wirelesscfg() {
26632741
</div>
26642742
</td>
26652743
</tr>
2744+
<tr>
2745+
<td><a id="help_for_track6_prefix_range" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Reserved prefix range') ?></td>
2746+
<td>
2747+
<input name="track6_prefix_range" type="text" class="form-control" id="track6_prefix_range" placeholder="1" value="<?= $pconfig['track6_prefix_range'] ?>" />
2748+
</div>
2749+
<div class="hidden" data-for="help_for_track6_prefix_range">
2750+
<?= gettext('The value in this field is the length of the reserved prefix range for downstream prefix delegation. The range starts at the given prefix ID. The default is to only reserve the given prefix ID.') ?>
2751+
</div>
2752+
</td>
2753+
</tr>
26662754
<tr>
26672755
<td><a id="help_for_track6_ifid" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Optional interface ID') ?></td>
26682756
<td>
@@ -2675,10 +2763,19 @@ function toggle_wirelesscfg() {
26752763
</div>
26762764
</td>
26772765
</tr>
2766+
<tr>
2767+
<td><a id="help_for_track6_assoc_pd" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Optional prefix IAID') ?></td>
2768+
<td>
2769+
<input name="track6_assoc_pd" type="text" id="track6_assoc_pd" placeholder="<?= html_safe(interface_dhcpv6_id($pconfig['track6-interface'])) ?>" value="<?= html_safe($pconfig['track6_assoc_pd']) ?>" />
2770+
<div class="hidden" data-for="help_for_track6_assoc_pd">
2771+
<?= gettext('The ID to use for prefix request identity association if required to be non-standard.') ?>
2772+
</div>
2773+
</td>
2774+
</tr>
26782775
<tr>
26792776
<td><a id="help_for_dhcpd6_opt" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?= gettext('Manual configuration') ?></td>
26802777
<td>
2681-
<input name="dhcpd6track6allowoverride" type="checkbox" value="yes" <?= $pconfig['dhcpd6track6allowoverride'] ? 'checked="checked"' : '' ?>/>
2778+
<input name="dhcpd6track6allowoverride" type="checkbox" value="yes" <?= !empty($pconfig['dhcpd6track6allowoverride']) ? 'checked="checked"' : '' ?>/>
26822779
<?= gettext('Allow manual adjustment of DHCPv6 and Router Advertisements') ?>
26832780
<div class="hidden" data-for="help_for_dhcpd6_opt">
26842781
<?= gettext('If this option is set, you will be able to manually set the DHCPv6 and Router Advertisements service for this interface. Use with care.') ?>

0 commit comments

Comments
 (0)