Commit 248411b8 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by David S. Miller

net/tcp: Wire up l3index to TCP-AO

Similarly how TCP_MD5SIG_FLAG_IFINDEX works for TCP-MD5,
TCP_AO_KEYF_IFINDEX is an AO-key flag that binds that MKT to a specified
by L3 ifinndex. Similarly, without this flag the key will work in
the default VRF l3index = 0 for connections.
To prevent AO-keys from overlapping, it's restricted to add key B for a
socket that has key A, which have the same sndid/rcvid and one of
the following is true:
- !(A.keyflags & TCP_AO_KEYF_IFINDEX) or !(B.keyflags & TCP_AO_KEYF_IFINDEX)
  so that any key is non-bound to a VRF
- A.l3index == B.l3index
  both want to work for the same VRF

Additionally, it's restricted to match TCP-MD5 keys for the same peer
the following way:
|--------------|--------------------|----------------|---------------|
|              | MD5 key without    |     MD5 key    |    MD5 key    |
|              |     l3index        |    l3index=0   |   l3index=N   |
|--------------|--------------------|----------------|---------------|
|  TCP-AO key  |                    |                |               |
|  without     |       reject       |    reject      |   reject      |
|  l3index     |                    |                |               |
|--------------|--------------------|----------------|---------------|
|  TCP-AO key  |                    |                |               |
|  l3index=0   |       reject       |    reject      |   allow       |
|--------------|--------------------|----------------|---------------|
|  TCP-AO key  |                    |                |               |
|  l3index=N   |       reject       |    allow       |   reject      |
|--------------|--------------------|----------------|---------------|

