diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/skbuff.c | 10 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_core.c | 18 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 16 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 2 |
4 files changed, 17 insertions, 29 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6766f118f07..2144952d1c6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -411,6 +411,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) C(pkt_type); C(ip_summed); C(priority); +#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) + C(ipvs_property); +#endif C(protocol); n->destructor = NULL; #ifdef CONFIG_NETFILTER @@ -422,13 +425,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) C(nfct_reasm); nf_conntrack_get_reasm(skb->nfct_reasm); #endif -#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) - C(ipvs_property); -#endif -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) - C(nfct_reasm); - nf_conntrack_get_reasm(skb->nfct_reasm); -#endif #ifdef CONFIG_BRIDGE_NETFILTER C(nf_bridge); nf_bridge_get(skb->nf_bridge); diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index c1a61462507..1741d555ad0 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -434,6 +434,7 @@ int ip_nat_icmp_reply_translation(struct sk_buff **pskb, } *inside; struct ip_conntrack_tuple inner, target; int hdrlen = (*pskb)->nh.iph->ihl * 4; + unsigned long statusbit; if (!skb_make_writable(pskb, hdrlen + sizeof(*inside))) return 0; @@ -495,17 +496,16 @@ int ip_nat_icmp_reply_translation(struct sk_buff **pskb, /* Change outer to look the reply to an incoming packet * (proto 0 means don't invert per-proto part). */ + if (manip == IP_NAT_MANIP_SRC) + statusbit = IPS_SRC_NAT; + else + statusbit = IPS_DST_NAT; - /* Obviously, we need to NAT destination IP, but source IP - should be NAT'ed only if it is from a NAT'd host. + /* Invert if this is reply dir. */ + if (dir == IP_CT_DIR_REPLY) + statusbit ^= IPS_NAT_MASK; - Explanation: some people use NAT for anonymizing. Also, - CERT recommends dropping all packets from private IP - addresses (although ICMP errors from internal links with - such addresses are not too uncommon, as Alan Cox points - out) */ - if (manip != IP_NAT_MANIP_SRC - || ((*pskb)->nh.iph->saddr == ct->tuplehash[dir].tuple.src.ip)) { + if (ct->status & statusbit) { invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); if (!manip_pkt(0, pskb, 0, &target, manip)) return 0; diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 7c3f7d38024..ab1f88fa21e 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -200,20 +200,14 @@ ip_nat_in(unsigned int hooknum, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - struct ip_conntrack *ct; - enum ip_conntrack_info ctinfo; unsigned int ret; + u_int32_t daddr = (*pskb)->nh.iph->daddr; ret = ip_nat_fn(hooknum, pskb, in, out, okfn); if (ret != NF_DROP && ret != NF_STOLEN - && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { - enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); - - if (ct->tuplehash[dir].tuple.dst.ip != - ct->tuplehash[!dir].tuple.src.ip) { - dst_release((*pskb)->dst); - (*pskb)->dst = NULL; - } + && daddr != (*pskb)->nh.iph->daddr) { + dst_release((*pskb)->dst); + (*pskb)->dst = NULL; } return ret; } @@ -276,7 +270,7 @@ ip_nat_local_fn(unsigned int hooknum, ct->tuplehash[!dir].tuple.src.ip #ifdef CONFIG_XFRM || ct->tuplehash[dir].tuple.dst.u.all != - ct->tuplehash[dir].tuple.src.u.all + ct->tuplehash[!dir].tuple.src.u.all #endif ) return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 98ec53bd3ac..5e6b05ac126 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -885,8 +885,6 @@ restart: * We can't enlist stable bundles either. */ write_unlock_bh(&policy->lock); - - xfrm_pol_put(policy); if (dst) dst_free(dst); |