diff options
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/icmp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ip_gre.c | 3 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 16 | ||||
| -rw-r--r-- | net/ipv4/ipip.c | 3 | ||||
| -rw-r--r-- | net/ipv4/netfilter.c | 41 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 6 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 5 | ||||
| -rw-r--r-- | net/ipv4/xfrm4_output.c | 13 |
8 files changed, 69 insertions, 20 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4d1c40972a4b..e7bbff4340bb 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -192,7 +192,7 @@ int sysctl_icmp_echo_ignore_all; | |||
| 192 | int sysctl_icmp_echo_ignore_broadcasts = 1; | 192 | int sysctl_icmp_echo_ignore_broadcasts = 1; |
| 193 | 193 | ||
| 194 | /* Control parameter - ignore bogus broadcast responses? */ | 194 | /* Control parameter - ignore bogus broadcast responses? */ |
| 195 | int sysctl_icmp_ignore_bogus_error_responses; | 195 | int sysctl_icmp_ignore_bogus_error_responses = 1; |
| 196 | 196 | ||
| 197 | /* | 197 | /* |
| 198 | * Configurable global rate limit. | 198 | * Configurable global rate limit. |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index abe23923e4e7..9981dcd68f11 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -830,7 +830,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 830 | skb->h.raw = skb->nh.raw; | 830 | skb->h.raw = skb->nh.raw; |
| 831 | skb->nh.raw = skb_push(skb, gre_hlen); | 831 | skb->nh.raw = skb_push(skb, gre_hlen); |
| 832 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 832 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
| 833 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); | 833 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
| 834 | IPSKB_REROUTED); | ||
| 834 | dst_release(skb->dst); | 835 | dst_release(skb->dst); |
| 835 | skb->dst = &rt->u.dst; | 836 | skb->dst = &rt->u.dst; |
| 836 | 837 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3324fbfe528a..57d290d89ec2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -207,8 +207,10 @@ static inline int ip_finish_output(struct sk_buff *skb) | |||
| 207 | { | 207 | { |
| 208 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) | 208 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) |
| 209 | /* Policy lookup after SNAT yielded a new policy */ | 209 | /* Policy lookup after SNAT yielded a new policy */ |
| 210 | if (skb->dst->xfrm != NULL) | 210 | if (skb->dst->xfrm != NULL) { |
| 211 | return xfrm4_output_finish(skb); | 211 | IPCB(skb)->flags |= IPSKB_REROUTED; |
| 212 | return dst_output(skb); | ||
| 213 | } | ||
| 212 | #endif | 214 | #endif |
| 213 | if (skb->len > dst_mtu(skb->dst) && | 215 | if (skb->len > dst_mtu(skb->dst) && |
| 214 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | 216 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) |
| @@ -271,8 +273,9 @@ int ip_mc_output(struct sk_buff *skb) | |||
| 271 | newskb->dev, ip_dev_loopback_xmit); | 273 | newskb->dev, ip_dev_loopback_xmit); |
| 272 | } | 274 | } |
| 273 | 275 | ||
| 274 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, | 276 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, |
| 275 | ip_finish_output); | 277 | ip_finish_output, |
| 278 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 276 | } | 279 | } |
| 277 | 280 | ||
| 278 | int ip_output(struct sk_buff *skb) | 281 | int ip_output(struct sk_buff *skb) |
| @@ -284,8 +287,9 @@ int ip_output(struct sk_buff *skb) | |||
| 284 | skb->dev = dev; | 287 | skb->dev = dev; |
| 285 | skb->protocol = htons(ETH_P_IP); | 288 | skb->protocol = htons(ETH_P_IP); |
| 286 | 289 | ||
| 287 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, | 290 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, |
| 288 | ip_finish_output); | 291 | ip_finish_output, |
| 292 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 289 | } | 293 | } |
| 290 | 294 | ||
| 291 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 295 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e5cbe72c6b80..03d13742a4b8 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -622,7 +622,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 622 | skb->h.raw = skb->nh.raw; | 622 | skb->h.raw = skb->nh.raw; |
| 623 | skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); | 623 | skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); |
| 624 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 624 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
| 625 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); | 625 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
| 626 | IPSKB_REROUTED); | ||
| 626 | dst_release(skb->dst); | 627 | dst_release(skb->dst); |
| 627 | skb->dst = &rt->u.dst; | 628 | skb->dst = &rt->u.dst; |
| 628 | 629 | ||
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 52a3d7c57907..ed42cdc57cd9 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -78,6 +78,47 @@ int ip_route_me_harder(struct sk_buff **pskb) | |||
| 78 | } | 78 | } |
| 79 | EXPORT_SYMBOL(ip_route_me_harder); | 79 | EXPORT_SYMBOL(ip_route_me_harder); |
| 80 | 80 | ||
| 81 | #ifdef CONFIG_XFRM | ||
| 82 | int ip_xfrm_me_harder(struct sk_buff **pskb) | ||
| 83 | { | ||
| 84 | struct flowi fl; | ||
| 85 | unsigned int hh_len; | ||
| 86 | struct dst_entry *dst; | ||
| 87 | |||
| 88 | if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) | ||
| 89 | return 0; | ||
| 90 | if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0) | ||
| 91 | return -1; | ||
| 92 | |||
| 93 | dst = (*pskb)->dst; | ||
| 94 | if (dst->xfrm) | ||
| 95 | dst = ((struct xfrm_dst *)dst)->route; | ||
| 96 | dst_hold(dst); | ||
| 97 | |||
| 98 | if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0) | ||
| 99 | return -1; | ||
| 100 | |||
| 101 | dst_release((*pskb)->dst); | ||
| 102 | (*pskb)->dst = dst; | ||
| 103 | |||
| 104 | /* Change in oif may mean change in hh_len. */ | ||
| 105 | hh_len = (*pskb)->dst->dev->hard_header_len; | ||
| 106 | if (skb_headroom(*pskb) < hh_len) { | ||
| 107 | struct sk_buff *nskb; | ||
| 108 | |||
| 109 | nskb = skb_realloc_headroom(*pskb, hh_len); | ||
| 110 | if (!nskb) | ||
| 111 | return -1; | ||
| 112 | if ((*pskb)->sk) | ||
| 113 | skb_set_owner_w(nskb, (*pskb)->sk); | ||
| 114 | kfree_skb(*pskb); | ||
| 115 | *pskb = nskb; | ||
| 116 | } | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | EXPORT_SYMBOL(ip_xfrm_me_harder); | ||
| 120 | #endif | ||
| 121 | |||
| 81 | void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); | 122 | void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); |
| 82 | EXPORT_SYMBOL(ip_nat_decode_session); | 123 | EXPORT_SYMBOL(ip_nat_decode_session); |
| 83 | 124 | ||
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 92c54999a19d..7c3f7d380240 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
| @@ -235,19 +235,19 @@ ip_nat_out(unsigned int hooknum, | |||
| 235 | return NF_ACCEPT; | 235 | return NF_ACCEPT; |
| 236 | 236 | ||
| 237 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); | 237 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); |
| 238 | #ifdef CONFIG_XFRM | ||
| 238 | if (ret != NF_DROP && ret != NF_STOLEN | 239 | if (ret != NF_DROP && ret != NF_STOLEN |
| 239 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { | 240 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { |
| 240 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 241 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
| 241 | 242 | ||
| 242 | if (ct->tuplehash[dir].tuple.src.ip != | 243 | if (ct->tuplehash[dir].tuple.src.ip != |
| 243 | ct->tuplehash[!dir].tuple.dst.ip | 244 | ct->tuplehash[!dir].tuple.dst.ip |
| 244 | #ifdef CONFIG_XFRM | ||
| 245 | || ct->tuplehash[dir].tuple.src.u.all != | 245 | || ct->tuplehash[dir].tuple.src.u.all != |
| 246 | ct->tuplehash[!dir].tuple.dst.u.all | 246 | ct->tuplehash[!dir].tuple.dst.u.all |
| 247 | #endif | ||
| 248 | ) | 247 | ) |
| 249 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; | 248 | return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP; |
| 250 | } | 249 | } |
| 250 | #endif | ||
| 251 | return ret; | 251 | return ret; |
| 252 | } | 252 | } |
| 253 | 253 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 167619f638c6..6c8624a54933 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -529,15 +529,10 @@ static int init_or_cleanup(int init) | |||
| 529 | goto cleanup_localinops; | 529 | goto cleanup_localinops; |
| 530 | } | 530 | } |
| 531 | #endif | 531 | #endif |
| 532 | |||
| 533 | /* For use by REJECT target */ | ||
| 534 | ip_ct_attach = __nf_conntrack_attach; | ||
| 535 | |||
| 536 | return ret; | 532 | return ret; |
| 537 | 533 | ||
| 538 | cleanup: | 534 | cleanup: |
| 539 | synchronize_net(); | 535 | synchronize_net(); |
| 540 | ip_ct_attach = NULL; | ||
| 541 | #ifdef CONFIG_SYSCTL | 536 | #ifdef CONFIG_SYSCTL |
| 542 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | 537 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); |
| 543 | cleanup_localinops: | 538 | cleanup_localinops: |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d4df0ddd424b..32ad229b4fed 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -152,10 +152,16 @@ error_nolock: | |||
| 152 | goto out_exit; | 152 | goto out_exit; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int xfrm4_output_finish(struct sk_buff *skb) | 155 | static int xfrm4_output_finish(struct sk_buff *skb) |
| 156 | { | 156 | { |
| 157 | int err; | 157 | int err; |
| 158 | 158 | ||
| 159 | #ifdef CONFIG_NETFILTER | ||
| 160 | if (!skb->dst->xfrm) { | ||
| 161 | IPCB(skb)->flags |= IPSKB_REROUTED; | ||
| 162 | return dst_output(skb); | ||
| 163 | } | ||
| 164 | #endif | ||
| 159 | while (likely((err = xfrm4_output_one(skb)) == 0)) { | 165 | while (likely((err = xfrm4_output_one(skb)) == 0)) { |
| 160 | nf_reset(skb); | 166 | nf_reset(skb); |
| 161 | 167 | ||
| @@ -178,6 +184,7 @@ int xfrm4_output_finish(struct sk_buff *skb) | |||
| 178 | 184 | ||
| 179 | int xfrm4_output(struct sk_buff *skb) | 185 | int xfrm4_output(struct sk_buff *skb) |
| 180 | { | 186 | { |
| 181 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, | 187 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, |
| 182 | xfrm4_output_finish); | 188 | xfrm4_output_finish, |
| 189 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 183 | } | 190 | } |
