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 /include/linux | |
| 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 'include/linux')
| -rw-r--r-- | include/linux/snmp.h | 4 | ||||
| -rw-r--r-- | include/linux/tcp.h | 45 |
2 files changed, 46 insertions, 3 deletions
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 | ||
| 114 | struct tcp_repair_opt { | 115 | struct 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 */ |
| 251 | struct tcp_fastopen_cookie { | 253 | struct 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 | ||
| 320 | static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req) | 327 | static 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 | ||
| 518 | enum tsq_flags { | 529 | enum 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 | ||
| 566 | static 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 | |||
| 572 | static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc) | ||
| 573 | { | ||
| 574 | return foc->len != -1; | ||
| 575 | } | ||
| 576 | |||
| 577 | static 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 */ |
