Skip to content
Permalink
Browse files
tcp: ipv6: Add AO signing for tcp_v6_send_response
This is a special code path for acks and resets outside of normal
connection establishment and closing.

Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
  • Loading branch information
cdleonard authored and intel-lab-lkp committed Dec 8, 2021
1 parent e0f1ea8 commit c40d052f30af7bd56b0803412e4f391532253116
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
@@ -322,6 +322,7 @@ struct tcp_authopt_key_info *__tcp_authopt_select_key(const struct sock *sk,
{
return tcp_authopt_lookup_send(info, addr_sk, -1);
}
EXPORT_SYMBOL(__tcp_authopt_select_key);

static struct tcp_authopt_info *__tcp_authopt_info_get_or_create(struct sock *sk)
{
@@ -1197,6 +1198,7 @@ int tcp_authopt_hash(char *hash_location,
memset(hash_location, 0, TCP_AUTHOPT_MACLEN);
return err;
}
EXPORT_SYMBOL(tcp_authopt_hash);

static struct tcp_authopt_key_info *tcp_authopt_lookup_recv(struct sock *sk,
struct sk_buff *skb,
@@ -888,6 +888,44 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
.send_synack = tcp_v6_send_synack,
};

#ifdef CONFIG_TCP_AUTHOPT
static int tcp_v6_send_response_init_authopt(const struct sock *sk,
struct tcp_authopt_info **info,
struct tcp_authopt_key_info **key,
u8 *rnextkeyid)
{
/* Key lookup before SKB allocation */
if (!(tcp_authopt_needed && sk))
return 0;
if (sk->sk_state == TCP_TIME_WAIT)
*info = tcp_twsk(sk)->tw_authopt_info;
else
*info = rcu_dereference(tcp_sk(sk)->authopt_info);
if (!*info)
return 0;
*key = __tcp_authopt_select_key(sk, *info, sk, rnextkeyid);
if (*key)
return TCPOLEN_AUTHOPT_OUTPUT;
return 0;
}

static void tcp_v6_send_response_sign_authopt(const struct sock *sk,
struct tcp_authopt_info *info,
struct tcp_authopt_key_info *key,
struct sk_buff *skb,
struct tcphdr_authopt *ptr,
u8 rnextkeyid)
{
if (!(tcp_authopt_needed && key))
return;
ptr->num = TCPOPT_AUTHOPT;
ptr->len = TCPOLEN_AUTHOPT_OUTPUT;
ptr->keyid = key->send_id;
ptr->rnextkeyid = rnextkeyid;
tcp_authopt_hash(ptr->mac, key, info, (struct sock *)sk, skb);
}
#endif

static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq,
u32 ack, u32 win, u32 tsval, u32 tsecr,
int oif, struct tcp_md5sig_key *key, int rst,
@@ -903,9 +941,24 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
__be32 mrst = 0, *topt;
struct dst_entry *dst;
__u32 mark = 0;
#ifdef CONFIG_TCP_AUTHOPT
struct tcp_authopt_info *aoinfo;
struct tcp_authopt_key_info *aokey;
u8 aornextkeyid;
int aolen;
#endif

if (tsecr)
tot_len += TCPOLEN_TSTAMP_ALIGNED;
#ifdef CONFIG_TCP_AUTHOPT
/* Key lookup before SKB allocation */
aolen = tcp_v6_send_response_init_authopt(sk, &aoinfo, &aokey, &aornextkeyid);
if (aolen) {
tot_len += aolen;
/* Don't use MD5 */
key = NULL;
}
#endif
#ifdef CONFIG_TCP_MD5SIG
if (key)
tot_len += TCPOLEN_MD5SIG_ALIGNED;
@@ -962,6 +1015,10 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
&ipv6_hdr(skb)->daddr, t1);
}
#endif
#ifdef CONFIG_TCP_AUTHOPT
tcp_v6_send_response_sign_authopt(sk, aoinfo, aokey, buff,
(struct tcphdr_authopt *)topt, aornextkeyid);
#endif

memset(&fl6, 0, sizeof(fl6));
fl6.daddr = ipv6_hdr(skb)->saddr;

0 comments on commit c40d052

Please sign in to comment.