aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAndrea Mayer <andrea.mayer@uniroma2.it>2026-09-13 21:44:21 +0200
committerJakub Kicinski <kuba@kernel.org>2026-09-14 19:03:01 -0700
commit7616242a2b37883f7322aaa1d2bd6cd0fed28315 (patch)
tree14c54b2183cfab0d351bb5507445e285e7291b9c
parentnet: phy: mediatek: do not report link and per-speed LED rules together (diff)
seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
When an SRv6 packet arrives on an interface enslaved to a VRF, vrf_ip6_rcv() sets IP6SKB_L3SLAVE in IP6CB, but decap_and_validate() has never set IPSKB_L3SLAVE in IPCB. The bit stayed clear in the common case, and with CONFIG_IPV6_MIP6 the leftover frag_max_size of a reassembled outer packet could even set it, with no VRF involved. Commit 44930446dde4 ("ipv6: seg6: clear IPv4 control block on IPIP decapsulation") then made the unreliable bit reliably clear. The effect of the missing flag is visible with End.DX4 when a delivery to a local address of the node reaches the socket lookup. For example, a UDP socket bound to the enslaved ingress interface does not receive any of the decapsulated packets, while an unbound socket outside the VRF does. This contradicts Documentation/networking/vrf.rst: by default the scope of an unbound UDP or TCP socket is limited to the default VRF. Set IPSKB_L3SLAVE for IPv4 in decap_and_validate(), which already does the same for IPv6. The socket lookup then matches the decapsulated packet like any other packet received on that enslaved interface. Such a packet matches an unbound UDP or TCP socket only when udp_l3mdev_accept or tcp_l3mdev_accept is set. Fixes: 891ef8dd2a8d ("ipv6: sr: implement additional seg6local actions") Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn> Link: https://patch.msgid.link/20260913194421.31-1-andrea.mayer@uniroma2.it Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/ipv6/seg6_local.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 7b5212220185..d1070aec7b72 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -257,10 +257,13 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
return false;
if (proto == IPPROTO_IPIP) {
+ bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
int iif = IP6CB(skb)->iif;
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
IPCB(skb)->iif = iif;
+ if (l3slave)
+ IPCB(skb)->flags |= IPSKB_L3SLAVE;
} else if (proto == IPPROTO_IPV6) {
bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
int iif = IP6CB(skb)->iif;