* [PATCH RFC net] net: Prevent sk_bound_dev_if causing packet to be rerouted back into tunnel
@ 2025-04-15 4:50 Thomas Winter
2025-04-17 9:06 ` Steffen Klassert
0 siblings, 1 reply; 2+ messages in thread
From: Thomas Winter @ 2025-04-15 4:50 UTC (permalink / raw)
To: steffen.klassert, herbert, davem, dsahern, edumazet, kuba, pabeni,
horms, netdev, linux-kernel
Cc: Thomas Winter
We have found a situation where packets going into an IPsec tunnel get
encapsulated twice. For example, an icmp socket using SO_BINDTODEVICE
of a tunnel and some mangle rules to implement policy based routing.
After the first ESP encapsulation and running through the mangle table
again, a difference in skb->mark causes ip_route_me_harder to be called
but skb->sk->sk_bound_dev_if is still the tunnel. This causes the ESP
packet to get routed back into the tunnel and get xfrm'd again using
the same SA. The double encapsulated is then routed correctly out the
physical interface.
With a xfrmi interface on the other side, it was dropping the packet
with LINUX_MIB_XFRMINTMPLMISMATCH. A ipvti interface would accept it.
However the transmitting side should not have been doing the double
ESP encapsulation in the first place.
A potential fix for this is to drop the reference to skb->sk using
skb_orphan before transmission. scrub_packet would do this but only
if the packet is traversing namespaces. This allows ip_route_me_harder
to select the correct route for the ESP packet without getting fooled
by a sk_bound_dev_if of itself and get forwarded out the physical
interface.
Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
---
net/ipv4/ip_vti.c | 1 +
net/ipv6/ip6_vti.c | 1 +
net/xfrm/xfrm_interface_core.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 159b4473290e..096e9b51816f 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -260,6 +260,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
skb_dst_set(skb, dst);
skb->dev = skb_dst(skb)->dev;
+ skb_orphan(skb);
err = dst_output(tunnel->net, skb->sk, skb);
if (net_xmit_eval(err) == 0)
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 09ec4b0ad7dc..d1d5bbaa3d6d 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -530,6 +530,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
skb_dst_set(skb, dst);
skb->dev = skb_dst(skb)->dev;
+ skb_orphan(skb);
err = dst_output(t->net, skb->sk, skb);
if (net_xmit_eval(err) == 0)
diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c
index 622445f041d3..17b26409e6a0 100644
--- a/net/xfrm/xfrm_interface_core.c
+++ b/net/xfrm/xfrm_interface_core.c
@@ -504,6 +504,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
xfrmi_scrub_packet(skb, !net_eq(xi->net, dev_net(dev)));
skb_dst_set(skb, dst);
skb->dev = tdev;
+ skb_orphan(skb);
err = dst_output(xi->net, skb_to_full_sk(skb), skb);
if (net_xmit_eval(err) == 0) {
--
2.49.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH RFC net] net: Prevent sk_bound_dev_if causing packet to be rerouted back into tunnel
2025-04-15 4:50 [PATCH RFC net] net: Prevent sk_bound_dev_if causing packet to be rerouted back into tunnel Thomas Winter
@ 2025-04-17 9:06 ` Steffen Klassert
0 siblings, 0 replies; 2+ messages in thread
From: Steffen Klassert @ 2025-04-17 9:06 UTC (permalink / raw)
To: Thomas Winter
Cc: herbert, davem, dsahern, edumazet, kuba, pabeni, horms, netdev,
linux-kernel
On Tue, Apr 15, 2025 at 04:50:51PM +1200, Thomas Winter wrote:
> We have found a situation where packets going into an IPsec tunnel get
> encapsulated twice. For example, an icmp socket using SO_BINDTODEVICE
> of a tunnel and some mangle rules to implement policy based routing.
> After the first ESP encapsulation and running through the mangle table
> again, a difference in skb->mark causes ip_route_me_harder to be called
> but skb->sk->sk_bound_dev_if is still the tunnel. This causes the ESP
> packet to get routed back into the tunnel and get xfrm'd again using
> the same SA. The double encapsulated is then routed correctly out the
> physical interface.
>
> With a xfrmi interface on the other side, it was dropping the packet
> with LINUX_MIB_XFRMINTMPLMISMATCH. A ipvti interface would accept it.
> However the transmitting side should not have been doing the double
> ESP encapsulation in the first place.
>
> A potential fix for this is to drop the reference to skb->sk using
> skb_orphan before transmission. scrub_packet would do this but only
> if the packet is traversing namespaces. This allows ip_route_me_harder
> to select the correct route for the ESP packet without getting fooled
> by a sk_bound_dev_if of itself and get forwarded out the physical
> interface.
>
> Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
This looks ok to me.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-04-17 9:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-15 4:50 [PATCH RFC net] net: Prevent sk_bound_dev_if causing packet to be rerouted back into tunnel Thomas Winter
2025-04-17 9:06 ` Steffen Klassert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).