-
Notifications
You must be signed in to change notification settings - Fork 18.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
splitNetwork and addIntToIP fails for IPv6 addresses on /64+ size pools #42801
Comments
Here's some checks I ran to find this, which might be helpful for tests:
This may also be an opportunity to address #40275, where using a large base pool and a large split |
This seems to be quite a big issue for me and is blocking me from using ipv6 auto created networks right now. |
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, a new type offset has been introduced and is used by NetworkSplitter. It uses two uint64 to represents an unsigned int of 128 bits. Moreover, addIntToIP has been changed to take two uint64 (one upper and one lower addend) and computes two ordinals applied to, respectively, the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upper is not used). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, a new type offset has been introduced and is used by NetworkSplitter. It uses two uint64 to represents an unsigned int of 128 bits. Moreover, addIntToIP has been changed to take two uint64 (one upper and one lower addend) and computes two ordinals applied to, respectively, the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upper is not used). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
This bug is more or less a complete show stopper when using docker-compose 👎 |
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
Prior to this change, IPv6 subnets generation was broken because of a bitwise shift overflowing uint64. To solve this issue, addIntToIP has been changed to take an addend and computes two ordinals applied to respectively the lower 64 bits and the upper 64 bits of IPv6 addresses. Nothing change for IPv4 (ie. upperOrdinal is always 0). Signed-off-by: Albin Kerouanton <[email protected]>
A new Subnetter structure is added to lazily sub-divide an address pool into subnets. This fixes moby#40275. Prior to this change, the list of NetworkToSplit was eagerly split into smaller subnets when ipamutils package was loaded, when ConfigGlobalScopeDefaultNetworks was called or when the function SetDefaultIPAddressPool from the default IPAM driver was called. In the latter case, if the list of NetworkToSplit contained an IPv6 prefix, eagerly enumerating all subnets could eat all the available memory. For instance, fd00::/8 split into /96 would take ~5*10^27 bytes. Although this change trades memory consumption for computation cost, the Subnetter is used by libnetwork/ipam package in such a way that it only have to compute the address of the next subnet. When the Subnetter reach the end of NetworkToSplit, it's resetted by libnetwork/ipam only if there were some subnets released beforehand. In such case, ipam package might iterate over all the subnets before finding one available. Also, the Subnetter leverages the newly introduced ipbits package, which handles IPv6 addresses correctly. Before this commit, a bitwise shift was overflowing uint64 and thus only a single subnet could be enumerated from an IPv6 prefix. This fixes moby#42801. Signed-off-by: Albin Kerouanton <[email protected]>
A new Subnetter structure is added to lazily sub-divide an address pool into subnets. This fixes moby#40275. Prior to this change, the list of NetworkToSplit was eagerly split into smaller subnets when ipamutils package was loaded, when ConfigGlobalScopeDefaultNetworks was called or when the function SetDefaultIPAddressPool from the default IPAM driver was called. In the latter case, if the list of NetworkToSplit contained an IPv6 prefix, eagerly enumerating all subnets could eat all the available memory. For instance, fd00::/8 split into /96 would take ~5*10^27 bytes. Although this change trades memory consumption for computation cost, the Subnetter is used by libnetwork/ipam package in such a way that it only have to compute the address of the next subnet. When the Subnetter reach the end of NetworkToSplit, it's resetted by libnetwork/ipam only if there were some subnets released beforehand. In such case, ipam package might iterate over all the subnets before finding one available. Also, the Subnetter leverages the newly introduced ipbits package, which handles IPv6 addresses correctly. Before this commit, a bitwise shift was overflowing uint64 and thus only a single subnet could be enumerated from an IPv6 prefix. This fixes moby#42801. Signed-off-by: Albin Kerouanton <[email protected]>
Description
When attempting to create the pools for IPv6 addresses ranges, the output of
splitNetwork
produces the same CIDR N times rather than the N different CIDRs if the output network size is >= 64 bits. This is due to the value passed toaddIntToIP
being a 64 bit int, which is insufficient to contain the required value to offset IPv6 ranges.Steps to reproduce the issue:
default-address-pools
in config and enable IPv6.For example:
could not find an available, non-overlapping IPv6 address pool among the defaults to assign to the network
, suggesting there is only one pool availableDescribe the results you received:
Only a single IPv6 pool is available per entry in
default-address-pools
Describe the results you expected:
The output of splitting
fd00:0000:0000::/48
into/64
networks should yield2^16
pools, not one.Additional information you deem important (e.g. issue happens only occasionally):
This is caused by
splitNetwork
andaddIntToIP
, which works OK for IPv4 but fails for IPv6 networks of/64
or larger due to theordinal
argument toaddIntToIP
being a 64 bit int, which ends up being zero when using a/64
or larger. Crucially, the statementuint(i<<s)
yields zero here, sinces > 64
For example,
fmt.Println(splitNetworks([]*NetworkToSplit{{"fd00:0000:0000::/48", 50}}))
yields the same CIDR repeated 4 times rather than 4 separate CIDRs:To fix this, those two functions need to be amended to allow values up to 128 bits to be added to an IP, perhaps with an
ordinalUpper
andordinalLower
as two 64 bit uints.I believe this issue may be the underlying cause of #41438
Output of
docker version
:Output of
docker info
:Additional environment details (AWS, VirtualBox, physical, etc.):
None
The text was updated successfully, but these errors were encountered: