incus icon indicating copy to clipboard operation
incus copied to clipboard

Implement stateful DHCPv6 in forkdhcp

Open defect-track opened this issue 9 months ago • 13 comments

Is there an existing issue for this?

  • [x] There is no existing issue for this feature

What are you currently unable to do

This feature request is based on the following forum thread https://discuss.linuxcontainers.org/t/no-ipv6-for-incus-oci-containers/21086

In general you can work with dynamic IP addresses but for some services like DNS it is recommended to use a static IP. With the latest release 6.11 we can now configure custom DNS for OVN, bridge, etc. networks which is great. Trying to setup an OCI DNS on a static IPv6 only network. Current workaround is to have IPv4 enabled or use an container.

What do you think would need to be added

From my understanding of the forum topic stateful IPv6 support for OCI images.

defect-track avatar Mar 31 '25 02:03 defect-track

Hello, I'm a student at UT in Professor Chidambaram's Virtualization course. Could me and my partner take on this issue?

davidbockelman avatar Mar 31 '25 23:03 davidbockelman

For sure!

stgraber avatar Apr 01 '25 04:04 stgraber

Hello, our professor has advised us that this issue is harder than we initially thought, so we have chosen different issues to work on. I hope this doesn't cause you any inconvenience.

davidbockelman avatar Apr 02 '25 23:04 davidbockelman

Okay. I unassigned you.

For anyone else looking at this one, it should actually be pretty simple. We have a very minimal DHCP client in cmd/incusd/main_forknet.go (skip through all the C stuff, it's not relevant to the DHCP client, it's the RunDHCP struct and functions you want).

The current DHCPv4 client is implemented by using github.com/insomniacslk/dhcp which has support for both IPv4 and IPv6 DHCP client, so wiring up a basic stateful DHCPv6 client should be pretty straightforward unless there's something particularly different from their equivalent DHCPv4 client.

stgraber avatar Apr 03 '25 00:04 stgraber

hi! I'm a student at UT Austin's virtualization course and my partner and I were hoping to take this issue on. Can this be assigned to us? thank you!

rahafjrw avatar Apr 03 '25 19:04 rahafjrw

I'm in the group with rahafjrw, could I also be assigned this issue?

orcadennis avatar Apr 03 '25 19:04 orcadennis

Done!

stgraber avatar Apr 03 '25 19:04 stgraber

hello! I wanted to clarify--how do we know whether to set up a DHCPv4 client or a DHCPv6 clients? Specifically, in RunDHCP line 308, "client, err := nclient4.New(iface)" is executed. How do we determine whether to use nclient4 vs nclient6? Thank you in advance!

rahafjrw avatar Apr 21 '25 23:04 rahafjrw

We don't really know, so we'll just run both.

stgraber avatar Apr 21 '25 23:04 stgraber

Technically Incus can tell in some cases and could pass us that information as arguments, but for now, let's just make it easy and have both DHCPv4 and DHCPv6 running.

stgraber avatar Apr 21 '25 23:04 stgraber

hello! I wanted to run our approach by you before we implement it. We were thinking we would define a new function that takes in a client that we then call twice inside of RunDHCP--once with the DHCPv4 client and with the DHCPv6 client. This function would pretty much contain the functionality that's currently in RunDHCP. Are we missing anything/is there something else we need to add or consider?

rahafjrw avatar Apr 22 '25 21:04 rahafjrw

Right so the problem is that RunDHCP is a blocking function as it goes into an infinite renewal loop at the end.

The main guiding principles here should be:

  • Neither client should block the other. If running on a network with just DHCPv4, we shouldn't get stuck waiting for DHCPv6 and vice-versa.
  • Network configuration for the given client should be applied once the first lease is received, this means applying the IP address and any provided routes.
  • Background renewal of the lease must be handled.
  • DNS configuration (resolv.conf) needs special care as that file contains data coming from both DHCPv4 and DHCPv6, so neither client functions can directly write it.

The way I'd probably tackle this is by:

  • Adding two new fields to the cmdForknet struct. dhcpv4Lease and dhcpv6Lease, both pointers to the relevant DHCP Lease struct.
  • Adding new dhcpRunV4 and dhcpRunV6 functions to the cmdForknet struct. Those will setup the relevant client, perform the initial DHCP request, apply the IP config and handle lease renewal.
  • Adding a new dhcpApplyDNS function which will look at both dhcpv4Lease and dhcpv6Lease to generate the resolv.conf file. This function will be called by both dhcpRunV4 and dhcpRunV6 after they acquire a valid lease and have put a pointer to it in the shared struct.
  • RunDHCP would then just handle bringing up the interface and reading the hostname before calling both dhcpRunV4 and dhcpRunV6` inside of Go routines, using Go channels to block until both clients have returned an error before exiting the process.

stgraber avatar Apr 23 '25 05:04 stgraber

got it, thank you!!

rahafjrw avatar Apr 24 '25 05:04 rahafjrw