diff options
Diffstat (limited to 'net/ipv4')
-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/ipv4/route.c | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 5 |
4 files changed, 19 insertions, 22 deletions
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index c1a6146250..1741d555ad 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, | |||
434 | } *inside; | 434 | } *inside; |
435 | struct ip_conntrack_tuple inner, target; | 435 | struct ip_conntrack_tuple inner, target; |
436 | int hdrlen = (*pskb)->nh.iph->ihl * 4; | 436 | int hdrlen = (*pskb)->nh.iph->ihl * 4; |
437 | unsigned long statusbit; | ||
437 | 438 | ||
438 | if (!skb_make_writable(pskb, hdrlen + sizeof(*inside))) | 439 | if (!skb_make_writable(pskb, hdrlen + sizeof(*inside))) |
439 | return 0; | 440 | return 0; |
@@ -495,17 +496,16 @@ int ip_nat_icmp_reply_translation(struct sk_buff **pskb, | |||
495 | 496 | ||
496 | /* Change outer to look the reply to an incoming packet | 497 | /* Change outer to look the reply to an incoming packet |
497 | * (proto 0 means don't invert per-proto part). */ | 498 | * (proto 0 means don't invert per-proto part). */ |
499 | if (manip == IP_NAT_MANIP_SRC) | ||
500 | statusbit = IPS_SRC_NAT; | ||
501 | else | ||
502 | statusbit = IPS_DST_NAT; | ||
498 | 503 | ||
499 | /* Obviously, we need to NAT destination IP, but source IP | 504 | /* Invert if this is reply dir. */ |
500 | should be NAT'ed only if it is from a NAT'd host. | 505 | if (dir == IP_CT_DIR_REPLY) |
506 | statusbit ^= IPS_NAT_MASK; | ||
501 | 507 | ||
502 | Explanation: some people use NAT for anonymizing. Also, | 508 | if (ct->status & statusbit) { |
503 | CERT recommends dropping all packets from private IP | ||
504 | addresses (although ICMP errors from internal links with | ||
505 | such addresses are not too uncommon, as Alan Cox points | ||
506 | out) */ | ||
507 | if (manip != IP_NAT_MANIP_SRC | ||
508 | || ((*pskb)->nh.iph->saddr == ct->tuplehash[dir].tuple.src.ip)) { | ||
509 | invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); | 509 | invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); |
510 | if (!manip_pkt(0, pskb, 0, &target, manip)) | 510 | if (!manip_pkt(0, pskb, 0, &target, manip)) |
511 | return 0; | 511 | return 0; |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 7c3f7d3802..ab1f88fa21 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, | |||
200 | const struct net_device *out, | 200 | const struct net_device *out, |
201 | int (*okfn)(struct sk_buff *)) | 201 | int (*okfn)(struct sk_buff *)) |
202 | { | 202 | { |
203 | struct ip_conntrack *ct; | ||
204 | enum ip_conntrack_info ctinfo; | ||
205 | unsigned int ret; | 203 | unsigned int ret; |
204 | u_int32_t daddr = (*pskb)->nh.iph->daddr; | ||
206 | 205 | ||
207 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); | 206 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); |
208 | if (ret != NF_DROP && ret != NF_STOLEN | 207 | if (ret != NF_DROP && ret != NF_STOLEN |
209 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { | 208 | && daddr != (*pskb)->nh.iph->daddr) { |
210 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 209 | dst_release((*pskb)->dst); |
211 | 210 | (*pskb)->dst = NULL; | |
212 | if (ct->tuplehash[dir].tuple.dst.ip != | ||
213 | ct->tuplehash[!dir].tuple.src.ip) { | ||
214 | dst_release((*pskb)->dst); | ||
215 | (*pskb)->dst = NULL; | ||
216 | } | ||
217 | } | 211 | } |
218 | return ret; | 212 | return ret; |
219 | } | 213 | } |
@@ -276,7 +270,7 @@ ip_nat_local_fn(unsigned int hooknum, | |||
276 | ct->tuplehash[!dir].tuple.src.ip | 270 | ct->tuplehash[!dir].tuple.src.ip |
277 | #ifdef CONFIG_XFRM | 271 | #ifdef CONFIG_XFRM |
278 | || ct->tuplehash[dir].tuple.dst.u.all != | 272 | || ct->tuplehash[dir].tuple.dst.u.all != |
279 | ct->tuplehash[dir].tuple.src.u.all | 273 | ct->tuplehash[!dir].tuple.src.u.all |
280 | #endif | 274 | #endif |
281 | ) | 275 | ) |
282 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; | 276 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d82c242ea7..fca5fe0cf9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -835,7 +835,7 @@ static int rt_garbage_collect(void) | |||
835 | int r; | 835 | int r; |
836 | 836 | ||
837 | rthp = rt_remove_balanced_route( | 837 | rthp = rt_remove_balanced_route( |
838 | &rt_hash_table[i].chain, | 838 | &rt_hash_table[k].chain, |
839 | rth, | 839 | rth, |
840 | &r); | 840 | &r); |
841 | goal -= r; | 841 | goal -= r; |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 45f7ae58f2..f285bbf296 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -35,6 +35,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) | |||
35 | if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/ | 35 | if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/ |
36 | xdst->u.rt.fl.fl4_dst == fl->fl4_dst && | 36 | xdst->u.rt.fl.fl4_dst == fl->fl4_dst && |
37 | xdst->u.rt.fl.fl4_src == fl->fl4_src && | 37 | xdst->u.rt.fl.fl4_src == fl->fl4_src && |
38 | xdst->u.rt.fl.fl4_tos == fl->fl4_tos && | ||
38 | xfrm_bundle_ok(xdst, fl, AF_INET)) { | 39 | xfrm_bundle_ok(xdst, fl, AF_INET)) { |
39 | dst_clone(dst); | 40 | dst_clone(dst); |
40 | break; | 41 | break; |
@@ -61,7 +62,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
61 | .nl_u = { | 62 | .nl_u = { |
62 | .ip4_u = { | 63 | .ip4_u = { |
63 | .saddr = local, | 64 | .saddr = local, |
64 | .daddr = remote | 65 | .daddr = remote, |
66 | .tos = fl->fl4_tos | ||
65 | } | 67 | } |
66 | } | 68 | } |
67 | }; | 69 | }; |
@@ -230,6 +232,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) | |||
230 | fl->proto = iph->protocol; | 232 | fl->proto = iph->protocol; |
231 | fl->fl4_dst = iph->daddr; | 233 | fl->fl4_dst = iph->daddr; |
232 | fl->fl4_src = iph->saddr; | 234 | fl->fl4_src = iph->saddr; |
235 | fl->fl4_tos = iph->tos; | ||
233 | } | 236 | } |
234 | 237 | ||
235 | static inline int xfrm4_garbage_collect(void) | 238 | static inline int xfrm4_garbage_collect(void) |