diff options
| author | David S. Miller <davem@davemloft.net> | 2021-06-29 11:28:21 -0700 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2021-06-29 11:28:21 -0700 |
| commit | c79fa61c94f7a7aa7a185509fca1e1ae5c44ab23 (patch) | |
| tree | e9b4fecafa57b087fc3c3692c9c6ac9bf6d07311 /include | |
| parent | 7f4e5c5b8cb00138ad1a10cab87bbd1e2d4d3376 (diff) | |
| parent | e6a3e4434000de5c36d606e5b5da5f7ba49444bd (diff) | |
| download | linux-next-c79fa61c94f7a7aa7a185509fca1e1ae5c44ab23.tar.gz linux-next-c79fa61c94f7a7aa7a185509fca1e1ae5c44ab23.zip | |
Merge branch 'inet-sk_error-tracers'
Alexander Aring says:
====================
net: sock: add tracers for inet socket errors
this patch series introduce tracers for sk_error_report socket callback
calls. The use-case is that a user space application can monitor them
and making an own heuristic about bad peer connections even over a
socket lifetime. To make a specific example it could be use in the Linux
cluster world to fence a "bad" behaving node. For now it's okay to only
trace inet sockets. Other socket families can introduce their own tracers
easily.
Example output with trace-cmd:
<idle>-0 [003] 201.799437: inet_sk_error_report: family=AF_INET protocol=IPPROTO_TCP sport=21064 dport=38941 saddr=192.168.122.57 daddr=192.168.122.251 saddrv6=::ffff:192.168.122.57 daddrv6=::ffff:192.168.122.251 error=104
- Alex
changes since v2:
- change "sk.sk_error_report(&ipc->sk);" to "sk_error_report(&ipc->sk);"
in net/qrtr/qrtr.c
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/skmsg.h | 2 | ||||
| -rw-r--r-- | include/net/sock.h | 2 | ||||
| -rw-r--r-- | include/net/tls.h | 2 | ||||
| -rw-r--r-- | include/trace/events/sock.h | 60 |
4 files changed, 64 insertions, 2 deletions
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index fcaa9a7996c8..31866031e370 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -347,7 +347,7 @@ static inline void sk_psock_report_error(struct sk_psock *psock, int err) struct sock *sk = psock->sk; sk->sk_err = err; - sk->sk_error_report(sk); + sk_error_report(sk); } struct sk_psock *sk_psock_init(struct sock *sk, int node); diff --git a/include/net/sock.h b/include/net/sock.h index ced2fc965ec7..8bdd80027ffb 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2281,6 +2281,8 @@ static inline int sock_error(struct sock *sk) return -err; } +void sk_error_report(struct sock *sk); + static inline unsigned long sock_wspace(struct sock *sk) { int amt = 0; diff --git a/include/net/tls.h b/include/net/tls.h index 8d398a5de3ee..be4b3e1cac46 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -469,7 +469,7 @@ static inline bool tls_is_sk_tx_device_offloaded(struct sock *sk) static inline void tls_err_abort(struct sock *sk, int err) { sk->sk_err = err; - sk->sk_error_report(sk); + sk_error_report(sk); } static inline bool tls_bigint_increment(unsigned char *seq, int len) diff --git a/include/trace/events/sock.h b/include/trace/events/sock.h index a966d4b5ab37..12c315782766 100644 --- a/include/trace/events/sock.h +++ b/include/trace/events/sock.h @@ -201,6 +201,66 @@ TRACE_EVENT(inet_sock_set_state, show_tcp_state_name(__entry->newstate)) ); +TRACE_EVENT(inet_sk_error_report, + + TP_PROTO(const struct sock *sk), + + TP_ARGS(sk), + + TP_STRUCT__entry( + __field(int, error) + __field(__u16, sport) + __field(__u16, dport) + __field(__u16, family) + __field(__u16, protocol) + __array(__u8, saddr, 4) + __array(__u8, daddr, 4) + __array(__u8, saddr_v6, 16) + __array(__u8, daddr_v6, 16) + ), + + TP_fast_assign( + struct inet_sock *inet = inet_sk(sk); + struct in6_addr *pin6; + __be32 *p32; + + __entry->error = sk->sk_err; + __entry->family = sk->sk_family; + __entry->protocol = sk->sk_protocol; + __entry->sport = ntohs(inet->inet_sport); + __entry->dport = ntohs(inet->inet_dport); + + p32 = (__be32 *) __entry->saddr; + *p32 = inet->inet_saddr; + + p32 = (__be32 *) __entry->daddr; + *p32 = inet->inet_daddr; + +#if IS_ENABLED(CONFIG_IPV6) + if (sk->sk_family == AF_INET6) { + pin6 = (struct in6_addr *)__entry->saddr_v6; + *pin6 = sk->sk_v6_rcv_saddr; + pin6 = (struct in6_addr *)__entry->daddr_v6; + *pin6 = sk->sk_v6_daddr; + } else +#endif + { + pin6 = (struct in6_addr *)__entry->saddr_v6; + ipv6_addr_set_v4mapped(inet->inet_saddr, pin6); + pin6 = (struct in6_addr *)__entry->daddr_v6; + ipv6_addr_set_v4mapped(inet->inet_daddr, pin6); + } + ), + + TP_printk("family=%s protocol=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c error=%d", + show_family_name(__entry->family), + show_inet_protocol_name(__entry->protocol), + __entry->sport, __entry->dport, + __entry->saddr, __entry->daddr, + __entry->saddr_v6, __entry->daddr_v6, + __entry->error) +); + #endif /* _TRACE_SOCK_H */ /* This part must be outside protection */ |
