Skip to content

Commit 2717b5a

Browse files
0x7f454c46davem330
authored andcommitted
net/tcp: Add tcp_hash_fail() ratelimited logs
Add a helper for logging connection-detailed messages for failed TCP hash verification (both MD5 and AO). Co-developed-by: Francesco Ruggeri <[email protected]> Signed-off-by: Francesco Ruggeri <[email protected]> Co-developed-by: Salam Noureddine <[email protected]> Signed-off-by: Salam Noureddine <[email protected]> Signed-off-by: Dmitry Safonov <[email protected]> Acked-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 64382c7 commit 2717b5a

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

include/net/tcp.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,12 +2748,18 @@ tcp_inbound_hash(struct sock *sk, const struct request_sock *req,
27482748
int l3index;
27492749

27502750
/* Invalid option or two times meet any of auth options */
2751-
if (tcp_parse_auth_options(th, &md5_location, &aoh))
2751+
if (tcp_parse_auth_options(th, &md5_location, &aoh)) {
2752+
tcp_hash_fail("TCP segment has incorrect auth options set",
2753+
family, skb, "");
27522754
return SKB_DROP_REASON_TCP_AUTH_HDR;
2755+
}
27532756

27542757
if (req) {
27552758
if (tcp_rsk_used_ao(req) != !!aoh) {
27562759
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD);
2760+
tcp_hash_fail("TCP connection can't start/end using TCP-AO",
2761+
family, skb, "%s",
2762+
!aoh ? "missing AO" : "AO signed");
27572763
return SKB_DROP_REASON_TCP_AOFAILURE;
27582764
}
27592765
}
@@ -2770,10 +2776,14 @@ tcp_inbound_hash(struct sock *sk, const struct request_sock *req,
27702776
* the last key is impossible to remove, so there's
27712777
* always at least one current_key.
27722778
*/
2773-
if (tcp_ao_required(sk, saddr, family, true))
2779+
if (tcp_ao_required(sk, saddr, family, true)) {
2780+
tcp_hash_fail("AO hash is required, but not found",
2781+
family, skb, "L3 index %d", l3index);
27742782
return SKB_DROP_REASON_TCP_AONOTFOUND;
2783+
}
27752784
if (unlikely(tcp_md5_do_lookup(sk, l3index, saddr, family))) {
27762785
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND);
2786+
tcp_hash_fail("MD5 Hash not found", family, skb, "");
27772787
return SKB_DROP_REASON_TCP_MD5NOTFOUND;
27782788
}
27792789
return SKB_NOT_DROPPED_YET;

include/net/tcp_ao.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,35 @@ struct tcp_ao_info {
118118
struct rcu_head rcu;
119119
};
120120

