mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	tcp md5sig: Let the caller pass appropriate key for tcp_v{4,6}_do_calc_md5_hash().
As we do for other socket/timewait-socket specific parameters,
let the callers pass appropriate arguments to
tcp_v{4,6}_do_calc_md5_hash().
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
			
			
This commit is contained in:
		
							parent
							
								
									8d26d76dd4
								
							
						
					
					
						commit
						9501f97229
					
				
					 3 changed files with 42 additions and 51 deletions
				
			
		| 
						 | 
					@ -1142,6 +1142,16 @@ extern int			tcp_v4_md5_do_add(struct sock *sk,
 | 
				
			||||||
extern int			tcp_v4_md5_do_del(struct sock *sk,
 | 
					extern int			tcp_v4_md5_do_del(struct sock *sk,
 | 
				
			||||||
						  __be32 addr);
 | 
											  __be32 addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_TCP_MD5SIG
 | 
				
			||||||
 | 
					#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_keylen ? 		 \
 | 
				
			||||||
 | 
									 &(struct tcp_md5sig_key) {		 \
 | 
				
			||||||
 | 
										.key = (twsk)->tw_md5_key,	 \
 | 
				
			||||||
 | 
										.keylen = (twsk)->tw_md5_keylen, \
 | 
				
			||||||
 | 
									} : NULL)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define tcp_twsk_md5_key(twsk)	NULL
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(void);
 | 
					extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(void);
 | 
				
			||||||
extern void			tcp_free_md5sig_pool(void);
 | 
					extern void			tcp_free_md5sig_pool(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,6 +96,12 @@ static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
 | 
				
			||||||
static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
 | 
					static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
 | 
				
			||||||
				   __be32 saddr, __be32 daddr,
 | 
									   __be32 saddr, __be32 daddr,
 | 
				
			||||||
				   struct tcphdr *th, unsigned int tcplen);
 | 
									   struct tcphdr *th, unsigned int tcplen);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline
 | 
				
			||||||
 | 
					struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
 | 
					struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
 | 
				
			||||||
| 
						 | 
					@ -604,9 +610,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
   outside socket context is ugly, certainly. What can I do?
 | 
					   outside socket context is ugly, certainly. What can I do?
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
 | 
					static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
 | 
				
			||||||
			    struct sk_buff *skb, u32 seq, u32 ack,
 | 
								    u32 win, u32 ts, int oif,
 | 
				
			||||||
			    u32 win, u32 ts)
 | 
								    struct tcp_md5sig_key *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tcphdr *th = tcp_hdr(skb);
 | 
						struct tcphdr *th = tcp_hdr(skb);
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
| 
						 | 
					@ -618,10 +624,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
 | 
				
			||||||
			];
 | 
								];
 | 
				
			||||||
	} rep;
 | 
						} rep;
 | 
				
			||||||
	struct ip_reply_arg arg;
 | 
						struct ip_reply_arg arg;
 | 
				
			||||||
#ifdef CONFIG_TCP_MD5SIG
 | 
					 | 
				
			||||||
	struct tcp_md5sig_key *key;
 | 
					 | 
				
			||||||
	struct tcp_md5sig_key tw_key;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&rep.th, 0, sizeof(struct tcphdr));
 | 
						memset(&rep.th, 0, sizeof(struct tcphdr));
 | 
				
			||||||
	memset(&arg, 0, sizeof(arg));
 | 
						memset(&arg, 0, sizeof(arg));
 | 
				
			||||||
| 
						 | 
					@ -647,23 +649,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
 | 
				
			||||||
	rep.th.window  = htons(win);
 | 
						rep.th.window  = htons(win);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_TCP_MD5SIG
 | 
					#ifdef CONFIG_TCP_MD5SIG
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * The SKB holds an imcoming packet, but may not have a valid ->sk
 | 
					 | 
				
			||||||
	 * pointer. This is especially the case when we're dealing with a
 | 
					 | 
				
			||||||
	 * TIME_WAIT ack, because the sk structure is long gone, and only
 | 
					 | 
				
			||||||
	 * the tcp_timewait_sock remains. So the md5 key is stashed in that
 | 
					 | 
				
			||||||
	 * structure, and we use it in preference.  I believe that (twsk ||
 | 
					 | 
				
			||||||
	 * skb->sk) holds true, but we program defensively.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (!twsk && skb->sk) {
 | 
					 | 
				
			||||||
		key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr);
 | 
					 | 
				
			||||||
	} else if (twsk && twsk->tw_md5_keylen) {
 | 
					 | 
				
			||||||
		tw_key.key = twsk->tw_md5_key;
 | 
					 | 
				
			||||||
		tw_key.keylen = twsk->tw_md5_keylen;
 | 
					 | 
				
			||||||
		key = &tw_key;
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		key = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (key) {
 | 
						if (key) {
 | 
				
			||||||
		int offset = (ts) ? 3 : 0;
 | 
							int offset = (ts) ? 3 : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -685,8 +670,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
 | 
				
			||||||
				      ip_hdr(skb)->saddr, /* XXX */
 | 
									      ip_hdr(skb)->saddr, /* XXX */
 | 
				
			||||||
				      arg.iov[0].iov_len, IPPROTO_TCP, 0);
 | 
									      arg.iov[0].iov_len, IPPROTO_TCP, 0);
 | 
				
			||||||
	arg.csumoffset = offsetof(struct tcphdr, check) / 2;
 | 
						arg.csumoffset = offsetof(struct tcphdr, check) / 2;
 | 
				
			||||||
	if (twsk)
 | 
						if (oif)
 | 
				
			||||||
		arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
 | 
							arg.bound_dev_if = oif;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb,
 | 
						ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb,
 | 
				
			||||||
		      &arg, arg.iov[0].iov_len);
 | 
							      &arg, arg.iov[0].iov_len);
 | 
				
			||||||
| 
						 | 
					@ -699,9 +684,12 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	struct inet_timewait_sock *tw = inet_twsk(sk);
 | 
						struct inet_timewait_sock *tw = inet_twsk(sk);
 | 
				
			||||||
	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 | 
						struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 | 
						tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 | 
				
			||||||
			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 | 
								tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 | 
				
			||||||
			tcptw->tw_ts_recent);
 | 
								tcptw->tw_ts_recent,
 | 
				
			||||||
 | 
								tw->tw_bound_dev_if,
 | 
				
			||||||
 | 
								tcp_twsk_md5_key(tcptw)
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inet_twsk_put(tw);
 | 
						inet_twsk_put(tw);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -709,9 +697,11 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
 | 
					static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
 | 
				
			||||||
				  struct request_sock *req)
 | 
									  struct request_sock *req)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
 | 
						tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1,
 | 
				
			||||||
			tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
 | 
								tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
 | 
				
			||||||
			req->ts_recent);
 | 
								req->ts_recent,
 | 
				
			||||||
 | 
								0,
 | 
				
			||||||
 | 
								tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +82,12 @@ static struct inet_connection_sock_af_ops ipv6_specific;
 | 
				
			||||||
#ifdef CONFIG_TCP_MD5SIG
 | 
					#ifdef CONFIG_TCP_MD5SIG
 | 
				
			||||||
static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
 | 
					static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
 | 
				
			||||||
static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
 | 
					static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
 | 
				
			||||||
 | 
											   struct in6_addr *addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_v6_hash(struct sock *sk)
 | 
					static void tcp_v6_hash(struct sock *sk)
 | 
				
			||||||
| 
						 | 
					@ -1011,8 +1017,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	kfree_skb(buff);
 | 
						kfree_skb(buff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
 | 
					static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
 | 
				
			||||||
			    struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
 | 
								    struct tcp_md5sig_key *key)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tcphdr *th = tcp_hdr(skb), *t1;
 | 
						struct tcphdr *th = tcp_hdr(skb), *t1;
 | 
				
			||||||
	struct sk_buff *buff;
 | 
						struct sk_buff *buff;
 | 
				
			||||||
| 
						 | 
					@ -1021,22 +1027,6 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
 | 
				
			||||||
	struct sock *ctl_sk = net->ipv6.tcp_sk;
 | 
						struct sock *ctl_sk = net->ipv6.tcp_sk;
 | 
				
			||||||
	unsigned int tot_len = sizeof(struct tcphdr);
 | 
						unsigned int tot_len = sizeof(struct tcphdr);
 | 
				
			||||||
	__be32 *topt;
 | 
						__be32 *topt;
 | 
				
			||||||
#ifdef CONFIG_TCP_MD5SIG
 | 
					 | 
				
			||||||
	struct tcp_md5sig_key *key;
 | 
					 | 
				
			||||||
	struct tcp_md5sig_key tw_key;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_TCP_MD5SIG
 | 
					 | 
				
			||||||
	if (!tw && skb->sk) {
 | 
					 | 
				
			||||||
		key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
 | 
					 | 
				
			||||||
	} else if (tw && tw->tw_md5_keylen) {
 | 
					 | 
				
			||||||
		tw_key.key = tw->tw_md5_key;
 | 
					 | 
				
			||||||
		tw_key.keylen = tw->tw_md5_keylen;
 | 
					 | 
				
			||||||
		key = &tw_key;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		key = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ts)
 | 
						if (ts)
 | 
				
			||||||
		tot_len += TCPOLEN_TSTAMP_ALIGNED;
 | 
							tot_len += TCPOLEN_TSTAMP_ALIGNED;
 | 
				
			||||||
| 
						 | 
					@ -1116,16 +1106,17 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
 | 
				
			||||||
	struct inet_timewait_sock *tw = inet_twsk(sk);
 | 
						struct inet_timewait_sock *tw = inet_twsk(sk);
 | 
				
			||||||
	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 | 
						struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 | 
						tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
 | 
				
			||||||
			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 | 
								tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
 | 
				
			||||||
			tcptw->tw_ts_recent);
 | 
								tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inet_twsk_put(tw);
 | 
						inet_twsk_put(tw);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
 | 
					static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
 | 
						tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
 | 
				
			||||||
 | 
								tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue