[PATCH v2 1/2] udp: new provider
Alan Maguire <[email protected]>
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <[email protected]> |
Support UDP send and receive, using raw fbt probes; since udp.d changes sync dlibs also. Update test.x provider check for udp, and add udp to expected providers. Signed-off-by: Alan Maguire <[email protected]> --- dlibs/aarch64/5.11/udp.d | 11 +- dlibs/aarch64/5.12/udp.d | 11 +- dlibs/aarch64/5.14/udp.d | 11 +- dlibs/aarch64/5.16/udp.d | 11 +- dlibs/aarch64/5.2/udp.d | 11 +- dlibs/aarch64/5.6/udp.d | 11 +- dlibs/aarch64/6.1/udp.d | 11 +- dlibs/aarch64/6.10/udp.d | 11 +- dlibs/x86_64/5.11/udp.d | 11 +- dlibs/x86_64/5.12/udp.d | 11 +- dlibs/x86_64/5.14/udp.d | 11 +- dlibs/x86_64/5.16/udp.d | 11 +- dlibs/x86_64/5.2/udp.d | 11 +- dlibs/x86_64/5.6/udp.d | 11 +- dlibs/x86_64/6.1/udp.d | 11 +- dlibs/x86_64/6.10/udp.d | 11 +- libdtrace/Build | 2 + libdtrace/dt_prov_udp.c | 170 ++++++++++++++++++++ libdtrace/dt_provider.c | 1 + libdtrace/dt_provider.h | 1 + libdtrace/udp.d | 11 +- test/unittest/dtrace-util/tst.ListProbes.r | 1 + test/unittest/dtrace-util/tst.ListProbes.sh | 1 + test/unittest/udp/test.x | 6 +- 24 files changed, 279 insertions(+), 90 deletions(-) create mode 100644 libdtrace/dt_prov_udp.c diff --git a/dlibs/aarch64/5.11/udp.d b/dlibs/aarch64/5.11/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.11/udp.d +++ b/dlibs/aarch64/5.11/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/5.12/udp.d b/dlibs/aarch64/5.12/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.12/udp.d +++ b/dlibs/aarch64/5.12/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/5.14/udp.d b/dlibs/aarch64/5.14/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.14/udp.d +++ b/dlibs/aarch64/5.14/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/5.16/udp.d b/dlibs/aarch64/5.16/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.16/udp.d +++ b/dlibs/aarch64/5.16/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/5.2/udp.d b/dlibs/aarch64/5.2/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.2/udp.d +++ b/dlibs/aarch64/5.2/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/5.6/udp.d b/dlibs/aarch64/5.6/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/5.6/udp.d +++ b/dlibs/aarch64/5.6/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/6.1/udp.d b/dlibs/aarch64/6.1/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/6.1/udp.d +++ b/dlibs/aarch64/6.1/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/aarch64/6.10/udp.d b/dlibs/aarch64/6.10/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/aarch64/6.10/udp.d +++ b/dlibs/aarch64/6.10/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.11/udp.d b/dlibs/x86_64/5.11/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.11/udp.d +++ b/dlibs/x86_64/5.11/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.12/udp.d b/dlibs/x86_64/5.12/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.12/udp.d +++ b/dlibs/x86_64/5.12/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.14/udp.d b/dlibs/x86_64/5.14/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.14/udp.d +++ b/dlibs/x86_64/5.14/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.16/udp.d b/dlibs/x86_64/5.16/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.16/udp.d +++ b/dlibs/x86_64/5.16/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.2/udp.d b/dlibs/x86_64/5.2/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.2/udp.d +++ b/dlibs/x86_64/5.2/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/5.6/udp.d b/dlibs/x86_64/5.6/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/5.6/udp.d +++ b/dlibs/x86_64/5.6/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/6.1/udp.d b/dlibs/x86_64/6.1/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/6.1/udp.d +++ b/dlibs/x86_64/6.1/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/dlibs/x86_64/6.10/udp.d b/dlibs/x86_64/6.10/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/dlibs/x86_64/6.10/udp.d +++ b/dlibs/x86_64/6.10/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/libdtrace/Build b/libdtrace/Build index 3540d1c1..722f787d 100644 --- a/libdtrace/Build +++ b/libdtrace/Build @@ -59,6 +59,7 @@ libdtrace-build_SOURCES = dt_aggregate.c \ dt_prov_sdt.c \ dt_prov_syscall.c \ dt_prov_tcp.c \ + dt_prov_udp.c \ dt_prov_uprobe.c \ dt_provider.c \ dt_provider_sdt.c \ @@ -120,6 +121,7 @@ dt_prov_sched.c_CFLAGS := -Wno-pedantic dt_prov_sdt.c_CFLAGS := -Wno-pedantic dt_prov_syscall.c_CFLAGS := -Wno-pedantic dt_prov_tcp.c_CFLAGS := -Wno-pedantic +dt_prov_udp.c_CFLAGS := -Wno-pedantic dt_prov_uprobe.c_CFLAGS := -Wno-pedantic dt_debug.c_CFLAGS := -Wno-prio-ctor-dtor diff --git a/libdtrace/dt_prov_udp.c b/libdtrace/dt_prov_udp.c new file mode 100644 index 00000000..33a975a5 --- /dev/null +++ b/libdtrace/dt_prov_udp.c @@ -0,0 +1,170 @@ +/* + * Oracle Linux DTrace. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + * + * The 'udp' SDT provider for DTrace-specific probes. + */ +#include <assert.h> +#include <errno.h> +#include <netinet/in.h> + +#include "dt_dctx.h" +#include "dt_cg.h" +#include "dt_provider_sdt.h" +#include "dt_probe.h" + +static const char prvname[] = "udp"; +static const char modname[] = "vmlinux"; + +enum { + NET_PROBE_OUTBOUND = 0, + NET_PROBE_INBOUND, +}; + +static probe_dep_t probes[] = { + { "receive", + DTRACE_PROBESPEC_NAME, "rawfbt::udp_queue_rcv_skb:entry" }, + { "receive", + DTRACE_PROBESPEC_NAME, "rawfbt::udpv6_queue_rcv_skb:entry" }, + { "send", + DTRACE_PROBESPEC_NAME, "rawfbt::ip_send_skb:entry" }, + { "send", + DTRACE_PROBESPEC_NAME, "rawfbt::ip6_send_skb:entry" }, + { NULL, } +}; + +static probe_arg_t probe_args[] = { + + { "receive", 0, { 0, 0, "struct sk_buff *", "pktinfo_t *" } }, + { "receive", 1, { 1, 0, "struct sock *", "csinfo_t *" } }, + { "receive", 2, { 2, 0, "void_ip_t *", "ipinfo_t *" } }, + { "receive", 3, { 3, 0, "struct udp_sock *", "udpsinfo_t *" } }, + { "receive", 4, { 4, 0, "struct udphdr *", "udpinfo_t *" } }, + + { "send", 0, { 0, 0, "struct sk_buff *", "pktinfo_t *" } }, + { "send", 1, { 1, 0, "struct sock *", "csinfo_t *" } }, + { "send", 2, { 2, 0, "void_ip_t *", "ipinfo_t *" } }, + { "send", 3, { 3, 0, "struct udp_sock *", "udpsinfo_t *" } }, + { "send", 4, { 4, 0, "struct udphdr *", "udpinfo_t *" } }, + + { NULL, } +}; + +static const dtrace_pattr_t pattr = { +{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, +{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, +{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, +{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, +{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, +}; + +/* + * Provide all the "udp" SDT probes. + */ +static int populate(dtrace_hdl_t *dtp) +{ + return dt_sdt_populate(dtp, prvname, modname, &dt_udp, &pattr, + probe_args, probes); +} + +/* + * Generate a BPF trampoline for a SDT probe. + * + * The trampoline function is called when a SDT probe triggers, and it must + * satisfy the following prototype: + * + * int dt_udp(void *data) + * + * The trampoline will populate a dt_dctx_t struct and then call the function + * that implements the compiled D clause. It returns the value that it gets + * back from that function. + */ +static int trampoline(dt_pcb_t *pcb, uint_t exitlbl) +{ + dt_irlist_t *dlp = &pcb->pcb_ir; + dt_probe_t *prp = pcb->pcb_probe; + dt_probe_t *uprp = pcb->pcb_parent_probe; + int skbarg = 1; + int direction; + + /* + * We construct the udp::: probe arguments as follows: + * arg0 = skb + * arg1 = sk + * arg2 = ip_hdr(skb) [if available] + * arg3 = sk [struct udp_sock *] + * arg4 = udp_hdr(skb) + * arg5 = NET_PROBE_INBOUND (0x1) | NET_PROBE_OUTBOUND (0x0) + * arg5 never makes it into supported args[], it is simply set to + * help inform translators about whether it is an inbound/outbound probe + */ + + if (strcmp(prp->desc->prb, "receive") == 0) { + direction = NET_PROBE_INBOUND; + /* get sk from arg0, store in arg3 */ + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(0))); + emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_6, 0, exitlbl)); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(3), BPF_REG_6)); + } else { + if (strcmp(uprp->desc->fun, "ip6_send_skb") == 0) + skbarg = 0; + direction = NET_PROBE_OUTBOUND; + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(skbarg))); + /* get sk from skb->sk, store in arg3 */ + dt_cg_tramp_get_member(pcb, "struct sk_buff", BPF_REG_6, "sk"); + emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, exitlbl)); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(3), BPF_REG_0)); + } + + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(skbarg))); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_6)); + + /* Now get sk from arg3, store it in arg1 and ensure it is UDP */ + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(3))); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0)); + dt_cg_tramp_get_member(pcb, "struct sock", BPF_REG_6, + "sk_protocol"); + emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, IPPROTO_UDP, exitlbl)); + + /* + * ip_hdr(skb) = + * skb_network_header(skb) = (include/linux/ip.h) + * skb->head + skb->network_header (include/linux/skbuff.h) + */ + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(0))); + dt_cg_tramp_get_member(pcb, "struct sk_buff", BPF_REG_6, "head"); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(2), BPF_REG_0)); + + dt_cg_tramp_get_member(pcb, "struct sk_buff", BPF_REG_6, + "network_header"); + emit(dlp, BPF_XADD_REG(BPF_DW, BPF_REG_7, DMST_ARG(2), BPF_REG_0)); + + /* + * udp_hdr(skb) = + * skb_transport_header(skb) = (include/linux/ip.h) + * skb->head + skb->transport_header (include/linux/skbuff.h) + */ + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_7, DMST_ARG(0))); + dt_cg_tramp_get_member(pcb, "struct sk_buff", BPF_REG_6, "head"); + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(4), BPF_REG_0)); + dt_cg_tramp_get_member(pcb, "struct sk_buff", BPF_REG_6, + "transport_header"); + emit(dlp, BPF_XADD_REG(BPF_DW, BPF_REG_7, DMST_ARG(4), BPF_REG_0)); + + emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(5), direction)); + + return 0; +} + +dt_provimpl_t dt_udp = { + .name = prvname, + .prog_type = BPF_PROG_TYPE_UNSPEC, + .populate = &populate, + .enable = &dt_sdt_enable, + .load_prog = &dt_bpf_prog_load, + .trampoline = &trampoline, + .probe_info = &dt_sdt_probe_info, + .destroy = &dt_sdt_destroy, +}; diff --git a/libdtrace/dt_provider.c b/libdtrace/dt_provider.c index b9a7196b..848fdc13 100644 --- a/libdtrace/dt_provider.c +++ b/libdtrace/dt_provider.c @@ -41,6 +41,7 @@ const dt_provimpl_t *dt_providers[] = { &dt_sdt, &dt_syscall, &dt_tcp, + &dt_udp, &dt_uprobe, &dt_usdt, NULL diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h index 9d60e5ec..dc126671 100644 --- a/libdtrace/dt_provider.h +++ b/libdtrace/dt_provider.h @@ -89,6 +89,7 @@ extern dt_provimpl_t dt_sched; extern dt_provimpl_t dt_sdt; extern dt_provimpl_t dt_syscall; extern dt_provimpl_t dt_tcp; +extern dt_provimpl_t dt_udp; extern dt_provimpl_t dt_uprobe; extern dt_provimpl_t dt_usdt; diff --git a/libdtrace/udp.d b/libdtrace/udp.d index 0e44ed64..e5a0fc9b 100644 --- a/libdtrace/udp.d +++ b/libdtrace/udp.d @@ -7,6 +7,7 @@ #pragma D depends_on module vmlinux #pragma D depends_on library net.d +#pragma D depends_on library ip.d #pragma D depends_on provider udp /* @@ -48,24 +49,24 @@ translator udpsinfo_t < struct udp_sock *S > { */ udps_addr = (uintptr_t)S; udps_lport = arg4 ? - (probename == "send" ? ntohs(((struct udphdr *)arg4)->source) : + (arg5 == NET_PROBE_OUTBOUND ? ntohs(((struct udphdr *)arg4)->source) : ntohs(((struct udphdr *)arg4)->dest)) : 0; udps_rport = arg4 ? (probename == "send" ? ntohs(((struct udphdr *)arg4)->dest) : ntohs(((struct udphdr *)arg4)->source)) : 0; udps_laddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->saddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->saddr : &((struct iphdr *)arg2)->daddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->saddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->saddr : &((struct ipv6hdr *)arg2)->daddr) : "<unknown>"; udps_raddr = arg2 && *(uint8_t *)arg2 >> 4 == 4 ? - inet_ntoa(probename == "send" ? &((struct iphdr *)arg2)->daddr : + inet_ntoa(arg5 == NET_PROBE_OUTBOUND ? &((struct iphdr *)arg2)->daddr : &((struct iphdr *)arg2)->saddr) : arg2 && *(uint8_t *)arg2 >> 4 == 6 ? - inet_ntoa6(probename == "send" ? &((struct ipv6hdr *)arg2)->daddr : + inet_ntoa6(arg5 == NET_PROBE_OUTBOUND ? &((struct ipv6hdr *)arg2)->daddr : &((struct ipv6hdr *)arg2)->saddr) : "<unknown>"; }; diff --git a/test/unittest/dtrace-util/tst.ListProbes.r b/test/unittest/dtrace-util/tst.ListProbes.r index ad557253..a1e185d4 100644 --- a/test/unittest/dtrace-util/tst.ListProbes.r +++ b/test/unittest/dtrace-util/tst.ListProbes.r @@ -12,3 +12,4 @@ sched sdt syscall tcp +udp diff --git a/test/unittest/dtrace-util/tst.ListProbes.sh b/test/unittest/dtrace-util/tst.ListProbes.sh index a747a045..744bb8ad 100755 --- a/test/unittest/dtrace-util/tst.ListProbes.sh +++ b/test/unittest/dtrace-util/tst.ListProbes.sh @@ -70,6 +70,7 @@ $dtrace $dt_flags -l \ $2 == "sdt" { mycheck($2, $1, 600, 6000); next } $2 == "syscall" { mycheck($2, $1, 300, 3000); next } $2 == "tcp" { mycheck($2, $1, 8, 8); next } + $2 == "udp" { mycheck($2, $1, 2, 2); next } # nothing for usdt # Unrecognized line. diff --git a/test/unittest/udp/test.x b/test/unittest/udp/test.x index d3d7a598..2ff8d675 100755 --- a/test/unittest/udp/test.x +++ b/test/unittest/udp/test.x @@ -1,14 +1,10 @@ #!/bin/bash # # Oracle Linux DTrace. -# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2025 Oracle and/or its affiliates. All rights reserved. # Licensed under the Universal Permissive License v 1.0 as shown at # http://oss.oracle.com/licenses/upl. -if ! check_provider udp; then - echo "Could not load udp provider" - exit 1 -fi if ! perl -MIO::Socket::IP -e 'exit(0);' 2>/dev/null; then exit 1 fi -- 2.43.5