Project

General

Profile

Actions

Bug #15032

closed

Kea DHCP sends wrong bootloader file for UEFI

Added by David Masshardt 5 months ago. Updated 4 days ago.

Status:
Resolved
Priority:
Normal
Category:
DHCP (IPv4)
Target version:
Start date:
Due date:
% Done:

100%

Estimated time:
Plus Target Version:
24.03
Release Notes:
Default
Affected Version:
2.7.1
Affected Architecture:
All

Description

I already posted this problem in the pfSense forum and was asked to report this issue here. Here is the link of the discussion thread:
https://forum.netgate.com/topic/184301/kea-dhcp-uefi-pxe-boot-sends-wrong-boot-file

I'm using netboot.xyz for network booting and I just switched to Kea DHCP. After the migration I noticed that network booting from UEFI bios does not work anymore, but legacy bios boot still does work.

Here are the configuration values I set in pfSense:

TFTP Server: IP of my netboot server
Next Server: IP of my netboot server
Default BIOS File Name: netboot.xyz.kpxe
UEFI 32 bit File Name: netboot.xyz.efi
UEFI 64 bit File Name: netboot.xyz.efi
ARM 64 bit File Name: netboot.xyz-arm64.efi

The Kea DHCP server always offers the default netboot.xyz.kpxe file to UEFI machines.

Here are the logs from Kea DHCP for an UEFI bios:

Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcp4.0x3e2f2f5b9300] EVAL_RESULT Expression ipxe_64_lan_pool_0 evaluated to 1
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcp4.0x3e2f2f5b9300] EVAL_RESULT Expression ipxe_legacy_lan_pool_0 evaluated to 1
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcp4.0x3e2f2f5b9300] EVAL_RESULT Expression ipxe_64_lan evaluated to 1
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcp4.0x3e2f2f5b9300] EVAL_RESULT Expression ipxe_legacy_lan evaluated to 1
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.leases.0x3e2f2f5b9300] DHCP4_LEASE_ALLOC [hwtype=1 46:15:16:cd:59:84], cid=[no info], tid=0xaccc68dd: lease 172.17.128.2 has been allocated for 86400 seconds
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcpsrv.0x3e2f2f5b9300] EVAL_RESULT Expression pool_opt1_0 evaluated to 1
Nov 23 12:23:55    kea-dhcp4    14098    INFO [kea-dhcp4.dhcpsrv.0x3e2f2f5b9300] EVAL_RESULT Expression pool_lan_0 evaluated to 1

And here is the generated kea-dhcp4.conf file. (I just removed the reservations)

