diff options
author | Florian Westphal <fw@strlen.de> | 2014-11-03 11:35:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-04 16:06:08 -0500 |
commit | 274e2da0ecb4d28e3d4e9f029b096e0e8c401a66 (patch) | |
tree | 641b8c19c7f26efddc74839c5a0d0ed15e34de1b | |
parent | 436f7c206860729d543a457aca5887e52039a5f4 (diff) |
syncookies: avoid magic values and document which-bit-is-what-option
Was a bit more difficult to read than needed due to magic shifts;
add defines and document the used encoding scheme.
Joint work with Daniel Borkmann.
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/syncookies.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 4ac7bcaf2f46..c3792c0557dd 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -19,10 +19,6 @@ | |||
19 | #include <net/tcp.h> | 19 | #include <net/tcp.h> |
20 | #include <net/route.h> | 20 | #include <net/route.h> |
21 | 21 | ||
22 | /* Timestamps: lowest bits store TCP options */ | ||
23 | #define TSBITS 6 | ||
24 | #define TSMASK (((__u32)1 << TSBITS) - 1) | ||
25 | |||
26 | extern int sysctl_tcp_syncookies; | 22 | extern int sysctl_tcp_syncookies; |
27 | 23 | ||
28 | static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly; | 24 | static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly; |
@@ -30,6 +26,30 @@ static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS] __read_mostly; | |||
30 | #define COOKIEBITS 24 /* Upper bits store count */ | 26 | #define COOKIEBITS 24 /* Upper bits store count */ |
31 | #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) | 27 | #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) |
32 | 28 | ||
29 | /* TCP Timestamp: 6 lowest bits of timestamp sent in the cookie SYN-ACK | ||
30 | * stores TCP options: | ||
31 | * | ||
32 | * MSB LSB | ||
33 | * | 31 ... 6 | 5 | 4 | 3 2 1 0 | | ||
34 | * | Timestamp | ECN | SACK | WScale | | ||
35 | * | ||
36 | * When we receive a valid cookie-ACK, we look at the echoed tsval (if | ||
37 | * any) to figure out which TCP options we should use for the rebuilt | ||
38 | * connection. | ||
39 | * | ||
40 | * A WScale setting of '0xf' (which is an invalid scaling value) | ||
41 | * means that original syn did not include the TCP window scaling option. | ||
42 | */ | ||
43 | #define TS_OPT_WSCALE_MASK 0xf | ||
44 | #define TS_OPT_SACK BIT(4) | ||
45 | #define TS_OPT_ECN BIT(5) | ||
46 | /* There is no TS_OPT_TIMESTAMP: | ||
47 | * if ACK contains timestamp option, we already know it was | ||
48 | * requested/supported by the syn/synack exchange. | ||
49 | */ | ||
50 | #define TSBITS 6 | ||
51 | #define TSMASK (((__u32)1 << TSBITS) - 1) | ||
52 | |||
33 | static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS], | 53 | static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS], |
34 | ipv4_cookie_scratch); | 54 | ipv4_cookie_scratch); |
35 | 55 | ||
@@ -67,9 +87,11 @@ __u32 cookie_init_timestamp(struct request_sock *req) | |||
67 | 87 | ||
68 | ireq = inet_rsk(req); | 88 | ireq = inet_rsk(req); |
69 | 89 | ||
70 | options = ireq->wscale_ok ? ireq->snd_wscale : 0xf; | 90 | options = ireq->wscale_ok ? ireq->snd_wscale : TS_OPT_WSCALE_MASK; |
71 | options |= ireq->sack_ok << 4; | 91 | if (ireq->sack_ok) |
72 | options |= ireq->ecn_ok << 5; | 92 | options |= TS_OPT_SACK; |
93 | if (ireq->ecn_ok) | ||
94 | options |= TS_OPT_ECN; | ||
73 | 95 | ||
74 | ts = ts_now & ~TSMASK; | 96 | ts = ts_now & ~TSMASK; |
75 | ts |= options; | 97 | ts |= options; |
@@ -219,16 +241,13 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | |||
219 | * additional tcp options in the timestamp. | 241 | * additional tcp options in the timestamp. |
220 | * This extracts these options from the timestamp echo. | 242 | * This extracts these options from the timestamp echo. |
221 | * | 243 | * |
222 | * The lowest 4 bits store snd_wscale. | ||
223 | * next 2 bits indicate SACK and ECN support. | ||
224 | * | ||
225 | * return false if we decode an option that should not be. | 244 | * return false if we decode an option that should not be. |
226 | */ | 245 | */ |
227 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, | 246 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, |
228 | struct net *net, bool *ecn_ok) | 247 | struct net *net, bool *ecn_ok) |
229 | { | 248 | { |
230 | /* echoed timestamp, lowest bits contain options */ | 249 | /* echoed timestamp, lowest bits contain options */ |
231 | u32 options = tcp_opt->rcv_tsecr & TSMASK; | 250 | u32 options = tcp_opt->rcv_tsecr; |
232 | 251 | ||
233 | if (!tcp_opt->saw_tstamp) { | 252 | if (!tcp_opt->saw_tstamp) { |
234 | tcp_clear_options(tcp_opt); | 253 | tcp_clear_options(tcp_opt); |
@@ -238,19 +257,20 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, | |||
238 | if (!sysctl_tcp_timestamps) | 257 | if (!sysctl_tcp_timestamps) |
239 | return false; | 258 | return false; |
240 | 259 | ||
241 | tcp_opt->sack_ok = (options & (1 << 4)) ? TCP_SACK_SEEN : 0; | 260 | tcp_opt->sack_ok = (options & TS_OPT_SACK) ? TCP_SACK_SEEN : 0; |
242 | *ecn_ok = (options >> 5) & 1; | 261 | *ecn_ok = options & TS_OPT_ECN; |
243 | if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn) | 262 | if (*ecn_ok && !net->ipv4.sysctl_tcp_ecn) |
244 | return false; | 263 | return false; |
245 | 264 | ||
246 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) | 265 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) |
247 | return false; | 266 | return false; |
248 | 267 | ||
249 | if ((options & 0xf) == 0xf) | 268 | if ((options & TS_OPT_WSCALE_MASK) == TS_OPT_WSCALE_MASK) |
250 | return true; /* no window scaling */ | 269 | return true; /* no window scaling */ |
251 | 270 | ||
252 | tcp_opt->wscale_ok = 1; | 271 | tcp_opt->wscale_ok = 1; |
253 | tcp_opt->snd_wscale = options & 0xf; | 272 | tcp_opt->snd_wscale = options & TS_OPT_WSCALE_MASK; |
273 | |||
254 | return sysctl_tcp_window_scaling != 0; | 274 | return sysctl_tcp_window_scaling != 0; |
255 | } | 275 | } |
256 | EXPORT_SYMBOL(cookie_check_timestamp); | 276 | EXPORT_SYMBOL(cookie_check_timestamp); |