diff options
Diffstat (limited to 'net/ipv4/syncookies.c')
-rw-r--r-- | net/ipv4/syncookies.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 8896329aebd0..650cace2180d 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <net/route.h> | 19 | #include <net/route.h> |
20 | 20 | ||
21 | /* Timestamps: lowest bits store TCP options */ | 21 | /* Timestamps: lowest bits store TCP options */ |
22 | #define TSBITS 5 | 22 | #define TSBITS 6 |
23 | #define TSMASK (((__u32)1 << TSBITS) - 1) | 23 | #define TSMASK (((__u32)1 << TSBITS) - 1) |
24 | 24 | ||
25 | extern int sysctl_tcp_syncookies; | 25 | extern int sysctl_tcp_syncookies; |
@@ -73,6 +73,7 @@ __u32 cookie_init_timestamp(struct request_sock *req) | |||
73 | 73 | ||
74 | options = ireq->wscale_ok ? ireq->snd_wscale : 0xf; | 74 | options = ireq->wscale_ok ? ireq->snd_wscale : 0xf; |
75 | options |= ireq->sack_ok << 4; | 75 | options |= ireq->sack_ok << 4; |
76 | options |= ireq->ecn_ok << 5; | ||
76 | 77 | ||
77 | ts = ts_now & ~TSMASK; | 78 | ts = ts_now & ~TSMASK; |
78 | ts |= options; | 79 | ts |= options; |
@@ -226,11 +227,11 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | |||
226 | * This extracts these options from the timestamp echo. | 227 | * This extracts these options from the timestamp echo. |
227 | * | 228 | * |
228 | * The lowest 4 bits store snd_wscale. | 229 | * The lowest 4 bits store snd_wscale. |
229 | * The next lsb is for sack_ok | 230 | * next 2 bits indicate SACK and ECN support. |
230 | * | 231 | * |
231 | * return false if we decode an option that should not be. | 232 | * return false if we decode an option that should not be. |
232 | */ | 233 | */ |
233 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) | 234 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok) |
234 | { | 235 | { |
235 | /* echoed timestamp, lowest bits contain options */ | 236 | /* echoed timestamp, lowest bits contain options */ |
236 | u32 options = tcp_opt->rcv_tsecr & TSMASK; | 237 | u32 options = tcp_opt->rcv_tsecr & TSMASK; |
@@ -244,6 +245,9 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) | |||
244 | return false; | 245 | return false; |
245 | 246 | ||
246 | tcp_opt->sack_ok = (options >> 4) & 0x1; | 247 | tcp_opt->sack_ok = (options >> 4) & 0x1; |
248 | *ecn_ok = (options >> 5) & 1; | ||
249 | if (*ecn_ok && !sysctl_tcp_ecn) | ||
250 | return false; | ||
247 | 251 | ||
248 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) | 252 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) |
249 | return false; | 253 | return false; |
@@ -272,6 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
272 | int mss; | 276 | int mss; |
273 | struct rtable *rt; | 277 | struct rtable *rt; |
274 | __u8 rcv_wscale; | 278 | __u8 rcv_wscale; |
279 | bool ecn_ok; | ||
275 | 280 | ||
276 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
277 | goto out; | 282 | goto out; |
@@ -288,7 +293,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
288 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | 293 | memset(&tcp_opt, 0, sizeof(tcp_opt)); |
289 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0); | 294 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0); |
290 | 295 | ||
291 | if (!cookie_check_timestamp(&tcp_opt)) | 296 | if (!cookie_check_timestamp(&tcp_opt, &ecn_ok)) |
292 | goto out; | 297 | goto out; |
293 | 298 | ||
294 | ret = NULL; | 299 | ret = NULL; |
@@ -305,7 +310,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
305 | ireq->rmt_port = th->source; | 310 | ireq->rmt_port = th->source; |
306 | ireq->loc_addr = ip_hdr(skb)->daddr; | 311 | ireq->loc_addr = ip_hdr(skb)->daddr; |
307 | ireq->rmt_addr = ip_hdr(skb)->saddr; | 312 | ireq->rmt_addr = ip_hdr(skb)->saddr; |
308 | ireq->ecn_ok = 0; | 313 | ireq->ecn_ok = ecn_ok; |
309 | ireq->snd_wscale = tcp_opt.snd_wscale; | 314 | ireq->snd_wscale = tcp_opt.snd_wscale; |
310 | ireq->sack_ok = tcp_opt.sack_ok; | 315 | ireq->sack_ok = tcp_opt.sack_ok; |
311 | ireq->wscale_ok = tcp_opt.wscale_ok; | 316 | ireq->wscale_ok = tcp_opt.wscale_ok; |