Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'add-ip-port-information-to-udp-drop-tracepoint'

Balazs Scheidler says:

====================
Add IP/port information to UDP drop tracepoint

In our use-case we would like to recover the properties of dropped UDP
packets. Unfortunately the current udp_fail_queue_rcv_skb tracepoint
only exposes the port number of the receiving socket.

This patch-set will add the source/dest ip/port to the tracepoint, while
keeping the socket's local port as well for compatibility.

Thanks for the review comments by Jason and Kuniyuki, they helped me a lot
and I tried to address all of their comments in this new iteration.
====================

Link: https://lore.kernel.org/r/cover.1711475011.git.balazs.scheidler@axoflow.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+69 -50
+40
include/trace/events/net_probe_common.h
··· 70 70 TP_STORE_V4MAPPED(__entry, saddr, daddr) 71 71 #endif 72 72 73 + #define TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb, protoh) \ 74 + do { \ 75 + struct sockaddr_in *v4 = (void *)__entry->saddr; \ 76 + \ 77 + v4->sin_family = AF_INET; \ 78 + v4->sin_port = protoh->source; \ 79 + v4->sin_addr.s_addr = ip_hdr(skb)->saddr; \ 80 + v4 = (void *)__entry->daddr; \ 81 + v4->sin_family = AF_INET; \ 82 + v4->sin_port = protoh->dest; \ 83 + v4->sin_addr.s_addr = ip_hdr(skb)->daddr; \ 84 + } while (0) 85 + 86 + #if IS_ENABLED(CONFIG_IPV6) 87 + 88 + #define TP_STORE_ADDR_PORTS_SKB(__entry, skb, protoh) \ 89 + do { \ 90 + const struct iphdr *iph = ip_hdr(skb); \ 91 + \ 92 + if (iph->version == 6) { \ 93 + struct sockaddr_in6 *v6 = (void *)__entry->saddr; \ 94 + \ 95 + v6->sin6_family = AF_INET6; \ 96 + v6->sin6_port = protoh->source; \ 97 + v6->sin6_addr = ipv6_hdr(skb)->saddr; \ 98 + v6 = (void *)__entry->daddr; \ 99 + v6->sin6_family = AF_INET6; \ 100 + v6->sin6_port = protoh->dest; \ 101 + v6->sin6_addr = ipv6_hdr(skb)->daddr; \ 102 + } else \ 103 + TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb, protoh); \ 104 + } while (0) 105 + 106 + #else 107 + 108 + #define TP_STORE_ADDR_PORTS_SKB(__entry, skb, protoh) \ 109 + TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb, protoh) 110 + 111 + #endif 112 + 73 113 #endif
+2 -43
include/trace/events/tcp.h
··· 273 273 __entry->skbaddr, __entry->skaddr) 274 274 ); 275 275 276 - #define TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb) \ 277 - do { \ 278 - const struct tcphdr *th = (const struct tcphdr *)skb->data; \ 279 - struct sockaddr_in *v4 = (void *)__entry->saddr; \ 280 - \ 281 - v4->sin_family = AF_INET; \ 282 - v4->sin_port = th->source; \ 283 - v4->sin_addr.s_addr = ip_hdr(skb)->saddr; \ 284 - v4 = (void *)__entry->daddr; \ 285 - v4->sin_family = AF_INET; \ 286 - v4->sin_port = th->dest; \ 287 - v4->sin_addr.s_addr = ip_hdr(skb)->daddr; \ 288 - } while (0) 289 - 290 - #if IS_ENABLED(CONFIG_IPV6) 291 - 292 - #define TP_STORE_ADDR_PORTS_SKB(__entry, skb) \ 293 - do { \ 294 - const struct iphdr *iph = ip_hdr(skb); \ 295 - \ 296 - if (iph->version == 6) { \ 297 - const struct tcphdr *th = (const struct tcphdr *)skb->data; \ 298 - struct sockaddr_in6 *v6 = (void *)__entry->saddr; \ 299 - \ 300 - v6->sin6_family = AF_INET6; \ 301 - v6->sin6_port = th->source; \ 302 - v6->sin6_addr = ipv6_hdr(skb)->saddr; \ 303 - v6 = (void *)__entry->daddr; \ 304 - v6->sin6_family = AF_INET6; \ 305 - v6->sin6_port = th->dest; \ 306 - v6->sin6_addr = ipv6_hdr(skb)->daddr; \ 307 - } else \ 308 - TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb); \ 309 - } while (0) 310 - 311 - #else 312 - 313 - #define TP_STORE_ADDR_PORTS_SKB(__entry, skb) \ 314 - TP_STORE_ADDR_PORTS_SKB_V4(__entry, skb) 315 - 316 - #endif 317 - 318 276 /* 319 277 * tcp event with only skb 320 278 */ ··· 289 331 ), 290 332 291 333 TP_fast_assign( 334 + const struct tcphdr *th = (const struct tcphdr *)skb->data; 292 335 __entry->skbaddr = skb; 293 336 294 337 memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); 295 338 memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); 296 339 297 - TP_STORE_ADDR_PORTS_SKB(__entry, skb); 340 + TP_STORE_ADDR_PORTS_SKB(__entry, skb, th); 298 341 ), 299 342 300 343 TP_printk("skbaddr=%p src=%pISpc dest=%pISpc",
+24 -5
include/trace/events/udp.h
··· 7 7 8 8 #include <linux/udp.h> 9 9 #include <linux/tracepoint.h> 10 + #include <trace/events/net_probe_common.h> 10 11 11 12 TRACE_EVENT(udp_fail_queue_rcv_skb, 12 13 13 - TP_PROTO(int rc, struct sock *sk), 14 + TP_PROTO(int rc, struct sock *sk, struct sk_buff *skb), 14 15 15 - TP_ARGS(rc, sk), 16 + TP_ARGS(rc, sk, skb), 16 17 17 18 TP_STRUCT__entry( 18 19 __field(int, rc) 19 - __field(__u16, lport) 20 + 21 + __field(__u16, sport) 22 + __field(__u16, dport) 23 + __field(__u16, family) 24 + __array(__u8, saddr, sizeof(struct sockaddr_in6)) 25 + __array(__u8, daddr, sizeof(struct sockaddr_in6)) 20 26 ), 21 27 22 28 TP_fast_assign( 29 + const struct udphdr *uh = (const struct udphdr *)udp_hdr(skb); 30 + 23 31 __entry->rc = rc; 24 - __entry->lport = inet_sk(sk)->inet_num; 32 + 33 + /* for filtering use */ 34 + __entry->sport = ntohs(uh->source); 35 + __entry->dport = ntohs(uh->dest); 36 + __entry->family = sk->sk_family; 37 + 38 + memset(__entry->saddr, 0, sizeof(struct sockaddr_in6)); 39 + memset(__entry->daddr, 0, sizeof(struct sockaddr_in6)); 40 + 41 + TP_STORE_ADDR_PORTS_SKB(__entry, skb, uh); 25 42 ), 26 43 27 - TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) 44 + TP_printk("rc=%d family=%s src=%pISpc dest=%pISpc", __entry->rc, 45 + show_family_name(__entry->family), 46 + __entry->saddr, __entry->daddr) 28 47 ); 29 48 30 49 #endif /* _TRACE_UDP_H */
+1 -1
net/ipv4/udp.c
··· 2049 2049 drop_reason = SKB_DROP_REASON_PROTO_MEM; 2050 2050 } 2051 2051 UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 2052 + trace_udp_fail_queue_rcv_skb(rc, sk, skb); 2052 2053 kfree_skb_reason(skb, drop_reason); 2053 - trace_udp_fail_queue_rcv_skb(rc, sk); 2054 2054 return -1; 2055 2055 } 2056 2056
+2 -1
net/ipv6/udp.c
··· 34 34 #include <linux/slab.h> 35 35 #include <linux/uaccess.h> 36 36 #include <linux/indirect_call_wrapper.h> 37 + #include <trace/events/udp.h> 37 38 38 39 #include <net/addrconf.h> 39 40 #include <net/ndisc.h> ··· 659 658 drop_reason = SKB_DROP_REASON_PROTO_MEM; 660 659 } 661 660 UDP6_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 661 + trace_udp_fail_queue_rcv_skb(rc, sk, skb); 662 662 kfree_skb_reason(skb, drop_reason); 663 - trace_udp_fail_queue_rcv_skb(rc, sk); 664 663 return -1; 665 664 } 666 665