[PATCH 2/3] ipv6: ioam6: use transformed packet nexthdr for ECMP re-lookup
From: Hangbin Liu
Date: Wed Oct 28 2026 - 01:47:05 EST
From: Hangbin Liu <liuhangbin@xxxxxxxxxx>
RFC 9486 (C2) requires that the ECMP hash of a packet carrying IOAM
options is the same as the hash of the identical packet without them.
When the ioam6 output path misses the destination cache, it re-looks
up the route for the transformed packet. Under the default hash
policy 0 that lookup hashed NEXTHDR_HOP rather than the nexthdr the
identical packet without IOAM would carry, so it could pick a
different ECMP sibling.
Use the Hop-by-Hop nexthdr already stored by do_inline()/do_encap()
(eh.nexthdr) for the re-lookup, and precompute the multipath hash
from the packet: ip6_route_output() lookups carry no skb, so without
this ICMPv6 errors would stop hashing their quoted flow and L4 hash
policy packets would lose their ports.
Fixes: 8cb3bf8bff3c ("ipv6: ioam: Add support for the ip6ip6 encapsulation")
Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxxx>
---
net/ipv6/ioam6_iptunnel.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c
index cfb2c41634a0..713e625bfa3a 100644
--- a/net/ipv6/ioam6_iptunnel.c
+++ b/net/ipv6/ioam6_iptunnel.c
@@ -13,6 +13,7 @@
#include <linux/ioam6.h>
#include <linux/ioam6_iptunnel.h>
#include <net/dst.h>
+#include <net/ip6_route.h>
#include <net/sock.h>
#include <net/lwtunnel.h>
#include <net/ioam6.h>
@@ -412,7 +413,8 @@ static int ioam6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
fl6.saddr = hdr->saddr;
fl6.flowlabel = ip6_flowinfo(hdr);
fl6.flowi6_mark = skb->mark;
- fl6.flowi6_proto = hdr->nexthdr;
+ fl6.flowi6_proto = ilwt->tuninfo.eh.nexthdr;
+ fl6.mp_hash = rt6_multipath_hash(net, &fl6, skb, NULL);
dst = ip6_route_output(net, NULL, &fl6);
if (dst->error) {
--
2.56.0