diff mbox

[RFC] xfrm{4,6}: only report errors back to local sockets if we don't cross address family

Message ID 20130808224440.GJ14001@order.stressinduktion.org
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Hannes Frederic Sowa Aug. 8, 2013, 10:44 p.m. UTC
On Thu, Aug 01, 2013 at 12:05:22PM +0200, Steffen Klassert wrote:
> On Thu, Aug 01, 2013 at 10:11:50AM +0200, Hannes Frederic Sowa wrote:
> > 
> > If you have not yet done so, I would try to find a solution over the weekend.
> > 
> 
> I have not yet done so, please go ahead.

Ok, this patch should do the trick. In xfrm6 error path we now generate
a plain icmpv6 packet back to us in this specific case vi0oss reported. I
wonder if we should suppress these.

Btw. is the memset(IPCB, 0) actually needed in the ipv4 output path?

[PATCH RFC] net: orphan socket when skb traverses tunnel interface

When a local generated packet traverses a tunnel the socket has to be
orphaned from the skb. Otherwise lower layer, like xfrm, try to report
errors directly to this socket. If, because of a transitioning tunnel,
the address family changes we deliver an invalid error or panic in the
error reporting functions.

Also add a call to secpath_reset() in the ipv6 tunnel xmit path. It
seems like it was just forgotten.

Reported-by: <vi0oss@gmail.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
 include/net/ip6_tunnel.h  | 5 +++++
 net/ipv4/ip_tunnel_core.c | 1 +
 2 files changed, 6 insertions(+)

Comments

Eric Dumazet Aug. 8, 2013, 10:57 p.m. UTC | #1
On Fri, 2013-08-09 at 00:44 +0200, Hannes Frederic Sowa wrote:
> On Thu, Aug 01, 2013 at 12:05:22PM +0200, Steffen Klassert wrote:
> > On Thu, Aug 01, 2013 at 10:11:50AM +0200, Hannes Frederic Sowa wrote:
> > > 
> > > If you have not yet done so, I would try to find a solution over the weekend.
> > > 
> > 
> > I have not yet done so, please go ahead.
> 
> Ok, this patch should do the trick. In xfrm6 error path we now generate
> a plain icmpv6 packet back to us in this specific case vi0oss reported. I
> wonder if we should suppress these.
> 
> Btw. is the memset(IPCB, 0) actually needed in the ipv4 output path?
> 
> [PATCH RFC] net: orphan socket when skb traverses tunnel interface
> 
> When a local generated packet traverses a tunnel the socket has to be
> orphaned from the skb. Otherwise lower layer, like xfrm, try to report
> errors directly to this socket. If, because of a transitioning tunnel,
> the address family changes we deliver an invalid error or panic in the
> error reporting functions.
> 
> Also add a call to secpath_reset() in the ipv6 tunnel xmit path. It
> seems like it was just forgotten.
> 
> Reported-by: <vi0oss@gmail.com>
> Cc: Steffen Klassert <steffen.klassert@secunet.com>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> ---

Doing so breaks flow control.

A single socket can flood and fill the Qdisc, even a friendly one like a
local TCP flow (see TCP Small Queues)

Can't we make the error reporting more robust instead ?


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hannes Frederic Sowa Aug. 8, 2013, 11:06 p.m. UTC | #2
On Thu, Aug 08, 2013 at 03:57:57PM -0700, Eric Dumazet wrote:
> On Fri, 2013-08-09 at 00:44 +0200, Hannes Frederic Sowa wrote:
> > On Thu, Aug 01, 2013 at 12:05:22PM +0200, Steffen Klassert wrote:
> > > On Thu, Aug 01, 2013 at 10:11:50AM +0200, Hannes Frederic Sowa wrote:
> > > > 
> > > > If you have not yet done so, I would try to find a solution over the weekend.
> > > > 
> > > 
> > > I have not yet done so, please go ahead.
> > 
> > Ok, this patch should do the trick. In xfrm6 error path we now generate
> > a plain icmpv6 packet back to us in this specific case vi0oss reported. I
> > wonder if we should suppress these.
> > 
> > Btw. is the memset(IPCB, 0) actually needed in the ipv4 output path?
> > 
> > [PATCH RFC] net: orphan socket when skb traverses tunnel interface
> > 
> > When a local generated packet traverses a tunnel the socket has to be
> > orphaned from the skb. Otherwise lower layer, like xfrm, try to report
> > errors directly to this socket. If, because of a transitioning tunnel,
> > the address family changes we deliver an invalid error or panic in the
> > error reporting functions.
> > 
> > Also add a call to secpath_reset() in the ipv6 tunnel xmit path. It
> > seems like it was just forgotten.
> > 
> > Reported-by: <vi0oss@gmail.com>
> > Cc: Steffen Klassert <steffen.klassert@secunet.com>
> > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> > ---
> 
> Doing so breaks flow control.
> 
> A single socket can flood and fill the Qdisc, even a friendly one like a
> local TCP flow (see TCP Small Queues)
> 
> Can't we make the error reporting more robust instead ?

Hm, I thought so. My other patch (some mails above in this thread) checks for
a switch in address family and does prohibit the panic, but generates wrong
error reports back to the socket if the address family does not switch (which
maybe get ignored).

I will check if the skb->encapsulated bit could help. Actually I don't
know what the correct behaviour for error reporting should be in the end,
maybe: dispatch packet back to tunnel interface, let tunnel interface
decapsulate the inner packet and use this inner header to inform the
original socket about the error.

Thanks,

  Hannes

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 4da5de1..92770de 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -6,6 +6,8 @@ 
 #include <linux/if_tunnel.h>
 #include <linux/ip6_tunnel.h>
 
+#include <net/xfrm.h>
+
 #define IP6TUNNEL_ERR_TIMEO (30*HZ)
 
 /* capable of sending packets */
@@ -74,7 +76,10 @@  static inline void ip6tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct net_device_stats *stats = &dev->stats;
 	int pkt_len, err;
 
+	skb_orphan(skb);
 	nf_reset(skb);
+	secpath_reset(skb);
+	skb->rxhash = 0;
 	pkt_len = skb->len;
 	err = ip6_local_out(skb);
 
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 7167b08..8a1a378 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -55,6 +55,7 @@  int iptunnel_xmit(struct net *net, struct rtable *rt,
 	struct iphdr *iph;
 	int err;
 
+	skb_orphan(skb);
 	nf_reset(skb);
 	secpath_reset(skb);
 	skb->rxhash = 0;