aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-11-23 12:34:58 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-11-23 12:34:58 -0500
commit9b8b317d58084b9a44f6f33b355c4278d9f841fb (patch)
treee0df89800bf4301c4017db3cdf04a2056ec1a852 /net/ipv4
parent78c210efdefe07131f91ed512a3308b15bb14e2f (diff)
parent648f4e3e50c4793d9dbf9a09afa193631f76fa26 (diff)
Merge commit 'v2.6.32-rc8' into HEAD
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c5
-rw-r--r--net/ipv4/inet_connection_sock.c34
-rw-r--r--net/ipv4/ip_gre.c28
-rw-r--r--net/ipv4/ip_sockglue.c7
-rw-r--r--net/ipv4/ipip.c32
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c34
-rw-r--r--net/ipv4/raw.c24
-rw-r--r--net/ipv4/route.c8
-rw-r--r--net/ipv4/tcp.c74
-rw-r--r--net/ipv4/tcp_minisocks.c5
-rw-r--r--net/ipv4/udp.c4
13 files changed, 180 insertions, 82 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e2f950592566..aa00398be80e 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -229,14 +229,17 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
229 */ 229 */
230 230
231int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, 231int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
232 struct net_device *dev, __be32 *spec_dst, u32 *itag) 232 struct net_device *dev, __be32 *spec_dst,
233 u32 *itag, u32 mark)
233{ 234{
234 struct in_device *in_dev; 235 struct in_device *in_dev;
235 struct flowi fl = { .nl_u = { .ip4_u = 236 struct flowi fl = { .nl_u = { .ip4_u =
236 { .daddr = src, 237 { .daddr = src,
237 .saddr = dst, 238 .saddr = dst,
238 .tos = tos } }, 239 .tos = tos } },
240 .mark = mark,
239 .iif = oif }; 241 .iif = oif };
242
240 struct fib_result res; 243 struct fib_result res;
241 int no_addr, rpf; 244 int no_addr, rpf;
242 int ret; 245 int ret;
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4351ca2cf0b8..537731b3bcb3 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -446,6 +446,28 @@ extern int sysctl_tcp_synack_retries;
446 446
447EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add); 447EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_hash_add);
448 448
449/* Decide when to expire the request and when to resend SYN-ACK */
450static inline void syn_ack_recalc(struct request_sock *req, const int thresh,
451 const int max_retries,
452 const u8 rskq_defer_accept,
453 int *expire, int *resend)
454{
455 if (!rskq_defer_accept) {
456 *expire = req->retrans >= thresh;
457 *resend = 1;
458 return;
459 }
460 *expire = req->retrans >= thresh &&
461 (!inet_rsk(req)->acked || req->retrans >= max_retries);
462 /*
463 * Do not resend while waiting for data after ACK,
464 * start to resend on end of deferring period to give
465 * last chance for data or ACK to create established socket.
466 */
467 *resend = !inet_rsk(req)->acked ||
468 req->retrans >= rskq_defer_accept - 1;
469}
470
449void inet_csk_reqsk_queue_prune(struct sock *parent, 471void inet_csk_reqsk_queue_prune(struct sock *parent,
450 const unsigned long interval, 472 const unsigned long interval,
451 const unsigned long timeout, 473 const unsigned long timeout,
@@ -501,9 +523,15 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
501 reqp=&lopt->syn_table[i]; 523 reqp=&lopt->syn_table[i];
502 while ((req = *reqp) != NULL) { 524 while ((req = *reqp) != NULL) {
503 if (time_after_eq(now, req->expires)) { 525 if (time_after_eq(now, req->expires)) {
504 if ((req->retrans < thresh || 526 int expire = 0, resend = 0;
505 (inet_rsk(req)->acked && req->retrans < max_retries)) 527
506 && !req->rsk_ops->rtx_syn_ack(parent, req)) { 528 syn_ack_recalc(req, thresh, max_retries,
529 queue->rskq_defer_accept,
530 &expire, &resend);
531 if (!expire &&
532 (!resend ||
533 !req->rsk_ops->rtx_syn_ack(parent, req) ||
534 inet_rsk(req)->acked)) {
507 unsigned long timeo; 535 unsigned long timeo;
508 536
509 if (req->retrans++ == 0) 537 if (req->retrans++ == 0)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 41ada9904d31..143333852624 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1464,7 +1464,7 @@ static void ipgre_tap_setup(struct net_device *dev)
1464 1464
1465 ether_setup(dev); 1465 ether_setup(dev);
1466 1466
1467 dev->netdev_ops = &ipgre_netdev_ops; 1467 dev->netdev_ops = &ipgre_tap_netdev_ops;
1468 dev->destructor = free_netdev; 1468 dev->destructor = free_netdev;
1469 1469
1470 dev->iflink = 0; 1470 dev->iflink = 0;
@@ -1525,25 +1525,29 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
1525 if (t->dev != dev) 1525 if (t->dev != dev)
1526 return -EEXIST; 1526 return -EEXIST;
1527 } else { 1527 } else {
1528 unsigned nflags = 0;
1529
1530 t = nt; 1528 t = nt;
1531 1529
1532 if (ipv4_is_multicast(p.iph.daddr)) 1530 if (dev->type != ARPHRD_ETHER) {
1533 nflags = IFF_BROADCAST; 1531 unsigned nflags = 0;
1534 else if (p.iph.daddr)
1535 nflags = IFF_POINTOPOINT;
1536 1532
1537 if ((dev->flags ^ nflags) & 1533 if (ipv4_is_multicast(p.iph.daddr))
1538 (IFF_POINTOPOINT | IFF_BROADCAST)) 1534 nflags = IFF_BROADCAST;
1539 return -EINVAL; 1535 else if (p.iph.daddr)
1536 nflags = IFF_POINTOPOINT;
1537
1538 if ((dev->flags ^ nflags) &
1539 (IFF_POINTOPOINT | IFF_BROADCAST))
1540 return -EINVAL;
1541 }
1540 1542
1541 ipgre_tunnel_unlink(ign, t); 1543 ipgre_tunnel_unlink(ign, t);
1542 t->parms.iph.saddr = p.iph.saddr; 1544 t->parms.iph.saddr = p.iph.saddr;
1543 t->parms.iph.daddr = p.iph.daddr; 1545 t->parms.iph.daddr = p.iph.daddr;
1544 t->parms.i_key = p.i_key; 1546 t->parms.i_key = p.i_key;
1545 memcpy(dev->dev_addr, &p.iph.saddr, 4); 1547 if (dev->type != ARPHRD_ETHER) {
1546 memcpy(dev->broadcast, &p.iph.daddr, 4); 1548 memcpy(dev->dev_addr, &p.iph.saddr, 4);
1549 memcpy(dev->broadcast, &p.iph.daddr, 4);
1550 }
1547 ipgre_tunnel_link(ign, t); 1551 ipgre_tunnel_link(ign, t);
1548 netdev_state_change(dev); 1552 netdev_state_change(dev);
1549 } 1553 }
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 0c0b6e363a20..e982b5c1ee17 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -634,17 +634,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
634 break; 634 break;
635 } 635 }
636 dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr); 636 dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
637 if (dev) { 637 if (dev)
638 mreq.imr_ifindex = dev->ifindex; 638 mreq.imr_ifindex = dev->ifindex;
639 dev_put(dev);
640 }
641 } else 639 } else
642 dev = __dev_get_by_index(sock_net(sk), mreq.imr_ifindex); 640 dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
643 641
644 642
645 err = -EADDRNOTAVAIL; 643 err = -EADDRNOTAVAIL;
646 if (!dev) 644 if (!dev)
647 break; 645 break;
646 dev_put(dev);
648 647
649 err = -EINVAL; 648 err = -EINVAL;
650 if (sk->sk_bound_dev_if && 649 if (sk->sk_bound_dev_if &&
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 08ccd344de7a..ae40ed1ba560 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
438 goto tx_error; 438 goto tx_error;
439 } 439 }
440 440
441 if (tiph->frag_off) 441 df |= old_iph->frag_off & htons(IP_DF);
442
443 if (df) {
442 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); 444 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
443 else
444 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
445 445
446 if (mtu < 68) { 446 if (mtu < 68) {
447 stats->collisions++; 447 stats->collisions++;
448 ip_rt_put(rt); 448 ip_rt_put(rt);
449 goto tx_error; 449 goto tx_error;
450 } 450 }
451 if (skb_dst(skb))
452 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
453 451
454 df |= (old_iph->frag_off&htons(IP_DF)); 452 if (skb_dst(skb))
453 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
455 454
456 if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { 455 if ((old_iph->frag_off & htons(IP_DF)) &&
457 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 456 mtu < ntohs(old_iph->tot_len)) {
458 ip_rt_put(rt); 457 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
459 goto tx_error; 458 htonl(mtu));
459 ip_rt_put(rt);
460 goto tx_error;
461 }
460 } 462 }
461 463
462 if (tunnel->err_count > 0) { 464 if (tunnel->err_count > 0) {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 630a56df7b47..99508d66a642 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
483 return -EINVAL; 483 return -EINVAL;
484 } 484 }
485 485
486 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) 486 if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
487 dev_put(dev);
487 return -EADDRNOTAVAIL; 488 return -EADDRNOTAVAIL;
489 }
488 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; 490 IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
489 ip_rt_multicast_event(in_dev); 491 ip_rt_multicast_event(in_dev);
490 492
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 68afc6ecd343..fe1a64479dd0 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -750,6 +750,8 @@ static int __init nf_nat_init(void)
750 BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); 750 BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
751 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, 751 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
752 nfnetlink_parse_nat_setup); 752 nfnetlink_parse_nat_setup);
753 BUG_ON(nf_ct_nat_offset != NULL);
754 rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset);
753 return 0; 755 return 0;
754 756
755 cleanup_extend: 757 cleanup_extend:
@@ -764,6 +766,7 @@ static void __exit nf_nat_cleanup(void)
764 nf_ct_extend_unregister(&nat_extend); 766 nf_ct_extend_unregister(&nat_extend);
765 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); 767 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
766 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); 768 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
769 rcu_assign_pointer(nf_ct_nat_offset, NULL);
767 synchronize_net(); 770 synchronize_net();
768} 771}
769 772
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 09172a65d9b6..f9520fa3aba9 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -73,6 +73,28 @@ adjust_tcp_sequence(u32 seq,
73 DUMP_OFFSET(this_way); 73 DUMP_OFFSET(this_way);
74} 74}
75 75
76/* Get the offset value, for conntrack */
77s16 nf_nat_get_offset(const struct nf_conn *ct,
78 enum ip_conntrack_dir dir,
79 u32 seq)
80{
81 struct nf_conn_nat *nat = nfct_nat(ct);
82 struct nf_nat_seq *this_way;
83 s16 offset;
84
85 if (!nat)
86 return 0;
87
88 this_way = &nat->seq[dir];
89 spin_lock_bh(&nf_nat_seqofs_lock);
90 offset = after(seq, this_way->correction_pos)
91 ? this_way->offset_after : this_way->offset_before;
92 spin_unlock_bh(&nf_nat_seqofs_lock);
93
94 return offset;
95}
96EXPORT_SYMBOL_GPL(nf_nat_get_offset);
97
76/* Frobs data inside this packet, which is linear. */ 98/* Frobs data inside this packet, which is linear. */
77static void mangle_contents(struct sk_buff *skb, 99static void mangle_contents(struct sk_buff *skb,
78 unsigned int dataoff, 100 unsigned int dataoff,
@@ -189,11 +211,6 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
189 adjust_tcp_sequence(ntohl(tcph->seq), 211 adjust_tcp_sequence(ntohl(tcph->seq),
190 (int)rep_len - (int)match_len, 212 (int)rep_len - (int)match_len,
191 ct, ctinfo); 213 ct, ctinfo);
192 /* Tell TCP window tracking about seq change */
193 nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
194 ct, CTINFO2DIR(ctinfo),
195 (int)rep_len - (int)match_len);
196
197 nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); 214 nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
198 } 215 }
199 return 1; 216 return 1;
@@ -415,12 +432,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
415 tcph->seq = newseq; 432 tcph->seq = newseq;
416 tcph->ack_seq = newack; 433 tcph->ack_seq = newack;
417 434
418 if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) 435 return nf_nat_sack_adjust(skb, tcph, ct, ctinfo);
419 return 0;
420
421 nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff);
422
423 return 1;
424} 436}
425 437
426/* Setup NAT on this expected conntrack so it follows master. */ 438/* Setup NAT on this expected conntrack so it follows master. */
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 757c9171e7c2..ab996f9c0fe0 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -352,13 +352,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
352 skb->ip_summed = CHECKSUM_NONE; 352 skb->ip_summed = CHECKSUM_NONE;
353 353
354 skb->transport_header = skb->network_header; 354 skb->transport_header = skb->network_header;
355 err = memcpy_fromiovecend((void *)iph, from, 0, length); 355 err = -EFAULT;
356 if (err) 356 if (memcpy_fromiovecend((void *)iph, from, 0, length))
357 goto error_fault; 357 goto error_free;
358 358
359 /* We don't modify invalid header */
360 iphlen = iph->ihl * 4; 359 iphlen = iph->ihl * 4;
361 if (iphlen >= sizeof(*iph) && iphlen <= length) { 360
361 /*
362 * We don't want to modify the ip header, but we do need to
363 * be sure that it won't cause problems later along the network
364 * stack. Specifically we want to make sure that iph->ihl is a
365 * sane value. If ihl points beyond the length of the buffer passed
366 * in, reject the frame as invalid
367 */
368 err = -EINVAL;
369 if (iphlen > length)
370 goto error_free;
371
372 if (iphlen >= sizeof(*iph)) {
362 if (!iph->saddr) 373 if (!iph->saddr)
363 iph->saddr = rt->rt_src; 374 iph->saddr = rt->rt_src;
364 iph->check = 0; 375 iph->check = 0;
@@ -381,8 +392,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
381out: 392out:
382 return 0; 393 return 0;
383 394
384error_fault: 395error_free:
385 err = -EFAULT;
386 kfree_skb(skb); 396 kfree_skb(skb);
387error: 397error:
388 IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); 398 IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bb4199252026..5b1050a5d874 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1854,7 +1854,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1854 goto e_inval; 1854 goto e_inval;
1855 spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); 1855 spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
1856 } else if (fib_validate_source(saddr, 0, tos, 0, 1856 } else if (fib_validate_source(saddr, 0, tos, 0,
1857 dev, &spec_dst, &itag) < 0) 1857 dev, &spec_dst, &itag, 0) < 0)
1858 goto e_inval; 1858 goto e_inval;
1859 1859
1860 rth = dst_alloc(&ipv4_dst_ops); 1860 rth = dst_alloc(&ipv4_dst_ops);
@@ -1967,7 +1967,7 @@ static int __mkroute_input(struct sk_buff *skb,
1967 1967
1968 1968
1969 err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res), 1969 err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
1970 in_dev->dev, &spec_dst, &itag); 1970 in_dev->dev, &spec_dst, &itag, skb->mark);
1971 if (err < 0) { 1971 if (err < 0) {
1972 ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr, 1972 ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
1973 saddr); 1973 saddr);
@@ -2141,7 +2141,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2141 int result; 2141 int result;
2142 result = fib_validate_source(saddr, daddr, tos, 2142 result = fib_validate_source(saddr, daddr, tos,
2143 net->loopback_dev->ifindex, 2143 net->loopback_dev->ifindex,
2144 dev, &spec_dst, &itag); 2144 dev, &spec_dst, &itag, skb->mark);
2145 if (result < 0) 2145 if (result < 0)
2146 goto martian_source; 2146 goto martian_source;
2147 if (result) 2147 if (result)
@@ -2170,7 +2170,7 @@ brd_input:
2170 spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK); 2170 spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
2171 else { 2171 else {
2172 err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst, 2172 err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
2173 &itag); 2173 &itag, skb->mark);
2174 if (err < 0) 2174 if (err < 0)
2175 goto martian_source; 2175 goto martian_source;
2176 if (err) 2176 if (err)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 64d0af675823..f1813bc71088 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -326,6 +326,43 @@ void tcp_enter_memory_pressure(struct sock *sk)
326 326
327EXPORT_SYMBOL(tcp_enter_memory_pressure); 327EXPORT_SYMBOL(tcp_enter_memory_pressure);
328 328
329/* Convert seconds to retransmits based on initial and max timeout */
330static u8 secs_to_retrans(int seconds, int timeout, int rto_max)
331{
332 u8 res = 0;
333
334 if (seconds > 0) {
335 int period = timeout;
336
337 res = 1;
338 while (seconds > period && res < 255) {
339 res++;
340 timeout <<= 1;
341 if (timeout > rto_max)
342 timeout = rto_max;
343 period += timeout;
344 }
345 }
346 return res;
347}
348
349/* Convert retransmits to seconds based on initial and max timeout */
350static int retrans_to_secs(u8 retrans, int timeout, int rto_max)
351{
352 int period = 0;
353
354 if (retrans > 0) {
355 period = timeout;
356 while (--retrans) {
357 timeout <<= 1;
358 if (timeout > rto_max)
359 timeout = rto_max;
360 period += timeout;
361 }
362 }
363 return period;
364}
365
329/* 366/*
330 * Wait for a TCP event. 367 * Wait for a TCP event.
331 * 368 *
@@ -1146,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
1146#if TCP_DEBUG 1183#if TCP_DEBUG
1147 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); 1184 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
1148 1185
1149 WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); 1186 WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
1187 KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
1188 tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
1150#endif 1189#endif
1151 1190
1152 if (inet_csk_ack_scheduled(sk)) { 1191 if (inet_csk_ack_scheduled(sk)) {
@@ -1393,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1393 /* Now that we have two receive queues this 1432 /* Now that we have two receive queues this
1394 * shouldn't happen. 1433 * shouldn't happen.
1395 */ 1434 */
1396 if (before(*seq, TCP_SKB_CB(skb)->seq)) { 1435 if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
1397 printk(KERN_INFO "recvmsg bug: copied %X " 1436 KERN_INFO "recvmsg bug: copied %X "
1398 "seq %X\n", *seq, TCP_SKB_CB(skb)->seq); 1437 "seq %X rcvnxt %X fl %X\n", *seq,
1438 TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
1439 flags))
1399 break; 1440 break;
1400 } 1441
1401 offset = *seq - TCP_SKB_CB(skb)->seq; 1442 offset = *seq - TCP_SKB_CB(skb)->seq;
1402 if (tcp_hdr(skb)->syn) 1443 if (tcp_hdr(skb)->syn)
1403 offset--; 1444 offset--;
@@ -1405,7 +1446,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1405 goto found_ok_skb; 1446 goto found_ok_skb;
1406 if (tcp_hdr(skb)->fin) 1447 if (tcp_hdr(skb)->fin)
1407 goto found_fin_ok; 1448 goto found_fin_ok;
1408 WARN_ON(!(flags & MSG_PEEK)); 1449 WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
1450 "copied %X seq %X rcvnxt %X fl %X\n",
1451 *seq, TCP_SKB_CB(skb)->seq,
1452 tp->rcv_nxt, flags);
1409 } 1453 }
1410 1454
1411 /* Well, if we have backlog, try to process it now yet. */ 1455 /* Well, if we have backlog, try to process it now yet. */
@@ -2163,16 +2207,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2163 break; 2207 break;
2164 2208
2165 case TCP_DEFER_ACCEPT: 2209 case TCP_DEFER_ACCEPT:
2166 icsk->icsk_accept_queue.rskq_defer_accept = 0; 2210 /* Translate value in seconds to number of retransmits */
2167 if (val > 0) { 2211 icsk->icsk_accept_queue.rskq_defer_accept =
2168 /* Translate value in seconds to number of 2212 secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ,
2169 * retransmits */ 2213 TCP_RTO_MAX / HZ);
2170 while (icsk->icsk_accept_queue.rskq_defer_accept < 32 &&
2171 val > ((TCP_TIMEOUT_INIT / HZ) <<
2172 icsk->icsk_accept_queue.rskq_defer_accept))
2173 icsk->icsk_accept_queue.rskq_defer_accept++;
2174 icsk->icsk_accept_queue.rskq_defer_accept++;
2175 }
2176 break; 2214 break;
2177 2215
2178 case TCP_WINDOW_CLAMP: 2216 case TCP_WINDOW_CLAMP:
@@ -2353,8 +2391,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
2353 val = (val ? : sysctl_tcp_fin_timeout) / HZ; 2391 val = (val ? : sysctl_tcp_fin_timeout) / HZ;
2354 break; 2392 break;
2355 case TCP_DEFER_ACCEPT: 2393 case TCP_DEFER_ACCEPT:
2356 val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : 2394 val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept,
2357 ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); 2395 TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ);
2358 break; 2396 break;
2359 case TCP_WINDOW_CLAMP: 2397 case TCP_WINDOW_CLAMP:
2360 val = tp->window_clamp; 2398 val = tp->window_clamp;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index e320afea07fc..4c03598ed924 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -641,10 +641,9 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
641 if (!(flg & TCP_FLAG_ACK)) 641 if (!(flg & TCP_FLAG_ACK))
642 return NULL; 642 return NULL;
643 643
644 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ 644 /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */
645 if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && 645 if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
646 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { 646 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
647 inet_csk(sk)->icsk_accept_queue.rskq_defer_accept--;
648 inet_rsk(req)->acked = 1; 647 inet_rsk(req)->acked = 1;
649 return NULL; 648 return NULL;
650 } 649 }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d0d436d6216c..0fa9f70e4b19 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -999,9 +999,7 @@ try_again:
999 err = ulen; 999 err = ulen;
1000 1000
1001out_free: 1001out_free:
1002 lock_sock(sk); 1002 skb_free_datagram_locked(sk, skb);
1003 skb_free_datagram(sk, skb);
1004 release_sock(sk);
1005out: 1003out:
1006 return err; 1004 return err;
1007 1005