{
    "Dhcp4": {
        "interfaces-config": {
            "interfaces": [
                "mlxen0",
                "mlxen0.2" 
            ]
        },
        "lease-database": {
            "type": "memfile",
            "persist": true,
            "name": "/var/lib/kea/dhcp4.leases" 
        },
        "loggers": [
            {
                "name": "kea-dhcp4",
                "output_options": [
                    {
                        "output": "syslog" 
                    }
                ],
                "severity": "INFO" 
            }
        ],
        "valid-lifetime": 7200,
        "max-valid-lifetime": 86400,
        "ip-reservations-unique": false,
        "echo-client-id": false,
        "option-data": [
            {
                "name": "domain-name",
                "data": "mydomain" 
            }
        ],
        "option-def": [
            {
                "space": "dhcp4",
                "name": "ldap-server",
                "code": 95,
                "type": "string" 
            }
        ],
        "hooks-libraries": [
            {
                "library": "/usr/local/lib/kea/hooks/libdhcp_lease_cmds.so" 
            }
        ],
        "control-socket": {
            "socket-type": "unix",
            "socket-name": "/tmp/kea4-ctrl-socket" 
        },
        "authoritative": true,
        "client-classes": [
            {
                "name": "ipxe_32_lan_pool_0",
                "test": "option[93].hex == 0x0006",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_64_lan_pool_0",
                "test": "option[93].hex == 0x0007 or option[93].hex == 0x0009",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_64arm_lan_pool_0",
                "test": "option[93].hex == 0x000b",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz-arm64.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_legacy_lan_pool_0",
                "test": "not member('ipxe_32_lan_pool_0') and not member('ipxe_64_lan_pool_0') and not member('ipxe_64arm_lan_pool_0')",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.kpxe" 
                    }
                ]
            },
            {
                "name": "pool_lan_0",
                "test": "member('ALL')" 
            },
            {
                "name": "ipxe_32_lan",
                "test": "option[93].hex == 0x0006",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_64_lan",
                "test": "option[93].hex == 0x0007 or option[93].hex == 0x0009",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_64arm_lan",
                "test": "option[93].hex == 0x000b",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz-arm64.efi" 
                    }
                ]
            },
            {
                "name": "ipxe_legacy_lan",
                "test": "not member('ipxe_32_lan') and not member('ipxe_64_lan') and not member('ipxe_64arm_lan')",
                "only-if-required": true,
                "option-data": [
                    {
                        "name": "boot-file-name",
                        "data": "netboot.xyz.kpxe" 
                    }
                ]
            },
            {
                "name": "pool_opt1_0",
                "test": "member('ALL')" 
            }
        ],
        "subnet4": [
            {
                "id": 1,
                "subnet": "172.17.0.0/16",
                "option-data": [
                    {
                        "name": "domain-name",
                        "data": "mydomain" 
                    },
                    {
                        "name": "domain-search",
                        "data": "mydomain" 
                    },
                    {
                        "name": "domain-name-servers",
                        "data": "172.17.1.1" 
                    },
                    {
                        "name": "routers",
                        "data": "172.17.1.1" 
                    },
                    {
                        "name": "netbios-name-servers",
                        "data": "172.17.2.1" 
                    },
                    {
                        "name": "netbios-node-type",
                        "data": "8" 
                    }
                ],
                "pools": [
                    {
                        "pool": "172.17.128.0 - 172.17.128.199",
                        "client-class": "pool_lan_0",
                        "option-data": [
                            {
                                "name": "domain-name-servers",
                                "data": "172.17.1.1" 
                            },
                            {
                                "name": "tftp-server-name",
                                "data": "172.17.2.17" 
                            }
                        ],
                        "require-client-classes": [
                            "ipxe_legacy_lan_pool_0",
                            "ipxe_32_lan_pool_0",
                            "ipxe_64_lan_pool_0",
                            "ipxe_64arm_lan_pool_0" 
                        ]
                    }
                ],
                "valid-lifetime": 86400,
                "next-server": "172.17.2.17",
                "require-client-classes": [
                    "ipxe_legacy_lan",
                    "ipxe_32_lan",
                    "ipxe_64_lan",
                    "ipxe_64arm_lan" 
                ],
                "reservations-in-subnet": true
            },
            {
                "id": 2,
                "subnet": "172.20.0.0/16",
                "option-data": [
                    {
                        "name": "domain-name-servers",
                        "data": "172.20.1.1" 
                    },
                    {
                        "name": "routers",
                        "data": "172.20.1.1" 
                    }
                ],
                "pools": [
                    {
                        "pool": "172.20.128.0 - 172.20.128.255",
                        "client-class": "pool_opt1_0",
                        "option-data": [
                            {
                                "name": "domain-name-servers",
                                "data": "172.20.1.1" 
                            }
                        ]
                    }
                ],
                "valid-lifetime": 86400,
                "reservations-in-subnet": true
            }
        ]
}

I noticed that the legacy classes in the require-client-classes are on top of all the other classes. After i changed the order so that the legacy classes are at the bottom netboot worked for legacy and UEFI boot.

I also created a patch file that fixes the problem in the services.inc file:

--- /etc/inc/services.inc.save    2023-11-24 15:19:26.797541000 +0100
+++ /etc/inc/services.inc    2023-11-24 15:24:17.000000000 +0100
@@ -1548,7 +1548,7 @@
                     if (!is_array($keapool['require-client-classes'])) {
                         $keapool['require-client-classes'] = [];
                     }
-                    array_unshift($keapool['require-client-classes'], $name);
+                    $keapool['require-client-classes'][] = $name;
                 }

                 if (!empty($poolconf['rootpath'])) {
@@ -1719,7 +1719,7 @@
                 if (!is_array($keasubnet['require-client-classes'])) {
                     $keasubnet['require-client-classes'] = [];
                 }
-                array_unshift($keasubnet['require-client-classes'], $name);
+                $keasubnet['require-client-classes'][] = $name;
             }

             if (!empty($dhcpifconf['rootpath'])) {

Can you please take a look at this if this is the correct solution to this problem?

Actions #1

Updated by Jim Pingle 5 months ago

  • Assignee set to Christian McDonald
  • Target version set to 2.8.0
  • Plus Target Version set to 24.03
Actions #2

Updated by Lev Prokofev about 1 month ago

I can confirm this behavior on 23.09.1.
The patch makes it work for both legacy and UEFI boot.

Actions #3

Updated by Jim Pingle about 1 month ago

  • Status changed from New to Feedback
  • % Done changed from 0 to 100
Actions #4

Updated by Jim Pingle 15 days ago

  • Subject changed from Kea DHCP sends wrong bootloader file for uefi boot to Kea DHCP sends wrong bootloader file for UEFI
Actions #5

Updated by Jim Pingle 4 days ago

  • Status changed from Feedback to Resolved
Actions

Also available in: Atom PDF