netfilter: nat: propagate errors from xfrm_me_harder()
authorPatrick McHardy <kaber@trash.net>
Fri, 5 Apr 2013 06:41:12 +0000 (06:41 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Apr 2013 10:34:01 +0000 (12:34 +0200)
Propagate errors from ip_xfrm_me_harder() instead of returning EPERM in
all cases.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/ipv4/netfilter/iptable_nat.c
net/ipv6/netfilter/ip6table_nat.c
net/netfilter/nf_nat_core.c

index c2937c81bb679bc4782a369d58980dd7215d2c3c..6383273d54e17da9080dc5b5c12380058a18a3ee 100644 (file)
@@ -176,6 +176,7 @@ nf_nat_ipv4_out(unsigned int hooknum,
 #ifdef CONFIG_XFRM
        const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
+       int err;
 #endif
        unsigned int ret;
 
@@ -195,9 +196,11 @@ nf_nat_ipv4_out(unsigned int hooknum,
                     ct->tuplehash[!dir].tuple.dst.u3.ip) ||
                    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
                     ct->tuplehash[dir].tuple.src.u.all !=
-                    ct->tuplehash[!dir].tuple.dst.u.all))
-                       if (nf_xfrm_me_harder(skb, AF_INET) < 0)
-                               ret = NF_DROP;
+                    ct->tuplehash[!dir].tuple.dst.u.all)) {
+                       err = nf_xfrm_me_harder(skb, AF_INET);
+                       if (err < 0)
+                               ret = NF_DROP_ERR(err);
+               }
        }
 #endif
        return ret;
@@ -235,9 +238,11 @@ nf_nat_ipv4_local_fn(unsigned int hooknum,
                else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
                         ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
                         ct->tuplehash[dir].tuple.dst.u.all !=
-                        ct->tuplehash[!dir].tuple.src.u.all)
-                       if (nf_xfrm_me_harder(skb, AF_INET) < 0)
-                               ret = NF_DROP;
+                        ct->tuplehash[!dir].tuple.src.u.all) {
+                       err = nf_xfrm_me_harder(skb, AF_INET);
+                       if (err < 0)
+                               ret = NF_DROP_ERR(err);
+               }
 #endif
        }
        return ret;
index 97e2edd8c209201006d026c6c775a0cbbce6c3ad..6383f90efda82c23ad04ef05be9deec70bd8c08f 100644 (file)
@@ -179,6 +179,7 @@ nf_nat_ipv6_out(unsigned int hooknum,
 #ifdef CONFIG_XFRM
        const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
+       int err;
 #endif
        unsigned int ret;
 
@@ -197,9 +198,11 @@ nf_nat_ipv6_out(unsigned int hooknum,
                                      &ct->tuplehash[!dir].tuple.dst.u3) ||
                    (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
                     ct->tuplehash[dir].tuple.src.u.all !=
-                    ct->tuplehash[!dir].tuple.dst.u.all))
-                       if (nf_xfrm_me_harder(skb, AF_INET6) < 0)
-                               ret = NF_DROP;
+                    ct->tuplehash[!dir].tuple.dst.u.all)) {
+                       err = nf_xfrm_me_harder(skb, AF_INET6);
+                       if (err < 0)
+                               ret = NF_DROP_ERR(err);
+               }
        }
 #endif
        return ret;
@@ -236,9 +239,11 @@ nf_nat_ipv6_local_fn(unsigned int hooknum,
                else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
                         ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
                         ct->tuplehash[dir].tuple.dst.u.all !=
-                        ct->tuplehash[!dir].tuple.src.u.all)
-                       if (nf_xfrm_me_harder(skb, AF_INET6))
-                               ret = NF_DROP;
+                        ct->tuplehash[!dir].tuple.src.u.all) {
+                       err = nf_xfrm_me_harder(skb, AF_INET6);
+                       if (err < 0)
+                               ret = NF_DROP_ERR(err);
+               }
 #endif
        }
        return ret;
index 8d5769c6d16e505ed6239889faee03ab34d4c15d..346f871cf096489e5eb63f339435043d8b29b7a2 100644 (file)
@@ -87,9 +87,10 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
        struct flowi fl;
        unsigned int hh_len;
        struct dst_entry *dst;
+       int err;
 
-       if (xfrm_decode_session(skb, &fl, family) < 0)
-               return -1;
+       err = xfrm_decode_session(skb, &fl, family);
+               return err;
 
        dst = skb_dst(skb);
        if (dst->xfrm)
@@ -98,7 +99,7 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
 
        dst = xfrm_lookup(dev_net(dst->dev), dst, &fl, skb->sk, 0);
        if (IS_ERR(dst))
-               return -1;
+               return PTR_ERR(dst);
 
        skb_dst_drop(skb);
        skb_dst_set(skb, dst);
@@ -107,7 +108,7 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
        hh_len = skb_dst(skb)->dev->hard_header_len;
        if (skb_headroom(skb) < hh_len &&
            pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
-               return -1;
+               return -ENOMEM;
        return 0;
 }
 EXPORT_SYMBOL(nf_xfrm_me_harder);