]> Pileus Git - ~andy/linux/blobdiff - net/xfrm/xfrm_output.c
xfrm: make local error reporting more robust
[~andy/linux] / net / xfrm / xfrm_output.c
index 0cf003dfa8fcd3d4f2f974f21649b164f76429b3..6f5fc612b162f699069a85bab552b14b29744aa8 100644 (file)
@@ -89,7 +89,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 
                err = x->type->output(x, skb);
                if (err == -EINPROGRESS)
-                       goto out_exit;
+                       goto out;
 
 resume:
                if (err) {
@@ -107,15 +107,14 @@ resume:
                x = dst->xfrm;
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
-       err = 0;
+       return 0;
 
-out_exit:
-       return err;
 error:
        spin_unlock_bh(&x->lock);
 error_nolock:
        kfree_skb(skb);
-       goto out_exit;
+out:
+       return err;
 }
 
 int xfrm_output_resume(struct sk_buff *skb, int err)
@@ -215,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);