121+
#define tcp_hash_fail(msg, family, skb, fmt, ...) \
122+
do { \
123+
const struct tcphdr *th = tcp_hdr(skb); \
124+
char hdr_flags[5] = {}; \
125+
char *f = hdr_flags; \
126+
\
127+
if (th->fin) \
128+
*f++ = 'F'; \
129+
if (th->syn) \
130+
*f++ = 'S'; \
131+
if (th->rst) \
132+
*f++ = 'R'; \
133+
if (th->ack) \
134+
*f++ = 'A'; \
135+
if (f != hdr_flags) \
136+
*f = ' '; \
137+
if ((family) == AF_INET) { \
138+
net_info_ratelimited("%s for (%pI4, %d)->(%pI4, %d) %s" fmt "\n", \
139+
msg, &ip_hdr(skb)->saddr, ntohs(th->source), \
140+
&ip_hdr(skb)->daddr, ntohs(th->dest), \
141+
hdr_flags, ##__VA_ARGS__); \
142+
} else { \
143+
net_info_ratelimited("%s for [%pI6c]:%u->[%pI6c]:%u %s" fmt "\n", \
144+
msg, &ipv6_hdr(skb)->saddr, ntohs(th->source), \
145+
&ipv6_hdr(skb)->daddr, ntohs(th->dest), \
146+
hdr_flags, ##__VA_ARGS__); \
147+
} \
148+
} while (0)
149+
121150
#ifdef CONFIG_TCP_AO
122151
/* TCP-AO structures and functions */
123152

net/ipv4/tcp.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4383,7 +4383,6 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
43834383
* o MD5 hash and we're not expecting one.
43844384
* o MD5 hash and its wrong.
43854385
*/
4386-
const struct tcphdr *th = tcp_hdr(skb);
43874386
const struct tcp_sock *tp = tcp_sk(sk);
43884387
struct tcp_md5sig_key *key;
43894388
u8 newhash[16];
@@ -4393,6 +4392,7 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
43934392

43944393
if (!key && hash_location) {
43954394
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED);
4395+
tcp_hash_fail("Unexpected MD5 Hash found", family, skb, "");
43964396
return SKB_DROP_REASON_TCP_MD5UNEXPECTED;
43974397
}
43984398

@@ -4408,16 +4408,19 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
44084408
if (genhash || memcmp(hash_location, newhash, 16) != 0) {
44094409
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE);
44104410
if (family == AF_INET) {
4411-
net_info_ratelimited("MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s L3 index %d\n",
4412-
saddr, ntohs(th->source),
4413-
daddr, ntohs(th->dest),
4414-
genhash ? " tcp_v4_calc_md5_hash failed"
4415-
: "", l3index);
4411+
tcp_hash_fail("MD5 Hash failed", AF_INET, skb, "%s L3 index %d",
4412+
genhash ? "tcp_v4_calc_md5_hash failed"
4413+
: "", l3index);
44164414
} else {
4417-
net_info_ratelimited("MD5 Hash %s for [%pI6c]:%u->[%pI6c]:%u L3 index %d\n",
4418-
genhash ? "failed" : "mismatch",
4419-
saddr, ntohs(th->source),
4420-
daddr, ntohs(th->dest), l3index);
4415+
if (genhash) {
4416+
tcp_hash_fail("MD5 Hash failed",
4417+
AF_INET6, skb, "L3 index %d",
4418+
l3index);
4419+
} else {
4420+
tcp_hash_fail("MD5 Hash mismatch",
4421+
AF_INET6, skb, "L3 index %d",
4422+
l3index);
4423+
}
44214424
}
44224425
return SKB_DROP_REASON_TCP_MD5FAILURE;
44234426
}

net/ipv4/tcp_ao.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ tcp_ao_verify_hash(const struct sock *sk, const struct sk_buff *skb,
800800
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD);
801801
atomic64_inc(&info->counters.pkt_bad);
802802
atomic64_inc(&key->pkt_bad);
803+
tcp_hash_fail("AO hash wrong length", family, skb,
804+
"%u != %d", maclen, tcp_ao_maclen(key));
803805
return SKB_DROP_REASON_TCP_AOFAILURE;
804806
}
805807

@@ -814,6 +816,7 @@ tcp_ao_verify_hash(const struct sock *sk, const struct sk_buff *skb,
814816
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD);
815817
atomic64_inc(&info->counters.pkt_bad);
816818
atomic64_inc(&key->pkt_bad);
819+
tcp_hash_fail("AO hash mismatch", family, skb, "");
817820
kfree(hash_buf);
818821
return SKB_DROP_REASON_TCP_AOFAILURE;
819822
}
@@ -841,6 +844,8 @@ tcp_inbound_ao_hash(struct sock *sk, const struct sk_buff *skb,
841844
info = rcu_dereference(tcp_sk(sk)->ao_info);
842845
if (!info) {
843846
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOKEYNOTFOUND);
847+
tcp_hash_fail("AO key not found", family, skb,
848+
"keyid: %u", aoh->keyid);
844849
return SKB_DROP_REASON_TCP_AOUNEXPECTED;
845850
}
846851

@@ -942,6 +947,8 @@ tcp_inbound_ao_hash(struct sock *sk, const struct sk_buff *skb,
942947
key_not_found:
943948
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOKEYNOTFOUND);
944949
atomic64_inc(&info->counters.key_not_found);
950+
tcp_hash_fail("Requested by the peer AO key id not found",
951+
family, skb, "");
945952
return SKB_DROP_REASON_TCP_AOKEYNOTFOUND;
946953
}
947954

0 commit comments

Comments
 (0)