gre: Reapply IPv6 link-local address generation fix.
Subsystems (4)
cover gre: Reapply IPv6 link-local address generation fix.
Reintroduce the IPv6 link-local address generation fix for GRE and its kernel selftest. These patches were introduced by merge commit b3fc5927de4b ("Merge branch 'gre-fix-regressions-in-ipv6-link-local-address-generation'") but have been reverted by commit 8417db0be5bb ("Merge branch 'gre-revert-ipv6-link-local-address-fix'"), because it uncovered another bug in multipath routing. Now that this bug has been investigated and fixed, we can apply the GRE link-local address fix and its kernel selftest again.
For convenience, here's the original cover letter:
IPv6 link-local address generation has some special cases for GRE devices. This has led to several regressions in the past, and some of them are still not fixed. This series fixes the remaining problems, like the ipv6.conf.<dev>.addr_gen_mode sysctl being ignored and the router discovery process not being started (see details in patch 1).
To avoid any further regressions, patch 2 adds selftests covering IPv4 and IPv6 gre/gretap devices with all combinations of currently supported addr_gen_mode values.
Guillaume Nault (2):
gre: Fix again IPv6 link-local address generation.
selftests: Add IPv6 link-local address generation tests for GRE
devices.
net/ipv6/addrconf.c | 15 +- tools/testing/selftests/net/Makefile | 1 + .../testing/selftests/net/gre_ipv6_lladdr.sh | 177 ++++++++++++++++++ 3 files changed, 187 insertions(+), 6 deletions(-) create mode 100755 tools/testing/selftests/net/gre_ipv6_lladdr.sh
Signature · 1 line
2.39.2
PATCH 1/2 gre: Fix again IPv6 link-local address generation.
Use addrconf_addr_gen() to generate IPv6 link-local addresses on GRE devices in most cases and fall back to using add_v4_addrs() only in case the GRE configuration is incompatible with addrconf_addr_gen().
GRE used to use addrconf_addr_gen() until commit e5dd729460ca ("ip/ip6_gre:
use the same logic as SIT interfaces when computing v6LL address") restricted this use to gretap and ip6gretap devices, and created add_v4_addrs() (borrowed from SIT) for non-Ethernet GRE ones.
The original problem came when commit 9af28511be10 ("addrconf: refuse isatap eui64 for INADDR_ANY") made __ipv6_isatap_ifid() fail when its addr parameter was 0. The commit says that this would create an invalid address, however, I couldn't find any RFC saying that the generated interface identifier would be wrong. Anyway, since gre over IPv4 devices pass their local tunnel address to __ipv6_isatap_ifid(), that commit broke their IPv6 link-local address generation when the local address was unspecified.
Then commit e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") tried to fix that case by defining add_v4_addrs() and calling it to generate the IPv6 link-local address instead of using addrconf_addr_gen() (apart for gretap and ip6gretap devices, which would still use the regular addrconf_addr_gen(), since they have a MAC address).
That broke several use cases because add_v4_addrs() isn't properly integrated into the rest of IPv6 Neighbor Discovery code. Several of these shortcomings have been fixed over time, but add_v4_addrs() remains broken on several aspects. In particular, it doesn't send any Router Sollicitations, so the SLAAC process doesn't start until the interface receives a Router Advertisement. Also, add_v4_addrs() mostly ignores the address generation mode of the interface (/proc/sys/net/ipv6/conf/*/addr_gen_mode), thus breaking the IN6_ADDR_GEN_MODE_RANDOM and IN6_ADDR_GEN_MODE_STABLE_PRIVACY cases.
Fix the situation by using add_v4_addrs() only in the specific scenario where the normal method would fail. That is, for interfaces that have all of the following characteristics:
* run over IPv4,
* transport IP packets directly, not Ethernet (that is, not gretap interfaces),
* tunnel endpoint is INADDR_ANY (that is, 0),
* device address generation mode is EUI64.
In all other cases, revert back to the regular addrconf_addr_gen().
Also, remove the special case for ip6gre interfaces in add_v4_addrs(), since ip6gre devices now always use addrconf_addr_gen() instead.
Note:
This patch was originally applied as commit 183185a18ff9 ("gre: Fix IPv6 link-local address generation."). However, it was then reverted by commit fc486c2d060f ("Revert "gre: Fix IPv6 link-local address generation."") because it uncovered another bug that ended up breaking net/forwarding/ip6gre_custom_multipath_hash.sh. That other bug has now been fixed by commit 4d0ab3a6885e ("ipv6: Start path selection from the first nexthop"). Therefore we can now revive this GRE patch (no changes since original commit 183185a18ff9 ("gre: Fix IPv6 link-local address generation.").
--- net/ipv6/addrconf.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
net/ipv6/addrconf.c +9 -6
@@ -3214,16 +3214,13 @@ static void add_v4_addrs(struct inet6_dev *idev)struct in6_addr addr;struct net_device *dev;struct net *net =dev_net (idev->dev); -int scope, plen, offset =0 ; +int scope, plen;u32 pflags =0 ;ASSERT_RTNL ();memset (&addr,0 ,sizeof (struct in6_addr )); -/* in case of IP6GRE the dev_addr is an IPv6 and therefore we use only the last 4 bytes */ -if (idev->dev->addr_len ==sizeof (struct in6_addr )) - offset =sizeof (struct in6_addr ) -4 ; -memcpy (&addr.s6_addr32[3 ], idev->dev->dev_addr + offset,4 ); +memcpy (&addr.s6_addr32[3 ], idev->dev->dev_addr,4 );if (!(idev->dev->flags &IFF_POINTOPOINT ) && idev->dev->type ==ARPHRD_SIT ) { scope = IPV6_ADDR_COMPATv4;
@@ -3534,7 +3531,13 @@ static void addrconf_gre_config(struct net_device *dev)return ; } -if (dev->type ==ARPHRD_ETHER ) { +/* Generate the IPv6 link-local address using addrconf_addr_gen(), +* unless we have an IPv4 GRE device not bound to an IP address and +* which is in EUI64 mode (as __ipv6_isatap_ifid() would fail in this +* case). Such devices fall back to add_v4_addrs() instead. +*/ +if (!(dev->type ==ARPHRD_IPGRE && *(__be32 *)dev->dev_addr ==0 && + idev->cnf.addr_gen_mode ==IN6_ADDR_GEN_MODE_EUI64 )) {addrconf_addr_gen (idev, true);return ; }
Signature · 1 line
2.39.2
Re: [PATCH net 1/2] gre: Fix again IPv6 link-local address generation.
Quoted 61 lines · Guillaume Nault
Use
addrconf_addr_gen()to generate IPv6 link-local addresses on GRE devices in most cases and fall back to usingadd_v4_addrs()only in case the GRE configuration is incompatible withaddrconf_addr_gen().GRE used to use
addrconf_addr_gen()until commite5dd729460ca("ip/ip6_gre:
use the same logic as SIT interfaces when computing v6LL address") restricted this use to gretap and ip6gretap devices, and createdadd_v4_addrs()(borrowed from SIT) for non-Ethernet GRE ones.The original problem came when commit
9af28511be10("addrconf: refuse isatap eui64 forINADDR_ANY") made__ipv6_isatap_ifid()fail when its addr parameter was 0. The commit says that this would create an invalid address, however, I couldn't find any RFC saying that the generated interface identifier would be wrong. Anyway, since gre over IPv4 devices pass their local tunnel address to__ipv6_isatap_ifid(), that commit broke their IPv6 link-local address generation when the local address was unspecified.Then commit
e5dd729460ca("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address") tried to fix that case by definingadd_v4_addrs()and calling it to generate the IPv6 link-local address instead of usingaddrconf_addr_gen()(apart for gretap and ip6gretap devices, which would still use the regularaddrconf_addr_gen(), since they have a MAC address).That broke several use cases because
add_v4_addrs()isn't properly integrated into the rest of IPv6 Neighbor Discovery code. Several of these shortcomings have been fixed over time, butadd_v4_addrs()remains broken on several aspects. In particular, it doesn't send any Router Sollicitations, so the SLAAC process doesn't start until the interface receives a Router Advertisement. Also,add_v4_addrs()mostly ignores the address generation mode of the interface (/proc/sys/net/ipv6/conf/*/addr_gen_mode), thus breaking theIN6_ADDR_GEN_MODE_RANDOMandIN6_ADDR_GEN_MODE_STABLE_PRIVACYcases.Fix the situation by using
add_v4_addrs()only in the specific scenario where the normal method would fail. That is, for interfaces that have all of the following characteristics:* run over IPv4,
* transport IP packets directly, not Ethernet (that is, not gretap interfaces),
* tunnel endpoint isINADDR_ANY(that is, 0),
* device address generation mode is EUI64.In all other cases, revert back to the regular
addrconf_addr_gen().Also, remove the special case for ip6gre interfaces in
add_v4_addrs(), since ip6gre devices now always useaddrconf_addr_gen()instead.Note:
This patch was originally applied as commit183185a18ff9("gre: Fix IPv6 link-local address generation."). However, it was then reverted by commitfc486c2d060f("Revert "gre: Fix IPv6 link-local address generation."") because it uncovered another bug that ended up breakingnet/forwarding/ip6gre_custom_multipath_hash.sh. That other bug has now been fixed by commit4d0ab3a6885e("ipv6: Start path selection from the first nexthop"). Therefore we can now revive this GRE patch (no changes since original commit183185a18ff9("gre: Fix IPv6 link-local address generation.").
Quoted 2 lines
Fixes e5dd729460ca ("ip/ip6_gre: use the same logic as SIT interfaces when computing v6LL address")Signed-off-by Guillaume Nault <[email protected]>
PATCH 2/2 selftests: Add IPv6 link-local address generation tests for GRE devices.
In reply to Guillaume NaultGRE devices have their special code for IPv6 link-local address generation that has been the source of several regressions in the past.
Add selftest to check that all gre, ip6gre, gretap and ip6gretap get an IPv6 link-link local address in accordance with the net.ipv6.conf.<dev>.addr_gen_mode sysctl.
Note:
This patch was originally applied as commit 6f50175ccad4 ("selftests:
Add IPv6 link-local address generation tests for GRE devices."). However, it was then reverted by commit 355d940f4d5a ("Revert "selftests:
Add IPv6 link-local address generation tests for GRE devices."") because the commit it depended on was going to be reverted. Now that the situation is resolved, we can add this selftest again (no changes since original patch, appart from context update in tools/testing/selftests/net/Makefile).
--- tools/testing/selftests/net/Makefile | 1 + .../testing/selftests/net/gre_ipv6_lladdr.sh | 177 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100755 tools/testing/selftests/net/gre_ipv6_lladdr.sh
tools/testing/selftests/net/Makefile +1 -0
@@ -31,6 +31,7 @@ TEST_PROGS += veth.sh TEST_PROGS += ioam6.sh TEST_PROGS += gro.sh TEST_PROGS += gre_gso.sh +TEST_PROGS += gre_ipv6_lladdr.sh TEST_PROGS += cmsg_so_mark.sh TEST_PROGS += cmsg_so_priority.sh TEST_PROGS += test_so_rcv.sh
tools/testing/selftests/net/gre_ipv6_lladdr.sh new file +177 -0
177 lines not on this page · raw message
Signature · 1 line
2.39.2
Re: [PATCH net 2/2] selftests: Add IPv6 link-local address generation tests for GRE devices.
Quoted 16 lines · Guillaume Nault
GRE devices have their special code for IPv6 link-local address generation that has been the source of several regressions in the past.
Add selftest to check that all gre, ip6gre, gretap and ip6gretap get an IPv6 link-link local address in accordance with the net.ipv6.conf.<dev>.addr_gen_mode sysctl.
Note:
This patch was originally applied as commit6f50175ccad4("selftests:
Add IPv6 link-local address generation tests for GRE devices."). However, it was then reverted by commit355d940f4d5a("Revert "selftests:
Add IPv6 link-local address generation tests for GRE devices."") because the commit it depended on was going to be reverted. Now that the situation is resolved, we can add this selftest again (no changes since original patch, appart from context update intools/testing/selftests/net/Makefile).
Quoted 1 line
Signed-off-by Guillaume Nault <[email protected]>
This series was applied to netdev/net.git (main) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net.git (main)
by Jakub Kicinski <[email protected]>:
Quoted 11 lines · On Sat, 3 May 2025 00:57:45 +0200 you wrote:
Reintroduce the IPv6 link-local address generation fix for GRE and its kernel selftest. These patches were introduced by merge commit
b3fc5927de4b("Merge branch 'gre-fix-regressions-in-ipv6-link-local-address-generation'") but have been reverted by commit8417db0be5bb("Merge branch 'gre-revert-ipv6-link-local-address-fix'"), because it uncovered another bug in multipath routing. Now that this bug has been investigated and fixed, we can apply the GRE link-local address fix and its kernel selftest again.[...]
Here is the summary with links:
- [net,1/2] gre: Fix again IPv6 link-local address generation.
https://git.kernel.org/netdev/net/c/3e6a0243ff00 - [net,2/2] selftests: Add IPv6 link-local address generation tests for GRE devices. https://git.kernel.org/netdev/net/c/b6a6006b0e3d
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html