diff options
author | Jerry Chu <hkchu@google.com> | 2012-08-31 08:29:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-31 20:02:18 -0400 |
commit | 1046716368979dee857a2b8a91c4a8833f21b9cb (patch) | |
tree | fdda70278e6fa56c27d242fb1a0ec9b7e3e81d38 /net/ipv4/sysctl_net_ipv4.c | |
parent | 2a35cfa591ac63f17815c2d9432b799e37527980 (diff) |
tcp: TCP Fast Open Server - header & support functions
This patch adds all the necessary data structure and support
functions to implement TFO server side. It also documents a number
of flags for the sysctl_tcp_fastopen knob, and adds a few Linux
extension MIBs.
In addition, it includes the following:
1. a new TCP_FASTOPEN socket option an application must call to
supply a max backlog allowed in order to enable TFO on its listener.
2. A number of key data structures:
"fastopen_rsk" in tcp_sock - for a big socket to access its
request_sock for retransmission and ack processing purpose. It is
non-NULL iff 3WHS not completed.
"fastopenq" in request_sock_queue - points to a per Fast Open
listener data structure "fastopen_queue" to keep track of qlen (# of
outstanding Fast Open requests) and max_qlen, among other things.
"listener" in tcp_request_sock - to point to the original listener
for book-keeping purpose, i.e., to maintain qlen against max_qlen
as part of defense against IP spoofing attack.
3. various data structure and functions, many in tcp_fastopen.c, to
support server side Fast Open cookie operations, including
/proc/sys/net/ipv4/tcp_fastopen_key to allow manual rekeying.
Signed-off-by: H.K. Jerry Chu <hkchu@google.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 3e78c79b5586..9205e492dc9d 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -232,6 +232,45 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write, | |||
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | 234 | ||
235 | int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer, | ||
236 | size_t *lenp, loff_t *ppos) | ||
237 | { | ||
238 | ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; | ||
239 | struct tcp_fastopen_context *ctxt; | ||
240 | int ret; | ||
241 | u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */ | ||
242 | |||
243 | tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL); | ||
244 | if (!tbl.data) | ||
245 | return -ENOMEM; | ||
246 | |||
247 | rcu_read_lock(); | ||
248 | ctxt = rcu_dereference(tcp_fastopen_ctx); | ||
249 | if (ctxt) | ||
250 | memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); | ||
251 | rcu_read_unlock(); | ||
252 | |||
253 | snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", | ||
254 | user_key[0], user_key[1], user_key[2], user_key[3]); | ||
255 | ret = proc_dostring(&tbl, write, buffer, lenp, ppos); | ||
256 | |||
257 | if (write && ret == 0) { | ||
258 | if (sscanf(tbl.data, "%x-%x-%x-%x", user_key, user_key + 1, | ||
259 | user_key + 2, user_key + 3) != 4) { | ||
260 | ret = -EINVAL; | ||
261 | goto bad_key; | ||
262 | } | ||
263 | tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); | ||
264 | } | ||
265 | |||
266 | bad_key: | ||
267 | pr_debug("proc FO key set 0x%x-%x-%x-%x <- 0x%s: %u\n", | ||
268 | user_key[0], user_key[1], user_key[2], user_key[3], | ||
269 | (char *)tbl.data, ret); | ||
270 | kfree(tbl.data); | ||
271 | return ret; | ||
272 | } | ||
273 | |||
235 | static struct ctl_table ipv4_table[] = { | 274 | static struct ctl_table ipv4_table[] = { |
236 | { | 275 | { |
237 | .procname = "tcp_timestamps", | 276 | .procname = "tcp_timestamps", |
@@ -386,6 +425,12 @@ static struct ctl_table ipv4_table[] = { | |||
386 | .proc_handler = proc_dointvec, | 425 | .proc_handler = proc_dointvec, |
387 | }, | 426 | }, |
388 | { | 427 | { |
428 | .procname = "tcp_fastopen_key", | ||
429 | .mode = 0600, | ||
430 | .maxlen = ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10), | ||
431 | .proc_handler = proc_tcp_fastopen_key, | ||
432 | }, | ||
433 | { | ||
389 | .procname = "tcp_tw_recycle", | 434 | .procname = "tcp_tw_recycle", |
390 | .data = &tcp_death_row.sysctl_tw_recycle, | 435 | .data = &tcp_death_row.sysctl_tw_recycle, |
391 | .maxlen = sizeof(int), | 436 | .maxlen = sizeof(int), |