The issue I have is that the container gets its static IP on boot, but then losses it. It seems it get a delay for the lease (DHCPv6 client: Valid lifetime expires in 1h), and renew fails :
2025-11-28T17:43:31.807216+11:00 front systemd-networkd[374]: eth0: DHCPv6 client: Sent Renew 2025-11-28T17:43:31.807589+11:00 front systemd-networkd[374]: eth0: DHCPv6 client: Next retransmission in 19s
With TCPdump I can see the renew request, but dnsmasq doesn’t reply to it…
I’ve been trying to sort this one out on and off but haven’t yet gotten to the bottom of it. It’s certainly possible to add/relax the rules to make it work, but not in a way that wouldn’t also allow potential spoofing or DoS… It’s also really weird as the very packet we see in tcpdump matches perfectly the rule in nft and in fact clears it during the initial request.
@stgraber The thing is that I need to have a static IPV6 for my proxy device :
root@server:~# incus restart front Error: Failed to start device “proxy-http6”: Connect IP “fd00:[redacted]::2” must be one of the instance’s static IPv6 addresses Try incus info --show-log front for more info
I put together a dnsmasq DHCP script a while back for doing IPv6 filtering, etc. with an externally managed bridge. While it might not help directly with your problem, maybe you can work around it by configuring a bridge manually (e.g., with systemd-networkd) and running your own dnsmasq on it. In my admittedly limited testing, I don’t think I have had any problems with DHCPv6 renewal until now.
There is no release yet, but from my perspective it’s currently feature complete:
But it would need to be supplemented with your own nftables config for the bridge, in which you’d “jump” to the generated chains. So, it’s probably a bit much effort and you’d need to ensure security on your own instead of leaving it to Incus. It might be an alternative to consider, though.
@stgraber Retested this on Incus 7.3 (Zabbly stable, Ubuntu 26.04, Zabbly kernel, nftables driver). Still reproducible, and the behavior is very clean to observe with a short lease:
incus network set br-test ipv6.dhcp.stateful=true ipv6.dhcp.expiry=3m
Container NIC has security.ipv6_filtering=true, address assigned from the stateful range at boot (fd42:100::d000:0:0:1). Then valid_lft just counts down to zero, not a single renewal gets through:
Restarting the container brings the address back immediately, which matches the rule analysis from this thread: the filtering accept rule only matches DHCPv6 to the multicast address (ip6 daddr ff02::1:2 udp dport 547), so the initial multicast SOLICIT works while the unicast RENEW to the server is dropped before dnsmasq ever sees it.
So on 7.3 the practical options are still the same: ipv6.dhcp.expiry=87600h on the bridge, or static ipv6.address on the NIC device (which is what pins the filtering anyway). Would extending the accept rule to also match unicast DHCPv6 from fe80::/10 to the bridge’s own address on port 547 be an acceptable relaxation? That would keep the source restriction while letting renewals reach dnsmasq.