summary refs log tree commit diff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/tcp.h35
-rw-r--r--include/net/request_sock.h3
-rw-r--r--include/net/tcp.h143
-rw-r--r--include/net/timewait_sock.h3
4 files changed, 180 insertions, 4 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 2d36f6db3706..0aecfc955591 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -19,6 +19,7 @@
 
 #include <linux/types.h>
 #include <asm/byteorder.h>
+#include <linux/socket.h>
 
 struct tcphdr {
 	__be16	source;
@@ -94,6 +95,7 @@ enum {
 #define TCP_INFO		11	/* Information about this connection. */
 #define TCP_QUICKACK		12	/* Block/reenable quick acks */
 #define TCP_CONGESTION		13	/* Congestion control algorithm */
+#define TCP_MD5SIG		14	/* TCP MD5 Signature (RFC2385) */
 
 #define TCPI_OPT_TIMESTAMPS	1
 #define TCPI_OPT_SACK		2
@@ -157,6 +159,17 @@ struct tcp_info
 	__u32	tcpi_total_retrans;
 };
 
+/* for TCP_MD5SIG socket option */
+#define TCP_MD5SIG_MAXKEYLEN	80
+
+struct tcp_md5sig {
+	struct __kernel_sockaddr_storage tcpm_addr;	/* address associated */
+	__u16	__tcpm_pad1;				/* zero */
+	__u16	tcpm_keylen;				/* key length */
+	__u32	__tcpm_pad2;				/* zero */
+	__u8	tcpm_key[TCP_MD5SIG_MAXKEYLEN];		/* key (binary) */
+};
+
 #ifdef __KERNEL__
 
 #include <linux/skbuff.h>
@@ -197,9 +210,13 @@ struct tcp_options_received {
 };
 
 struct tcp_request_sock {
-	struct inet_request_sock req;
-	__u32			 rcv_isn;
-	__u32			 snt_isn;
+	struct inet_request_sock 	req;
+#ifdef CONFIG_TCP_MD5SIG
+	/* Only used by TCP MD5 Signature so far. */
+	struct tcp_request_sock_ops	*af_specific;
+#endif
+	__u32			 	rcv_isn;
+	__u32			 	snt_isn;
 };
 
 static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req)
@@ -363,6 +380,14 @@ struct tcp_sock {
 		__u32		  probe_seq_start;
 		__u32		  probe_seq_end;
 	} mtu_probe;
+
+#ifdef CONFIG_TCP_MD5SIG
+/* TCP AF-Specific parts; only used by MD5 Signature support so far */
+	struct tcp_sock_af_ops	*af_specific;
+
+/* TCP MD5 Signagure Option information */
+	struct tcp_md5sig_info	*md5sig_info;
+#endif
 };
 
 static inline struct tcp_sock *tcp_sk(const struct sock *sk)
@@ -377,6 +402,10 @@ struct tcp_timewait_sock {
 	__u32			  tw_rcv_wnd;
 	__u32			  tw_ts_recent;
 	long			  tw_ts_recent_stamp;
+#ifdef CONFIG_TCP_MD5SIG
+	__u16			  tw_md5_keylen;
+	__u8			  tw_md5_key[TCP_MD5SIG_MAXKEYLEN];
+#endif
 };
 
 static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk)
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index b5b023e79e5f..e37baaf2080b 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -35,7 +35,8 @@ struct request_sock_ops {
 				       struct dst_entry *dst);
 	void		(*send_ack)(struct sk_buff *skb,
 				    struct request_sock *req);
-	void		(*send_reset)(struct sk_buff *skb);
+	void		(*send_reset)(struct sock *sk,
+				      struct sk_buff *skb);
 	void		(*destructor)(struct request_sock *req);
 };
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index e1a5d29d0a1f..363960872de0 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -28,6 +28,7 @@
 #include <linux/percpu.h>
 #include <linux/skbuff.h>
 #include <linux/dmaengine.h>
+#include <linux/crypto.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_timewait_sock.h>
@@ -161,6 +162,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOPT_SACK_PERM        4       /* SACK Permitted */
 #define TCPOPT_SACK             5       /* SACK Block */
 #define TCPOPT_TIMESTAMP	8	/* Better RTT estimations/PAWS */
+#define TCPOPT_MD5SIG		19	/* MD5 Signature (RFC2385) */
 
 /*
  *     TCP option lengths
@@ -170,6 +172,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOLEN_WINDOW         3
 #define TCPOLEN_SACK_PERM      2
 #define TCPOLEN_TIMESTAMP      10
+#define TCPOLEN_MD5SIG         18
 
 /* But this is what stacks really send out. */
 #define TCPOLEN_TSTAMP_ALIGNED		12
@@ -178,6 +181,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 #define TCPOLEN_SACK_BASE		2
 #define TCPOLEN_SACK_BASE_ALIGNED	4
 #define TCPOLEN_SACK_PERBLOCK		8
+#define TCPOLEN_MD5SIG_ALIGNED		20
 
 /* Flags in tp->nonagle */
 #define TCP_NAGLE_OFF		1	/* Nagle's algo is disabled */
@@ -299,6 +303,8 @@ extern void			tcp_cleanup_rbuf(struct sock *sk, int copied);
 extern int			tcp_twsk_unique(struct sock *sk,
 						struct sock *sktw, void *twp);
 