This is done with the help of tcp_md5_do_lookup_any_l3index() to reject
adding AO key without TCP_AO_KEYF_IFINDEX if there's TCP-MD5 in any VRF.
This is important for case where sysctl_tcp_l3mdev_accept = 1
Similarly, for TCP-AO lookups tcp_ao_do_lookup() may be used with
l3index < 0, so that __tcp_ao_key_cmp() will match TCP-AO key in any VRF.
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Acked-by: default avatarDavid Ahern <dsahern@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 67fa83f7
...@@ -2717,7 +2717,7 @@ static inline int tcp_parse_auth_options(const struct tcphdr *th, ...@@ -2717,7 +2717,7 @@ static inline int tcp_parse_auth_options(const struct tcphdr *th,
} }
static inline bool tcp_ao_required(struct sock *sk, const void *saddr, static inline bool tcp_ao_required(struct sock *sk, const void *saddr,
int family, bool stat_inc) int family, int l3index, bool stat_inc)
{ {
#ifdef CONFIG_TCP_AO #ifdef CONFIG_TCP_AO
struct tcp_ao_info *ao_info; struct tcp_ao_info *ao_info;
...@@ -2731,7 +2731,7 @@ static inline bool tcp_ao_required(struct sock *sk, const void *saddr, ...@@ -2731,7 +2731,7 @@ static inline bool tcp_ao_required(struct sock *sk, const void *saddr,
if (!ao_info) if (!ao_info)
return false; return false;
ao_key = tcp_ao_do_lookup(sk, saddr, family, -1, -1); ao_key = tcp_ao_do_lookup(sk, l3index, saddr, family, -1, -1);
if (ao_info->ao_required || ao_key) { if (ao_info->ao_required || ao_key) {
if (stat_inc) { if (stat_inc) {
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOREQUIRED); NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOREQUIRED);
...@@ -2784,21 +2784,22 @@ tcp_inbound_hash(struct sock *sk, const struct request_sock *req, ...@@ -2784,21 +2784,22 @@ tcp_inbound_hash(struct sock *sk, const struct request_sock *req,
* the last key is impossible to remove, so there's * the last key is impossible to remove, so there's
* always at least one current_key. * always at least one current_key.
*/ */
if (tcp_ao_required(sk, saddr, family, true)) { if (tcp_ao_required(sk, saddr, family, l3index, true)) {
tcp_hash_fail("AO hash is required, but not found", tcp_hash_fail("AO hash is required, but not found",
family, skb, "L3 index %d", l3index); family, skb, "L3 index %d", l3index);
return SKB_DROP_REASON_TCP_AONOTFOUND; return SKB_DROP_REASON_TCP_AONOTFOUND;
} }
if (unlikely(tcp_md5_do_lookup(sk, l3index, saddr, family))) { if (unlikely(tcp_md5_do_lookup(sk, l3index, saddr, family))) {
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
tcp_hash_fail("MD5 Hash not found", family, skb, ""); tcp_hash_fail("MD5 Hash not found",
family, skb, "L3 index %d", l3index);
return SKB_DROP_REASON_TCP_MD5NOTFOUND; return SKB_DROP_REASON_TCP_MD5NOTFOUND;
} }
return SKB_NOT_DROPPED_YET; return SKB_NOT_DROPPED_YET;
} }
if (aoh) if (aoh)
return tcp_inbound_ao_hash(sk, skb, family, req, aoh); return tcp_inbound_ao_hash(sk, skb, family, req, l3index, aoh);
return tcp_inbound_md5_hash(sk, skb, saddr, daddr, family, return tcp_inbound_md5_hash(sk, skb, saddr, daddr, family,
l3index, md5_location); l3index, md5_location);
......
...@@ -33,6 +33,7 @@ struct tcp_ao_key { ...@@ -33,6 +33,7 @@ struct tcp_ao_key {
u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align; u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align;
unsigned int tcp_sigpool_id; unsigned int tcp_sigpool_id;
unsigned int digest_size; unsigned int digest_size;
int l3index;
u8 prefixlen; u8 prefixlen;
u8 family; u8 family;
u8 keylen; u8 keylen;
...@@ -200,10 +201,10 @@ int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen); ...@@ -200,10 +201,10 @@ int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen);
int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen); int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen);
enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk, enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
const struct sk_buff *skb, unsigned short int family, const struct sk_buff *skb, unsigned short int family,
const struct request_sock *req, const struct request_sock *req, int l3index,
const struct tcp_ao_hdr *aoh); const struct tcp_ao_hdr *aoh);
u32 tcp_ao_compute_sne(u32 next_sne, u32 next_seq, u32 seq); u32 tcp_ao_compute_sne(u32 next_sne, u32 next_seq, u32 seq);
struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, int l3index,
const union tcp_ao_addr *addr, const union tcp_ao_addr *addr,
int family, int sndid, int rcvid); int family, int sndid, int rcvid);
int tcp_ao_hash_hdr(unsigned short family, char *ao_hash, int tcp_ao_hash_hdr(unsigned short family, char *ao_hash,
...@@ -245,9 +246,6 @@ int tcp_v6_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key, ...@@ -245,9 +246,6 @@ int tcp_v6_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
__be32 disn, bool send); __be32 disn, bool send);
int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key, int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
struct request_sock *req); struct request_sock *req);
struct tcp_ao_key *tcp_v6_ao_do_lookup(const struct sock *sk,
const struct in6_addr *addr,
int sndid, int rcvid);
struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk, struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
struct sock *addr_sk, int sndid, int rcvid); struct sock *addr_sk, int sndid, int rcvid);
struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk, struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk,
...@@ -265,7 +263,7 @@ void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb); ...@@ -265,7 +263,7 @@ void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb);
void tcp_ao_connect_init(struct sock *sk); void tcp_ao_connect_init(struct sock *sk);
void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb, void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
struct tcp_request_sock *treq, struct tcp_request_sock *treq,
unsigned short int family); unsigned short int family, int l3index);
#else /* CONFIG_TCP_AO */ #else /* CONFIG_TCP_AO */
static inline int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb, static inline int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb,
...@@ -277,7 +275,7 @@ static inline int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb, ...@@ -277,7 +275,7 @@ static inline int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb,
static inline void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb, static inline void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
struct tcp_request_sock *treq, struct tcp_request_sock *treq,
unsigned short int family) unsigned short int family, int l3index)
{ {
} }
...@@ -289,13 +287,15 @@ static inline bool tcp_ao_ignore_icmp(const struct sock *sk, int family, ...@@ -289,13 +287,15 @@ static inline bool tcp_ao_ignore_icmp(const struct sock *sk, int family,
static inline enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk, static inline enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
const struct sk_buff *skb, unsigned short int family, const struct sk_buff *skb, unsigned short int family,
const struct request_sock *req, const struct tcp_ao_hdr *aoh) const struct request_sock *req, int l3index,
const struct tcp_ao_hdr *aoh)
{ {
return SKB_NOT_DROPPED_YET; return SKB_NOT_DROPPED_YET;
} }
static inline struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, static inline struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk,
const union tcp_ao_addr *addr, int family, int sndid, int rcvid) int l3index, const union tcp_ao_addr *addr,
int family, int sndid, int rcvid)
{ {
return NULL; return NULL;
} }
......
...@@ -344,6 +344,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) ...@@ -344,6 +344,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
__u8 rcv_wscale; __u8 rcv_wscale;
struct flowi4 fl4; struct flowi4 fl4;
u32 tsoff = 0; u32 tsoff = 0;
int l3index;
if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) || if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
!th->ack || th->rst) !th->ack || th->rst)
...@@ -400,13 +401,14 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) ...@@ -400,13 +401,14 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
treq->snt_synack = 0; treq->snt_synack = 0;
treq->tfo_listener = false; treq->tfo_listener = false;
tcp_ao_syncookie(sk, skb, treq, AF_INET);
if (IS_ENABLED(CONFIG_SMC)) if (IS_ENABLED(CONFIG_SMC))
ireq->smc_ok = 0; ireq->smc_ok = 0;
ireq->ir_iif = inet_request_bound_dev_if(sk, skb); ireq->ir_iif = inet_request_bound_dev_if(sk, skb);
l3index = l3mdev_master_ifindex_by_index(sock_net(sk), ireq->ir_iif);
tcp_ao_syncookie(sk, skb, treq, AF_INET, l3index);
/* We throwed the options of the initial SYN away, so we hope /* We throwed the options of the initial SYN away, so we hope
* the ACK carries the same options again (see RFC1122 4.2.3.8) * the ACK carries the same options again (see RFC1122 4.2.3.8)
*/ */
......
This diff is collapsed.
...@@ -1087,6 +1087,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ...@@ -1087,6 +1087,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
tcp_rsk_used_ao(req)) { tcp_rsk_used_ao(req)) {
const union tcp_md5_addr *addr; const union tcp_md5_addr *addr;
const struct tcp_ao_hdr *aoh; const struct tcp_ao_hdr *aoh;
int l3index;
/* Invalid TCP option size or twice included auth */ /* Invalid TCP option size or twice included auth */
if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh)) if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh))
...@@ -1095,11 +1096,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ...@@ -1095,11 +1096,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
return; return;
addr = (union tcp_md5_addr *)&ip_hdr(skb)->saddr; addr = (union tcp_md5_addr *)&ip_hdr(skb)->saddr;
key.ao_key = tcp_ao_do_lookup(sk, addr, AF_INET, l3index = tcp_v4_sdif(skb) ? inet_iif(skb) : 0;
key.ao_key = tcp_ao_do_lookup(sk, l3index, addr, AF_INET,
aoh->rnext_keyid, -1); aoh->rnext_keyid, -1);
if (unlikely(!key.ao_key)) { if (unlikely(!key.ao_key)) {
/* Send ACK with any matching MKT for the peer */ /* Send ACK with any matching MKT for the peer */
key.ao_key = tcp_ao_do_lookup(sk, addr, AF_INET, -1, -1); key.ao_key = tcp_ao_do_lookup(sk, l3index, addr, AF_INET, -1, -1);
/* Matching key disappeared (user removed the key?) /* Matching key disappeared (user removed the key?)
* let the handshake timeout. * let the handshake timeout.
*/ */
...@@ -1493,6 +1495,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname, ...@@ -1493,6 +1495,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname,
const union tcp_md5_addr *addr; const union tcp_md5_addr *addr;
u8 prefixlen = 32; u8 prefixlen = 32;
int l3index = 0; int l3index = 0;
bool l3flag;
u8 flags; u8 flags;
if (optlen < sizeof(cmd)) if (optlen < sizeof(cmd))
...@@ -1505,6 +1508,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname, ...@@ -1505,6 +1508,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname,
return -EINVAL; return -EINVAL;
flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX; flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX;
l3flag = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX;
if (optname == TCP_MD5SIG_EXT && if (optname == TCP_MD5SIG_EXT &&
cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) { cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) {
...@@ -1542,7 +1546,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname, ...@@ -1542,7 +1546,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, int optname,
/* Don't allow keys for peers that have a matching TCP-AO key. /* Don't allow keys for peers that have a matching TCP-AO key.
* See the comment in tcp_ao_add_cmd() * See the comment in tcp_ao_add_cmd()
*/ */
if (tcp_ao_required(sk, addr, AF_INET, false)) if (tcp_ao_required(sk, addr, AF_INET, l3flag ? l3index : -1, false))
return -EKEYREJECTED; return -EKEYREJECTED;
return tcp_md5_do_add(sk, addr, AF_INET, prefixlen, l3index, flags, return tcp_md5_do_add(sk, addr, AF_INET, prefixlen, l3index, flags,
......
...@@ -140,6 +140,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) ...@@ -140,6 +140,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
struct dst_entry *dst; struct dst_entry *dst;
__u8 rcv_wscale; __u8 rcv_wscale;
u32 tsoff = 0; u32 tsoff = 0;
int l3index;
if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) || if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_syncookies) ||
!th->ack || th->rst) !th->ack || th->rst)
...@@ -214,7 +215,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) ...@@ -214,7 +215,9 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
treq->snt_isn = cookie; treq->snt_isn = cookie;
treq->ts_off = 0; treq->ts_off = 0;
treq->txhash = net_tx_rndhash(); treq->txhash = net_tx_rndhash();
tcp_ao_syncookie(sk, skb, treq, AF_INET6);
l3index = l3mdev_master_ifindex_by_index(sock_net(sk), ireq->ir_iif);
tcp_ao_syncookie(sk, skb, treq, AF_INET6, l3index);
if (IS_ENABLED(CONFIG_SMC)) if (IS_ENABLED(CONFIG_SMC))
ireq->smc_ok = 0; ireq->smc_ok = 0;
......
...@@ -87,30 +87,29 @@ int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key, ...@@ -87,30 +87,29 @@ int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
htonl(tcp_rsk(req)->rcv_isn)); htonl(tcp_rsk(req)->rcv_isn));
} }
struct tcp_ao_key *tcp_v6_ao_do_lookup(const struct sock *sk,
const struct in6_addr *addr,
int sndid, int rcvid)
{
return tcp_ao_do_lookup(sk, (union tcp_ao_addr *)addr, AF_INET6,
sndid, rcvid);
}
struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk, struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
struct sock *addr_sk, struct sock *addr_sk,
int sndid, int rcvid) int sndid, int rcvid)
{ {
int l3index = l3mdev_master_ifindex_by_index(sock_net(sk),
addr_sk->sk_bound_dev_if);
struct in6_addr *addr = &addr_sk->sk_v6_daddr; struct in6_addr *addr = &addr_sk->sk_v6_daddr;
return tcp_v6_ao_do_lookup(sk, addr, sndid, rcvid); return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
AF_INET6, sndid, rcvid);
} }
struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk, struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk,
struct request_sock *req, struct request_sock *req,
int sndid, int rcvid) int sndid, int rcvid)
{ {
struct in6_addr *addr = &inet_rsk(req)->ir_v6_rmt_addr; struct inet_request_sock *ireq = inet_rsk(req);
struct in6_addr *addr = &ireq->ir_v6_rmt_addr;
int l3index;
return tcp_v6_ao_do_lookup(sk, addr, sndid, rcvid); l3index = l3mdev_master_ifindex_by_index(sock_net(sk), ireq->ir_iif);
return tcp_ao_do_lookup(sk, l3index, (union tcp_ao_addr *)addr,
AF_INET6, sndid, rcvid);
} }
int tcp_v6_ao_hash_pseudoheader(struct tcp_sigpool *hp, int tcp_v6_ao_hash_pseudoheader(struct tcp_sigpool *hp,
......
...@@ -610,6 +610,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, ...@@ -610,6 +610,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname,
union tcp_ao_addr *addr; union tcp_ao_addr *addr;
int l3index = 0; int l3index = 0;
u8 prefixlen; u8 prefixlen;
bool l3flag;
u8 flags; u8 flags;
if (optlen < sizeof(cmd)) if (optlen < sizeof(cmd))
...@@ -622,6 +623,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, ...@@ -622,6 +623,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname,
return -EINVAL; return -EINVAL;
flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX; flags = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX;
l3flag = cmd.tcpm_flags & TCP_MD5SIG_FLAG_IFINDEX;
if (optname == TCP_MD5SIG_EXT && if (optname == TCP_MD5SIG_EXT &&
cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) { cmd.tcpm_flags & TCP_MD5SIG_FLAG_PREFIX) {
...@@ -668,7 +670,8 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, ...@@ -668,7 +670,8 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname,
/* Don't allow keys for peers that have a matching TCP-AO key. /* Don't allow keys for peers that have a matching TCP-AO key.
* See the comment in tcp_ao_add_cmd() * See the comment in tcp_ao_add_cmd()
*/ */
if (tcp_ao_required(sk, addr, AF_INET, false)) if (tcp_ao_required(sk, addr, AF_INET,
l3flag ? l3index : -1, false))
return -EKEYREJECTED; return -EKEYREJECTED;
return tcp_md5_do_add(sk, addr, return tcp_md5_do_add(sk, addr,
AF_INET, prefixlen, l3index, flags, AF_INET, prefixlen, l3index, flags,
...@@ -680,7 +683,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname, ...@@ -680,7 +683,7 @@ static int tcp_v6_parse_md5_keys(struct sock *sk, int optname,
/* Don't allow keys for peers that have a matching TCP-AO key. /* Don't allow keys for peers that have a matching TCP-AO key.
* See the comment in tcp_ao_add_cmd() * See the comment in tcp_ao_add_cmd()
*/ */
if (tcp_ao_required(sk, addr, AF_INET6, false)) if (tcp_ao_required(sk, addr, AF_INET6, l3flag ? l3index : -1, false))
return -EKEYREJECTED; return -EKEYREJECTED;
return tcp_md5_do_add(sk, addr, AF_INET6, prefixlen, l3index, flags, return tcp_md5_do_add(sk, addr, AF_INET6, prefixlen, l3index, flags,
...@@ -1220,10 +1223,14 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, ...@@ -1220,10 +1223,14 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
return; return;
if (!aoh) if (!aoh)
return; return;
key.ao_key = tcp_v6_ao_do_lookup(sk, addr, aoh->rnext_keyid, -1); key.ao_key = tcp_ao_do_lookup(sk, l3index,
(union tcp_ao_addr *)addr,
AF_INET6, aoh->rnext_keyid, -1);
if (unlikely(!key.ao_key)) { if (unlikely(!key.ao_key)) {
/* Send ACK with any matching MKT for the peer */ /* Send ACK with any matching MKT for the peer */
key.ao_key = tcp_v6_ao_do_lookup(sk, addr, -1, -1); key.ao_key = tcp_ao_do_lookup(sk, l3index,
(union tcp_ao_addr *)addr,
AF_INET6, -1, -1);
/* Matching key disappeared (user removed the key?) /* Matching key disappeared (user removed the key?)
* let the handshake timeout. * let the handshake timeout.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment