Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315511
b: refs/heads/master
c: 2100c8d
h: refs/heads/master
i:
  315509: e9581bf
  315507: ac7ab4f
  315503: dbbf622
v: v3
  • Loading branch information
Yuchung Cheng authored and David S. Miller committed Jul 19, 2012
1 parent 7f68e19 commit 59c688a
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4cce66cdd14aa5006a011505865d932adb49f600
refs/heads/master: 2100c8d2d9db23c0a09901a782bb4e3b21bee298
10 changes: 10 additions & 0 deletions trunk/include/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
return (tcp_hdr(skb)->doff - 5) * 4;
}

/* TCP Fast Open */
#define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */
#define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */

/* TCP Fast Open Cookie as stored in memory */
struct tcp_fastopen_cookie {
s8 len;
u8 val[TCP_FASTOPEN_COOKIE_MAX];
};

/* This defines a selective acknowledgement block. */
struct tcp_sack_block_wire {
__be32 start_seq;
Expand Down
9 changes: 8 additions & 1 deletion trunk/include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
#define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
#define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */
#define TCPOPT_COOKIE 253 /* Cookie extension (experimental) */
#define TCPOPT_EXP 254 /* Experimental */
/* Magic number to be after the option value for sharing TCP
* experimental options. See draft-ietf-tcpm-experimental-options-00.txt
*/
#define TCPOPT_FASTOPEN_MAGIC 0xF989

/*
* TCP option lengths
Expand All @@ -180,6 +185,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
#define TCPOLEN_SACK_PERM 2
#define TCPOLEN_TIMESTAMP 10
#define TCPOLEN_MD5SIG 18
#define TCPOLEN_EXP_FASTOPEN_BASE 4
#define TCPOLEN_COOKIE_BASE 2 /* Cookie-less header extension */
#define TCPOLEN_COOKIE_PAIR 3 /* Cookie pair header extension */
#define TCPOLEN_COOKIE_MIN (TCPOLEN_COOKIE_BASE+TCP_COOKIE_MIN)
Expand Down Expand Up @@ -222,6 +228,7 @@ extern int sysctl_tcp_retries1;
extern int sysctl_tcp_retries2;
extern int sysctl_tcp_orphan_retries;
extern int sysctl_tcp_syncookies;
extern int sysctl_tcp_fastopen;
extern int sysctl_tcp_retrans_collapse;
extern int sysctl_tcp_stdurg;
extern int sysctl_tcp_rfc1337;
Expand Down Expand Up @@ -418,7 +425,7 @@ extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int nonblock, int flags, int *addr_len);
extern void tcp_parse_options(const struct sk_buff *skb,
struct tcp_options_received *opt_rx, const u8 **hvpp,
int estab);
int estab, struct tcp_fastopen_cookie *foc);
extern const u8 *tcp_parse_md5sig_option(const struct tcphdr *th);

/*
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ obj-y := route.o inetpeer.o protocol.o \
ip_output.o ip_sockglue.o inet_hashtables.o \
inet_timewait_sock.o inet_connection_sock.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
tcp_minisocks.o tcp_cong.o tcp_metrics.o \
tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
datagram.o raw.o udp.o udplite.o \
arp.o icmp.o devinet.o af_inet.o igmp.o \
fib_frontend.o fib_semantics.o fib_trie.o \
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,

/* check for timestamp cookie support */
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);

if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
goto out;
Expand Down
7 changes: 7 additions & 0 deletions trunk/net/ipv4/sysctl_net_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ static struct ctl_table ipv4_table[] = {
.proc_handler = proc_dointvec
},
#endif
{
.procname = "tcp_fastopen",
.data = &sysctl_tcp_fastopen,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "tcp_tw_recycle",
.data = &tcp_death_row.sysctl_tw_recycle,
Expand Down
11 changes: 11 additions & 0 deletions trunk/net/ipv4/tcp_fastopen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <linux/init.h>
#include <linux/kernel.h>

int sysctl_tcp_fastopen;

static int __init tcp_fastopen_init(void)
{
return 0;
}

late_initcall(tcp_fastopen_init);
26 changes: 22 additions & 4 deletions trunk/net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -3732,7 +3732,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
* the fast version below fails.
*/
void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *opt_rx,
const u8 **hvpp, int estab)
const u8 **hvpp, int estab,
struct tcp_fastopen_cookie *foc)
{
const unsigned char *ptr;
const struct tcphdr *th = tcp_hdr(skb);
Expand Down Expand Up @@ -3839,8 +3840,25 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o
break;
}
break;
}

