diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 329 |
1 files changed, 272 insertions, 57 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fcd278a7080e..93316a96d820 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -59,6 +59,10 @@ int sysctl_tcp_base_mss __read_mostly = 512; | |||
59 | /* By default, RFC2861 behavior. */ | 59 | /* By default, RFC2861 behavior. */ |
60 | int sysctl_tcp_slow_start_after_idle __read_mostly = 1; | 60 | int sysctl_tcp_slow_start_after_idle __read_mostly = 1; |
61 | 61 | ||
62 | int sysctl_tcp_cookie_size __read_mostly = 0; /* TCP_COOKIE_MAX */ | ||
63 | EXPORT_SYMBOL_GPL(sysctl_tcp_cookie_size); | ||
64 | |||
65 | |||
62 | /* Account for new data that has been sent to the network. */ | 66 | /* Account for new data that has been sent to the network. */ |
63 | static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) | 67 | static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) |
64 | { | 68 | { |
@@ -362,15 +366,45 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp) | |||
362 | #define OPTION_TS (1 << 1) | 366 | #define OPTION_TS (1 << 1) |
363 | #define OPTION_MD5 (1 << 2) | 367 | #define OPTION_MD5 (1 << 2) |
364 | #define OPTION_WSCALE (1 << 3) | 368 | #define OPTION_WSCALE (1 << 3) |
369 | #define OPTION_COOKIE_EXTENSION (1 << 4) | ||
365 | 370 | ||
366 | struct tcp_out_options { | 371 | struct tcp_out_options { |
367 | u8 options; /* bit field of OPTION_* */ | 372 | u8 options; /* bit field of OPTION_* */ |
368 | u8 ws; /* window scale, 0 to disable */ | 373 | u8 ws; /* window scale, 0 to disable */ |
369 | u8 num_sack_blocks; /* number of SACK blocks to include */ | 374 | u8 num_sack_blocks; /* number of SACK blocks to include */ |
375 | u8 hash_size; /* bytes in hash_location */ | ||
370 | u16 mss; /* 0 to disable */ | 376 | u16 mss; /* 0 to disable */ |
371 | __u32 tsval, tsecr; /* need to include OPTION_TS */ | 377 | __u32 tsval, tsecr; /* need to include OPTION_TS */ |
378 | __u8 *hash_location; /* temporary pointer, overloaded */ | ||
372 | }; | 379 | }; |
373 | 380 | ||
381 | /* The sysctl int routines are generic, so check consistency here. | ||
382 | */ | ||
383 | static u8 tcp_cookie_size_check(u8 desired) | ||
384 | { | ||
385 | if (desired > 0) { | ||
386 | /* previously specified */ | ||
387 | return desired; | ||
388 | } | ||
389 | if (sysctl_tcp_cookie_size <= 0) { | ||
390 | /* no default specified */ | ||
391 | return 0; | ||
392 | } | ||
393 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | ||
394 | /* value too small, specify minimum */ | ||
395 | return TCP_COOKIE_MIN; | ||
396 | } | ||
397 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | ||
398 | /* value too large, specify maximum */ | ||
399 | return TCP_COOKIE_MAX; | ||
400 | } | ||
401 | if (0x1 & sysctl_tcp_cookie_size) { | ||
402 | /* 8-bit multiple, illegal, fix it */ | ||
403 | return (u8)(sysctl_tcp_cookie_size + 0x1); | ||
404 | } | ||
405 | return (u8)sysctl_tcp_cookie_size; | ||
406 | } | ||
407 | |||
374 | /* Write previously computed TCP options to the packet. | 408 | /* Write previously computed TCP options to the packet. |
375 | * | 409 | * |
376 | * Beware: Something in the Internet is very sensitive to the ordering of | 410 | * Beware: Something in the Internet is very sensitive to the ordering of |
@@ -385,17 +419,34 @@ struct tcp_out_options { | |||
385 | * (but it may well be that other scenarios fail similarly). | 419 | * (but it may well be that other scenarios fail similarly). |
386 | */ | 420 | */ |
387 | static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | 421 | static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, |
388 | const struct tcp_out_options *opts, | 422 | struct tcp_out_options *opts) |
389 | __u8 **md5_hash) { | 423 | { |
390 | if (unlikely(OPTION_MD5 & opts->options)) { | 424 | u8 options = opts->options; /* mungable copy */ |
391 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 425 | |
392 | (TCPOPT_NOP << 16) | | 426 | /* Having both authentication and cookies for security is redundant, |
393 | (TCPOPT_MD5SIG << 8) | | 427 | * and there's certainly not enough room. Instead, the cookie-less |
394 | TCPOLEN_MD5SIG); | 428 | * extension variant is proposed. |
395 | *md5_hash = (__u8 *)ptr; | 429 | * |
430 | * Consider the pessimal case with authentication. The options | ||
431 | * could look like: | ||
432 | * COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40 | ||
433 | */ | ||
434 | if (unlikely(OPTION_MD5 & options)) { | ||
435 | if (unlikely(OPTION_COOKIE_EXTENSION & options)) { | ||
436 | *ptr++ = htonl((TCPOPT_COOKIE << 24) | | ||
437 | (TCPOLEN_COOKIE_BASE << 16) | | ||
438 | (TCPOPT_MD5SIG << 8) | | ||
439 | TCPOLEN_MD5SIG); | ||
440 | } else { | ||
441 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
442 | (TCPOPT_NOP << 16) | | ||
443 | (TCPOPT_MD5SIG << 8) | | ||
444 | TCPOLEN_MD5SIG); | ||
445 | } | ||
446 | options &= ~OPTION_COOKIE_EXTENSION; | ||
447 | /* overload cookie hash location */ | ||
448 | opts->hash_location = (__u8 *)ptr; | ||
396 | ptr += 4; | 449 | ptr += 4; |
397 | } else { | ||
398 | *md5_hash = NULL; | ||
399 | } | 450 | } |
400 | 451 | ||
401 | if (unlikely(opts->mss)) { | 452 | if (unlikely(opts->mss)) { |
@@ -404,12 +455,13 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
404 | opts->mss); | 455 | opts->mss); |
405 | } | 456 | } |
406 | 457 | ||
407 | if (likely(OPTION_TS & opts->options)) { | 458 | if (likely(OPTION_TS & options)) { |
408 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) { | 459 | if (unlikely(OPTION_SACK_ADVERTISE & options)) { |
409 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | | 460 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | |
410 | (TCPOLEN_SACK_PERM << 16) | | 461 | (TCPOLEN_SACK_PERM << 16) | |
411 | (TCPOPT_TIMESTAMP << 8) | | 462 | (TCPOPT_TIMESTAMP << 8) | |
412 | TCPOLEN_TIMESTAMP); | 463 | TCPOLEN_TIMESTAMP); |
464 | options &= ~OPTION_SACK_ADVERTISE; | ||
413 | } else { | 465 | } else { |
414 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 466 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
415 | (TCPOPT_NOP << 16) | | 467 | (TCPOPT_NOP << 16) | |
@@ -420,15 +472,52 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
420 | *ptr++ = htonl(opts->tsecr); | 472 | *ptr++ = htonl(opts->tsecr); |
421 | } | 473 | } |
422 | 474 | ||
423 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options && | 475 | /* Specification requires after timestamp, so do it now. |
424 | !(OPTION_TS & opts->options))) { | 476 | * |
477 | * Consider the pessimal case without authentication. The options | ||
478 | * could look like: | ||
479 | * MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40 | ||
480 | */ | ||
481 | if (unlikely(OPTION_COOKIE_EXTENSION & options)) { | ||
482 | __u8 *cookie_copy = opts->hash_location; | ||
483 | u8 cookie_size = opts->hash_size; | ||
484 | |||
485 | /* 8-bit multiple handled in tcp_cookie_size_check() above, | ||
486 | * and elsewhere. | ||
487 | */ | ||
488 | if (0x2 & cookie_size) { | ||
489 | __u8 *p = (__u8 *)ptr; | ||
490 | |||
491 | /* 16-bit multiple */ | ||
492 | *p++ = TCPOPT_COOKIE; | ||
493 | *p++ = TCPOLEN_COOKIE_BASE + cookie_size; | ||
494 | *p++ = *cookie_copy++; | ||
495 | *p++ = *cookie_copy++; | ||
496 | ptr++; | ||
497 | cookie_size -= 2; | ||
498 | } else { | ||
499 | /* 32-bit multiple */ | ||
500 | *ptr++ = htonl(((TCPOPT_NOP << 24) | | ||
501 | (TCPOPT_NOP << 16) | | ||
502 | (TCPOPT_COOKIE << 8) | | ||
503 | TCPOLEN_COOKIE_BASE) + | ||
504 | cookie_size); | ||
505 | } | ||
506 | |||
507 | if (cookie_size > 0) { | ||
508 | memcpy(ptr, cookie_copy, cookie_size); | ||
509 | ptr += (cookie_size / 4); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | if (unlikely(OPTION_SACK_ADVERTISE & options)) { | ||
425 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 514 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
426 | (TCPOPT_NOP << 16) | | 515 | (TCPOPT_NOP << 16) | |
427 | (TCPOPT_SACK_PERM << 8) | | 516 | (TCPOPT_SACK_PERM << 8) | |
428 | TCPOLEN_SACK_PERM); | 517 | TCPOLEN_SACK_PERM); |
429 | } | 518 | } |
430 | 519 | ||
431 | if (unlikely(OPTION_WSCALE & opts->options)) { | 520 | if (unlikely(OPTION_WSCALE & options)) { |
432 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 521 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
433 | (TCPOPT_WINDOW << 16) | | 522 | (TCPOPT_WINDOW << 16) | |
434 | (TCPOLEN_WINDOW << 8) | | 523 | (TCPOLEN_WINDOW << 8) | |
@@ -463,13 +552,18 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb, | |||
463 | struct tcp_out_options *opts, | 552 | struct tcp_out_options *opts, |
464 | struct tcp_md5sig_key **md5) { | 553 | struct tcp_md5sig_key **md5) { |
465 | struct tcp_sock *tp = tcp_sk(sk); | 554 | struct tcp_sock *tp = tcp_sk(sk); |
466 | unsigned size = 0; | 555 | struct tcp_cookie_values *cvp = tp->cookie_values; |
556 | struct dst_entry *dst = __sk_dst_get(sk); | ||
557 | unsigned remaining = MAX_TCP_OPTION_SPACE; | ||
558 | u8 cookie_size = (!tp->rx_opt.cookie_out_never && cvp != NULL) ? | ||
559 | tcp_cookie_size_check(cvp->cookie_desired) : | ||
560 | 0; | ||
467 | 561 | ||
468 | #ifdef CONFIG_TCP_MD5SIG | 562 | #ifdef CONFIG_TCP_MD5SIG |
469 | *md5 = tp->af_specific->md5_lookup(sk, sk); | 563 | *md5 = tp->af_specific->md5_lookup(sk, sk); |
470 | if (*md5) { | 564 | if (*md5) { |
471 | opts->options |= OPTION_MD5; | 565 | opts->options |= OPTION_MD5; |
472 | size += TCPOLEN_MD5SIG_ALIGNED; | 566 | remaining -= TCPOLEN_MD5SIG_ALIGNED; |
473 | } | 567 | } |
474 | #else | 568 | #else |
475 | *md5 = NULL; | 569 | *md5 = NULL; |
@@ -485,26 +579,76 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb, | |||
485 | * SACKs don't matter, we never delay an ACK when we have any of those | 579 | * SACKs don't matter, we never delay an ACK when we have any of those |
486 | * going out. */ | 580 | * going out. */ |
487 | opts->mss = tcp_advertise_mss(sk); | 581 | opts->mss = tcp_advertise_mss(sk); |
488 | size += TCPOLEN_MSS_ALIGNED; | 582 | remaining -= TCPOLEN_MSS_ALIGNED; |
489 | 583 | ||
490 | if (likely(sysctl_tcp_timestamps && *md5 == NULL)) { | 584 | if (likely(sysctl_tcp_timestamps && |
585 | !dst_feature(dst, RTAX_FEATURE_NO_TSTAMP) && | ||
586 | *md5 == NULL)) { | ||
491 | opts->options |= OPTION_TS; | 587 | opts->options |= OPTION_TS; |
492 | opts->tsval = TCP_SKB_CB(skb)->when; | 588 | opts->tsval = TCP_SKB_CB(skb)->when; |
493 | opts->tsecr = tp->rx_opt.ts_recent; | 589 | opts->tsecr = tp->rx_opt.ts_recent; |
494 | size += TCPOLEN_TSTAMP_ALIGNED; | 590 | remaining -= TCPOLEN_TSTAMP_ALIGNED; |
495 | } | 591 | } |
496 | if (likely(sysctl_tcp_window_scaling)) { | 592 | if (likely(sysctl_tcp_window_scaling && |
593 | !dst_feature(dst, RTAX_FEATURE_NO_WSCALE))) { | ||
497 | opts->ws = tp->rx_opt.rcv_wscale; | 594 | opts->ws = tp->rx_opt.rcv_wscale; |
498 | opts->options |= OPTION_WSCALE; | 595 | opts->options |= OPTION_WSCALE; |
499 | size += TCPOLEN_WSCALE_ALIGNED; | 596 | remaining -= TCPOLEN_WSCALE_ALIGNED; |
500 | } | 597 | } |
501 | if (likely(sysctl_tcp_sack)) { | 598 | if (likely(sysctl_tcp_sack && |
599 | !dst_feature(dst, RTAX_FEATURE_NO_SACK))) { | ||
502 | opts->options |= OPTION_SACK_ADVERTISE; | 600 | opts->options |= OPTION_SACK_ADVERTISE; |
503 | if (unlikely(!(OPTION_TS & opts->options))) | 601 | if (unlikely(!(OPTION_TS & opts->options))) |
504 | size += TCPOLEN_SACKPERM_ALIGNED; | 602 | remaining -= TCPOLEN_SACKPERM_ALIGNED; |
505 | } | 603 | } |
506 | 604 | ||
507 | return size; | 605 | /* Note that timestamps are required by the specification. |
606 | * | ||
607 | * Odd numbers of bytes are prohibited by the specification, ensuring | ||
608 | * that the cookie is 16-bit aligned, and the resulting cookie pair is | ||
609 | * 32-bit aligned. | ||
610 | */ | ||
611 | if (*md5 == NULL && | ||
612 | (OPTION_TS & opts->options) && | ||
613 | cookie_size > 0) { | ||
614 | int need = TCPOLEN_COOKIE_BASE + cookie_size; | ||
615 | |||
616 | if (0x2 & need) { | ||
617 | /* 32-bit multiple */ | ||
618 | need += 2; /* NOPs */ | ||
619 | |||
620 | if (need > remaining) { | ||
621 | /* try shrinking cookie to fit */ | ||
622 | cookie_size -= 2; | ||
623 | need -= 4; | ||
624 | } | ||
625 | } | ||
626 | while (need > remaining && TCP_COOKIE_MIN <= cookie_size) { | ||
627 | cookie_size -= 4; | ||
628 | need -= 4; | ||
629 | } | ||
630 | if (TCP_COOKIE_MIN <= cookie_size) { | ||
631 | opts->options |= OPTION_COOKIE_EXTENSION; | ||
632 | opts->hash_location = (__u8 *)&cvp->cookie_pair[0]; | ||
633 | opts->hash_size = cookie_size; | ||
634 | |||
635 | /* Remember for future incarnations. */ | ||
636 | cvp->cookie_desired = cookie_size; | ||
637 | |||
638 | if (cvp->cookie_desired != cvp->cookie_pair_size) { | ||
639 | /* Currently use random bytes as a nonce, | ||
640 | * assuming these are completely unpredictable | ||
641 | * by hostile users of the same system. | ||
642 | */ | ||
643 | get_random_bytes(&cvp->cookie_pair[0], | ||
644 | cookie_size); | ||
645 | cvp->cookie_pair_size = cookie_size; | ||
646 | } | ||
647 | |||
648 | remaining -= need; | ||
649 | } | ||
650 | } | ||
651 | return MAX_TCP_OPTION_SPACE - remaining; | ||
508 | } | 652 | } |
509 | 653 | ||
510 | /* Set up TCP options for SYN-ACKs. */ | 654 | /* Set up TCP options for SYN-ACKs. */ |
@@ -512,48 +656,77 @@ static unsigned tcp_synack_options(struct sock *sk, | |||
512 | struct request_sock *req, | 656 | struct request_sock *req, |
513 | unsigned mss, struct sk_buff *skb, | 657 | unsigned mss, struct sk_buff *skb, |
514 | struct tcp_out_options *opts, | 658 | struct tcp_out_options *opts, |
515 | struct tcp_md5sig_key **md5) { | 659 | struct tcp_md5sig_key **md5, |
516 | unsigned size = 0; | 660 | struct tcp_extend_values *xvp) |
661 | { | ||
517 | struct inet_request_sock *ireq = inet_rsk(req); | 662 | struct inet_request_sock *ireq = inet_rsk(req); |
518 | char doing_ts; | 663 | unsigned remaining = MAX_TCP_OPTION_SPACE; |
664 | u8 cookie_plus = (xvp != NULL && !xvp->cookie_out_never) ? | ||
665 | xvp->cookie_plus : | ||
666 | 0; | ||
667 | bool doing_ts = ireq->tstamp_ok; | ||
519 | 668 | ||
520 | #ifdef CONFIG_TCP_MD5SIG | 669 | #ifdef CONFIG_TCP_MD5SIG |
521 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); | 670 | *md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req); |
522 | if (*md5) { | 671 | if (*md5) { |
523 | opts->options |= OPTION_MD5; | 672 | opts->options |= OPTION_MD5; |
524 | size += TCPOLEN_MD5SIG_ALIGNED; | 673 | remaining -= TCPOLEN_MD5SIG_ALIGNED; |
674 | |||
675 | /* We can't fit any SACK blocks in a packet with MD5 + TS | ||
676 | * options. There was discussion about disabling SACK | ||
677 | * rather than TS in order to fit in better with old, | ||
678 | * buggy kernels, but that was deemed to be unnecessary. | ||
679 | */ | ||
680 | doing_ts &= !ireq->sack_ok; | ||
525 | } | 681 | } |
526 | #else | 682 | #else |
527 | *md5 = NULL; | 683 | *md5 = NULL; |
528 | #endif | 684 | #endif |
529 | 685 | ||
530 | /* we can't fit any SACK blocks in a packet with MD5 + TS | 686 | /* We always send an MSS option. */ |
531 | options. There was discussion about disabling SACK rather than TS in | ||
532 | order to fit in better with old, buggy kernels, but that was deemed | ||
533 | to be unnecessary. */ | ||
534 | doing_ts = ireq->tstamp_ok && !(*md5 && ireq->sack_ok); | ||
535 | |||
536 | opts->mss = mss; | 687 | opts->mss = mss; |
537 | size += TCPOLEN_MSS_ALIGNED; | 688 | remaining -= TCPOLEN_MSS_ALIGNED; |
538 | 689 | ||
539 | if (likely(ireq->wscale_ok)) { | 690 | if (likely(ireq->wscale_ok)) { |
540 | opts->ws = ireq->rcv_wscale; | 691 | opts->ws = ireq->rcv_wscale; |
541 | opts->options |= OPTION_WSCALE; | 692 | opts->options |= OPTION_WSCALE; |
542 | size += TCPOLEN_WSCALE_ALIGNED; | 693 | remaining -= TCPOLEN_WSCALE_ALIGNED; |
543 | } | 694 | } |
544 | if (likely(doing_ts)) { | 695 | if (likely(doing_ts)) { |
545 | opts->options |= OPTION_TS; | 696 | opts->options |= OPTION_TS; |
546 | opts->tsval = TCP_SKB_CB(skb)->when; | 697 | opts->tsval = TCP_SKB_CB(skb)->when; |
547 | opts->tsecr = req->ts_recent; | 698 | opts->tsecr = req->ts_recent; |
548 | size += TCPOLEN_TSTAMP_ALIGNED; | 699 | remaining -= TCPOLEN_TSTAMP_ALIGNED; |
549 | } | 700 | } |
550 | if (likely(ireq->sack_ok)) { | 701 | if (likely(ireq->sack_ok)) { |
551 | opts->options |= OPTION_SACK_ADVERTISE; | 702 | opts->options |= OPTION_SACK_ADVERTISE; |
552 | if (unlikely(!doing_ts)) | 703 | if (unlikely(!doing_ts)) |
553 | size += TCPOLEN_SACKPERM_ALIGNED; | 704 | remaining -= TCPOLEN_SACKPERM_ALIGNED; |
554 | } | 705 | } |
555 | 706 | ||
556 | return size; | 707 | /* Similar rationale to tcp_syn_options() applies here, too. |
708 | * If the <SYN> options fit, the same options should fit now! | ||
709 | */ | ||
710 | if (*md5 == NULL && | ||
711 | doing_ts && | ||
712 | cookie_plus > TCPOLEN_COOKIE_BASE) { | ||
713 | int need = cookie_plus; /* has TCPOLEN_COOKIE_BASE */ | ||
714 | |||
715 | if (0x2 & need) { | ||
716 | /* 32-bit multiple */ | ||
717 | need += 2; /* NOPs */ | ||
718 | } | ||
719 | if (need <= remaining) { | ||
720 | opts->options |= OPTION_COOKIE_EXTENSION; | ||
721 | opts->hash_size = cookie_plus - TCPOLEN_COOKIE_BASE; | ||
722 | remaining -= need; | ||
723 | } else { | ||
724 | /* There's no error return, so flag it. */ | ||
725 | xvp->cookie_out_never = 1; /* true */ | ||
726 | opts->hash_size = 0; | ||
727 | } | ||
728 | } | ||
729 | return MAX_TCP_OPTION_SPACE - remaining; | ||
557 | } | 730 | } |
558 | 731 | ||
559 | /* Compute TCP options for ESTABLISHED sockets. This is not the | 732 | /* Compute TCP options for ESTABLISHED sockets. This is not the |
@@ -619,7 +792,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
619 | struct tcp_out_options opts; | 792 | struct tcp_out_options opts; |
620 | unsigned tcp_options_size, tcp_header_size; | 793 | unsigned tcp_options_size, tcp_header_size; |
621 | struct tcp_md5sig_key *md5; | 794 | struct tcp_md5sig_key *md5; |
622 | __u8 *md5_hash_location; | ||
623 | struct tcphdr *th; | 795 | struct tcphdr *th; |
624 | int err; | 796 | int err; |
625 | 797 | ||
@@ -661,8 +833,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
661 | 833 | ||
662 | /* Build TCP header and checksum it. */ | 834 | /* Build TCP header and checksum it. */ |
663 | th = tcp_hdr(skb); | 835 | th = tcp_hdr(skb); |
664 | th->source = inet->sport; | 836 | th->source = inet->inet_sport; |
665 | th->dest = inet->dport; | 837 | th->dest = inet->inet_dport; |
666 | th->seq = htonl(tcb->seq); | 838 | th->seq = htonl(tcb->seq); |
667 | th->ack_seq = htonl(tp->rcv_nxt); | 839 | th->ack_seq = htonl(tp->rcv_nxt); |
668 | *(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) | | 840 | *(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) | |
@@ -690,7 +862,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
690 | } | 862 | } |
691 | } | 863 | } |
692 | 864 | ||
693 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); | 865 | tcp_options_write((__be32 *)(th + 1), tp, &opts); |
694 | if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0)) | 866 | if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0)) |
695 | TCP_ECN_send(sk, skb, tcp_header_size); | 867 | TCP_ECN_send(sk, skb, tcp_header_size); |
696 | 868 | ||
@@ -698,7 +870,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
698 | /* Calculate the MD5 hash, as we have all we need now */ | 870 | /* Calculate the MD5 hash, as we have all we need now */ |
699 | if (md5) { | 871 | if (md5) { |
700 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 872 | sk->sk_route_caps &= ~NETIF_F_GSO_MASK; |
701 | tp->af_specific->calc_md5_hash(md5_hash_location, | 873 | tp->af_specific->calc_md5_hash(opts.hash_location, |
702 | md5, sk, NULL, skb); | 874 | md5, sk, NULL, skb); |
703 | } | 875 | } |
704 | #endif | 876 | #endif |
@@ -1918,8 +2090,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
1918 | * case, when window is shrunk to zero. In this case | 2090 | * case, when window is shrunk to zero. In this case |
1919 | * our retransmit serves as a zero window probe. | 2091 | * our retransmit serves as a zero window probe. |
1920 | */ | 2092 | */ |
1921 | if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)) | 2093 | if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)) && |
1922 | && TCP_SKB_CB(skb)->seq != tp->snd_una) | 2094 | TCP_SKB_CB(skb)->seq != tp->snd_una) |
1923 | return -EAGAIN; | 2095 | return -EAGAIN; |
1924 | 2096 | ||
1925 | if (skb->len > cur_mss) { | 2097 | if (skb->len > cur_mss) { |
@@ -2219,16 +2391,17 @@ int tcp_send_synack(struct sock *sk) | |||
2219 | 2391 | ||
2220 | /* Prepare a SYN-ACK. */ | 2392 | /* Prepare a SYN-ACK. */ |
2221 | struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | 2393 | struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, |
2222 | struct request_sock *req) | 2394 | struct request_sock *req, |
2395 | struct request_values *rvp) | ||
2223 | { | 2396 | { |
2397 | struct tcp_out_options opts; | ||
2398 | struct tcp_extend_values *xvp = tcp_xv(rvp); | ||
2224 | struct inet_request_sock *ireq = inet_rsk(req); | 2399 | struct inet_request_sock *ireq = inet_rsk(req); |
2225 | struct tcp_sock *tp = tcp_sk(sk); | 2400 | struct tcp_sock *tp = tcp_sk(sk); |
2226 | struct tcphdr *th; | 2401 | struct tcphdr *th; |
2227 | int tcp_header_size; | ||
2228 | struct tcp_out_options opts; | ||
2229 | struct sk_buff *skb; | 2402 | struct sk_buff *skb; |
2230 | struct tcp_md5sig_key *md5; | 2403 | struct tcp_md5sig_key *md5; |
2231 | __u8 *md5_hash_location; | 2404 | int tcp_header_size; |
2232 | int mss; | 2405 | int mss; |
2233 | 2406 | ||
2234 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); | 2407 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); |
@@ -2266,8 +2439,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2266 | #endif | 2439 | #endif |
2267 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2440 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
2268 | tcp_header_size = tcp_synack_options(sk, req, mss, | 2441 | tcp_header_size = tcp_synack_options(sk, req, mss, |
2269 | skb, &opts, &md5) + | 2442 | skb, &opts, &md5, xvp) |
2270 | sizeof(struct tcphdr); | 2443 | + sizeof(*th); |
2271 | 2444 | ||
2272 | skb_push(skb, tcp_header_size); | 2445 | skb_push(skb, tcp_header_size); |
2273 | skb_reset_transport_header(skb); | 2446 | skb_reset_transport_header(skb); |
@@ -2284,19 +2457,58 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2284 | */ | 2457 | */ |
2285 | tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn, | 2458 | tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn, |
2286 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); | 2459 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); |
2460 | |||
2461 | if (OPTION_COOKIE_EXTENSION & opts.options) { | ||
2462 | const struct tcp_cookie_values *cvp = tp->cookie_values; | ||
2463 | |||
2464 | if (cvp != NULL && | ||
2465 | cvp->s_data_constant && | ||
2466 | cvp->s_data_desired > 0) { | ||
2467 | u8 *buf = skb_put(skb, cvp->s_data_desired); | ||
2468 | |||
2469 | /* copy data directly from the listening socket. */ | ||
2470 | memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); | ||
2471 | TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; | ||
2472 | } | ||
2473 | |||
2474 | if (opts.hash_size > 0) { | ||
2475 | __u32 workspace[SHA_WORKSPACE_WORDS]; | ||
2476 | u32 *mess = &xvp->cookie_bakery[COOKIE_DIGEST_WORDS]; | ||
2477 | u32 *tail = &mess[COOKIE_MESSAGE_WORDS-1]; | ||
2478 | |||
2479 | /* Secret recipe depends on the Timestamp, (future) | ||
2480 | * Sequence and Acknowledgment Numbers, Initiator | ||
2481 | * Cookie, and others handled by IP variant caller. | ||
2482 | */ | ||
2483 | *tail-- ^= opts.tsval; | ||
2484 | *tail-- ^= tcp_rsk(req)->rcv_isn + 1; | ||
2485 | *tail-- ^= TCP_SKB_CB(skb)->seq + 1; | ||
2486 | |||
2487 | /* recommended */ | ||
2488 | *tail-- ^= ((th->dest << 16) | th->source); | ||
2489 | *tail-- ^= (u32)(unsigned long)cvp; /* per sockopt */ | ||
2490 | |||
2491 | sha_transform((__u32 *)&xvp->cookie_bakery[0], | ||
2492 | (char *)mess, | ||
2493 | &workspace[0]); | ||
2494 | opts.hash_location = | ||
2495 | (__u8 *)&xvp->cookie_bakery[0]; | ||
2496 | } | ||
2497 | } | ||
2498 | |||
2287 | th->seq = htonl(TCP_SKB_CB(skb)->seq); | 2499 | th->seq = htonl(TCP_SKB_CB(skb)->seq); |
2288 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); | 2500 | th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); |
2289 | 2501 | ||
2290 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ | 2502 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ |
2291 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2503 | th->window = htons(min(req->rcv_wnd, 65535U)); |
2292 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); | 2504 | tcp_options_write((__be32 *)(th + 1), tp, &opts); |
2293 | th->doff = (tcp_header_size >> 2); | 2505 | th->doff = (tcp_header_size >> 2); |
2294 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2506 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); |
2295 | 2507 | ||
2296 | #ifdef CONFIG_TCP_MD5SIG | 2508 | #ifdef CONFIG_TCP_MD5SIG |
2297 | /* Okay, we have all we need - do the md5 hash if needed */ | 2509 | /* Okay, we have all we need - do the md5 hash if needed */ |
2298 | if (md5) { | 2510 | if (md5) { |
2299 | tcp_rsk(req)->af_specific->calc_md5_hash(md5_hash_location, | 2511 | tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location, |
2300 | md5, NULL, req, skb); | 2512 | md5, NULL, req, skb); |
2301 | } | 2513 | } |
2302 | #endif | 2514 | #endif |
@@ -2315,7 +2527,9 @@ static void tcp_connect_init(struct sock *sk) | |||
2315 | * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT. | 2527 | * See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT. |
2316 | */ | 2528 | */ |
2317 | tp->tcp_header_len = sizeof(struct tcphdr) + | 2529 | tp->tcp_header_len = sizeof(struct tcphdr) + |
2318 | (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0); | 2530 | (sysctl_tcp_timestamps && |
2531 | (!dst_feature(dst, RTAX_FEATURE_NO_TSTAMP) ? | ||
2532 | TCPOLEN_TSTAMP_ALIGNED : 0)); | ||
2319 | 2533 | ||
2320 | #ifdef CONFIG_TCP_MD5SIG | 2534 | #ifdef CONFIG_TCP_MD5SIG |
2321 | if (tp->af_specific->md5_lookup(sk, sk) != NULL) | 2535 | if (tp->af_specific->md5_lookup(sk, sk) != NULL) |
@@ -2341,7 +2555,8 @@ static void tcp_connect_init(struct sock *sk) | |||
2341 | tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), | 2555 | tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), |
2342 | &tp->rcv_wnd, | 2556 | &tp->rcv_wnd, |
2343 | &tp->window_clamp, | 2557 | &tp->window_clamp, |
2344 | sysctl_tcp_window_scaling, | 2558 | (sysctl_tcp_window_scaling && |
2559 | !dst_feature(dst, RTAX_FEATURE_NO_WSCALE)), | ||
2345 | &rcv_wscale); | 2560 | &rcv_wscale); |
2346 | 2561 | ||
2347 | tp->rx_opt.rcv_wscale = rcv_wscale; | 2562 | tp->rx_opt.rcv_wscale = rcv_wscale; |