mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
@ 2026-09-13 19:44 Andrea Mayer
  2026-09-13 20:19 ` David Ahern
  2026-09-14  6:34 ` Hangbin Liu
  0 siblings, 2 replies; 3+ messages in thread
From: Andrea Mayer @ 2026-09-13 19:44 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Simon Horman
  Cc: netdev, linux-kernel, David Lebrun, Stefano Salsano, Andrea Mayer

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>
---
 net/ipv6/seg6_local.c | 3 +++
 1 file changed, 3 insertions(+)

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;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
  2026-09-13 19:44 [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Andrea Mayer
@ 2026-09-13 20:19 ` David Ahern
  2026-09-14  6:34 ` Hangbin Liu
  1 sibling, 0 replies; 3+ messages in thread
From: David Ahern @ 2026-09-13 20:19 UTC (permalink / raw)
  To: Andrea Mayer, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman
  Cc: netdev, linux-kernel, David Lebrun, Stefano Salsano

On 9/13/26 2:44 PM, Andrea Mayer wrote:
> 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>
> ---
>  net/ipv6/seg6_local.c | 3 +++
>  1 file changed, 3 insertions(+)
> 

Reviewed-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
  2026-09-13 19:44 [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Andrea Mayer
  2026-09-13 20:19 ` David Ahern
@ 2026-09-14  6:34 ` Hangbin Liu
  1 sibling, 0 replies; 3+ messages in thread
From: Hangbin Liu @ 2026-09-14  6:34 UTC (permalink / raw)
  To: Andrea Mayer
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	David Ahern, Simon Horman, netdev, linux-kernel, David Lebrun,
	Stefano Salsano

On Sun, Sep 13, 2026 at 09:44:21PM +0200, Andrea Mayer wrote:
> 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>
> ---
>  net/ipv6/seg6_local.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> 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;
> -- 
> 2.43.0
> 

Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-14  6:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-13 19:44 [PATCH net] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Andrea Mayer
2026-09-13 20:19 ` David Ahern
2026-09-14  6:34 ` Hangbin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®