aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJerry Chu <hkchu@google.com>2012-08-31 08:29:11 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-31 20:02:18 -0400
commit1046716368979dee857a2b8a91c4a8833f21b9cb (patch)
treefdda70278e6fa56c27d242fb1a0ec9b7e3e81d38
parent2a35cfa591ac63f17815c2d9432b799e37527980 (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>
-rw-r--r--Documentation/networking/ip-sysctl.txt29
-rw-r--r--include/linux/snmp.h4
-rw-r--r--include/linux/tcp.h45
-rw-r--r--include/net/request_sock.h36
-rw-r--r--include/net/tcp.h46
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c45
-rw-r--r--net/ipv4/tcp_fastopen.c83
-rw-r--r--net/ipv4/tcp_input.c4
9 files changed, 276 insertions, 20 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index d64e53124b8c..c7fc10724948 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -467,16 +467,31 @@ tcp_syncookies - BOOLEAN
467tcp_fastopen - INTEGER 467tcp_fastopen - INTEGER
468 Enable TCP Fast Open feature (draft-ietf-tcpm-fastopen) to send data 468 Enable TCP Fast Open feature (draft-ietf-tcpm-fastopen) to send data
469 in the opening SYN packet. To use this feature, the client application 469 in the opening SYN packet. To use this feature, the client application
470 must not use connect(). Instead, it should use sendmsg() or sendto() 470 must use sendmsg() or sendto() with MSG_FASTOPEN flag rather than
471 with MSG_FASTOPEN flag which performs a TCP handshake automatically. 471 connect() to perform a TCP handshake automatically.
472 472
473 The values (bitmap) are: 473 The values (bitmap) are
474 1: Enables sending data in the opening SYN on the client 474 1: Enables sending data in the opening SYN on the client.
475 5: Enables sending data in the opening SYN on the client regardless 475 2: Enables TCP Fast Open on the server side, i.e., allowing data in
476 of cookie availability. 476 a SYN packet to be accepted and passed to the application before
477 3-way hand shake finishes.
478 4: Send data in the opening SYN regardless of cookie availability and
479 without a cookie option.
480 0x100: Accept SYN data w/o validating the cookie.
481 0x200: Accept data-in-SYN w/o any cookie option present.
482 0x400/0x800: Enable Fast Open on all listeners regardless of the
483 TCP_FASTOPEN socket option. The two different flags designate two
484 different ways of setting max_qlen without the TCP_FASTOPEN socket
485 option.
477 486
478 Default: 0 487 Default: 0
479 488
489 Note that the client & server side Fast Open flags (1 and 2
490 respectively) must be also enabled before the rest of flags can take
491 effect.
492
493 See include/net/tcp.h and the code for more details.
494
480tcp_syn_retries - INTEGER 495tcp_syn_retries - INTEGER
481 Number of times initial SYNs for an active TCP connection attempt 496 Number of times initial SYNs for an active TCP connection attempt
482 will be retransmitted. Should not be higher than 255. Default value 497 will be retransmitted. Should not be higher than 255. Default value
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index ad6e3a6bf9fb..fdfba235f9f1 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -241,6 +241,10 @@ enum
241 LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ 241 LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */
242 LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ 242 LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */
243 LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */ 243 LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */
244 LINUX_MIB_TCPFASTOPENPASSIVE, /* TCPFastOpenPassive*/
245 LINUX_MIB_TCPFASTOPENPASSIVEFAIL, /* TCPFastOpenPassiveFail */
246 LINUX_MIB_TCPFASTOPENLISTENOVERFLOW, /* TCPFastOpenListenOverflow */
247 LINUX_MIB_TCPFASTOPENCOOKIEREQD, /* TCPFastOpenCookieReqd */
244 __LINUX_MIB_MAX 248 __LINUX_MIB_MAX
245}; 249};
246 250
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index eb125a4c30b3..ae46df590629 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -110,6 +110,7 @@ enum {
110#define TCP_REPAIR_QUEUE 20 110#define TCP_REPAIR_QUEUE 20
111#define TCP_QUEUE_SEQ 21 111#define TCP_QUEUE_SEQ 21
112#define TCP_REPAIR_OPTIONS 22 112#define TCP_REPAIR_OPTIONS 22
113#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */
113 114
114struct tcp_repair_opt { 115struct tcp_repair_opt {
115 __u32 opt_code; 116 __u32 opt_code;
@@ -246,6 +247,7 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
246/* TCP Fast Open */ 247/* TCP Fast Open */
247#define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ 248#define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */
248#define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ 249#define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */
250#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */
249 251
250/* TCP Fast Open Cookie as stored in memory */ 252/* TCP Fast Open Cookie as stored in memory */
251struct tcp_fastopen_cookie { 253struct tcp_fastopen_cookie {
@@ -312,9 +314,14 @@ struct tcp_request_sock {
312 /* Only used by TCP MD5 Signature so far. */ 314 /* Only used by TCP MD5 Signature so far. */
313 const struct tcp_request_sock_ops *af_specific; 315 const struct tcp_request_sock_ops *af_specific;
314#endif 316#endif
317 struct sock *listener; /* needed for TFO */
315 u32 rcv_isn; 318 u32 rcv_isn;
316 u32 snt_isn; 319 u32 snt_isn;
317 u32 snt_synack; /* synack sent time */ 320 u32 snt_synack; /* synack sent time */
321 u32 rcv_nxt; /* the ack # by SYNACK. For
322 * FastOpen it's the seq#
323 * after data-in-SYN.
324 */
318}; 325};
319 326
320static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req) 327static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req)
@@ -505,14 +512,18 @@ struct tcp_sock {
505 struct tcp_md5sig_info __rcu *md5sig_info; 512 struct tcp_md5sig_info __rcu *md5sig_info;
506#endif 513#endif
507 514
508/* TCP fastopen related information */
509 struct tcp_fastopen_request *fastopen_req;
510
511 /* When the cookie options are generated and exchanged, then this 515 /* When the cookie options are generated and exchanged, then this
512 * object holds a reference to them (cookie_values->kref). Also 516 * object holds a reference to them (cookie_values->kref). Also
513 * contains related tcp_cookie_transactions fields. 517 * contains related tcp_cookie_transactions fields.
514 */ 518 */
515 struct tcp_cookie_values *cookie_values; 519 struct tcp_cookie_values *cookie_values;
520
521/* TCP fastopen related information */
522 struct tcp_fastopen_request *fastopen_req;
523 /* fastopen_rsk points to request_sock that resulted in this big
524 * socket. Used to retransmit SYNACKs etc.
525 */
526 struct request_sock *fastopen_rsk;
516}; 527};
517 528
518enum tsq_flags { 529enum tsq_flags {
@@ -552,6 +563,34 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)
552 return (struct tcp_timewait_sock *)sk; 563 return (struct tcp_timewait_sock *)sk;
553} 564}
554 565
566static inline bool tcp_passive_fastopen(const struct sock *sk)
567{
568 return (sk->sk_state == TCP_SYN_RECV &&
569 tcp_sk(sk)->fastopen_rsk != NULL);
570}
571
572static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc)
573{
574 return foc->len != -1;
575}
576
577static inline int fastopen_init_queue(struct sock *sk, int backlog)
578{
579 struct request_sock_queue *queue =
580 &inet_csk(sk)->icsk_accept_queue;
581
582 if (queue->fastopenq == NULL) {
583 queue->fastopenq = kzalloc(
584 sizeof(struct fastopen_queue),
585 sk->sk_allocation);
586 if (queue->fastopenq == NULL)
587 return -ENOMEM;
588 spin_lock_init(&queue->fastopenq->lock);
589 }
590 queue->fastopenq->max_qlen = backlog;
591 return 0;
592}
593
555#endif /* __KERNEL__ */ 594#endif /* __KERNEL__ */
556 595
557#endif /* _LINUX_TCP_H */ 596#endif /* _LINUX_TCP_H */
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index 4c0766e201e3..c3cdd6c9f448 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -106,6 +106,34 @@ struct listen_sock {
106 struct request_sock *syn_table[0]; 106 struct request_sock *syn_table[0];
107}; 107};
108 108
109/*
110 * For a TCP Fast Open listener -
111 * lock - protects the access to all the reqsk, which is co-owned by
112 * the listener and the child socket.