diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-13 23:52:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-13 23:52:39 -0400 |
commit | 4ae127d1b6c71f9240dd4245f240e6dd8fc98014 (patch) | |
tree | b7aa27b3e0c655f4613fe2146cb57d7f69e421f6 /net/ipv4 | |
parent | 875ec4333b99144e2589e900a0bcd2c25c757b27 (diff) | |
parent | 7775c9753b94fe429dc4323360d6502c95e0dd6e (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/smc911x.c
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_semantics.c | 5 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 11 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_snmp_basic.c | 14 | ||||
-rw-r--r-- | net/ipv4/syncookies.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 18 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 45 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 10 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 32 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 5 |
9 files changed, 51 insertions, 92 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 9335eba683c3..ded2ae34eab1 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -958,7 +958,10 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
958 | rtm->rtm_dst_len = dst_len; | 958 | rtm->rtm_dst_len = dst_len; |
959 | rtm->rtm_src_len = 0; | 959 | rtm->rtm_src_len = 0; |
960 | rtm->rtm_tos = tos; | 960 | rtm->rtm_tos = tos; |
961 | rtm->rtm_table = tb_id; | 961 | if (tb_id < 256) |
962 | rtm->rtm_table = tb_id; | ||
963 | else | ||
964 | rtm->rtm_table = RT_TABLE_COMPAT; | ||
962 | NLA_PUT_U32(skb, RTA_TABLE, tb_id); | 965 | NLA_PUT_U32(skb, RTA_TABLE, tb_id); |
963 | rtm->rtm_type = type; | 966 | rtm->rtm_type = type; |
964 | rtm->rtm_flags = fi->fib_flags; | 967 | rtm->rtm_flags = fi->fib_flags; |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 828ea211ff21..045e799d3e1d 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -419,7 +419,8 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
419 | struct inet_connection_sock *icsk = inet_csk(parent); | 419 | struct inet_connection_sock *icsk = inet_csk(parent); |
420 | struct request_sock_queue *queue = &icsk->icsk_accept_queue; | 420 | struct request_sock_queue *queue = &icsk->icsk_accept_queue; |
421 | struct listen_sock *lopt = queue->listen_opt; | 421 | struct listen_sock *lopt = queue->listen_opt; |
422 | int thresh = icsk->icsk_syn_retries ? : sysctl_tcp_synack_retries; | 422 | int max_retries = icsk->icsk_syn_retries ? : sysctl_tcp_synack_retries; |
423 | int thresh = max_retries; | ||
423 | unsigned long now = jiffies; | 424 | unsigned long now = jiffies; |
424 | struct request_sock **reqp, *req; | 425 | struct request_sock **reqp, *req; |
425 | int i, budget; | 426 | int i, budget; |
@@ -455,6 +456,9 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
455 | } | 456 | } |
456 | } | 457 | } |
457 | 458 | ||
459 | if (queue->rskq_defer_accept) | ||
460 | max_retries = queue->rskq_defer_accept; | ||
461 | |||
458 | budget = 2 * (lopt->nr_table_entries / (timeout / interval)); | 462 | budget = 2 * (lopt->nr_table_entries / (timeout / interval)); |
459 | i = lopt->clock_hand; | 463 | i = lopt->clock_hand; |
460 | 464 | ||
@@ -462,8 +466,9 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, | |||
462 | reqp=&lopt->syn_table[i]; | 466 | reqp=&lopt->syn_table[i]; |
463 | while ((req = *reqp) != NULL) { | 467 | while ((req = *reqp) != NULL) { |
464 | if (time_after_eq(now, req->expires)) { | 468 | if (time_after_eq(now, req->expires)) { |
465 | if (req->retrans < thresh && | 469 | if ((req->retrans < (inet_rsk(req)->acked ? max_retries : thresh)) && |
466 | !req->rsk_ops->rtx_syn_ack(parent, req)) { | 470 | (inet_rsk(req)->acked || |
471 | !req->rsk_ops->rtx_syn_ack(parent, req))) { | ||
467 | unsigned long timeo; | 472 | unsigned long timeo; |
468 | 473 | ||
469 | if (req->retrans++ == 0) | 474 | if (req->retrans++ == 0) |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 5daefad3d193..7750c97fde7b 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -232,6 +232,11 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx, | |||
232 | } | 232 | } |
233 | } | 233 | } |
234 | } | 234 | } |
235 | |||
236 | /* don't trust len bigger than ctx buffer */ | ||
237 | if (*len > ctx->end - ctx->pointer) | ||
238 | return 0; | ||
239 | |||
235 | return 1; | 240 | return 1; |
236 | } | 241 | } |
237 | 242 | ||
@@ -250,6 +255,10 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx, | |||
250 | if (!asn1_length_decode(ctx, &def, &len)) | 255 | if (!asn1_length_decode(ctx, &def, &len)) |
251 | return 0; | 256 | return 0; |
252 | 257 | ||
258 | /* primitive shall be definite, indefinite shall be constructed */ | ||
259 | if (*con == ASN1_PRI && !def) | ||
260 | return 0; | ||
261 | |||
253 | if (def) | 262 | if (def) |
254 | *eoc = ctx->pointer + len; | 263 | *eoc = ctx->pointer + len; |
255 | else | 264 | else |
@@ -434,6 +443,11 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, | |||
434 | unsigned long *optr; | 443 | unsigned long *optr; |
435 | 444 | ||
436 | size = eoc - ctx->pointer + 1; | 445 | size = eoc - ctx->pointer + 1; |
446 | |||
447 | /* first subid actually encodes first two subids */ | ||
448 | if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) | ||
449 | return 0; | ||
450 | |||
437 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); | 451 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); |
438 | if (*oid == NULL) { | 452 | if (*oid == NULL) { |
439 | if (net_ratelimit()) | 453 | if (net_ratelimit()) |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 6317d3c8dc0d..fdde2ae07e24 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -283,7 +283,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
283 | cookie_check_timestamp(&tcp_opt); | 283 | cookie_check_timestamp(&tcp_opt); |
284 | 284 | ||
285 | ret = NULL; | 285 | ret = NULL; |
286 | req = reqsk_alloc(&tcp_request_sock_ops); /* for safety */ | 286 | req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ |
287 | if (!req) | 287 | if (!req) |
288 | goto out; | 288 | goto out; |
289 | 289 | ||
@@ -299,7 +299,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
299 | ireq->rmt_port = th->source; | 299 | ireq->rmt_port = th->source; |
300 | ireq->loc_addr = ip_hdr(skb)->daddr; | 300 | ireq->loc_addr = ip_hdr(skb)->daddr; |
301 | ireq->rmt_addr = ip_hdr(skb)->saddr; | 301 | ireq->rmt_addr = ip_hdr(skb)->saddr; |
302 | ireq->opt = NULL; | ||
303 | ireq->snd_wscale = tcp_opt.snd_wscale; | 302 | ireq->snd_wscale = tcp_opt.snd_wscale; |
304 | ireq->rcv_wscale = tcp_opt.rcv_wscale; | 303 | ireq->rcv_wscale = tcp_opt.rcv_wscale; |
305 | ireq->sack_ok = tcp_opt.sack_ok; | 304 | ireq->sack_ok = tcp_opt.sack_ok; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6d30ca559c64..cf0850c068f5 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2110,12 +2110,15 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2110 | break; | 2110 | break; |
2111 | 2111 | ||
2112 | case TCP_DEFER_ACCEPT: | 2112 | case TCP_DEFER_ACCEPT: |
2113 | if (val < 0) { | 2113 | icsk->icsk_accept_queue.rskq_defer_accept = 0; |
2114 | err = -EINVAL; | 2114 | if (val > 0) { |
2115 | } else { | 2115 | /* Translate value in seconds to number of |
2116 | if (val > MAX_TCP_ACCEPT_DEFERRED) | 2116 | * retransmits */ |
2117 | val = MAX_TCP_ACCEPT_DEFERRED; | 2117 | while (icsk->icsk_accept_queue.rskq_defer_accept < 32 && |
2118 | icsk->icsk_accept_queue.rskq_defer_accept = val; | 2118 | val > ((TCP_TIMEOUT_INIT / HZ) << |
2119 | icsk->icsk_accept_queue.rskq_defer_accept)) | ||
2120 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
2121 | icsk->icsk_accept_queue.rskq_defer_accept++; | ||
2119 | } | 2122 | } |
2120 | break; | 2123 | break; |
2121 | 2124 | ||
@@ -2297,7 +2300,8 @@ static int do_tcp_getsockopt(struct sock *sk, int level, | |||
2297 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; | 2300 | val = (val ? : sysctl_tcp_fin_timeout) / HZ; |
2298 | break; | 2301 | break; |
2299 | case TCP_DEFER_ACCEPT: | 2302 | case TCP_DEFER_ACCEPT: |
2300 | val = icsk->icsk_accept_queue.rskq_defer_accept; | 2303 | val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : |
2304 | ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); | ||
2301 | break; | 2305 | break; |
2302 | case TCP_WINDOW_CLAMP: | 2306 | case TCP_WINDOW_CLAMP: |
2303 | val = tp->window_clamp; | 2307 | val = tp->window_clamp; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bc7f62e2792b..de30e70ff256 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4576,49 +4576,6 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th) | |||
4576 | } | 4576 | } |
4577 | } | 4577 | } |
4578 | 4578 | ||
4579 | static int tcp_defer_accept_check(struct sock *sk) | ||
4580 | { | ||
4581 | struct tcp_sock *tp = tcp_sk(sk); | ||
4582 | |||
4583 | if (tp->defer_tcp_accept.request) { | ||
4584 | int queued_data = tp->rcv_nxt - tp->copied_seq; | ||
4585 | int hasfin = !skb_queue_empty(&sk->sk_receive_queue) ? | ||
4586 | tcp_hdr((struct sk_buff *) | ||
4587 | sk->sk_receive_queue.prev)->fin : 0; | ||
4588 | |||
4589 | if (queued_data && hasfin) | ||
4590 | queued_data--; | ||
4591 | |||
4592 | if (queued_data && | ||
4593 | tp->defer_tcp_accept.listen_sk->sk_state == TCP_LISTEN) { | ||
4594 | if (sock_flag(sk, SOCK_KEEPOPEN)) { | ||
4595 | inet_csk_reset_keepalive_timer(sk, | ||
4596 | keepalive_time_when(tp)); | ||
4597 | } else { | ||
4598 | inet_csk_delete_keepalive_timer(sk); | ||
4599 | } | ||
4600 | |||
4601 | inet_csk_reqsk_queue_add( | ||
4602 | tp->defer_tcp_accept.listen_sk, | ||
4603 | tp->defer_tcp_accept.request, | ||
4604 | sk); | ||
4605 | |||
4606 | tp->defer_tcp_accept.listen_sk->sk_data_ready( | ||
4607 | tp->defer_tcp_accept.listen_sk, 0); | ||
4608 | |||
4609 | sock_put(tp->defer_tcp_accept.listen_sk); | ||
4610 | sock_put(sk); | ||
4611 | tp->defer_tcp_accept.listen_sk = NULL; | ||
4612 | tp->defer_tcp_accept.request = NULL; | ||
4613 | } else if (hasfin || | ||
4614 | tp->defer_tcp_accept.listen_sk->sk_state != TCP_LISTEN) { | ||
4615 | tcp_reset(sk); | ||
4616 | return -1; | ||
4617 | } | ||
4618 | } | ||
4619 | return 0; | ||
4620 | } | ||
4621 | |||
4622 | static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) | 4579 | static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) |
4623 | { | 4580 | { |
4624 | struct tcp_sock *tp = tcp_sk(sk); | 4581 | struct tcp_sock *tp = tcp_sk(sk); |
@@ -4979,8 +4936,6 @@ step5: | |||
4979 | 4936 | ||
4980 | tcp_data_snd_check(sk); | 4937 | tcp_data_snd_check(sk); |
4981 | tcp_ack_snd_check(sk); | 4938 | tcp_ack_snd_check(sk); |
4982 | |||
4983 | tcp_defer_accept_check(sk); | ||
4984 | return 0; | 4939 | return 0; |
4985 | 4940 | ||
4986 | csum_error: | 4941 | csum_error: |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9088d709725e..b219a7a7cd08 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1185,7 +1185,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1185 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 1185 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
1186 | goto drop; | 1186 | goto drop; |
1187 | 1187 | ||
1188 | req = reqsk_alloc(&tcp_request_sock_ops); | 1188 | req = inet_reqsk_alloc(&tcp_request_sock_ops); |
1189 | if (!req) | 1189 | if (!req) |
1190 | goto drop; | 1190 | goto drop; |
1191 | 1191 | ||
@@ -1818,14 +1818,6 @@ int tcp_v4_destroy_sock(struct sock *sk) | |||
1818 | sk->sk_sndmsg_page = NULL; | 1818 | sk->sk_sndmsg_page = NULL; |
1819 | } | 1819 | } |
1820 | 1820 | ||
1821 | if (tp->defer_tcp_accept.request) { | ||
1822 | reqsk_free(tp->defer_tcp_accept.request); | ||
1823 | sock_put(tp->defer_tcp_accept.listen_sk); | ||
1824 | sock_put(sk); | ||
1825 | tp->defer_tcp_accept.listen_sk = NULL; | ||
1826 | tp->defer_tcp_accept.request = NULL; | ||
1827 | } | ||
1828 | |||
1829 | atomic_dec(&tcp_sockets_allocated); | 1821 | atomic_dec(&tcp_sockets_allocated); |
1830 | 1822 | ||
1831 | return 0; | 1823 | return 0; |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 1276cab85e3e..ea68a478fad6 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -569,8 +569,10 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
569 | does sequence test, SYN is truncated, and thus we consider | 569 | does sequence test, SYN is truncated, and thus we consider |
570 | it a bare ACK. | 570 | it a bare ACK. |
571 | 571 | ||
572 | Both ends (listening sockets) accept the new incoming | 572 | If icsk->icsk_accept_queue.rskq_defer_accept, we silently drop this |
573 | connection and try to talk to each other. 8-) | 573 | bare ACK. Otherwise, we create an established connection. Both |
574 | ends (listening sockets) accept the new incoming connection and try | ||
575 | to talk to each other. 8-) | ||
574 | 576 | ||
575 | Note: This case is both harmless, and rare. Possibility is about the | 577 | Note: This case is both harmless, and rare. Possibility is about the |
576 | same as us discovering intelligent life on another plant tomorrow. | 578 | same as us discovering intelligent life on another plant tomorrow. |
@@ -638,6 +640,13 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
638 | if (!(flg & TCP_FLAG_ACK)) | 640 | if (!(flg & TCP_FLAG_ACK)) |
639 | return NULL; | 641 | return NULL; |
640 | 642 | ||
643 | /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ | ||
644 | if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | ||
645 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | ||
646 | inet_rsk(req)->acked = 1; | ||
647 | return NULL; | ||
648 | } | ||
649 | |||
641 | /* OK, ACK is valid, create big socket and | 650 | /* OK, ACK is valid, create big socket and |
642 | * feed this segment to it. It will repeat all | 651 | * feed this segment to it. It will repeat all |
643 | * the tests. THIS SEGMENT MUST MOVE SOCKET TO | 652 | * the tests. THIS SEGMENT MUST MOVE SOCKET TO |
@@ -676,24 +685,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
676 | inet_csk_reqsk_queue_unlink(sk, req, prev); | 685 | inet_csk_reqsk_queue_unlink(sk, req, prev); |
677 | inet_csk_reqsk_queue_removed(sk, req); | 686 | inet_csk_reqsk_queue_removed(sk, req); |
678 | 687 | ||
679 | if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && | 688 | inet_csk_reqsk_queue_add(sk, req, child); |
680 | TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { | ||
681 | |||
682 | /* the accept queue handling is done is est recv slow | ||
683 | * path so lets make sure to start there | ||
684 | */ | ||
685 | tcp_sk(child)->pred_flags = 0; | ||
686 | sock_hold(sk); | ||
687 | sock_hold(child); | ||
688 | tcp_sk(child)->defer_tcp_accept.listen_sk = sk; | ||
689 | tcp_sk(child)->defer_tcp_accept.request = req; | ||
690 | |||
691 | inet_csk_reset_keepalive_timer(child, | ||
692 | inet_csk(sk)->icsk_accept_queue.rskq_defer_accept * HZ); | ||
693 | } else { | ||
694 | inet_csk_reqsk_queue_add(sk, req, child); | ||
695 | } | ||
696 | |||
697 | return child; | 689 | return child; |
698 | 690 | ||
699 | listen_overflow: | 691 | listen_overflow: |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index e77e7ae0bf2c..3e358cbb1247 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -487,11 +487,6 @@ static void tcp_keepalive_timer (unsigned long data) | |||
487 | goto death; | 487 | goto death; |
488 | } | 488 | } |
489 | 489 | ||
490 | if (tp->defer_tcp_accept.request && sk->sk_state == TCP_ESTABLISHED) { | ||
491 | tcp_send_active_reset(sk, GFP_ATOMIC); | ||
492 | goto death; | ||
493 | } | ||
494 | |||
495 | if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE) | 490 | if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE) |
496 | goto out; | 491 | goto out; |
497 | 492 | ||