case TCPOPT_EXP:
/* Fast Open option shares code 254 using a
* 16 bits magic number. It's valid only in
* SYN or SYN-ACK with an even size.
*/
if (opsize < TCPOLEN_EXP_FASTOPEN_BASE ||
get_unaligned_be16(ptr) != TCPOPT_FASTOPEN_MAGIC ||
foc == NULL || !th->syn || (opsize & 1))
break;
foc->len = opsize - TCPOLEN_EXP_FASTOPEN_BASE;
if (foc->len >= TCP_FASTOPEN_COOKIE_MIN &&
foc->len <= TCP_FASTOPEN_COOKIE_MAX)
memcpy(foc->val, ptr + 2, foc->len);
else if (foc->len != 0)
foc->len = -1;
break;

}
ptr += opsize-2;
length -= opsize;
}
Expand Down Expand Up @@ -3882,7 +3900,7 @@ static bool tcp_fast_parse_options(const struct sk_buff *skb,
if (tcp_parse_aligned_timestamp(tp, th))
return true;
}
tcp_parse_options(skb, &tp->rx_opt, hvpp, 1);
tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL);
return true;
}

Expand Down Expand Up @@ -5637,7 +5655,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
struct tcp_cookie_values *cvp = tp->cookie_values;
int saved_clamp = tp->rx_opt.mss_clamp;

tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0);
tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, NULL);

if (th->ack) {
/* rfc793:
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
tcp_clear_options(&tmp_opt);
tmp_opt.mss_clamp = TCP_MSS_DEFAULT;
tmp_opt.user_mss = tp->rx_opt.user_mss;
tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);

if (tmp_opt.cookie_plus > 0 &&
tmp_opt.saw_tstamp &&
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/tcp_minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,

tmp_opt.saw_tstamp = 0;
if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) {
tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);

if (tmp_opt.saw_tstamp) {
tmp_opt.ts_recent = tcptw->tw_ts_recent;
Expand Down Expand Up @@ -534,7 +534,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,

tmp_opt.saw_tstamp = 0;
if (th->doff > (sizeof(struct tcphdr)>>2)) {
tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);

if (tmp_opt.saw_tstamp) {
tmp_opt.ts_recent = req->ts_recent;
Expand Down
25 changes: 21 additions & 4 deletions trunk/net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,15 +385,17 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp)
#define OPTION_MD5 (1 << 2)
#define OPTION_WSCALE (1 << 3)
#define OPTION_COOKIE_EXTENSION (1 << 4)
#define OPTION_FAST_OPEN_COOKIE (1 << 8)

struct tcp_out_options {
u8 options; /* bit field of OPTION_* */
u16 options; /* bit field of OPTION_* */
u16 mss; /* 0 to disable */
u8 ws; /* window scale, 0 to disable */
u8 num_sack_blocks; /* number of SACK blocks to include */
u8 hash_size; /* bytes in hash_location */
u16 mss; /* 0 to disable */
__u32 tsval, tsecr; /* need to include OPTION_TS */
__u8 *hash_location; /* temporary pointer, overloaded */
__u32 tsval, tsecr; /* need to include OPTION_TS */
struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */
};

/* The sysctl int routines are generic, so check consistency here.
Expand Down Expand Up @@ -442,7 +444,7 @@ static u8 tcp_cookie_size_check(u8 desired)
static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
struct tcp_out_options *opts)
{
u8 options = opts->options; /* mungable copy */
u16 options = opts->options; /* mungable copy */

/* Having both authentication and cookies for security is redundant,
* and there's certainly not enough room. Instead, the cookie-less
Expand Down Expand Up @@ -564,6 +566,21 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,

tp->rx_opt.dsack = 0;
}

if (unlikely(OPTION_FAST_OPEN_COOKIE & options)) {
struct tcp_fastopen_cookie *foc = opts->fastopen_cookie;

*ptr++ = htonl((TCPOPT_EXP << 24) |
((TCPOLEN_EXP_FASTOPEN_BASE + foc->len) << 16) |
TCPOPT_FASTOPEN_MAGIC);

memcpy(ptr, foc->val, foc->len);
if ((foc->len & 3) == 2) {
u8 *align = ((u8 *)ptr) + foc->len;
align[0] = align[1] = TCPOPT_NOP;
}
ptr += (foc->len + 3) >> 2;
}
}

/* Compute TCP options for SYN packets. This is not the final
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)

/* check for timestamp cookie support */
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);

if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
goto out;
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
tcp_clear_options(&tmp_opt);
tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
tmp_opt.user_mss = tp->rx_opt.user_mss;
tcp_parse_options(skb, &tmp_opt, &hash_location, 0);
tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);

if (tmp_opt.cookie_plus > 0 &&
tmp_opt.saw_tstamp &&
Expand Down

0 comments on commit 59c688a

Please sign in to comment.