diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fa24e7ae1f40..f17c6577e337 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -1356,8 +1356,9 @@ int tcp_send_synack(struct sock *sk) | |||
| 1356 | * Prepare a SYN-ACK. | 1356 | * Prepare a SYN-ACK. |
| 1357 | */ | 1357 | */ |
| 1358 | struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | 1358 | struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, |
| 1359 | struct open_request *req) | 1359 | struct request_sock *req) |
| 1360 | { | 1360 | { |
| 1361 | struct inet_request_sock *ireq = inet_rsk(req); | ||
| 1361 | struct tcp_sock *tp = tcp_sk(sk); | 1362 | struct tcp_sock *tp = tcp_sk(sk); |
| 1362 | struct tcphdr *th; | 1363 | struct tcphdr *th; |
| 1363 | int tcp_header_size; | 1364 | int tcp_header_size; |
| @@ -1373,47 +1374,47 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 1373 | skb->dst = dst_clone(dst); | 1374 | skb->dst = dst_clone(dst); |
| 1374 | 1375 | ||
| 1375 | tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + | 1376 | tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS + |
| 1376 | (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + | 1377 | (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) + |
| 1377 | (req->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + | 1378 | (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + |
| 1378 | /* SACK_PERM is in the place of NOP NOP of TS */ | 1379 | /* SACK_PERM is in the place of NOP NOP of TS */ |
| 1379 | ((req->sack_ok && !req->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); | 1380 | ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); |
| 1380 | skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); | 1381 | skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); |
| 1381 | 1382 | ||
| 1382 | memset(th, 0, sizeof(struct tcphdr)); | 1383 | memset(th, 0, sizeof(struct tcphdr)); |
| 1383 | th->syn = 1; | 1384 | th->syn = 1; |
| 1384 | th->ack = 1; | 1385 | th->ack = 1; |
| 1385 | if (dst->dev->features&NETIF_F_TSO) | 1386 | if (dst->dev->features&NETIF_F_TSO) |
| 1386 | req->ecn_ok = 0; | 1387 | ireq->ecn_ok = 0; |
| 1387 | TCP_ECN_make_synack(req, th); | 1388 | TCP_ECN_make_synack(req, th); |
| 1388 | th->source = inet_sk(sk)->sport; | 1389 | th->source = inet_sk(sk)->sport; |
| 1389 | th->dest = req->rmt_port; | 1390 | th->dest = ireq->rmt_port; |
| 1390 | TCP_SKB_CB(skb)->seq = req->snt_isn; | 1391 | TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn; |
| 1391 | TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; | 1392 | TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; |
| 1392 | TCP_SKB_CB(skb)->sacked = 0; | 1393 | TCP_SKB_CB(skb)->sacked = 0; |
| 1393 | skb_shinfo(skb)->tso_segs = 1; | 1394 | skb_shinfo(skb)->tso_segs = 1; |
| 1394 | skb_shinfo(skb)->tso_size = 0; | 1395 | skb_shinfo(skb)->tso_size = 0; |
| 1395 | th->seq = htonl(TCP_SKB_CB(skb)->seq); | 1396 | th->seq = htonl(TCP_SKB_CB(skb)->seq); |
| 1396 | th->ack_seq = htonl(req->rcv_isn + 1); | 1397 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); |
| 1397 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ | 1398 | if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ |
| 1398 | __u8 rcv_wscale; | 1399 | __u8 rcv_wscale; |
| 1399 | /* Set this up on the first call only */ | 1400 | /* Set this up on the first call only */ |
| 1400 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); | 1401 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); |
| 1401 | /* tcp_full_space because it is guaranteed to be the first packet */ | 1402 | /* tcp_full_space because it is guaranteed to be the first packet */ |
| 1402 | tcp_select_initial_window(tcp_full_space(sk), | 1403 | tcp_select_initial_window(tcp_full_space(sk), |
| 1403 | dst_metric(dst, RTAX_ADVMSS) - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | 1404 | dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), |
| 1404 | &req->rcv_wnd, | 1405 | &req->rcv_wnd, |
| 1405 | &req->window_clamp, | 1406 | &req->window_clamp, |
| 1406 | req->wscale_ok, | 1407 | ireq->wscale_ok, |
| 1407 | &rcv_wscale); | 1408 | &rcv_wscale); |
| 1408 | req->rcv_wscale = rcv_wscale; | 1409 | ireq->rcv_wscale = rcv_wscale; |
| 1409 | } | 1410 | } |
| 1410 | 1411 | ||
| 1411 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ | 1412 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ |
| 1412 | th->window = htons(req->rcv_wnd); | 1413 | th->window = htons(req->rcv_wnd); |
| 1413 | 1414 | ||
| 1414 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 1415 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
| 1415 | tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), req->tstamp_ok, | 1416 | tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok, |
| 1416 | req->sack_ok, req->wscale_ok, req->rcv_wscale, | 1417 | ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale, |
| 1417 | TCP_SKB_CB(skb)->when, | 1418 | TCP_SKB_CB(skb)->when, |
| 1418 | req->ts_recent); | 1419 | req->ts_recent); |
| 1419 | 1420 | ||
