diff options
author | Surjit Reang <surjit.reang@neterion.com> | 2008-02-03 07:27:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-03 07:27:38 -0500 |
commit | c88559539bd16eae4e9056d4734b3fe8a9858c45 (patch) | |
tree | a90ea2bc129d9e4d944f49fd669ab36c98a9f15d /drivers/net | |
parent | 03157ac31eb4a8883382a212b161d2e6c5059fbf (diff) |
S2io: Fix for LRO Bugs
Resubmitting patch from Al Viro <viro@zeniv.linux.org.uk>, with subject -
[PATCH] s2io LRO bugs.
a) initiate_new_session() sets ->tcp_ack to ntohl(...); everything
else stores and expects to find there the net-endian value.
b) check for monotonic timestamps in verify_l3_l4_lro_capable()
compares the value sitting in TCP option (right there in the skb->data,
net-endian 32bit) with the value picked from earlier packet.
Doing that without ntohl() is an interesting idea and it might even
work occasionally; unfortunately, it's quite broken.
Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/s2io.c | 20 | ||||
-rw-r--r-- | drivers/net/s2io.h | 2 |
2 files changed, 11 insertions, 11 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 5fab7d7b5d74..6179a0a2032c 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -8118,7 +8118,7 @@ static void initiate_new_session(struct lro *lro, u8 *l2h, | |||
8118 | lro->iph = ip; | 8118 | lro->iph = ip; |
8119 | lro->tcph = tcp; | 8119 | lro->tcph = tcp; |
8120 | lro->tcp_next_seq = tcp_pyld_len + ntohl(tcp->seq); | 8120 | lro->tcp_next_seq = tcp_pyld_len + ntohl(tcp->seq); |
8121 | lro->tcp_ack = ntohl(tcp->ack_seq); | 8121 | lro->tcp_ack = tcp->ack_seq; |
8122 | lro->sg_num = 1; | 8122 | lro->sg_num = 1; |
8123 | lro->total_len = ntohs(ip->tot_len); | 8123 | lro->total_len = ntohs(ip->tot_len); |
8124 | lro->frags_len = 0; | 8124 | lro->frags_len = 0; |
@@ -8127,10 +8127,10 @@ static void initiate_new_session(struct lro *lro, u8 *l2h, | |||
8127 | * already been done. | 8127 | * already been done. |
8128 | */ | 8128 | */ |
8129 | if (tcp->doff == 8) { | 8129 | if (tcp->doff == 8) { |
8130 | u32 *ptr; | 8130 | __be32 *ptr; |
8131 | ptr = (u32 *)(tcp+1); | 8131 | ptr = (__be32 *)(tcp+1); |
8132 | lro->saw_ts = 1; | 8132 | lro->saw_ts = 1; |
8133 | lro->cur_tsval = *(ptr+1); | 8133 | lro->cur_tsval = ntohl(*(ptr+1)); |
8134 | lro->cur_tsecr = *(ptr+2); | 8134 | lro->cur_tsecr = *(ptr+2); |
8135 | } | 8135 | } |
8136 | lro->in_use = 1; | 8136 | lro->in_use = 1; |
@@ -8156,7 +8156,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) | |||
8156 | 8156 | ||
8157 | /* Update tsecr field if this session has timestamps enabled */ | 8157 | /* Update tsecr field if this session has timestamps enabled */ |
8158 | if (lro->saw_ts) { | 8158 | if (lro->saw_ts) { |
8159 | u32 *ptr = (u32 *)(tcp + 1); | 8159 | __be32 *ptr = (__be32 *)(tcp + 1); |
8160 | *(ptr+2) = lro->cur_tsecr; | 8160 | *(ptr+2) = lro->cur_tsecr; |
8161 | } | 8161 | } |
8162 | 8162 | ||
@@ -8181,10 +8181,10 @@ static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, | |||
8181 | lro->window = tcp->window; | 8181 | lro->window = tcp->window; |
8182 | 8182 | ||
8183 | if (lro->saw_ts) { | 8183 | if (lro->saw_ts) { |
8184 | u32 *ptr; | 8184 | __be32 *ptr; |
8185 | /* Update tsecr and tsval from this packet */ | 8185 | /* Update tsecr and tsval from this packet */ |
8186 | ptr = (u32 *) (tcp + 1); | 8186 | ptr = (__be32 *)(tcp+1); |
8187 | lro->cur_tsval = *(ptr + 1); | 8187 | lro->cur_tsval = ntohl(*(ptr+1)); |
8188 | lro->cur_tsecr = *(ptr + 2); | 8188 | lro->cur_tsecr = *(ptr + 2); |
8189 | } | 8189 | } |
8190 | } | 8190 | } |
@@ -8235,11 +8235,11 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, | |||
8235 | 8235 | ||
8236 | /* Ensure timestamp value increases monotonically */ | 8236 | /* Ensure timestamp value increases monotonically */ |
8237 | if (l_lro) | 8237 | if (l_lro) |
8238 | if (l_lro->cur_tsval > *((u32 *)(ptr+2))) | 8238 | if (l_lro->cur_tsval > ntohl(*((__be32 *)(ptr+2)))) |
8239 | return -1; | 8239 | return -1; |
8240 | 8240 | ||
8241 | /* timestamp echo reply should be non-zero */ | 8241 | /* timestamp echo reply should be non-zero */ |
8242 | if (*((u32 *)(ptr+6)) == 0) | 8242 | if (*((__be32 *)(ptr+6)) == 0) |
8243 | return -1; | 8243 | return -1; |
8244 | } | 8244 | } |
8245 | 8245 | ||
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 9f6016c6f135..64b88eb48287 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -809,7 +809,7 @@ struct lro { | |||
809 | int in_use; | 809 | int in_use; |
810 | __be16 window; | 810 | __be16 window; |
811 | u32 cur_tsval; | 811 | u32 cur_tsval; |
812 | u32 cur_tsecr; | 812 | __be32 cur_tsecr; |
813 | u8 saw_ts; | 813 | u8 saw_ts; |
814 | }; | 814 | }; |
815 | 815 | ||