diff options
Diffstat (limited to 'net/ipv4/tcp_ao.c')
| -rw-r--r-- | net/ipv4/tcp_ao.c | 30 | 
1 files changed, 18 insertions, 12 deletions
| diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c index 37c42b63ff99..85531437890c 100644 --- a/net/ipv4/tcp_ao.c +++ b/net/ipv4/tcp_ao.c @@ -16,6 +16,7 @@  #include <net/tcp.h>  #include <net/ipv6.h>  #include <net/icmp.h> +#include <trace/events/tcp.h>  DEFINE_STATIC_KEY_DEFERRED_FALSE(tcp_ao_needed, HZ); @@ -884,17 +885,16 @@ tcp_ao_verify_hash(const struct sock *sk, const struct sk_buff *skb,  		   const struct tcp_ao_hdr *aoh, struct tcp_ao_key *key,  		   u8 *traffic_key, u8 *phash, u32 sne, int l3index)  { -	u8 maclen = aoh->length - sizeof(struct tcp_ao_hdr);  	const struct tcphdr *th = tcp_hdr(skb); +	u8 maclen = tcp_ao_hdr_maclen(aoh);  	void *hash_buf = NULL;  	if (maclen != tcp_ao_maclen(key)) {  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD);  		atomic64_inc(&info->counters.pkt_bad);  		atomic64_inc(&key->pkt_bad); -		tcp_hash_fail("AO hash wrong length", family, skb, -			      "%u != %d L3index: %d", maclen, -			      tcp_ao_maclen(key), l3index); +		trace_tcp_ao_wrong_maclen(sk, skb, aoh->keyid, +					  aoh->rnext_keyid, maclen);  		return SKB_DROP_REASON_TCP_AOFAILURE;  	} @@ -909,8 +909,8 @@ tcp_ao_verify_hash(const struct sock *sk, const struct sk_buff *skb,  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD);  		atomic64_inc(&info->counters.pkt_bad);  		atomic64_inc(&key->pkt_bad); -		tcp_hash_fail("AO hash mismatch", family, skb, -			      "L3index: %d", l3index); +		trace_tcp_ao_mismatch(sk, skb, aoh->keyid, +				      aoh->rnext_keyid, maclen);  		kfree(hash_buf);  		return SKB_DROP_REASON_TCP_AOFAILURE;  	} @@ -927,6 +927,7 @@ tcp_inbound_ao_hash(struct sock *sk, const struct sk_buff *skb,  		    int l3index, const struct tcp_ao_hdr *aoh)  {  	const struct tcphdr *th = tcp_hdr(skb); +	u8 maclen = tcp_ao_hdr_maclen(aoh);  	u8 *phash = (u8 *)(aoh + 1); /* hash goes just after the header */  	struct tcp_ao_info *info;  	enum skb_drop_reason ret; @@ -939,8 +940,8 @@ tcp_inbound_ao_hash(struct sock *sk, const struct sk_buff *skb,  	info = rcu_dereference(tcp_sk(sk)->ao_info);  	if (!info) {  		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOKEYNOTFOUND); -		tcp_hash_fail("AO key not found", family, skb, -			      "keyid: %u L3index: %d", aoh->keyid, l3index); +		trace_tcp_ao_key_not_found(sk, skb, aoh->keyid, +					   aoh->rnext_keyid, maclen);  		return SKB_DROP_REASON_TCP_AOUNEXPECTED;  	} @@ -981,6 +982,9 @@ tcp_inbound_ao_hash(struct sock *sk, const struct sk_buff *skb,  		current_key = READ_ONCE(info->current_key);  		/* Key rotation: the peer asks us to use new key (RNext) */  		if (unlikely(aoh->rnext_keyid != current_key->sndid)) { +			trace_tcp_ao_rnext_request(sk, skb, current_key->sndid, +						   aoh->rnext_keyid, +						   tcp_ao_hdr_maclen(aoh));  			/* If the key is not found we do nothing. */  			key = tcp_ao_established_key(info, aoh->rnext_keyid, -1);  			if (key) @@ -1046,8 +1050,8 @@ verify_hash:  key_not_found:  	NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOKEYNOTFOUND);  	atomic64_inc(&info->counters.key_not_found); -	tcp_hash_fail("Requested by the peer AO key id not found", -		      family, skb, "L3index: %d", l3index); +	trace_tcp_ao_key_not_found(sk, skb, aoh->keyid, +				   aoh->rnext_keyid, maclen);  	return SKB_DROP_REASON_TCP_AOKEYNOTFOUND;  } @@ -1968,8 +1972,10 @@ static int tcp_ao_info_cmd(struct sock *sk, unsigned short int family,  		first = true;  	} -	if (cmd.ao_required && tcp_ao_required_verify(sk)) -		return -EKEYREJECTED; +	if (cmd.ao_required && tcp_ao_required_verify(sk)) { +		err = -EKEYREJECTED; +		goto out; +	}  	/* For sockets in TCP_CLOSED it's possible set keys that aren't  	 * matching the future peer (address/port/VRF/etc), |