From patchwork Tue Oct 27 12:18:49 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Allen Simpson X-Patchwork-Id: 36976 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 30273B7C04 for ; Tue, 27 Oct 2009 23:18:59 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753907AbZJ0MSs (ORCPT ); Tue, 27 Oct 2009 08:18:48 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753887AbZJ0MSs (ORCPT ); Tue, 27 Oct 2009 08:18:48 -0400 Received: from mail-gx0-f216.google.com ([209.85.217.216]:40495 "EHLO mail-gx0-f216.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753760AbZJ0MSr (ORCPT ); Tue, 27 Oct 2009 08:18:47 -0400 Received: by gxk8 with SMTP id 8so902964gxk.1 for ; Tue, 27 Oct 2009 05:18:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :content-type; bh=0F3fndMwmIBpvw7QDNIeVE3KZG+HCNoOno3Td7xpxpo=; b=vBi1LkaXOFMnNOQb9qtV3HwolsPC7oCKy7h2F65jSvFYqYagXcqHA//HXlvy0+lgY6 S0+WrZjYlU0rjnfvnhInDxiVrHAgN9A+ms/VSaWmgcbLReZ4JtsmTmqE8zcrv8/QGHHV EAeZZegcOhrqW6JuO4vpjBCvcEoarbvz2nXtE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; b=qeBgWUfm4THjhNZ5z/4Sp58bcEpJ0N5QbxYNkH+r4t5BRYT6aF7iCd7ljr3wX0jWE6 QZp9NQXd+dszQ7ZIRojIGhhlYfZMYG2nHOiyKJKBYGiJJIrvz4IAhI5cSN3JfcZ1LHfJ Ghje0wmVMtobntCpgH1h/kVuWTCr8ndCIhvvM= Received: by 10.150.22.2 with SMTP id 2mr844772ybv.293.1256645931909; Tue, 27 Oct 2009 05:18:51 -0700 (PDT) Received: from Wastrel.local (c-68-42-73-61.hsd1.mi.comcast.net [68.42.73.61]) by mx.google.com with ESMTPS id 13sm372622gxk.5.2009.10.27.05.18.50 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 27 Oct 2009 05:18:50 -0700 (PDT) Message-ID: <4AE6E529.706@gmail.com> Date: Tue, 27 Oct 2009 08:18:49 -0400 From: William Allen Simpson User-Agent: Thunderbird 2.0.0.23 (Macintosh/20090812) MIME-Version: 1.0 To: Linux Kernel Network Developers Subject: [net-next-2.6 PATCH v4 2/3] TCPCT part 1b: sysctl_tcp_cookie_size, socket option TCP_COOKIE_TRANSACTIONS, functions References: <4AE6E35C.2050101@gmail.com> In-Reply-To: <4AE6E35C.2050101@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Define sysctl (tcp_cookie_size) to turn on and off the cookie option default globally, instead of a compiled configuration option. Define per socket option (TCP_COOKIE_TRANSACTIONS) for setting constant data values, retrieving variable cookie values, and other facilities. Redefine two TCP header functions to accept TCP header pointer. When subtracting, return signed int to allow error checking. Move inline tcp_clear_options() unchanged from net/tcp.h to linux/tcp.h, near its corresponding struct tcp_options_received (prior to changes). This is a straightforward re-implementation of an earlier (year-old) patch that no longer applies cleanly, with permission of the original author (Adam Langley). The patch was previously reviewed: http://thread.gmane.org/gmane.linux.network/102586 These functions will also be used in subsequent patches that implement additional features. Signed-off-by: William.Allen.Simpson@gmail.com --- Documentation/networking/ip-sysctl.txt | 8 +++++ include/linux/tcp.h | 47 +++++++++++++++++++++++++++++++- include/net/tcp.h | 6 +--- net/ipv4/sysctl_net_ipv4.c | 8 +++++ net/ipv4/tcp_output.c | 8 +++++ 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index a0e134d..d47c000 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -164,6 +164,14 @@ tcp_congestion_control - STRING additional choices may be available based on kernel configuration. Default is set as part of kernel configuration. +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. + Default: 0 (off). + tcp_dsack - BOOLEAN Allows TCP to send "duplicate" SACKs. diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 61723a7..6fd59d1 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -96,6 +96,7 @@ 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 TCPI_OPT_TIMESTAMPS 1 #define TCPI_OPT_SACK 2 @@ -170,6 +171,34 @@ struct tcp_md5sig { __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ }; +/* for TCP_COOKIE_TRANSACTIONS (TCPCT) socket option */ +#define TCP_COOKIE_MAX 16 /* 128-bits */ +#define TCP_COOKIE_MIN 8 /* 64-bits */ +#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX) + +#define TCP_S_DATA_MAX 64U /* after TCP+IP options */ +#define TCP_S_DATA_MSS_DEFAULT 536U /* default MSS (RFC1122) */ + +/* 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 else. */ +#define TCP_EXTEND_TIMESTAMP (1 << 4) /* Initiate 64-bit timestamps */ + +/* 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_S_DATA_MSS_DEFAULT]; +}; + #ifdef __KERNEL__ #include @@ -193,6 +222,17 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb) return (tcp_hdr(skb)->doff - 5) * 4; } +static inline unsigned int tcp_header_len_th(const struct tcphdr *th) +{ + return th->doff * 4; +} + +/* When doff is bad, this could be negative. */ +static inline int tcp_option_len_th(const struct tcphdr *th) +{ + return (int)(th->doff * 4) - sizeof(*th); +} + /* This defines a selective acknowledgement block. */ struct tcp_sack_block_wire { __be32 start_seq; @@ -223,6 +263,11 @@ struct tcp_options_received { u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ }; +static inline void tcp_clear_options(struct tcp_options_received *rx_opt) +{ + rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0; +} + /* This is the max number of SACKS that we'll generate and process. It's safe * to increse this, although since: * size = TCPOLEN_SACK_BASE_ALIGNED (4) + n * TCPOLEN_SACK_PERBLOCK (8) @@ -431,6 +476,6 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) return (struct tcp_timewait_sock *)sk; } -#endif +#endif /* __KERNEL__ */ #endif /* _LINUX_TCP_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 4abdb4d..142f32e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -237,6 +237,7 @@ extern int sysctl_tcp_base_mss; extern int sysctl_tcp_workaround_signed_windows; extern int sysctl_tcp_slow_start_after_idle; extern int sysctl_tcp_max_ssthresh; +extern int sysctl_tcp_cookie_size; extern atomic_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; @@ -343,11 +344,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, extern void tcp_enter_quickack_mode(struct sock *sk); -static inline void tcp_clear_options(struct tcp_options_received *rx_opt) -{ - rx_opt->tstamp_ok = rx_opt->sack_ok = rx_opt->wscale_ok = rx_opt->snd_wscale = 0; -} - #define TCP_ECN_OK 1 #define TCP_ECN_QUEUE_CWR 2 #define TCP_ECN_DEMAND_CWR 4 diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 2dcf04d..3422c54 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -714,6 +714,14 @@ static struct ctl_table ipv4_table[] = { }, { .ctl_name = CTL_UNNUMBERED, + .procname = "tcp_cookie_size", + .data = &sysctl_tcp_cookie_size, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, + { + .ctl_name = CTL_UNNUMBERED, .procname = "udp_mem", .data = &sysctl_udp_mem, .maxlen = sizeof(sysctl_udp_mem), diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 79042f4..bcfbe41 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -59,6 +59,14 @@ int sysctl_tcp_base_mss __read_mostly = 512; /* By default, RFC2861 behavior. */ int sysctl_tcp_slow_start_after_idle __read_mostly = 1; +#ifdef CONFIG_SYSCTL +/* By default, let the user enable it. */ +int sysctl_tcp_cookie_size __read_mostly = 0; +#else +int sysctl_tcp_cookie_size __read_mostly = TCP_COOKIE_MAX; +#endif + + /* Account for new data that has been sent to the network. */ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) {