diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 22:19:54 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 22:19:54 -0400 |
| commit | 2242d5eff17cf91110a3c44747f9f2e1a938cbda (patch) | |
| tree | a6459b4d1aeb7f6f08dea3db2e2780f6276abdb0 /net/ipv4 | |
| parent | 5579a782ad7ffa162b1060993e4a298dd50e7a33 (diff) | |
| parent | fd6149d332973bafa50f03ddb0ea9513e67f4517 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (29 commits)
tcp: Restore ordering of TCP options for the sake of inter-operability
net: Fix disjunct computation of netdev features
sctp: Fix to handle SHUTDOWN in SHUTDOWN_RECEIVED state
sctp: Fix to handle SHUTDOWN in SHUTDOWN-PENDING state
sctp: Add check for the TSN field of the SHUTDOWN chunk
sctp: Drop ICMP packet too big message with MTU larger than current PMTU
p54: enable 2.4/5GHz spectrum by eeprom bits.
orinoco: reduce stack usage in firmware download path
ath5k: fix suspend-related oops on rmmod
[netdrvr] fec_mpc52xx: Implement polling, to make netconsole work.
qlge: Fix MSI/legacy single interrupt bug.
smc911x: Make the driver safer on SMP
smc911x: Add IRQ polarity configuration
smc911x: Allow Kconfig dependency on ARM
sis190: add identifier for Atheros AR8021 PHY
8139x: reduce message severity on driver overlap
igb: add IGB_DCA instead of selecting INTEL_IOATDMA
igb: fix tx data corruption with transition to L0s on 82575
ehea: Fix memory hotplug support
netdev: DM9000: remove BLACKFIN hacking in DM9000 netdev driver
...
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/tcp_output.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 990a58493235..e4c5ac9fe89b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -362,6 +362,17 @@ struct tcp_out_options { | |||
| 362 | __u32 tsval, tsecr; /* need to include OPTION_TS */ | 362 | __u32 tsval, tsecr; /* need to include OPTION_TS */ |
| 363 | }; | 363 | }; |
| 364 | 364 | ||
| 365 | /* Beware: Something in the Internet is very sensitive to the ordering of | ||
| 366 | * TCP options, we learned this through the hard way, so be careful here. | ||
| 367 | * Luckily we can at least blame others for their non-compliance but from | ||
| 368 | * inter-operatibility perspective it seems that we're somewhat stuck with | ||
| 369 | * the ordering which we have been using if we want to keep working with | ||
| 370 | * those broken things (not that it currently hurts anybody as there isn't | ||
| 371 | * particular reason why the ordering would need to be changed). | ||
| 372 | * | ||
| 373 | * At least SACK_PERM as the first option is known to lead to a disaster | ||
| 374 | * (but it may well be that other scenarios fail similarly). | ||
| 375 | */ | ||
| 365 | static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | 376 | static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, |
| 366 | const struct tcp_out_options *opts, | 377 | const struct tcp_out_options *opts, |
| 367 | __u8 **md5_hash) { | 378 | __u8 **md5_hash) { |
| @@ -376,6 +387,12 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
| 376 | *md5_hash = NULL; | 387 | *md5_hash = NULL; |
| 377 | } | 388 | } |
| 378 | 389 | ||
| 390 | if (unlikely(opts->mss)) { | ||
| 391 | *ptr++ = htonl((TCPOPT_MSS << 24) | | ||
| 392 | (TCPOLEN_MSS << 16) | | ||
| 393 | opts->mss); | ||
| 394 | } | ||
| 395 | |||
| 379 | if (likely(OPTION_TS & opts->options)) { | 396 | if (likely(OPTION_TS & opts->options)) { |
| 380 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) { | 397 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) { |
| 381 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | | 398 | *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | |
| @@ -392,12 +409,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
| 392 | *ptr++ = htonl(opts->tsecr); | 409 | *ptr++ = htonl(opts->tsecr); |
| 393 | } | 410 | } |
| 394 | 411 | ||
| 395 | if (unlikely(opts->mss)) { | ||
| 396 | *ptr++ = htonl((TCPOPT_MSS << 24) | | ||
| 397 | (TCPOLEN_MSS << 16) | | ||
| 398 | opts->mss); | ||
| 399 | } | ||
| 400 | |||
| 401 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options && | 412 | if (unlikely(OPTION_SACK_ADVERTISE & opts->options && |
| 402 | !(OPTION_TS & opts->options))) { | 413 | !(OPTION_TS & opts->options))) { |
| 403 | *ptr++ = htonl((TCPOPT_NOP << 24) | | 414 | *ptr++ = htonl((TCPOPT_NOP << 24) | |
| @@ -432,7 +443,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, | |||
| 432 | 443 | ||
| 433 | if (tp->rx_opt.dsack) { | 444 | if (tp->rx_opt.dsack) { |
| 434 | tp->rx_opt.dsack = 0; | 445 | tp->rx_opt.dsack = 0; |
| 435 | tp->rx_opt.eff_sacks--; | 446 | tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks; |
| 436 | } | 447 | } |
| 437 | } | 448 | } |
| 438 | } | 449 | } |
