docker/for-linux

Incorrect IPV6 prefix address assigned to container interface

vorlando opened this issue · 3 comments

I have created a macvlan network with the following

docker network create -d macvlan \
   --ipv6 \
   --subnet=xxx.xxx.8.0/24 \
   --gateway=xxx.xxx.8.1  \
   --subnet=xxxx:xxxx:200::/42 \
   --gateway=xxxx:xxxx:200::1 \
   -o parent=eth0 testnet

Then create a docker container with

docker run -it --rm --net testnet  \
     --privileged \
     --mac-address=xx:xx:xx:xx:xx:xx \
     --ip xxx.xxx.8.252 \
     --ip6=xxxx:xxxx:200:0400:0135:7700:ef0a:1 \
     <container> bash

When I run ifconfig in the container I get

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.8.252  netmask 255.255.255.0  broadcast xxx.xxx.8.255
        inet6 fe80::2877:66ff:fe39:dfb2  prefixlen 64  scopeid 0x20<link>
        inet6 xxxx:xxxx:200:0:135:7700:ef0a:1  prefixlen 42  scopeid 0x0<global>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 0  (Ethernet)
        RX packets 54  bytes 4344 (4.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 596 (596.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The inet6 address does not have the correct prefix

Was expecting

xxxx:xxxx:200:0400:0135:7700:ef0a:1

but received

xxxx:xxxx:200:0:135:7700:ef0a:1

daemon.config is

{
    "dns": ["8.8.8.8"],
    "ipv6": true,
    "fixed-cidr-v6": "2001:db8:1::/64"
}

Docker version

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:28:22 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Docker info

 Debug Mode: false

Server:
 Containers: 5
  Running: 0
  Paused: 0
  Stopped: 5
 Images: 95
 Server Version: 19.03.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
 init version: fec3683
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 4.15.0-74-generic
 Operating System: Ubuntu 18.04.3 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 12
 Total Memory: 125.8GiB
 Name: nodes
 ID: DMC2:TF7O:SKLM:SSAX:XO7Q:VEH3:PGOB:LIVS:PM2F:IZH5:KPWX:CN5I
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Thanks in advance...

I'd say it is caused by uint64 type being used to count and give out addresses from subnets. It may be fine for IPv4 (even 32 bit type would do) but is definitely too small for IPv6.

Due to this limitation Docker effectively hands containers network address of subnet + last 64 bits from --ip6 address.

It is quite a bug! Unfortunately I was hit by it, too.

Examples:

network: 2001:db8::/32
--ip6=2001:db8:db8::1
container will have IP: 2001:db8::1

network: 2001:db8::/32
--ip6=2001:db8:db1:db2:db3:db4:db5:db6
container will have IP: 2001:db8::db3:db4:db5:db6

For now I am using custom IPAM driver to work around the issue:
https://github.com/jacekkow/docker-plugin-pyipam