summaryrefslogtreecommitdiff
path: root/net/xfrm/xfrm_output.c
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2013-08-14 15:05:23 +0400
committerSteffen Klassert <steffen.klassert@secunet.com>2013-08-14 15:07:12 +0400
commit628e341f319f1a64a4639088faba952e4ec8f0a8 (patch)
tree28fd4b1a02ca00a1abe0b1e71898ab8db6a81dad /net/xfrm/xfrm_output.c
parentd9bf5f130946695063469749bfd190087b7fad39 (diff)
downloadlinux-628e341f319f1a64a4639088faba952e4ec8f0a8.tar.xz
xfrm: make local error reporting more robust
In xfrm4 and xfrm6 we need to take care about sockets of the other address family. This could happen because a 6in4 or 4in6 tunnel could get protected by ipsec. Because we don't want to have a run-time dependency on ipv6 when only using ipv4 xfrm we have to embed a pointer to the correct local_error function in xfrm_state_afinet and look it up when returning an error depending on the socket address family. Thanks to vi0ss for the great bug report: <https://bugzilla.kernel.org/show_bug.cgi?id=58691> v2: a) fix two more unsafe interpretations of skb->sk as ipv6 socket (xfrm6_local_dontfrag and __xfrm6_output) v3: a) add an EXPORT_SYMBOL_GPL(xfrm_local_error) to fix a link error when building ipv6 as a module (thanks to Steffen Klassert) Reported-by: <vi0oss@gmail.com> Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_output.c')
-rw-r--r--net/xfrm/xfrm_output.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index eb4a84288648..6f5fc612b162 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -214,5 +214,18 @@ int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
return inner_mode->afinfo->extract_output(x, skb);
}
+void xfrm_local_error(struct sk_buff *skb, int mtu)
+{
+ struct xfrm_state_afinfo *afinfo;
+
+ afinfo = xfrm_state_get_afinfo(skb->sk->sk_family);
+ if (!afinfo)
+ return;
+
+ afinfo->local_error(skb, mtu);
+ xfrm_state_put_afinfo(afinfo);
+}
+
EXPORT_SYMBOL_GPL(xfrm_output);
EXPORT_SYMBOL_GPL(xfrm_inner_extract_output);
+EXPORT_SYMBOL_GPL(xfrm_local_error);