xref: /aosp_15_r20/external/bcc/tools/rdmaucma.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker# @lint-avoid-python-3-compatibility-imports
3*387f9dfdSAndroid Build Coastguard Worker#
4*387f9dfdSAndroid Build Coastguard Worker# rdmaucma: Trace RDMA Userspace Connection Manager Access Event.
5*387f9dfdSAndroid Build Coastguard Worker#           For Linux, uses BCC, eBPF.
6*387f9dfdSAndroid Build Coastguard Worker#
7*387f9dfdSAndroid Build Coastguard Worker# USAGE: rdmaucma [-h]
8*387f9dfdSAndroid Build Coastguard Worker#
9*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) 2023 zhenwei pi
10*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
11*387f9dfdSAndroid Build Coastguard Worker#
12*387f9dfdSAndroid Build Coastguard Worker# 29-MAY-2023  zhenwei pi  Created this.
13*387f9dfdSAndroid Build Coastguard Worker
14*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
15*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
16*387f9dfdSAndroid Build Coastguard Workerfrom socket import inet_ntop, AF_INET, AF_INET6
17*387f9dfdSAndroid Build Coastguard Workerimport socket, struct
18*387f9dfdSAndroid Build Coastguard Workerimport argparse
19*387f9dfdSAndroid Build Coastguard Workerimport ctypes
20*387f9dfdSAndroid Build Coastguard Workerfrom time import strftime
21*387f9dfdSAndroid Build Coastguard Worker
22*387f9dfdSAndroid Build Coastguard Worker# arguments
23*387f9dfdSAndroid Build Coastguard Workerexamples = """examples:
24*387f9dfdSAndroid Build Coastguard Worker    ./rdmaucma            # Trace all RDMA Userspace Connection Manager Access Event
25*387f9dfdSAndroid Build Coastguard Worker"""
26*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
27*387f9dfdSAndroid Build Coastguard Worker    description="Trace RDMA Userspace Connection Manager Access Event",
28*387f9dfdSAndroid Build Coastguard Worker    formatter_class=argparse.RawDescriptionHelpFormatter,
29*387f9dfdSAndroid Build Coastguard Worker    epilog=examples)
30*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-D", "--debug", action="store_true",
31*387f9dfdSAndroid Build Coastguard Worker    help="print BPF program before starting (for debugging purposes)")
32*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true",
33*387f9dfdSAndroid Build Coastguard Worker    help=argparse.SUPPRESS)
34*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker# define BPF program
37*387f9dfdSAndroid Build Coastguard Workerbpf_text = """
38*387f9dfdSAndroid Build Coastguard Worker#include <linux/bpf.h>
39*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
40*387f9dfdSAndroid Build Coastguard Worker#include <rdma/rdma_cm.h>
41*387f9dfdSAndroid Build Coastguard Worker
42*387f9dfdSAndroid Build Coastguard Workerstruct ipv4_data_t {
43*387f9dfdSAndroid Build Coastguard Worker    u32 saddr;
44*387f9dfdSAndroid Build Coastguard Worker    u32 daddr;
45*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
46*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
47*387f9dfdSAndroid Build Coastguard Worker    int event;
48*387f9dfdSAndroid Build Coastguard Worker};
49*387f9dfdSAndroid Build Coastguard Worker
50*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv4_events);
51*387f9dfdSAndroid Build Coastguard Worker
52*387f9dfdSAndroid Build Coastguard Workerstruct ipv6_data_t {
53*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 saddr;
54*387f9dfdSAndroid Build Coastguard Worker    unsigned __int128 daddr;
55*387f9dfdSAndroid Build Coastguard Worker    u16 sport;
56*387f9dfdSAndroid Build Coastguard Worker    u16 dport;
57*387f9dfdSAndroid Build Coastguard Worker    int event;
58*387f9dfdSAndroid Build Coastguard Worker};
59*387f9dfdSAndroid Build Coastguard Worker
60*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(ipv6_events);
61*387f9dfdSAndroid Build Coastguard Worker
62*387f9dfdSAndroid Build Coastguard Workerint trace_ucma_event_handler(struct pt_regs *ctx,
63*387f9dfdSAndroid Build Coastguard Worker                             struct rdma_cm_id *cm_id,
64*387f9dfdSAndroid Build Coastguard Worker                             struct rdma_cm_event *event)
65*387f9dfdSAndroid Build Coastguard Worker{
66*387f9dfdSAndroid Build Coastguard Worker    struct sockaddr_storage *ss = &cm_id->route.addr.src_addr;
67*387f9dfdSAndroid Build Coastguard Worker
68*387f9dfdSAndroid Build Coastguard Worker    if (ss->ss_family == AF_INET) {
69*387f9dfdSAndroid Build Coastguard Worker        struct ipv4_data_t ipv4_data = { 0 };
70*387f9dfdSAndroid Build Coastguard Worker        struct sockaddr_in *addr4 = (struct sockaddr_in *)ss;
71*387f9dfdSAndroid Build Coastguard Worker        ipv4_data.sport = addr4->sin_port;
72*387f9dfdSAndroid Build Coastguard Worker        ipv4_data.saddr = addr4->sin_addr.s_addr;
73*387f9dfdSAndroid Build Coastguard Worker
74*387f9dfdSAndroid Build Coastguard Worker        addr4 = (struct sockaddr_in *)&cm_id->route.addr.dst_addr;
75*387f9dfdSAndroid Build Coastguard Worker        ipv4_data.dport = addr4->sin_port;
76*387f9dfdSAndroid Build Coastguard Worker        ipv4_data.daddr = addr4->sin_addr.s_addr;
77*387f9dfdSAndroid Build Coastguard Worker
78*387f9dfdSAndroid Build Coastguard Worker        ipv4_data.event = event->event;
79*387f9dfdSAndroid Build Coastguard Worker        ipv4_events.perf_submit(ctx, &ipv4_data, sizeof(ipv4_data));
80*387f9dfdSAndroid Build Coastguard Worker    } else if (ss->ss_family == AF_INET6) {
81*387f9dfdSAndroid Build Coastguard Worker        struct ipv6_data_t ipv6_data = { 0 };
82*387f9dfdSAndroid Build Coastguard Worker        struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)ss;
83*387f9dfdSAndroid Build Coastguard Worker        ipv6_data.sport = addr6->sin6_port;
84*387f9dfdSAndroid Build Coastguard Worker        bpf_probe_read_kernel(&ipv6_data.saddr, sizeof(ipv6_data.saddr), addr6->sin6_addr.in6_u.u6_addr32);
85*387f9dfdSAndroid Build Coastguard Worker
86*387f9dfdSAndroid Build Coastguard Worker        addr6 = (struct sockaddr_in6 *)&cm_id->route.addr.dst_addr;
87*387f9dfdSAndroid Build Coastguard Worker        ipv6_data.dport = addr6->sin6_port;
88*387f9dfdSAndroid Build Coastguard Worker        bpf_probe_read_kernel(&ipv6_data.daddr, sizeof(ipv6_data.daddr), addr6->sin6_addr.in6_u.u6_addr32);
89*387f9dfdSAndroid Build Coastguard Worker
90*387f9dfdSAndroid Build Coastguard Worker        ipv6_data.event = event->event;
91*387f9dfdSAndroid Build Coastguard Worker        ipv6_events.perf_submit(ctx, &ipv6_data, sizeof(ipv6_data));
92*387f9dfdSAndroid Build Coastguard Worker    } else {
93*387f9dfdSAndroid Build Coastguard Worker        return -EPROTONOSUPPORT;
94*387f9dfdSAndroid Build Coastguard Worker    }
95*387f9dfdSAndroid Build Coastguard Worker
96*387f9dfdSAndroid Build Coastguard Worker    return 0;
97*387f9dfdSAndroid Build Coastguard Worker}
98*387f9dfdSAndroid Build Coastguard Worker"""
99*387f9dfdSAndroid Build Coastguard Worker
100*387f9dfdSAndroid Build Coastguard Worker# debug/dump ebpf enable or not
101*387f9dfdSAndroid Build Coastguard Workerif args.debug or args.ebpf:
102*387f9dfdSAndroid Build Coastguard Worker    print(bpf_text)
103*387f9dfdSAndroid Build Coastguard Worker    if args.ebpf:
104*387f9dfdSAndroid Build Coastguard Worker        exit()
105*387f9dfdSAndroid Build Coastguard Worker
106*387f9dfdSAndroid Build Coastguard Worker# load BPF program
107*387f9dfdSAndroid Build Coastguard Workerb = BPF(text=bpf_text)
108*387f9dfdSAndroid Build Coastguard Workerb.attach_kprobe(event="ucma_event_handler", fn_name="trace_ucma_event_handler")
109*387f9dfdSAndroid Build Coastguard Worker
110*387f9dfdSAndroid Build Coastguard Worker# see linux/include/rdma/rdma_cm.h
111*387f9dfdSAndroid Build Coastguard Workerrdma_cm_event = [
112*387f9dfdSAndroid Build Coastguard Worker        "address resolved",
113*387f9dfdSAndroid Build Coastguard Worker        "address error",
114*387f9dfdSAndroid Build Coastguard Worker        "route resolved ",
115*387f9dfdSAndroid Build Coastguard Worker        "route error",
116*387f9dfdSAndroid Build Coastguard Worker        "connect request",
117*387f9dfdSAndroid Build Coastguard Worker        "connect response",
118*387f9dfdSAndroid Build Coastguard Worker        "connect error",
119*387f9dfdSAndroid Build Coastguard Worker        "unreachable",
120*387f9dfdSAndroid Build Coastguard Worker        "rejected",
121*387f9dfdSAndroid Build Coastguard Worker        "established",
122*387f9dfdSAndroid Build Coastguard Worker        "disconnected",
123*387f9dfdSAndroid Build Coastguard Worker        "device removal",
124*387f9dfdSAndroid Build Coastguard Worker        "multicast join",
125*387f9dfdSAndroid Build Coastguard Worker        "multicast error",
126*387f9dfdSAndroid Build Coastguard Worker        "address change",
127*387f9dfdSAndroid Build Coastguard Worker        "timewait exit" ]
128*387f9dfdSAndroid Build Coastguard Worker
129*387f9dfdSAndroid Build Coastguard Workerdef print_ipv4_event(cpu, data, size):
130*387f9dfdSAndroid Build Coastguard Worker    event = b["ipv4_events"].event(data)
131*387f9dfdSAndroid Build Coastguard Worker
132*387f9dfdSAndroid Build Coastguard Worker    cm_event = "unknown event"
133*387f9dfdSAndroid Build Coastguard Worker    if event.event < len(rdma_cm_event):
134*387f9dfdSAndroid Build Coastguard Worker        cm_event = rdma_cm_event[event.event]
135*387f9dfdSAndroid Build Coastguard Worker
136*387f9dfdSAndroid Build Coastguard Worker    print("%-9s %-16s %-6s %-45s %-45s" % (strftime("%H:%M:%S").encode('ascii'),
137*387f9dfdSAndroid Build Coastguard Worker        cm_event, "IPv4",
138*387f9dfdSAndroid Build Coastguard Worker        inet_ntop(AF_INET, struct.pack("I", event.saddr)) + ":" + str(socket.ntohs(event.sport)),
139*387f9dfdSAndroid Build Coastguard Worker        inet_ntop(AF_INET, struct.pack("I", event.daddr)) + ":" + str(socket.ntohs(event.dport))))
140*387f9dfdSAndroid Build Coastguard Worker
141*387f9dfdSAndroid Build Coastguard Workerdef print_ipv6_event(cpu, data, size):
142*387f9dfdSAndroid Build Coastguard Worker    event = b["ipv6_events"].event(data)
143*387f9dfdSAndroid Build Coastguard Worker
144*387f9dfdSAndroid Build Coastguard Worker    cm_event = "unknown event"
145*387f9dfdSAndroid Build Coastguard Worker    if event.event < len(rdma_cm_event):
146*387f9dfdSAndroid Build Coastguard Worker        cm_event = rdma_cm_event[event.event]
147*387f9dfdSAndroid Build Coastguard Worker
148*387f9dfdSAndroid Build Coastguard Worker    print("%-9s %-16s %-6s %-45s %-45s" % (strftime("%H:%M:%S").encode('ascii'),
149*387f9dfdSAndroid Build Coastguard Worker        cm_event, "IPv6",
150*387f9dfdSAndroid Build Coastguard Worker        inet_ntop(AF_INET6, event.saddr) + ":" + str(socket.ntohs(event.sport)),
151*387f9dfdSAndroid Build Coastguard Worker        inet_ntop(AF_INET6, event.daddr) + ":" + str(socket.ntohs(event.dport))))
152*387f9dfdSAndroid Build Coastguard Worker
153*387f9dfdSAndroid Build Coastguard Worker
154*387f9dfdSAndroid Build Coastguard Workerb["ipv4_events"].open_perf_buffer(print_ipv4_event)
155*387f9dfdSAndroid Build Coastguard Workerb["ipv6_events"].open_perf_buffer(print_ipv6_event)
156*387f9dfdSAndroid Build Coastguard Worker
157*387f9dfdSAndroid Build Coastguard Worker# output
158*387f9dfdSAndroid Build Coastguard Workerprint("Tracing RDMA Userspace Connection Manager Access event... Hit Ctrl-C to end.")
159*387f9dfdSAndroid Build Coastguard Worker
160*387f9dfdSAndroid Build Coastguard Worker# address length 39 = max("2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b", "255.255.255.255")
161*387f9dfdSAndroid Build Coastguard Workerprint("%-9s %-16s %-4s %-45s %-45s" % ("Timestamp", "Event", "Family", "Local", "Remote"))
162*387f9dfdSAndroid Build Coastguard Worker
163*387f9dfdSAndroid Build Coastguard Workerwhile (1):
164*387f9dfdSAndroid Build Coastguard Worker    try:
165*387f9dfdSAndroid Build Coastguard Worker        b.perf_buffer_poll()
166*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
167*387f9dfdSAndroid Build Coastguard Worker        exit()
168