Bug report
Bug description:
Description
This is a peer issue to gh-151049 / PR 151050, which is addressing RFC 9665 ranges.
In this case, we similarly have the following examples return True:
ipaddress.ip_address('5f00::1').is_global
ipaddress.ip_address('100:0:0:1::1').is_global
Both blocks are registered by IANA with Globally Reachable = False.
The companion is_private returns False, so the documented-safe not ip.is_global check treats these addresses as ordinary public addresses.
IANA registration
The IANA IPv6 Special-Purpose Address Registry lists both blocks as Globally Reachable = False:
| Address Block |
Name |
RFC |
Globally Reachable |
| 5f00::/16 |
Segment Routing (SRv6) SIDs |
RFC 9602 |
False |
| 100:0:0:1::/64 |
Dummy IPv6 Prefix |
RFC 9780 |
False |
Registry: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
Both were added after the table was last revised: RFC 9602 (Segment Routing over IPv6 SIDs) registered 5f00::/16 in 2024, and RFC 9780 registered the 100:0:0:1::/64 Dummy IPv6 Prefix. Note that 100:0:0:1::/64 is disjoint from the already-listed 100::/64 (RFC 6666 Discard-Only), so the existing 100::/64 entry does not cover it.
The bug
_IPv6Constants._private_networks enumerates the not-globally-reachable blocks. It lists, among others, 100::/64, 2001:db8::/32, 2002::/16, 3fff::/20, but is missing 5f00::/16 and 100:0:0:1::/64, so addresses in those blocks fall through to globally-reachable.
This is the same class as gh-124217 (which added 3fff::/20) and the IPv4 case in bpo-42937 (the 192.0.0.8 dummy address), and the GR=False complement of the in-flight #151050 (which adds the GR=True 2001:1::3/128 to the exceptions list).
Reproduce
On current main:
>>> import ipaddress
>>> ipaddress.ip_address('5f00::1').is_global
True # expected: False (RFC 9602, IANA GR=False)
>>> ipaddress.ip_address('5f00::1').is_private
False # expected: True
>>> ipaddress.ip_address('100:0:0:1::1').is_global
True # expected: False (RFC 9780, IANA GR=False)
>>> ipaddress.ip_address('100:0:0:1::1').is_private
False # expected: True
>>> ipaddress.ip_address('3fff::1').is_global # already-fixed sibling, correct
False
>>> ipaddress.ip_address('100::1').is_global # adjacent in-table block, correct
False
Fix
Add the two blocks to _IPv6Constants._private_networks, with RFC reference comments, e.g.:
IPv6Network('5f00::/16'), # RFC 9602 (SRv6 SIDs)
IPv6Network('100:0:0:1::/64'), # RFC 9780 (Dummy IPv6 Prefix)
and extend testReservedIpv6 to assert that 5f00::1 and 100:0:0:1::1 are not global and are private, and that an adjacent unregistered address (e.g. 100:0:0:2::1) stays unchanged so the carve-out is exact. A Misc/NEWS entry as usual. The exceptions framework and the related entries landed in GH-113179 (first shipped in 3.13), so this applies to 3.13+.
CPython versions tested on:
3.15, CPython main branch
Operating systems tested on:
Linux
Linked PRs
Bug report
Bug description:
Description
This is a peer issue to gh-151049 / PR 151050, which is addressing RFC 9665 ranges.
In this case, we similarly have the following examples return
True:ipaddress.ip_address('5f00::1').is_globalipaddress.ip_address('100:0:0:1::1').is_globalBoth blocks are registered by IANA with Globally Reachable = False.
The companion
is_privatereturnsFalse, so the documented-safenot ip.is_globalcheck treats these addresses as ordinary public addresses.IANA registration
The IANA IPv6 Special-Purpose Address Registry lists both blocks as Globally Reachable = False:
Registry: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
Both were added after the table was last revised: RFC 9602 (Segment Routing over IPv6 SIDs) registered 5f00::/16 in 2024, and RFC 9780 registered the 100:0:0:1::/64 Dummy IPv6 Prefix. Note that 100:0:0:1::/64 is disjoint from the already-listed 100::/64 (RFC 6666 Discard-Only), so the existing 100::/64 entry does not cover it.
The bug
_IPv6Constants._private_networksenumerates the not-globally-reachable blocks. It lists, among others,100::/64,2001:db8::/32,2002::/16,3fff::/20, but is missing5f00::/16and100:0:0:1::/64, so addresses in those blocks fall through to globally-reachable.This is the same class as gh-124217 (which added
3fff::/20) and the IPv4 case in bpo-42937 (the 192.0.0.8 dummy address), and the GR=False complement of the in-flight #151050 (which adds the GR=True2001:1::3/128to the exceptions list).Reproduce
On current main:
Fix
Add the two blocks to
_IPv6Constants._private_networks, with RFC reference comments, e.g.:and extend
testReservedIpv6to assert that5f00::1and100:0:0:1::1are not global and are private, and that an adjacent unregistered address (e.g.100:0:0:2::1) stays unchanged so the carve-out is exact. A Misc/NEWS entry as usual. The exceptions framework and the related entries landed in GH-113179 (first shipped in 3.13), so this applies to 3.13+.CPython versions tested on:
3.15, CPython main branch
Operating systems tested on:
Linux
Linked PRs