IPv6 address is not appearing in 'lxc list' output

I am trying to get IPv6 working on a Gentoo container that is inside a VPS running Ubuntu 20.04.

I have the following bridge configuration on the host:

$ lxc network show lxdbr0
config:
  ipv4.address: 10.23.21.1/24
  ipv4.nat: "true"
  ipv6.address: fd42:774b:2bac:da6::1/64
  ipv6.dhcp.stateful: "true"
  ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
used_by:
- /1.0/instances/equal-parakeet
- /1.0/profiles/default
managed: true
status: Created
locations:
- none

The container has an IPv6 address:

equal-parakeet $ ip a show dev eth0
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:fc:a6:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.23.21.100/24 brd 10.23.21.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fefc:a628/64 scope link 
       valid_lft forever preferred_lft forever

But this address does not appear in ‘lxc list’ output:

$ lxc list
+----------------+---------+---------------------+------+-----------+-----------+
|      NAME      |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+----------------+---------+---------------------+------+-----------+-----------+
| equal-parakeet | RUNNING | 10.23.21.100 (eth0) |      | CONTAINER | 1         |
+----------------+---------+---------------------+------+-----------+-----------+

Why might this be?

Do you have a DHCPv6 stateful client running in your container?

Why using ipv6.dhcp.stateful: "true" btw?

The container is a Gentoo container that uses dhclient to obtain an IPv4 address.

The configuration documentation doesn’t describe a way of differentiating between IPv4 and IPv6 (see Gentoo Linux amd64 Handbook: Network configuration).

/etc/conf.d/net (in the container) contains

$ cat /etc/conf.d/net
config_eth0="dhcp"

I don’t know why ipv6.dhcp.stateful="true" is set, I don’t remember setting it, but you’d mentioned elsewhere that it is needed for IPv6 NAT. Have I misunderstood something?

If you don’t need it, then set it to false and use SLAAC instead.

Otherwise you’re going to need to ensure that your container’s OS is performing a DHCPv6 request (and that is likely different than DHCPv4 setup).

1 Like

What do I need to do on the container to use SLAAC? (A generic answer that makes use of ’ip’ would sufficient…)

Probably nothing, it usually works out of the box once ipv6.dhcp.stateful="false"

1 Like

Sure enough:

$ lxc network unset lxdbr0 ipv6.dhcp.stateful
$ lxc network show lxdbr0
config:
  ipv4.address: 10.23.21.1/24
  ipv4.nat: "true"
  ipv6.address: fd42:774b:2bac:da6::1/64
  ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
used_by:
- /1.0/instances/equal-parakeet
- /1.0/profiles/default
managed: true
status: Created
locations:
- none
$ lxc list
+----------------+---------+---------------------+----------------------------------------------+-----------+-----------+
|      NAME      |  STATE  |        IPV4         |                     IPV6                     |   TYPE    | SNAPSHOTS |
+----------------+---------+---------------------+----------------------------------------------+-----------+-----------+
| equal-parakeet | RUNNING | 10.23.21.100 (eth0) | fd42:774b:2bac:da6:216:3eff:fefc:a628 (eth0) | CONTAINER | 1         |
+----------------+---------+---------------------+----------------------------------------------+-----------+-----------+

On the container:

equal-parakeet ~ $ LANG=C ping6 -c 4 wikipedia.org
PING wikipedia.org(text-lb.esams.wikimedia.org (2620:0:862:ed1a::1)) 56 data bytes
64 bytes from text-lb.esams.wikimedia.org (2620:0:862:ed1a::1): icmp_seq=1 ttl=58 time=9.29 ms
64 bytes from text-lb.esams.wikimedia.org (2620:0:862:ed1a::1): icmp_seq=2 ttl=58 time=9.29 ms
64 bytes from text-lb.esams.wikimedia.org (2620:0:862:ed1a::1): icmp_seq=3 ttl=58 time=9.47 ms
64 bytes from text-lb.esams.wikimedia.org (2620:0:862:ed1a::1): icmp_seq=4 ttl=58 time=9.23 ms

--- wikipedia.org ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 9.228/9.319/9.471/0.091 ms

Thank you!

Now, given the above, two additional questions:

  • How do I allow the container to use the routable external IPv6 address from the host?
  • Can I set up IPv6 proxy devices just like the ones I use for passing IPv4 ports through from the host to the container?
1 Like

Yes, see Linux Containers - LXD - Has been moved to Canonical

This has been discussed a number of times on this forum, but the general approach with Hetzner’s /64 subnet is to pick a single IP at the start/end of the subnet, e.g. ::1 and assign that to the LXD host’s external interface as ...::1/128, then use lxc network set lxdbr0 ipv6.address=....::2/64 ipv6.nat=false.

Yes, I saw the Hetzner example. In my case only a single IP address is provided, and with a peculiar /48 subnet.

It’s a bit ridiculous, there’s no reason to be so miserly, but I suspect IPv4 thinking is being applied here. And capitalistic thinking :wink:

I thought that there might be a simple way to pass the whole IP address through to the container.

I don’t quite follow you, but if you want you can also use routed NIC type to pass specific IPv6 addresses without needing to configure a bridge.

See How to get LXD containers get IP from the LAN with routed network

Not sure what you mean, a /48 is made of of approx 65k /64, so there’s plenty to choose from, you can then just pick a /64 for your lxdbr0 subnet.