aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/syncookies.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/syncookies.c')
-rw-r--r--net/ipv4/syncookies.c15
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
25extern int sysctl_tcp_syncookies; 25extern 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 */
233bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) 234bool 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;