aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/esp4.c185
-rw-r--r--net/ipv4/fib_semantics.c2
-rw-r--r--net/ipv4/icmp.c7
-rw-r--r--net/ipv4/igmp.c4
-rw-r--r--net/ipv4/ip_gre.c3
-rw-r--r--net/ipv4/ip_output.c23
-rw-r--r--net/ipv4/ipip.c3
-rw-r--r--net/ipv4/multipath_wrandom.c8
-rw-r--r--net/ipv4/netfilter.c41
-rw-r--r--net/ipv4/netfilter/arp_tables.c9
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c18
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c22
-rw-r--r--net/ipv4/netfilter/ip_queue.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c7
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c7
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c26
-rw-r--r--net/ipv4/netfilter/ipt_policy.c11
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c5
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/tcp_highspeed.c2
-rw-r--r--net/ipv4/tcp_htcp.c1
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv4/xfrm4_output.c13
-rw-r--r--net/ipv4/xfrm4_policy.c6
30 files changed, 226 insertions, 199 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 95b9d81ac4..3ffa60dadc 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1135,7 +1135,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
1135 1135
1136 if (!skb) 1136 if (!skb)
1137 netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, ENOBUFS); 1137 netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, ENOBUFS);
1138 else if (inet_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) { 1138 else if (inet_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
1139 kfree_skb(skb); 1139 kfree_skb(skb);
1140 netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, EINVAL); 1140 netlink_set_err(rtnl, 0, RTNLGRP_IPV4_IFADDR, EINVAL);
1141 } else { 1141 } else {
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 73bfcae8af..09590f3560 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -12,13 +12,6 @@
12#include <net/protocol.h> 12#include <net/protocol.h>
13#include <net/udp.h> 13#include <net/udp.h>
14 14
15/* decapsulation data for use when post-processing */
16struct esp_decap_data {
17 xfrm_address_t saddr;
18 __u16 sport;
19 __u8 proto;
20};
21
22static int esp_output(struct xfrm_state *x, struct sk_buff *skb) 15static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
23{ 16{
24 int err; 17 int err;
@@ -150,6 +143,10 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
150 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; 143 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
151 int nfrags; 144 int nfrags;
152 int encap_len = 0; 145 int encap_len = 0;
146 u8 nexthdr[2];
147 struct scatterlist *sg;
148 u8 workbuf[60];
149 int padlen;
153 150
154 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) 151 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
155 goto out; 152 goto out;
@@ -185,122 +182,82 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
185 if (esp->conf.ivlen) 182 if (esp->conf.ivlen)
186 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 183 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm));
187 184
188 { 185 sg = &esp->sgbuf[0];
189 u8 nexthdr[2];
190 struct scatterlist *sg = &esp->sgbuf[0];
191 u8 workbuf[60];
192 int padlen;
193
194 if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
195 sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
196 if (!sg)
197 goto out;
198 }
199 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
200 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
201 if (unlikely(sg != &esp->sgbuf[0]))
202 kfree(sg);
203
204 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
205 BUG();
206 186
207 padlen = nexthdr[0]; 187 if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
208 if (padlen+2 >= elen) 188 sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
189 if (!sg)
209 goto out; 190 goto out;
210
211 /* ... check padding bits here. Silly. :-) */
212
213 if (x->encap && decap && decap->decap_type) {
214 struct esp_decap_data *encap_data;
215 struct udphdr *uh = (struct udphdr *) (iph+1);
216
217 encap_data = (struct esp_decap_data *) (decap->decap_data);
218 encap_data->proto = 0;
219
220 switch (decap->decap_type) {
221 case UDP_ENCAP_ESPINUDP:
222 case UDP_ENCAP_ESPINUDP_NON_IKE:
223 encap_data->proto = AF_INET;
224 encap_data->saddr.a4 = iph->saddr;
225 encap_data->sport = uh->source;
226 encap_len = (void*)esph - (void*)uh;
227 break;
228
229 default:
230 goto out;
231 }
232 }
233
234 iph->protocol = nexthdr[1];
235 pskb_trim(skb, skb->len - alen - padlen - 2);
236 memcpy(workbuf, skb->nh.raw, iph->ihl*4);
237 skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
238 skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
239 memcpy(skb->nh.raw, workbuf, iph->ihl*4);
240 skb->nh.iph->tot_len = htons(skb->len);
241 } 191 }
192 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
193 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
194 if (unlikely(sg != &esp->sgbuf[0]))
195 kfree(sg);
242 196
243 return 0; 197 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
198 BUG();
244 199
245out: 200 padlen = nexthdr[0];
246 return -EINVAL; 201 if (padlen+2 >= elen)
247} 202 goto out;
248 203
249static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 204 /* ... check padding bits here. Silly. :-) */
250{
251
252 if (x->encap) {
253 struct xfrm_encap_tmpl *encap;
254 struct esp_decap_data *decap_data;
255 205
256 encap = x->encap; 206 if (x->encap) {
257 decap_data = (struct esp_decap_data *)(decap->decap_data); 207 struct xfrm_encap_tmpl *encap = x->encap;
208 struct udphdr *uh;
258 209
259 /* first, make sure that the decap type == the encap type */
260 if (encap->encap_type != decap->decap_type) 210 if (encap->encap_type != decap->decap_type)
261 return -EINVAL; 211 goto out;
262 212
263 switch (encap->encap_type) { 213 uh = (struct udphdr *)(iph + 1);
264 default: 214 encap_len = (void*)esph - (void*)uh;
265 case UDP_ENCAP_ESPINUDP: 215
266 case UDP_ENCAP_ESPINUDP_NON_IKE: 216 /*
267 /* 217 * 1) if the NAT-T peer's IP or port changed then
268 * 1) if the NAT-T peer's IP or port changed then 218 * advertize the change to the keying daemon.
269 * advertize the change to the keying daemon. 219 * This is an inbound SA, so just compare
270 * This is an inbound SA, so just compare 220 * SRC ports.
271 * SRC ports. 221 */
272 */ 222 if (iph->saddr != x->props.saddr.a4 ||
273 if (decap_data->proto == AF_INET && 223 uh->source != encap->encap_sport) {
274 (decap_data->saddr.a4 != x->props.saddr.a4 || 224 xfrm_address_t ipaddr;
275 decap_data->sport != encap->encap_sport)) { 225
276 xfrm_address_t ipaddr; 226 ipaddr.a4 = iph->saddr;
277 227 km_new_mapping(x, &ipaddr, uh->source);
278 ipaddr.a4 = decap_data->saddr.a4; 228
279 km_new_mapping(x, &ipaddr, decap_data->sport); 229 /* XXX: perhaps add an extra
280 230 * policy check here, to see
281 /* XXX: perhaps add an extra 231 * if we should allow or
282 * policy check here, to see 232 * reject a packet from a
283 * if we should allow or 233 * different source
284 * reject a packet from a 234 * address/port.
285 * different source
286 * address/port.
287 */
288 }
289
290 /*
291 * 2) ignore UDP/TCP checksums in case
292 * of NAT-T in Transport Mode, or
293 * perform other post-processing fixes
294 * as per * draft-ietf-ipsec-udp-encaps-06,
295 * section 3.1.2
296 */ 235 */
297 if (!x->props.mode)
298 skb->ip_summed = CHECKSUM_UNNECESSARY;
299
300 break;
301 } 236 }
237
238 /*
239 * 2) ignore UDP/TCP checksums in case
240 * of NAT-T in Transport Mode, or
241 * perform other post-processing fixes
242 * as per draft-ietf-ipsec-udp-encaps-06,
243 * section 3.1.2
244 */
245 if (!x->props.mode)
246 skb->ip_summed = CHECKSUM_UNNECESSARY;
302 } 247 }
248
249 iph->protocol = nexthdr[1];
250 pskb_trim(skb, skb->len - alen - padlen - 2);
251 memcpy(workbuf, skb->nh.raw, iph->ihl*4);
252 skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen);
253 skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
254 memcpy(skb->nh.raw, workbuf, iph->ihl*4);
255 skb->nh.iph->tot_len = htons(skb->len);
256
303 return 0; 257 return 0;
258
259out:
260 return -EINVAL;
304} 261}
305 262
306static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) 263static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
@@ -458,7 +415,6 @@ static struct xfrm_type esp_type =
458 .destructor = esp_destroy, 415 .destructor = esp_destroy,
459 .get_max_size = esp4_get_max_size, 416 .get_max_size = esp4_get_max_size,
460 .input = esp_input, 417 .input = esp_input,
461 .post_input = esp_post_input,
462 .output = esp_output 418 .output = esp_output
463}; 419};
464 420
@@ -470,15 +426,6 @@ static struct net_protocol esp4_protocol = {
470 426
471static int __init esp4_init(void) 427static int __init esp4_init(void)
472{ 428{
473 struct xfrm_decap_state decap;
474
475 if (sizeof(struct esp_decap_data) >
476 sizeof(decap.decap_data)) {
477 extern void decap_data_too_small(void);
478
479 decap_data_too_small();
480 }
481
482 if (xfrm_register_type(&esp_type, AF_INET) < 0) { 429 if (xfrm_register_type(&esp_type, AF_INET) < 0) {
483 printk(KERN_INFO "ip esp init: can't add xfrm type\n"); 430 printk(KERN_INFO "ip esp init: can't add xfrm type\n");
484 return -EAGAIN; 431 return -EAGAIN;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index ef4724de73..0f4145babb 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1045,7 +1045,7 @@ fib_convert_rtentry(int cmd, struct nlmsghdr *nl, struct rtmsg *rtm,
1045 } 1045 }
1046 1046
1047 nl->nlmsg_flags = NLM_F_REQUEST; 1047 nl->nlmsg_flags = NLM_F_REQUEST;
1048 nl->nlmsg_pid = current->pid; 1048 nl->nlmsg_pid = 0;
1049 nl->nlmsg_seq = 0; 1049 nl->nlmsg_seq = 0;
1050 nl->nlmsg_len = NLMSG_LENGTH(sizeof(*rtm)); 1050 nl->nlmsg_len = NLMSG_LENGTH(sizeof(*rtm));
1051 if (cmd == SIOCDELRT) { 1051 if (cmd == SIOCDELRT) {
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 105039eb76..e7bbff4340 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -192,7 +192,7 @@ int sysctl_icmp_echo_ignore_all;
192int sysctl_icmp_echo_ignore_broadcasts = 1; 192int sysctl_icmp_echo_ignore_broadcasts = 1;
193 193
194/* Control parameter - ignore bogus broadcast responses? */ 194/* Control parameter - ignore bogus broadcast responses? */
195int sysctl_icmp_ignore_bogus_error_responses; 195int sysctl_icmp_ignore_bogus_error_responses = 1;
196 196
197/* 197/*
198 * Configurable global rate limit. 198 * Configurable global rate limit.
@@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
385 u32 daddr; 385 u32 daddr;
386 386
387 if (ip_options_echo(&icmp_param->replyopts, skb)) 387 if (ip_options_echo(&icmp_param->replyopts, skb))
388 goto out; 388 return;
389 389
390 if (icmp_xmit_lock()) 390 if (icmp_xmit_lock())
391 return; 391 return;
@@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
416 ip_rt_put(rt); 416 ip_rt_put(rt);
417out_unlock: 417out_unlock:
418 icmp_xmit_unlock(); 418 icmp_xmit_unlock();
419out:;
420} 419}
421 420
422 421
@@ -525,7 +524,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
525 iph->tos; 524 iph->tos;
526 525
527 if (ip_options_echo(&icmp_param.replyopts, skb_in)) 526 if (ip_options_echo(&icmp_param.replyopts, skb_in))
528 goto ende; 527 goto out_unlock;
529 528
530 529
531 /* 530 /*
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index d8ce7133cd..64ce52bf04 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -970,7 +970,7 @@ int igmp_rcv(struct sk_buff *skb)
970 case IGMP_MTRACE_RESP: 970 case IGMP_MTRACE_RESP:
971 break; 971 break;
972 default: 972 default:
973 NETDEBUG(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type); 973 break;
974 } 974 }
975 975
976drop: 976drop:
@@ -1578,7 +1578,7 @@ static int sf_setstate(struct ip_mc_list *pmc)
1578 new_in = psf->sf_count[MCAST_INCLUDE] != 0; 1578 new_in = psf->sf_count[MCAST_INCLUDE] != 0;
1579 if (new_in) { 1579 if (new_in) {
1580 if (!psf->sf_oldin) { 1580 if (!psf->sf_oldin) {
1581 struct ip_sf_list *prev = 0; 1581 struct ip_sf_list *prev = NULL;
1582 1582
1583 for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) { 1583 for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
1584 if (dpsf->sf_inaddr == psf->sf_inaddr) 1584 if (dpsf->sf_inaddr == psf->sf_inaddr)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index abe23923e4..9981dcd68f 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 3324fbfe52..8ee4d01674 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
278int ip_output(struct sk_buff *skb) 281int 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
291int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 295int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
@@ -843,10 +847,11 @@ int ip_append_data(struct sock *sk,
843 if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && 847 if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
844 (rt->u.dst.dev->features & NETIF_F_UFO)) { 848 (rt->u.dst.dev->features & NETIF_F_UFO)) {
845 849
846 if(ip_ufo_append_data(sk, getfrag, from, length, hh_len, 850 err = ip_ufo_append_data(sk, getfrag, from, length, hh_len,
847 fragheaderlen, transhdrlen, mtu, flags)) 851 fragheaderlen, transhdrlen, mtu,
852 flags);
853 if (err)
848 goto error; 854 goto error;
849
850 return 0; 855 return 0;
851 } 856 }
852 857
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index e5cbe72c6b..03d13742a4 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/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index d34a9fa608..342d0b9098 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network,
228 struct multipath_dest *d, *target_dest = NULL; 228 struct multipath_dest *d, *target_dest = NULL;
229 229
230 /* store the weight information for a certain route */ 230 /* store the weight information for a certain route */
231 spin_lock(&state[state_idx].lock); 231 spin_lock_bh(&state[state_idx].lock);
232 232
233 /* find state entry for gateway or add one if necessary */ 233 /* find state entry for gateway or add one if necessary */
234 list_for_each_entry_rcu(r, &state[state_idx].head, list) { 234 list_for_each_entry_rcu(r, &state[state_idx].head, list) {
@@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network,
276 * we are finished 276 * we are finished
277 */ 277 */
278 278
279 spin_unlock(&state[state_idx].lock); 279 spin_unlock_bh(&state[state_idx].lock);
280} 280}
281 281
282static void __multipath_free(struct rcu_head *head) 282static void __multipath_free(struct rcu_head *head)
@@ -302,7 +302,7 @@ static void wrandom_flush(void)
302 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { 302 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
303 struct multipath_route *r; 303 struct multipath_route *r;
304 304
305 spin_lock(&state[i].lock); 305 spin_lock_bh(&state[i].lock);
306 list_for_each_entry_rcu(r, &state[i].head, list) { 306 list_for_each_entry_rcu(r, &state[i].head, list) {
307 struct multipath_dest *d; 307 struct multipath_dest *d;
308 list_for_each_entry_rcu(d, &r->dests, list) { 308 list_for_each_entry_rcu(d, &r->dests, list) {
@@ -315,7 +315,7 @@ static void wrandom_flush(void)
315 __multipath_free); 315 __multipath_free);
316 } 316 }
317 317
318 spin_unlock(&state[i].lock); 318 spin_unlock_bh(&state[i].lock);
319 } 319 }
320} 320}
321 321
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 52a3d7c579..ed42cdc57c 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}
79EXPORT_SYMBOL(ip_route_me_harder); 79EXPORT_SYMBOL(ip_route_me_harder);
80 80
81#ifdef CONFIG_XFRM
82int 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}
119EXPORT_SYMBOL(ip_xfrm_me_harder);
120#endif
121
81void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); 122void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
82EXPORT_SYMBOL(ip_nat_decode_session); 123EXPORT_SYMBOL(ip_nat_decode_session);
83 124
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index afe3d8f817..7d7ab94a7a 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -771,7 +771,7 @@ static int get_entries(const struct arpt_get_entries *entries,
771 struct arpt_table *t; 771 struct arpt_table *t;
772 772
773 t = xt_find_table_lock(NF_ARP, entries->name); 773 t = xt_find_table_lock(NF_ARP, entries->name);
774 if (t || !IS_ERR(t)) { 774 if (t && !IS_ERR(t)) {
775 struct xt_table_info *private = t->private; 775 struct xt_table_info *private = t->private;
776 duprintf("t->private->number = %u\n", 776 duprintf("t->private->number = %u\n",
777 private->number); 777 private->number);
@@ -807,6 +807,13 @@ static int do_replace(void __user *user, unsigned int len)
807 if (len != sizeof(tmp) + tmp.size) 807 if (len != sizeof(tmp) + tmp.size)
808 return -ENOPROTOOPT; 808 return -ENOPROTOOPT;
809 809
810 /* overflow check */
811 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
812 SMP_CACHE_BYTES)
813 return -ENOMEM;
814 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
815 return -ENOMEM;
816
810 newinfo = xt_alloc_table_info(tmp.size); 817 newinfo = xt_alloc_table_info(tmp.size);
811 if (!newinfo) 818 if (!newinfo)
812 return -ENOMEM; 819 return -ENOMEM;
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index c9ebbe0d2d..e0b5926c76 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1216,7 +1216,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1216 1216
1217 b = skb->tail; 1217 b = skb->tail;
1218 1218
1219 type |= NFNL_SUBSYS_CTNETLINK << 8; 1219 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
1220 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 1220 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
1221 nfmsg = NLMSG_DATA(nlh); 1221 nfmsg = NLMSG_DATA(nlh);
1222 1222
@@ -1567,6 +1567,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1567}; 1567};
1568 1568
1569MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); 1569MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1570MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
1570 1571
1571static int __init ctnetlink_init(void) 1572static int __init ctnetlink_init(void)
1572{ 1573{
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index d3c5a371f9..4ba4463cec 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -71,6 +71,7 @@ static int tftp_help(struct sk_buff **pskb,
71 71
72 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; 72 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
73 exp->mask.src.ip = 0xffffffff; 73 exp->mask.src.ip = 0xffffffff;
74 exp->mask.src.u.udp.port = 0;
74 exp->mask.dst.ip = 0xffffffff; 75 exp->mask.dst.ip = 0xffffffff;
75 exp->mask.dst.u.udp.port = 0xffff; 76 exp->mask.dst.u.udp.port = 0xffff;
76 exp->mask.dst.protonum = 0xff; 77 exp->mask.dst.protonum = 0xff;
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 ad438fb185..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.src.ip !=
213 ct->tuplehash[!dir].tuple.dst.ip) {
214 dst_release((*pskb)->dst);
215 (*pskb)->dst = NULL;
216 }
217 } 211 }
218 return ret; 212 return ret;
219} 213}
@@ -235,19 +229,19 @@ ip_nat_out(unsigned int hooknum,
235 return NF_ACCEPT; 229 return NF_ACCEPT;
236 230
237 ret = ip_nat_fn(hooknum, pskb, in, out, okfn); 231 ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
232#ifdef CONFIG_XFRM
238 if (ret != NF_DROP && ret != NF_STOLEN 233 if (ret != NF_DROP && ret != NF_STOLEN
239 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { 234 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
240 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 235 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
241 236
242 if (ct->tuplehash[dir].tuple.src.ip != 237 if (ct->tuplehash[dir].tuple.src.ip !=
243 ct->tuplehash[!dir].tuple.dst.ip 238 ct->tuplehash[!dir].tuple.dst.ip
244#ifdef CONFIG_XFRM
245 || ct->tuplehash[dir].tuple.src.u.all != 239 || ct->tuplehash[dir].tuple.src.u.all !=
246 ct->tuplehash[!dir].tuple.dst.u.all 240 ct->tuplehash[!dir].tuple.dst.u.all
247#endif
248 ) 241 )
249 return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; 242 return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
250 } 243 }
244#endif
251 return ret; 245 return ret;
252} 246}
253 247
@@ -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/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 36339eb39e..08f80e2ea2 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -524,7 +524,7 @@ ipq_rcv_skb(struct sk_buff *skb)
524 write_unlock_bh(&queue_lock); 524 write_unlock_bh(&queue_lock);
525 525
526 status = ipq_receive_peer(NLMSG_DATA(nlh), type, 526 status = ipq_receive_peer(NLMSG_DATA(nlh), type,
527 skblen - NLMSG_LENGTH(0)); 527 nlmsglen - NLMSG_LENGTH(0));
528 if (status < 0) 528 if (status < 0)
529 RCV_SKB_FAIL(status); 529 RCV_SKB_FAIL(status);
530 530
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 2371b2062c..16f47c675f 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -921,6 +921,13 @@ do_replace(void __user *user, unsigned int len)
921 if (len != sizeof(tmp) + tmp.size) 921 if (len != sizeof(tmp) + tmp.size)
922 return -ENOPROTOOPT; 922 return -ENOPROTOOPT;
923 923
924 /* overflow check */
925 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
926 SMP_CACHE_BYTES)
927 return -ENOMEM;
928 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
929 return -ENOMEM;
930
924 newinfo = xt_alloc_table_info(tmp.size); 931 newinfo = xt_alloc_table_info(tmp.size);
925 if (!newinfo) 932 if (!newinfo)
926 return -ENOMEM; 933 return -ENOMEM;
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 6606ddb66a..cc27545ff9 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -425,7 +425,12 @@ ipt_log_target(struct sk_buff **pskb,
425 li.u.log.level = loginfo->level; 425 li.u.log.level = loginfo->level;
426 li.u.log.logflags = loginfo->logflags; 426 li.u.log.logflags = loginfo->logflags;
427 427
428 nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); 428 if (loginfo->logflags & IPT_LOG_NFLOG)
429 nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
430 loginfo->prefix);
431 else
432 ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
433 loginfo->prefix);
429 434
430 return IPT_CONTINUE; 435 return IPT_CONTINUE;
431} 436}
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 641dbc4776..180a9ea57b 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -35,6 +35,10 @@
35 * each nlgroup you are using, so the total kernel memory usage increases 35 * each nlgroup you are using, so the total kernel memory usage increases
36 * by that factor. 36 * by that factor.
37 * 37 *
38 * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since
39 * nlbufsiz is used with alloc_skb, which adds another
40 * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead.
41 *
38 * flushtimeout: 42 * flushtimeout:
39 * Specify, after how many hundredths of a second the queue should be 43 * Specify, after how many hundredths of a second the queue should be
40 * flushed even if it is not full yet. 44 * flushed even if it is not full yet.
@@ -76,7 +80,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
76 80
77#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) 81#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
78 82
79static unsigned int nlbufsiz = 4096; 83static unsigned int nlbufsiz = NLMSG_GOODSIZE;
80module_param(nlbufsiz, uint, 0400); 84module_param(nlbufsiz, uint, 0400);
81MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); 85MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
82 86
@@ -143,22 +147,26 @@ static void ulog_timer(unsigned long data)
143static struct sk_buff *ulog_alloc_skb(unsigned int size) 147static struct sk_buff *ulog_alloc_skb(unsigned int size)
144{ 148{
145 struct sk_buff *skb; 149 struct sk_buff *skb;
150 unsigned int n;
146 151
147 /* alloc skb which should be big enough for a whole 152 /* alloc skb which should be big enough for a whole
148 * multipart message. WARNING: has to be <= 131000 153 * multipart message. WARNING: has to be <= 131000
149 * due to slab allocator restrictions */ 154 * due to slab allocator restrictions */
150 155
151 skb = alloc_skb(nlbufsiz, GFP_ATOMIC); 156 n = max(size, nlbufsiz);
157 skb = alloc_skb(n, GFP_ATOMIC);
152 if (!skb) { 158 if (!skb) {
153 PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", 159 PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n);
154 nlbufsiz);
155 160
156 /* try to allocate only as much as we need for 161 if (n > size) {
157 * current packet */ 162 /* try to allocate only as much as we need for
163 * current packet */
158 164
159 skb = alloc_skb(size, GFP_ATOMIC); 165 skb = alloc_skb(size, GFP_ATOMIC);
160 if (!skb) 166 if (!skb)
161 PRINTR("ipt_ULOG: can't even allocate %ub\n", size); 167 PRINTR("ipt_ULOG: can't even allocate %ub\n",
168 size);
169 }
162 } 170 }
163 171
164 return skb; 172 return skb;
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
index 18ca8258a1..5a7a265280 100644
--- a/net/ipv4/netfilter/ipt_policy.c
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -26,10 +26,13 @@ MODULE_LICENSE("GPL");
26static inline int 26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) 27match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
28{ 28{
29#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) 29#define MATCH_ADDR(x,y,z) (!e->match.x || \
30 ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
31 ^ e->invert.x))
32#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
30 33
31 return MATCH(saddr, x->props.saddr.a4 & e->smask) && 34 return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
32 MATCH(daddr, x->id.daddr.a4 & e->dmask) && 35 MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
33 MATCH(proto, x->id.proto) && 36 MATCH(proto, x->id.proto) &&
34 MATCH(mode, x->props.mode) && 37 MATCH(mode, x->props.mode) &&
35 MATCH(spi, x->id.spi) && 38 MATCH(spi, x->id.spi) &&
@@ -89,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
89 return 0; 92 return 0;
90 } 93 }
91 94
92 return strict ? 1 : 0; 95 return strict ? i == info->len : 0;
93} 96}
94 97
95static int match(const struct sk_buff *skb, 98static int match(const struct sk_buff *skb,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 167619f638..6c8624a549 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/proc.c b/net/ipv4/proc.c
index 39d49dc333..1b167c4bb3 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto)
49 int res = 0; 49 int res = 0;
50 int cpu; 50 int cpu;
51 51
52 for (cpu = 0; cpu < NR_CPUS; cpu++) 52 for_each_cpu(cpu)
53 res += proto->stats[cpu].inuse; 53 res += proto->stats[cpu].inuse;
54 54
55 return res; 55 return res;
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/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
index 63cf7e5408..e0e9d1383c 100644
--- a/net/ipv4/tcp_highspeed.c
+++ b/net/ipv4/tcp_highspeed.c
@@ -125,7 +125,7 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
125 /* Update AIMD parameters */ 125 /* Update AIMD parameters */
126 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) { 126 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
127 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && 127 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
128 ca->ai < HSTCP_AIMD_MAX) 128 ca->ai < HSTCP_AIMD_MAX - 1)
129 ca->ai++; 129 ca->ai++;
130 } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) { 130 } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
131 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && 131 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 3284cfb993..128de4d7c0 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -230,7 +230,6 @@ static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
230 if (tp->snd_cwnd < tp->snd_cwnd_clamp) 230 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
231 tp->snd_cwnd++; 231 tp->snd_cwnd++;
232 tp->snd_cwnd_cnt = 0; 232 tp->snd_cwnd_cnt = 0;
233 ca->ccount++;
234 } 233 }
235 } 234 }
236} 235}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a97ed5416c..e9a54ae7d6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -456,7 +456,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
456 456
457 tp->rcvq_space.space = space; 457 tp->rcvq_space.space = space;
458 458
459 if (sysctl_tcp_moderate_rcvbuf) { 459 if (sysctl_tcp_moderate_rcvbuf &&
460 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
460 int new_clamp = space; 461 int new_clamp = space;
461 462
462 /* Receive space grows, normalize in order to 463 /* Receive space grows, normalize in order to
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 6ea353907a..233bdf2599 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -236,7 +236,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
236 if (err) 236 if (err)
237 goto failure; 237 goto failure;
238 238
239 err = ip_route_newports(&rt, inet->sport, inet->dport, sk); 239 err = ip_route_newports(&rt, IPPROTO_TCP, inet->sport, inet->dport, sk);
240 if (err) 240 if (err)
241 goto failure; 241 goto failure;
242 242
@@ -1845,7 +1845,6 @@ void __init tcp_v4_init(struct net_proto_family *ops)
1845} 1845}
1846 1846
1847EXPORT_SYMBOL(ipv4_specific); 1847EXPORT_SYMBOL(ipv4_specific);
1848EXPORT_SYMBOL(inet_bind_bucket_create);
1849EXPORT_SYMBOL(tcp_hashinfo); 1848EXPORT_SYMBOL(tcp_hashinfo);
1850EXPORT_SYMBOL(tcp_prot); 1849EXPORT_SYMBOL(tcp_prot);
1851EXPORT_SYMBOL(tcp_unhash); 1850EXPORT_SYMBOL(tcp_unhash);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a7623ead39..9f498a6c88 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1036,6 +1036,10 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
1036 1036
1037 limit = min(send_win, cong_win); 1037 limit = min(send_win, cong_win);
1038 1038
1039 /* If a full-sized TSO skb can be sent, do it. */
1040 if (limit >= 65536)
1041 return 0;
1042
1039 if (sysctl_tcp_tso_win_divisor) { 1043 if (sysctl_tcp_tso_win_divisor) {
1040 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); 1044 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
1041 1045
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index d4df0ddd42..32ad229b4f 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
155int xfrm4_output_finish(struct sk_buff *skb) 155static 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
179int xfrm4_output(struct sk_buff *skb) 185int 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}
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 42196ba3b0..f285bbf296 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,6 @@
8 * 8 *
9 */ 9 */
10 10
11#include <asm/bug.h>
12#include <linux/compiler.h> 11#include <linux/compiler.h>
13#include <linux/config.h> 12#include <linux/config.h>
14#include <linux/inetdevice.h> 13#include <linux/inetdevice.h>
@@ -36,6 +35,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
36 if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/ 35 if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/
37 xdst->u.rt.fl.fl4_dst == fl->fl4_dst && 36 xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
38 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 &&
39 xfrm_bundle_ok(xdst, fl, AF_INET)) { 39 xfrm_bundle_ok(xdst, fl, AF_INET)) {
40 dst_clone(dst); 40 dst_clone(dst);
41 break; 41 break;
@@ -62,7 +62,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
62 .nl_u = { 62 .nl_u = {
63 .ip4_u = { 63 .ip4_u = {
64 .saddr = local, 64 .saddr = local,
65 .daddr = remote 65 .daddr = remote,
66 .tos = fl->fl4_tos
66 } 67 }
67 } 68 }
68 }; 69 };
@@ -231,6 +232,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
231 fl->proto = iph->protocol; 232 fl->proto = iph->protocol;
232 fl->fl4_dst = iph->daddr; 233 fl->fl4_dst = iph->daddr;
233 fl->fl4_src = iph->saddr; 234 fl->fl4_src = iph->saddr;
235 fl->fl4_tos = iph->tos;
234} 236}
235 237
236static inline int xfrm4_garbage_collect(void) 238static inline int xfrm4_garbage_collect(void)