Part of netork#85. Fills in the three device-specific methods the new DhcpServerMixin subnet layer expects. searchSubnet only carries uuid/subnet/description, so get_dhcp_subnets follows each row with getSubnet for the option data. That is one request per subnet; a firewall serves a handful, so the round trips cost less than the reconfigure they help avoid. An option Kea does not carry is omitted rather than reported as empty, because the generic diff reads an absent key as "not managed" — reporting [] would make every unmanaged option look like a pending change. apply_dhcp_subnet honours the mixin's partial-update contract: on an update it reads the subnet's current options first and replaces only the named ones. Without that, managing domain_search alone would blank the routers Kea autocollected and strand every client on that VLAN without a gateway. Setting any option also forces option_data_autocollect off — left on, Kea keeps re-filling routers/DNS/NTP and the next diff sees a change again, which is a reconfigure loop rather than a converged state. OPNsense renders repeatable option fields as comma-separated strings in some versions and as a selection map in others, for the same logical field. Both shapes are accepted rather than pinning the driver to one release. Pools are a newline-separated text block. A subnet whose detail fetch fails is skipped with a log line instead of aborting, same rule as get_dhcp_reservations: one broken record must not make the whole inventory unreadable. 16 new tests. Not yet verified against a live device — no reachable OPNsense at the time of writing, same caveat the reservation support shipped with.