Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add boot file selection for Kea #7987

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,21 @@
<help>TFTP server address or fqdn</help>
</field>
<field>
<id>subnet4.option_data.boot_file_name</id>
<label>TFTP bootfile name</label>
<id>subnet4.client_classes.x86_uefi_file</id>
<label>x86 UEFI (32-bit) bootfile name</label>
<type>text</type>
<help>Boot filename to request</help>
<help>Boot filename to request for 32-bit x86 UEFI systems.</help>
</field>
<field>
<id>subnet4.client_classes.x64_uefi_file</id>
<label>x64 UEFI/EBC (64-bit) bootfile name</label>
<type>text</type>
<help>Boot filename to request for 64-bit x64 UEFI/EBC systems.</help>
</field>
<field>
<id>subnet4.client_classes.boot_file</id>
<label>Default bootfile name</label>
<type>text</type>
<help>Boot filename to request if no other boot file matches (e.g. legacy BIOS boot).</help>
</field>
</form>
64 changes: 62 additions & 2 deletions src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class KeaDhcpv4 extends BaseModel
{
/**
* Before persisting data into the model, update option_data fields for selected subnets.
* setNodes() is used in most cases (at least from our base controller), which should make this a relatvily
* save entrypoint to enforce some data.
* setNodes() is used in most cases (at least from our base controller), which should make this a relatively
* safe entrypoint to enforce some data.
*/
public function setNodes($data)
{
Expand Down Expand Up @@ -133,6 +133,60 @@ private function getConfigThisServerHostname()
return $hostname;
}

private function getClientClasses()
{
$result = [];
foreach ($this->subnets->subnet4->iterateItems() as $subnet) {
$nondefault_class_names = [];
/* client-classes */
foreach ($subnet->client_classes->iterateItems() as $key => $value) {
$class_name = str_replace(['.', '/', '_'], '-', (string)$subnet->subnet . '-' . $key);
$option_data = [
'name' => "boot-file-name",
'data' => (string)$value
];
if ($key == 'x86_uefi_file') {
$nondefault_class_names[] = $class_name;
$result[] = [
'name' => $class_name,
'test' => "option[93].hex == 0x0006",
'only-if-required' => true,
'option-data' => [$option_data]
];
} elseif ($key == 'x64_uefi_file') {
$nondefault_class_names[] = $class_name;
$result[] = [
'name' => $class_name,
'test' => "option[93].hex == 0x0007 or option[93].hex == 0x0009",
'only-if-required' => true,
'option-data' => [$option_data]
];
} elseif ($key == 'boot_file') {
$tests = [];
foreach ($nondefault_class_names as $nondefault_class_name) {
$tests[] = "not member('" . $nondefault_class_name . "')";
}
$result[] = [
'name' => $class_name,
'test' => implode(" and ", $tests),
'only-if-required' => true,
'option-data' => [$option_data]
];
}
}
}
return $result;
}

private function getClientClassNames($client_classes = [])
{
$result = [];
foreach ($client_classes as $client_class) {
$result[] = $client_class['name'];
}
return $result;
}

private function getConfigSubnets()
{
$result = [];
Expand All @@ -144,6 +198,7 @@ private function getConfigSubnets()
'next-server' => (string)$subnet->next_server,
'option-data' => [],
'pools' => [],
'require-client-classes' => [],
'reservations' => []
];
/* standard option-data elements */
Expand All @@ -165,6 +220,10 @@ private function getConfigSubnets()
foreach (array_filter(explode("\n", $subnet->pools)) as $pool) {
$record['pools'][] = ['pool' => $pool];
}
/* add required classes */
foreach ($this->getClientClassNames($this->getClientClasses()) as $client_class_name) {
$record['require-client-classes'][] = $client_class_name;
}
/* static reservations */
foreach ($this->reservations->reservation->iterateItems() as $key => $reservation) {
if ($reservation->subnet != $subnet_uuid) {
Expand Down Expand Up @@ -210,6 +269,7 @@ public function generateConfig($target = '/usr/local/etc/kea/kea-dhcp4.conf')
'severity' => 'INFO',
]
],
'client-classes' => $this->getClientClasses(),
'subnet4' => $this->getConfigSubnets(),
]
];
Expand Down
14 changes: 11 additions & 3 deletions src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,18 @@
<tftp_server_name type="TextField">
<Mask>/^([^\n"])*$/u</Mask>
</tftp_server_name>
<boot_file_name type="TextField">
<Mask>/^([^\n"])*$/u</Mask>
</boot_file_name>
</option_data>
<client_classes>
<x86_uefi_file type="TextField">
<Mask>/^([^\n"])*$/u</Mask>
</x86_uefi_file>
<x64_uefi_file type="TextField">
<Mask>/^([^\n"])*$/u</Mask>
</x64_uefi_file>
<boot_file type="TextField">
<Mask>/^([^\n"])*$/u</Mask>
</boot_file>
</client_classes>
<pools type=".\KeaPoolsField">
</pools>
<description type="DescriptionField"/>
Expand Down