aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/netfilter/iptable_nat.c17
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c17
-rw-r--r--net/netfilter/nf_nat_core.c9
3 files changed, 27 insertions, 16 deletions
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index c2937c81bb67..6383273d54e1 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -176,6 +176,7 @@ nf_nat_ipv4_out(unsigned int hooknum,
176#ifdef CONFIG_XFRM 176#ifdef CONFIG_XFRM
177 const struct nf_conn *ct; 177 const struct nf_conn *ct;
178 enum ip_conntrack_info ctinfo; 178 enum ip_conntrack_info ctinfo;
179 int err;
179#endif 180#endif
180 unsigned int ret; 181 unsigned int ret;
181 182
@@ -195,9 +196,11 @@ nf_nat_ipv4_out(unsigned int hooknum,
195 ct->tuplehash[!dir].tuple.dst.u3.ip) || 196 ct->tuplehash[!dir].tuple.dst.u3.ip) ||
196 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && 197 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
197 ct->tuplehash[dir].tuple.src.u.all != 198 ct->tuplehash[dir].tuple.src.u.all !=
198 ct->tuplehash[!dir].tuple.dst.u.all)) 199 ct->tuplehash[!dir].tuple.dst.u.all)) {
199 if (nf_xfrm_me_harder(skb, AF_INET) < 0) 200 err = nf_xfrm_me_harder(skb, AF_INET);
200 ret = NF_DROP; 201 if (err < 0)
202 ret = NF_DROP_ERR(err);
203 }
201 } 204 }
202#endif 205#endif
203 return ret; 206 return ret;
@@ -235,9 +238,11 @@ nf_nat_ipv4_local_fn(unsigned int hooknum,
235 else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && 238 else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
236 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && 239 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
237 ct->tuplehash[dir].tuple.dst.u.all != 240 ct->tuplehash[dir].tuple.dst.u.all !=
238 ct->tuplehash[!dir].tuple.src.u.all) 241 ct->tuplehash[!dir].tuple.src.u.all) {
239 if (nf_xfrm_me_harder(skb, AF_INET) < 0) 242 err = nf_xfrm_me_harder(skb, AF_INET);
240 ret = NF_DROP; 243 if (err < 0)
244 ret = NF_DROP_ERR(err);
245 }
241#endif 246#endif
242 } 247 }
243 return ret; 248 return ret;
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index 97e2edd8c209..6383f90efda8 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -179,6 +179,7 @@ nf_nat_ipv6_out(unsigned int hooknum,
179#ifdef CONFIG_XFRM 179#ifdef CONFIG_XFRM
180 const struct nf_conn *ct; 180 const struct nf_conn *ct;
181 enum ip_conntrack_info ctinfo; 181 enum ip_conntrack_info ctinfo;
182 int err;
182#endif 183#endif
183 unsigned int ret; 184 unsigned int ret;
184 185
@@ -197,9 +198,11 @@ nf_nat_ipv6_out(unsigned int hooknum,
197 &ct->tuplehash[!dir].tuple.dst.u3) || 198 &ct->tuplehash[!dir].tuple.dst.u3) ||
198 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && 199 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
199 ct->tuplehash[dir].tuple.src.u.all != 200 ct->tuplehash[dir].tuple.src.u.all !=
200 ct->tuplehash[!dir].tuple.dst.u.all)) 201 ct->tuplehash[!dir].tuple.dst.u.all)) {
201 if (nf_xfrm_me_harder(skb, AF_INET6) < 0) 202 err = nf_xfrm_me_harder(skb, AF_INET6);
202 ret = NF_DROP; 203 if (err < 0)
204 ret = NF_DROP_ERR(err);
205 }
203 } 206 }
204#endif 207#endif
205 return ret; 208 return ret;
@@ -236,9 +239,11 @@ nf_nat_ipv6_local_fn(unsigned int hooknum,
236 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 239 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
237 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && 240 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
238 ct->tuplehash[dir].tuple.dst.u.all != 241 ct->tuplehash[dir].tuple.dst.u.all !=
239 ct->tuplehash[!dir].tuple.src.u.all) 242 ct->tuplehash[!dir].tuple.src.u.all) {
240 if (nf_xfrm_me_harder(skb, AF_INET6)) 243 err = nf_xfrm_me_harder(skb, AF_INET6);
241 ret = NF_DROP; 244 if (err < 0)
245 ret = NF_DROP_ERR(err);
246 }
242#endif 247#endif
243 } 248 }
244 return ret; 249 return ret;
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 8d5769c6d16e..346f871cf096 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -87,9 +87,10 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
87 struct flowi fl; 87 struct flowi fl;
88 unsigned int hh_len; 88 unsigned int hh_len;
89 struct dst_entry *dst; 89 struct dst_entry *dst;
90 int err;
90 91
91 if (xfrm_decode_session(skb, &fl, family) < 0) 92 err = xfrm_decode_session(skb, &fl, family);
92 return -1; 93 return err;
93 94
94 dst = skb_dst(skb); 95 dst = skb_dst(skb);
95 if (dst->xfrm) 96 if (dst->xfrm)
@@ -98,7 +99,7 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
98 99
99 dst = xfrm_lookup(dev_net(dst->dev), dst, &fl, skb->sk, 0); 100 dst = xfrm_lookup(dev_net(dst->dev), dst, &fl, skb->sk, 0);
100 if (IS_ERR(dst)) 101 if (IS_ERR(dst))
101 return -1; 102 return PTR_ERR(dst);
102 103
103 skb_dst_drop(skb); 104 skb_dst_drop(skb);
104 skb_dst_set(skb, dst); 105 skb_dst_set(skb, dst);
@@ -107,7 +108,7 @@ int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family)
107 hh_len = skb_dst(skb)->dev->hard_header_len; 108 hh_len = skb_dst(skb)->dev->hard_header_len;
108 if (skb_headroom(skb) < hh_len && 109 if (skb_headroom(skb) < hh_len &&
109 pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) 110 pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
110 return -1; 111 return -ENOMEM;
111 return 0; 112 return 0;
112} 113}
113EXPORT_SYMBOL(nf_xfrm_me_harder); 114EXPORT_SYMBOL(nf_xfrm_me_harder);