+extern void			tcp_twsk_destructor(struct sock *sk);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
 					 const unsigned int pkts)
 {
@@ -1064,6 +1070,114 @@ static inline void clear_all_retrans_hints(struct tcp_sock *tp){
 	tp->fastpath_skb_hint = NULL;
 }
 
+/* MD5 Signature */
+struct crypto_hash;
+
+/* - key database */
+struct tcp_md5sig_key {
+	u8			*key;
+	u8			keylen;
+};
+
+struct tcp4_md5sig_key {
+	u8			*key;
+	u16			keylen;
+	__be32			addr;
+};
+
+struct tcp6_md5sig_key {
+	u8			*key;
+	u16			keylen;
+#if 0
+	u32			scope_id;	/* XXX */
+#endif
+	struct in6_addr		addr;
+};
+
+/* - sock block */
+struct tcp_md5sig_info {
+	struct tcp4_md5sig_key	*keys4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct tcp6_md5sig_key	*keys6;
+	u32			entries6;
+	u32			alloced6;
+#endif
+	u32			entries4;
+	u32			alloced4;
+};
+
+/* - pseudo header */
+struct tcp4_pseudohdr {
+	__be32		saddr;
+	__be32		daddr;
+	__u8		pad;
+	__u8		protocol;
+	__be16		len;
+};
+
+struct tcp6_pseudohdr {
+	struct in6_addr	saddr;
+	struct in6_addr daddr;
+	__be32		len;
+	__be32		protocol;	/* including padding */
+};
+
+union tcp_md5sum_block {
+	struct tcp4_pseudohdr ip4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct tcp6_pseudohdr ip6;
+#endif
+};
+
+/* - pool: digest algorithm, hash description and scratch buffer */
+struct tcp_md5sig_pool {
+	struct hash_desc	md5_desc;
+	union tcp_md5sum_block	md5_blk;
+};
+
+#define TCP_MD5SIG_MAXKEYS	(~(u32)0)	/* really?! */
+
+/* - functions */
+extern int			tcp_v4_calc_md5_hash(char *md5_hash,
+						     struct tcp_md5sig_key *key,
+						     struct sock *sk,
+						     struct dst_entry *dst,
+						     struct request_sock *req,
+						     struct tcphdr *th,
+						     int protocol, int tcplen);
+extern struct tcp_md5sig_key	*tcp_v4_md5_lookup(struct sock *sk,
+						   struct sock *addr_sk);
+
+extern int			tcp_v4_md5_do_add(struct sock *sk,
+						  __be32 addr,
+						  u8 *newkey,
+						  u8 newkeylen);
+
+extern int			tcp_v4_md5_do_del(struct sock *sk,
+						  u32 addr);
+
+extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(void);
+extern void			tcp_free_md5sig_pool(void);
+
+extern struct tcp_md5sig_pool	*__tcp_get_md5sig_pool(int cpu);
+extern void			__tcp_put_md5sig_pool(void);
+
+static inline
+struct tcp_md5sig_pool		*tcp_get_md5sig_pool(void)
+{
+	int cpu = get_cpu();
+	struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
+	if (!ret)
+		put_cpu();
+	return ret;
+}
+
+static inline void		tcp_put_md5sig_pool(void)
+{
+	__tcp_put_md5sig_pool();
+	put_cpu();
+}
+
 /* /proc */
 enum tcp_seq_states {
 	TCP_SEQ_STATE_LISTENING,
@@ -1103,6 +1217,35 @@ extern int  tcp4_proc_init(void);
 extern void tcp4_proc_exit(void);
 #endif
 
+/* TCP af-specific functions */
+struct tcp_sock_af_ops {
+#ifdef CONFIG_TCP_MD5SIG
+	struct tcp_md5sig_key	*(*md5_lookup) (struct sock *sk,
+						struct sock *addr_sk);
+	int			(*calc_md5_hash) (char *location,
+						  struct tcp_md5sig_key *md5,
+						  struct sock *sk,
+						  struct dst_entry *dst,
+						  struct request_sock *req,
+						  struct tcphdr *th,
+						  int protocol, int len);
+	int			(*md5_add) (struct sock *sk,
+					    struct sock *addr_sk,
+					    u8 *newkey,
+					    u8 len);
+	int			(*md5_parse) (struct sock *sk,
+					      char __user *optval,
+					      int optlen);
+#endif
+};
+
+struct tcp_request_sock_ops {
+#ifdef CONFIG_TCP_MD5SIG
+	struct tcp_md5sig_key	*(*md5_lookup) (struct sock *sk,
+						struct request_sock *req);
+#endif
+};
+
 extern void tcp_v4_init(struct net_proto_family *ops);
 extern void tcp_init(void);
 
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
index be293d795e38..d7a306ea560d 100644
--- a/include/net/timewait_sock.h
+++ b/include/net/timewait_sock.h
@@ -31,6 +31,9 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
 
 static inline void twsk_destructor(struct sock *sk)
 {
+	BUG_ON(sk == NULL);
+	BUG_ON(sk->sk_prot == NULL);
+	BUG_ON(sk->sk_prot->twsk_prot == NULL);
 	if (sk->sk_prot->twsk_prot->twsk_destructor != NULL)
 		sk->sk_prot->twsk_prot->twsk_destructor(sk);
 }