broadcast (dhcpv4) and multicast (dhcpv6) support + new Linux namespace based test lab - #54
broadcast (dhcpv4) and multicast (dhcpv6) support + new Linux namespace based test lab#54pallotron wants to merge 3 commits into
Conversation
18183f0 to
085db05
Compare
| return nil, fmt.Errorf("failed to set control message for IPv6: %w", err) | ||
| } | ||
|
|
||
| // Join DHCPv6 multicast group based on listening address. |
There was a problem hiding this comment.
Is the intention to make it work with both unicast and multicast(v6)/broadcast(v4) at the same time?
If dhcplb is running on a rack with many servers and the rack switch has a relay configured I think it might be good to let the relay do its job instead of dhcplb replying directly and the switch also forwarding the request.
Do you need both unicast and broadcast to work at the same time or just one of them at a time?
There was a problem hiding this comment.
Right now we are a V4 shop... I could split this PR into v4 and v6?
Or keep the PR and make this multicast/broadcast listening logic enabled by a flag?
There was a problem hiding this comment.
or have this logic only work when -server is passeed?
There was a problem hiding this comment.
also the logic only enables if you have "listen_addr": "::" in the JSON config... you could specify the address to listen taking from /etc/fbwhoami...
let me know which options you prefer :)
There was a problem hiding this comment.
Or keep the PR and make this multicast/broadcast listening logic enabled by a flag?
This one sounds good to me if current behaviour changes.
also the logic only enables if you have "listen_addr": "::"
Ok, then it should not modify its current behaviour. Thanks for the clarification. So we should be good.
There was a problem hiding this comment.
Ok, then it should not modify its current behaviour. Thanks for the clarification. So we should be good.
do you guys listen to specific /etc/fbwhoami address? if so we should be already good. but I would appreciate if you can do some local testing there :)
085db05 to
d9536a0
Compare
|
@pallotron has updated the pull request. You must reimport the pull request before landing. |
This commit addresses a long-standing limitation (issue #1) where `dhcplb` could only handle unicast DHCP traffic from relay agents. It now correctly processes direct client communication on the same local L2 network for both DHCPv4 (broadcast) and DHCPv6 (multicast), adopting robust networking patterns inspired by servers like `coredhcp` and `dnsmasq`. To achieve this, the networking layer was refactored from `net.UDPConn` to the more advanced `ipv4.PacketConn` and `ipv6.PacketConn`. This makes the server fully interface-aware, allowing it to determine which network interface received a request and to intelligently select the correct source IP for the reply. Key Improvements: - **DHCPv4:** Correctly handles broadcast requests. Implements a Layer 2 raw socket mechanism on Linux—mirroring the behavior of `dnsmasq` and `coredhcp`—for unicast replies to clients without an IP, with a fallback to broadcast on other platforms. - **DHCPv6:** The server now correctly joins the `ff02::1:2` multicast group on startup to handle direct `SOLICIT` messages from clients. This logic respects the `listen_addr` configuration: it joins on all interfaces for a wildcard address (`::`) or on a specific interface if a particular IP is configured. - **Unified Networking:** A new `dhcplbConn` struct provides a type-safe way to manage the distinct IPv4 and IPv6 connections. - **Dynamic Replies:** The static `ReplyAddr` configuration has been removed in favor of dynamically determining the reply address based on the ingress packet, making the server more robust and flexible. To make sure that broadcat/multicat feature worked I had to implement a basic DHCPv[46] handler that implements a simple lease based dhcp server. Leases are stored on the file system as JSON files. This actually is a good example of how to extend `dhcplb` to act as server. Testing is done on the subsequent commits/PRs where I kill Vagrant for a Linux namespace based test lab and CI.
The Vagrant-based test setup was slow, resource-intensive, and had several external dependencies, including VirtualBox and Chef. This made it cumbersome for local development and CI. I need something to test my recent multicast/broadcast changes and I don't have a lab in my current company. Hence this this diff. This commit replaces the Vagrant environment with a new test lab built on top of Linux network namespaces. This new setup is: - **Fast:** It runs natively on a Linux host without the overhead of virtual machines. - **Lightweight:** It only requires `bash` and `iproute2`, which are available on most Linux distributions. - **Portable:** The entire setup is self-contained within the repository and can be easily executed in CI environments. The new test lab is orchestrated by the `tests/setup_lab.sh` script, which can configure the environment in two modes: - **`relay`:** Simulates a network with a DHCP client, a DHCP relay (dnsmasq), `dhcplb`, and a DHCP server (dnsmasq), each in its own network namespace. - **`server`:** Simulates a simpler network with a DHCP client and `dhcplb` acting as a DHCP server. This change simplifies the development and testing workflow, making it easier to validate `dhcplb`'s functionality in a realistic network environment. The new test scripts are not compatible with macOS out of the box. They rely on Linux-specific networking features like network namespaces (ip netns), which are not available on macOS. To run the test lab on a Mac, you will need to use a Linux virtual machine. For your own convenience a `tests/Makefile` has been created to manage the vm using [`lima`](https://lima-vm.io/) and it assumes you have it installed on yoru maOS. ```bash ❯ make help Makefile for DHCPLB Test Lab Usage: make [target] Primary Targets: test-all - 🧪 Set up and run all test scenarios (relay and server). Relay Scenario: setup-relay - 🛠 Set up the relay test lab. test-relay-v4 - ▶ Run a DHCPv4 client test in the relay lab. test-relay-v6 - ▶ Run a DHCPv6 client test in the relay lab. Server Scenario: setup-server - 🛠 Set up the server/broadcast test lab. test-server-v4 - ▶ Run a DHCPv4 client test in the server lab. test-server-v6 - ▶ Run a DHCPv6 client test in the server lab. VM & Debugging: start - 🚀 Start the Lima VM instance 'dhcplb-vm'. logs - 📜 Tail the logs from all services. shell - 💻 Open an interactive shell inside the Lima VM. stop - 🛑 Stop the Lima VM instance. delete - 🗑 Delete the Lima VM instance and all its data. delete-lease - 📄 Force-deletes the client's DHCP lease file ```
d9536a0 to
1949747
Compare
|
@pallotron has updated the pull request. You must reimport the pull request before landing. |
1949747 to
348fde9
Compare
|
@pallotron has updated the pull request. You must reimport the pull request before landing. |
348fde9 to
ed1ba50
Compare
|
@pallotron has updated the pull request. You must reimport the pull request before landing. |
ed1ba50 to
2ba7b9d
Compare
|
@pallotron has updated the pull request. You must reimport the pull request before landing. |
This PR contains two commits:
feat(dhcp): Handle broadcast/multicast and refactor networking
This commit addresses a long-standing limitation (issue #1) where
dhcplbcould only handle unicast DHCP traffic from relay agents. It now correctly processes direct client communication on the same local L2 network for both DHCPv4 (broadcast) and DHCPv6 (multicast), adopting robust networking patterns inspired by servers likecoredhcpanddnsmasq.To achieve this, the networking layer was refactored from
net.UDPConnto the more advancedipv4.PacketConnandipv6.PacketConn. This makes the server fully interface-aware, allowing it to determine which network interface received a request and to intelligently select the correct source IP for the reply.Key Improvements:
dnsmasqandcoredhcp—for unicast replies to clients without an IP, with a fallback to broadcast on other platforms.ff02::1:2multicast group on startup to handle directSOLICITmessages from clients. This logic respects thelisten_addrconfiguration: it joins on all interfaces for a wildcard address (::) or on a specific interface if a particular IP is configured.dhcplbConnstruct provides a type-safe way to manage the distinct IPv4 and IPv6 connections.ReplyAddrconfiguration has been removed in favor of dynamically determining the reply address based on the ingress packet, making the server more robust and flexible.New RangeHandler
To make sure that broadcat/multicat feature worked I had to implement a basic DHCPv[46] handler that implements a simple lease based dhcp server. Leases are stored on the file system as JSON files. This actually is a good example of how to extend
dhcplbto act as server.Testing
Testing was done on the subsequent commit where I killed Vagrant for a Linux namespace based test lab and CI. See the example test run this PR kicked.
refactor(tests): replace Vagrant with network namespace-based test lab
The Vagrant-based test setup was slow, resource-intensive, and had several external dependencies, including VirtualBox and Chef. This made it cumbersome for local development and CI.
I need something to test my recent multicast/broadcast changes and I don't have a lab in my current company. Hence this this diff.
This commit replaces the Vagrant environment with a new test lab built on top of Linux network namespaces. This new setup is:
bashandiproute2, which are available on most Linux distributions.The new test lab is orchestrated by the
tests/setup_lab.shscript, which can configure the environment in two modes:relay: Simulates a network with a DHCP client, a DHCP relay (dnsmasq),dhcplb, and a DHCP server (dnsmasq), each in its own network namespace.server: Simulates a simpler network with a DHCP client anddhcplbacting as a DHCP server.This change simplifies the development and testing workflow, making it easier to validate
dhcplb's functionality in a realistic network environment.The new test scripts are not compatible with macOS out of the box.
They rely on Linux-specific networking features like network namespaces (ip netns), which are not available on macOS.
To run the test lab on a Mac, you will need to use a Linux virtual machine.
For your own convenience a
tests/Makefilehas been created to manage the vm usinglimaand it assumes you have it installed on your macOS.See the example test run this PR kicked: