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,
|
||||
__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 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,
|
||||
__be32 saddr, __be32 daddr,
|
||||
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
|
||||
|
||||
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?
|
||||
*/
|
||||
|
||||
static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
|
||||
struct sk_buff *skb, u32 seq, u32 ack,
|
||||
u32 win, u32 ts)
|
||||
static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
|
||||
u32 win, u32 ts, int oif,
|
||||
struct tcp_md5sig_key *key)
|
||||
{
|
||||
struct tcphdr *th = tcp_hdr(skb);
|
||||
struct {
|
||||
|
@ -618,10 +624,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
|
|||
];
|
||||
} rep;
|
||||
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(&arg, 0, sizeof(arg));
|
||||
|
@ -647,23 +649,6 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
|
|||
rep.th.window = htons(win);
|
||||
|
||||
#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) {
|
||||
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 */
|
||||
arg.iov[0].iov_len, IPPROTO_TCP, 0);
|
||||
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
|
||||
if (twsk)
|
||||
arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if;
|
||||
if (oif)
|
||||
arg.bound_dev_if = oif;
|
||||
|
||||
ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb,
|
||||
&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 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_ts_recent);
|
||||
tcptw->tw_ts_recent,
|
||||
tw->tw_bound_dev_if,
|
||||
tcp_twsk_md5_key(tcptw)
|
||||
);
|
||||
|
||||
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,
|
||||
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,
|
||||
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
|
||||
static struct tcp_sock_af_ops tcp_sock_ipv6_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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
|
||||
struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
|
||||
static void tcp_v6_send_ack(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 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;
|
||||
unsigned int tot_len = sizeof(struct tcphdr);
|
||||
__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)
|
||||
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 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_ts_recent);
|
||||
tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
|
||||
|
||||
inet_twsk_put(tw);
|
||||
}
|
||||
|
||||
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