Skip to content

Commit

Permalink
tcp: Remove TCPCT
Browse files Browse the repository at this point in the history
TCPCT uses option-number 253, reserved for experimental use and should
not be used in production environments.
Further, TCPCT does not fully implement RFC 6013.

As a nice side-effect, removing TCPCT increases TCP's performance for
very short flows:

Doing an apache-benchmark with -c 100 -n 100000, sending HTTP-requests
for files of 1KB size.

before this patch:
	average (among 7 runs) of 20845.5 Requests/Second
after:
	average (among 7 runs) of 21403.6 Requests/Second

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Christoph Paasch authored and David S. Miller committed Mar 17, 2013
1 parent 94d8f2b commit 1a2c618
Show file tree
Hide file tree
Showing 18 changed files with 38 additions and 841 deletions.
8 changes: 0 additions & 8 deletions Documentation/networking/ip-sysctl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,6 @@ tcp_congestion_control - STRING
is inherited.
[see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ]

tcp_cookie_size - INTEGER
Default size of TCP Cookie Transactions (TCPCT) option, that may be
overridden on a per socket basis by the TCPCT socket option.
Values greater than the maximum (16) are interpreted as the maximum.
Values greater than zero and less than the minimum (8) are interpreted
as the minimum. Odd values are interpreted as the next even value.
Default: 0 (off).

tcp_dsack - BOOLEAN
Allows TCP to send "duplicate" SACKs.

Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2915,7 +2915,7 @@ static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos)
*/
memset(&tmp_opt, 0, sizeof(tmp_opt));
tcp_clear_options(&tmp_opt);
tcp_parse_options(skb, &tmp_opt, NULL, 0, NULL);
tcp_parse_options(skb, &tmp_opt, 0, NULL);

req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
Expand Down
10 changes: 0 additions & 10 deletions include/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ struct tcp_options_received {
sack_ok : 4, /* SACK seen on SYN packet */
snd_wscale : 4, /* Window scaling received from sender */
rcv_wscale : 4; /* Window scaling to send to receiver */
u8 cookie_plus:6, /* bytes in authenticator/cookie option */
cookie_out_never:1,
cookie_in_always:1;
u8 num_sacks; /* Number of SACK blocks */
u16 user_mss; /* mss requested by user in ioctl */
u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
Expand All @@ -102,7 +99,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt)
{
rx_opt->tstamp_ok = rx_opt->sack_ok = 0;
rx_opt->wscale_ok = rx_opt->snd_wscale = 0;
rx_opt->cookie_plus = 0;
}

/* This is the max number of SACKS that we'll generate and process. It's safe
Expand Down Expand Up @@ -320,12 +316,6 @@ struct tcp_sock {
struct tcp_md5sig_info __rcu *md5sig_info;
#endif

/* When the cookie options are generated and exchanged, then this
* object holds a reference to them (cookie_values->kref). Also
* contains related tcp_cookie_transactions fields.
*/
struct tcp_cookie_values *cookie_values;

/* TCP fastopen related information */
struct tcp_fastopen_request *fastopen_req;
/* fastopen_rsk points to request_sock that resulted in this big
Expand Down
8 changes: 1 addition & 7 deletions include/net/request_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,13 @@ struct sk_buff;
struct dst_entry;
struct proto;

/* empty to "strongly type" an otherwise void parameter.
*/
struct request_values {
};

struct request_sock_ops {
int family;
int obj_size;
struct kmem_cache *slab;
char *slab_name;
int (*rtx_syn_ack)(struct sock *sk,
struct request_sock *req,
struct request_values *rvp);
struct request_sock *req);
void (*send_ack)(struct sock *sk, struct sk_buff *skb,
struct request_sock *req);
void (*send_reset)(struct sock *sk,
Expand Down
89 changes: 1 addition & 88 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
#define TCPOPT_SACK 5 /* SACK Block */
#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
Expand Down Expand Up @@ -454,7 +453,7 @@ extern void tcp_syn_ack_timeout(struct sock *sk, struct request_sock *req);
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,
struct tcp_options_received *opt_rx,
int estab, struct tcp_fastopen_cookie *foc);
extern const u8 *tcp_parse_md5sig_option(const struct tcphdr *th);

Expand All @@ -476,7 +475,6 @@ extern int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
extern int tcp_connect(struct sock *sk);
extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct request_sock *req,
struct request_values *rvp,
struct tcp_fastopen_cookie *foc);
extern int tcp_disconnect(struct sock *sk, int flags);

Expand Down Expand Up @@ -1589,91 +1587,6 @@ struct tcp_request_sock_ops {
#endif
};

/* Using SHA1 for now, define some constants.
*/
#define COOKIE_DIGEST_WORDS (SHA_DIGEST_WORDS)
#define COOKIE_MESSAGE_WORDS (SHA_MESSAGE_BYTES / 4)
#define COOKIE_WORKSPACE_WORDS (COOKIE_DIGEST_WORDS + COOKIE_MESSAGE_WORDS)

extern int tcp_cookie_generator(u32 *bakery);

/**
* struct tcp_cookie_values - each socket needs extra space for the
* cookies, together with (optional) space for any SYN data.
*
* A tcp_sock contains a pointer to the current value, and this is
* cloned to the tcp_timewait_sock.
*
* @cookie_pair: variable data from the option exchange.
*
* @cookie_desired: user specified tcpct_cookie_desired. Zero
* indicates default (sysctl_tcp_cookie_size).
* After cookie sent, remembers size of cookie.
* Range 0, TCP_COOKIE_MIN to TCP_COOKIE_MAX.
*
* @s_data_desired: user specified tcpct_s_data_desired. When the
* constant payload is specified (@s_data_constant),
* holds its length instead.
* Range 0 to TCP_MSS_DESIRED.
*
* @s_data_payload: constant data that is to be included in the
* payload of SYN or SYNACK segments when the
* cookie option is present.
*/
struct tcp_cookie_values {
struct kref kref;
u8 cookie_pair[TCP_COOKIE_PAIR_SIZE];
u8 cookie_pair_size;
u8 cookie_desired;
u16 s_data_desired:11,
s_data_constant:1,
s_data_in:1,
s_data_out:1,
s_data_unused:2;
u8 s_data_payload[0];
};

static inline void tcp_cookie_values_release(struct kref *kref)
{
kfree(container_of(kref, struct tcp_cookie_values, kref));
}

/* The length of constant payload data. Note that s_data_desired is
* overloaded, depending on s_data_constant: either the length of constant
* data (returned here) or the limit on variable data.
*/
static inline int tcp_s_data_size(const struct tcp_sock *tp)
{
return (tp->cookie_values != NULL && tp->cookie_values->s_data_constant)
? tp->cookie_values->s_data_desired
: 0;
}

/**
* struct tcp_extend_values - tcp_ipv?.c to tcp_output.c workspace.
*
* As tcp_request_sock has already been extended in other places, the
* only remaining method is to pass stack values along as function
* parameters. These parameters are not needed after sending SYNACK.
*
* @cookie_bakery: cryptographic secret and message workspace.
*
* @cookie_plus: bytes in authenticator/cookie option, copied from
* struct tcp_options_received (above).
*/
struct tcp_extend_values {
struct request_values rv;
u32 cookie_bakery[COOKIE_WORKSPACE_WORDS];
u8 cookie_plus:6,
cookie_out_never:1,
cookie_in_always:1;
};

static inline struct tcp_extend_values *tcp_xv(struct request_values *rvp)
{
return (struct tcp_extend_values *)rvp;
}

extern void tcp_v4_init(void);
extern void tcp_init(void);

Expand Down
26 changes: 0 additions & 26 deletions include/uapi/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ enum {
#define TCP_QUICKACK 12 /* Block/reenable quick acks */
#define TCP_CONGESTION 13 /* Congestion control algorithm */
#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */
#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/
#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */
#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
Expand Down Expand Up @@ -199,29 +198,4 @@ struct tcp_md5sig {
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
};

/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */
#define TCP_COOKIE_MIN 8 /* 64-bits */
#define TCP_COOKIE_MAX 16 /* 128-bits */
#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX)

/* Flags for both getsockopt and setsockopt */
#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */
#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies,
* supercedes everything. */

/* Flags for getsockopt */
#define TCP_S_DATA_IN (1 << 2) /* Was data received? */
#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */

/* TCP_COOKIE_TRANSACTIONS data */
struct tcp_cookie_transactions {
__u16 tcpct_flags; /* see above */
__u8 __tcpct_pad1; /* zero */
__u8 tcpct_cookie_desired; /* bytes */
__u16 tcpct_s_data_desired; /* bytes of variable data */
__u16 tcpct_used; /* bytes in value */
__u8 tcpct_value[TCP_MSS_DEFAULT];
};


#endif /* _UAPI_LINUX_TCP_H */
5 changes: 2 additions & 3 deletions net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
return &rt->dst;
}

static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
struct request_values *rv_unused)
static int dccp_v4_send_response(struct sock *sk, struct request_sock *req)
{
int err = -1;
struct sk_buff *skb;
Expand Down Expand Up @@ -658,7 +657,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service;

if (dccp_v4_send_response(sk, req, NULL))
if (dccp_v4_send_response(sk, req))
goto drop_and_free;

inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
Expand Down
5 changes: 2 additions & 3 deletions net/dccp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
}


static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
struct request_values *rv_unused)
static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
{
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
Expand Down Expand Up @@ -428,7 +427,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service;

if (dccp_v6_send_response(sk, req, NULL))
if (dccp_v6_send_response(sk, req))
goto drop_and_free;

inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/inet_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ static inline void syn_ack_recalc(struct request_sock *req, const int thresh,

int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req)
{
int err = req->rsk_ops->rtx_syn_ack(parent, req, NULL);
int err = req->rsk_ops->rtx_syn_ack(parent, req);

if (!err)
req->num_retrans++;
Expand Down
3 changes: 1 addition & 2 deletions net/ipv4/syncookies.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
struct ip_options *opt)
{
struct tcp_options_received tcp_opt;
const u8 *hash_location;
struct inet_request_sock *ireq;
struct tcp_request_sock *treq;
struct tcp_sock *tp = tcp_sk(sk);
Expand All @@ -294,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, NULL);
tcp_parse_options(skb, &tcp_opt, 0, NULL);

if (!cookie_check_timestamp(&tcp_opt, sock_net(sk), &ecn_ok))
goto out;
Expand Down
7 changes: 0 additions & 7 deletions net/ipv4/sysctl_net_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,13 +732,6 @@ static struct ctl_table ipv4_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "tcp_cookie_size",
.data = &sysctl_tcp_cookie_size,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_thin_linear_timeouts",
.data = &sysctl_tcp_thin_linear_timeouts,
Expand Down
Loading

0 comments on commit 1a2c618

Please sign in to comment.