program = BPF( text=r""" #include <linux/cred.h> #include <linux/sched.h> #include <linux/user_namespace.h> #include <uapi/linux/ptrace.h> BPF_HASH(procs, u32, u32); static inline int __print_uid_map(struct pt_regs* ctx) { struct task_struct* task; struct uid_gid_map* mapping; task = (struct task_struct*)bpf_get_current_task(); mapping = &task->cred->user_ns->uid_map; if (mapping->nr_extents < 1) { return 0; } bpf_trace_printk("%d,%d,%d\n", mapping->extent[0].first, mapping->extent[0].lower_first, mapping->extent[0].count); return 0; } int kr__create_user_ns(struct pt_regs* ctx) { bpf_trace_printk("create_user_ns\n"); return __print_uid_map(ctx); } int kr__proc_uid_map_write(struct pt_regs* ctx) { u32 pid = bpf_get_current_pid_tgid() >> 32; procs.update(&pid, &pid); bpf_trace_printk("proc_uid_map\n"); return __print_uid_map(ctx); } int k__generic_permission(struct pt_regs* ctx) { struct task_struct* task; struct uid_gid_map* mapping; u32 pid = bpf_get_current_pid_tgid() >> 32; u32 *pid_ptr = procs.lookup(&pid); if (pid_ptr == NULL) { return 0; } bpf_trace_printk("generic_permission\n"); task = (struct task_struct*)bpf_get_current_task(); bpf_trace_printk("fsuid=%d\n", task->cred->fsuid); return 0; } """ )
def test_gpl_helper_macro(self): b = BPF(text=self.gpl_only_text + self.license('GPL')) self.load_bpf_code(b)
def test_proprietary_words_macro(self): b = BPF(text=self.proprietary_text + self.license('Proprietary license')) self.load_bpf_code(b)
def setUp(self): b = BPF(text=text, debug=0) self.stats = b.get_table("stats") b.attach_kprobe(event="finish_task_switch", fn_name="count_sched")
def test_proprietary_cflags_fail(self): b = BPF(text=self.proprietary_text, cflags=["-DBPF_LICENSE=Proprietary"]) self.load_bpf_code(b)
#!/usr/bin/python from bcc import BPF import time import socket import struct import sys import imap, hosts import geoip2 hosts.init() device = "wlp8s0" bpf = BPF(src_file="packet-capture.c") fn = bpf.load_func("xdp_ip_counter", BPF.XDP) bpf.attach_xdp(device, fn, 0) counters = bpf.get_table("counters") myPrivateIP = imap.getMyPrivateIP() while True: print("watchdog") try: for k in counters.keys(): val = counters[k].value if val: source = socket.inet_ntoa(struct.pack("!I", k.s_v4_addr)) destination = socket.inet_ntoa(struct.pack("!I", k.d_v4_addr)) if destination != myPrivateIP: continue else: try: imap.addPeerToDB(source) except geoip2.errors.AddressNotFoundError:
struct data_t data = {.ts = now, .cpu = cpu, .len = len}; events.perf_submit(ctx, &data, sizeof(data)); return 0; } """ # code substitutions if debug or args.ebpf: print(bpf_text) if args.ebpf: exit() # initialize BPF & perf_events b = BPF(text=bpf_text) # TODO: check for HW counters first and use if more accurate b.attach_perf_event(ev_type=PerfType.SOFTWARE, ev_config=PerfSWConfig.TASK_CLOCK, fn_name="do_perf_event", sample_period=0, sample_freq=frequency) if args.csv: if args.timestamp: print("TIME", end=",") print("TIMESTAMP_ns", end=",") print(",".join("CPU" + str(c) for c in range(ncpu)), end="") if args.fullcsv: print(",", end="") print(",".join("OFFSET_ns_CPU" + str(c) for c in range(ncpu)), end="")
from bcc import BPF bpf_source = """ #include <uapi/linux/ptrace.h> int do_sys_execve(struct pt_regs *ctx) { char comm[16]; bpf_get_current_comm(&comm, sizeof(comm)); bpf_trace_printk("executing program: %s \\n", comm); return 0; } """ bpf = BPF(text=bpf_source) execve_function = bpf.get_syscall_fnname("execve") bpf.attach_kprobe(event=execve_function, fn_name="do_sys_execve") bpf.trace_print()
if (data_p) { data = *data_p; data.fun_ID = FID_RECV_MSG; data.fun_ret = 1; } data.ts = bpf_ktime_get_ns(); if (data.arg1 || data.arg2 || data.arg3 || data.arg4) { events.perf_submit(ctx, &data, sizeof(data)); } return 0; } """ bpf = BPF(text=intrucode) LIBPATH="/home/hermes/workspace/opensplice/install/HDE/x86_64.linux-dev/lib/" # Topic information recording bpf.attach_uprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_DomainParticipant_create_topic", fn_name="T_GetTopicName") bpf.attach_uretprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_DomainParticipant_create_topic", fn_name="T_MapTopic2TopicName") bpf.attach_uprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_Publisher_create_datawriter", fn_name="W_MapPID2Topic") bpf.attach_uretprobe(name="%slibddskernel.so"%LIBPATH, sym="v_writerNew", fn_name="W_MapVWriter2TopicName") bpf.attach_uretprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_Publisher_create_datawriter", fn_name="W_MapWriter2TopicName") bpf.attach_uprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_Subscriber_create_datareader", fn_name="R_MapPID2Topic") bpf.attach_uretprobe(name="%slibdcpssac.so"%LIBPATH, sym="DDS_Subscriber_create_datareader", fn_name="R_MapReader2TopicName") # Write/Read Records bpf.attach_uprobe(name="%slibdcpssac.so"%LIBPATH, sym= "DDS_DataWriter_write", fn_name="DDSWrite_Start")
exit() stacks = sys.argv[2] else: stacks = "1024" # load BPF program b = BPF(text=""" #include <uapi/linux/ptrace.h> BPF_HASH(calls, int); BPF_STACK_TRACE(stack_traces, """ + stacks + """); int alloc_enter(struct pt_regs *ctx, size_t size) { int key = stack_traces.get_stackid(ctx, BPF_F_USER_STACK); if (key < 0) return 0; // could also use `calls.increment(key, size);` u64 zero = 0, *val; val = calls.lookup_or_try_init(&key, &zero); if (val) { (*val) += size; } return 0; }; """) b.attach_uprobe(name="c", sym="malloc", fn_name="alloc_enter", pid=pid) print("Attaching to malloc in pid %d, Ctrl+C to quit." % pid) # sleep until Ctrl-C try:
b = BPF(text=""" #include <uapi/linux/bpf.h> #include <linux/in.h> #include <linux/if_ether.h> #include <linux/if_packet.h> #include <linux/if_vlan.h> #include <linux/ip.h> #include <linux/ipv6.h> BPF_TABLE(MAPTYPE, uint32_t, long, dropcnt, 256); static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) { struct iphdr *iph = data + nh_off; if ((void*)&iph[1] > data_end) return 0; return iph->protocol; } static inline int parse_ipv6(void *data, u64 nh_off, void *data_end) { struct ipv6hdr *ip6h = data + nh_off; if ((void*)&ip6h[1] > data_end) return 0; return ip6h->nexthdr; } int xdp_prog1(struct CTXTYPE *ctx) { void* data_end = (void*)(long)ctx->data_end; void* data = (void*)(long)ctx->data; struct ethhdr *eth = data; // drop packets int rc = RETURNCODE; // let pass XDP_PASS or redirect to tx via XDP_TX long *value; uint16_t h_proto; uint64_t nh_off = 0; uint32_t index; nh_off = sizeof(*eth); if (data + nh_off > data_end) return rc; h_proto = eth->h_proto; // parse double vlans #pragma unroll for (int i=0; i<2; i++) { if (h_proto == htons(ETH_P_8021Q) || h_proto == htons(ETH_P_8021AD)) { struct vlan_hdr *vhdr; vhdr = data + nh_off; nh_off += sizeof(struct vlan_hdr); if (data + nh_off > data_end) return rc; h_proto = vhdr->h_vlan_encapsulated_proto; } } if (h_proto == htons(ETH_P_IP)) index = parse_ipv4(data, nh_off, data_end); else if (h_proto == htons(ETH_P_IPV6)) index = parse_ipv6(data, nh_off, data_end); else index = 0; value = dropcnt.lookup(&index); if (value) __sync_fetch_and_add(value, 1); return rc; } """, cflags=[ "-w", "-DRETURNCODE=%s" % ret, "-DCTXTYPE=%s" % ctxtype, "-DMAPTYPE=\"%s\"" % maptype ], device=offload_device)
#! /usr/bin/env python3 import ctypes as ct import os, sys, signal, time, resource from bcc import BPF from bcc.libbcc import lib if __name__ == "__main__": bpf = BPF(src_file="bigdata.c") def on_event(cpu, data, size): event = bpf['event'].event(data) print(f'{event}') bpf['event'].open_perf_buffer(on_event) while True: try: bpf.perf_buffer_poll(30) time.sleep(1) except KeyboardInterrupt: sys.exit(0)
events.perf_submit(ctx, &data, sizeof(data)); #ifdef THRESHOLD } #endif //THRESHOLD temp.delete(&pid); return 0; }; """.replace("DEFINE_USDT", "#define USDT" if mode == "USDT" else "") \ .replace("DEFINE_MYSQL56", "#define MYSQL56" if mode == "MYSQL56" else "") \ .replace("DEFINE_MYSQL57", "#define MYSQL57" if mode == "MYSQL57" else "") \ .replace("DEFINE_THRESHOLD", "#define THRESHOLD %d" % threshold_ns if threshold_ns > 0 else "") if mode.startswith("MYSQL"): # Uprobes mode bpf = BPF(text=program) bpf.attach_uprobe(name=args.path, sym=mysql_func_name, fn_name="query_start") bpf.attach_uretprobe(name=args.path, sym=mysql_func_name, fn_name="query_end") else: # USDT mode if not args.pids or len(args.pids) == 0: if args.db == "mysql": args.pids = map(int, subprocess.check_output( "pidof mysqld".split()).split()) elif args.db == "postgres": args.pids = map(int, subprocess.check_output( "pidof postgres".split()).split()) usdts = map(lambda pid: USDT(pid=pid), args.pids)
int err_code = 0; bpf_usdt_readarg(6, ctx, &err_code); error_hist.increment(err_code); const char* addr = NULL; bpf_usdt_readarg(2, ctx, &addr); bpf_probe_read_str(out.name, sizeof(out.name), addr); out.error_code = err_code; failed.perf_submit(ctx, &out, sizeof(out)); return 0; }} """.format(NUM_ERR_CODES=len(ERROR_CODES)) command_failed = USDT(pid=int(sys.argv[1])) command_failed.enable_probe(probe="commandFail", fn_name="command_failed") b = BPF(text = text, usdt_contexts=[command_failed]) command_to_errors = dict() def print_event(cpu, data, size): event = b["failed"].event(data) event_name = str(event.name, 'utf-8') if event_name not in command_to_errors: command_to_errors[event_name] = dict() if event.error_code not in command_to_errors[event_name]: command_to_errors[event_name][event.error_code] = 0 command_to_errors[event_name][event.error_code] += 1 b["failed"].open_perf_buffer(print_event) print('listening until CTRL-C....') print("{:<30} | Occurrences".format("Commands"))
def test_exported_maps(self): b1 = BPF(text="""BPF_TABLE_PUBLIC("hash", int, int, table1, 10);""") b2 = BPF(text="""BPF_TABLE("extern", int, int, table1, 10);""")
#!/usr/bin/env python from bcc import BPF # sudo bpftrace -e 'kprobe:ext4_inode_csum { printf("trigger\n"); }' BPF(text=""" #include <uapi/linux/ptrace.h> int kprobe__ext4_inode_csum(struct pt_regs *ctx, struct inode *inode, struct ext4_inode *raw) { bpf_trace_printk("inode=%llx raw=%llx \\n", inode, raw); return 0; } int kretprobe__ext4_inode_csum(struct pt_regs *ctx) { unsigned long ret = PT_REGS_RC(ctx); bpf_trace_printk("ret: %llx\\n", ret); return 0; } """).trace_print()
def test_syntax_error(self): with self.assertRaises(Exception): b = BPF(text="""int failure(void *ctx) { if (); return 0; }""")
from bcc import BPF, USDT bpf_source = """ #include <uapi/linux/ptrace.h> int trace_binary_exec(struct pt_regs *ctx) { u64 pid = bpf_get_current_pid_tgid(); bpf_trace_printk("New hello_usdt process running with PID: %d", pid); } """ usdt = USDT(path="./hello_usdt") usdt.enable_probe(probe="probe-main", fn_name="trace_binary_exec") bpf = BPF(text=bpf_source, usdt=usdt) bpf.trace_print()
def test_brb2(self): try: b = BPF(src_file=arg1, debug=0) self.pem_fn = b.load_func("pem", BPF.SCHED_CLS) self.pem_dest = b.get_table("pem_dest") self.pem_stats = b.get_table("pem_stats") # set up the topology self.set_default_const() (ns1_ipdb, self.ns1_eth_out, _) = sim._create_ns(self.ns1, ipaddr=self.vm1_ip + '/24', fn=self.pem_fn, action='drop', disable_ipv6=True) (ns2_ipdb, self.ns2_eth_out, _) = sim._create_ns(self.ns2, ipaddr=self.vm2_ip + '/24', fn=self.pem_fn, action='drop', disable_ipv6=True) ns1_ipdb.routes.add({ 'dst': self.vm2_rtr_mask, 'gateway': self.vm1_rtr_ip }).commit() ns2_ipdb.routes.add({ 'dst': self.vm1_rtr_mask, 'gateway': self.vm2_rtr_ip }).commit() (_, self.nsrtr_eth0_out, _) = sim._create_ns(self.ns_router, ipaddr=self.vm1_rtr_ip + '/24', disable_ipv6=True) (rt_ipdb, self.nsrtr_eth1_out, _) = sim._ns_add_ifc(self.ns_router, "eth1", "ns_router2", ipaddr=self.vm2_rtr_ip + '/24', disable_ipv6=True) # enable ip forwarding in router ns nsp = NSPopen(rt_ipdb.nl.netns, ["sysctl", "-w", "net.ipv4.ip_forward=1"]) nsp.wait() nsp.release() # for each VM connecting to pem, there will be a corresponding veth connecting to the bridge self.setup_br(self.br1, self.nsrtr_eth0_out.ifname, self.veth_pem_2_br1, self.veth_br1_2_pem) self.setup_br(self.br2, self.nsrtr_eth1_out.ifname, self.veth_pem_2_br2, self.veth_br2_2_pem) # load the program and configure maps self.config_maps() # ping nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"]) nsp.wait() nsp.release() # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total self.assertEqual(self.pem_stats[c_uint(0)].value, 12) nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"]) sleep(1) nsp = NSPopen(ns1_ipdb.nl.netns, ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"]) nsp.wait() nsp.release() nsp_server.kill() nsp_server.wait() nsp_server.release() nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"]) sleep(1) nsp = NSPopen( ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"]) nsp.wait() nsp.release() nsp = NSPopen( ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"]) nsp.wait() nsp.release() nsp_server.kill() nsp_server.wait() nsp_server.release() finally: if self.br1 in ipdb.interfaces: ipdb.interfaces[self.br1].remove().commit() if self.br2 in ipdb.interfaces: ipdb.interfaces[self.br2].remove().commit() if self.veth_pem_2_br1 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br1].remove().commit() if self.veth_pem_2_br2 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br2].remove().commit() sim.release() ipdb.release()
if (valp == 0) return 0; // missed start //bpf_probe_read_kernel(&data.comm, sizeof(data.comm), valp->comm); bpf_get_current_comm(&data.comm, sizeof(data.comm)); data.pid = valp->pid; data.order = valp->order; data.delta = tsp - valp->ts; data.ts = valp->ts; events.perf_submit(ctx, &data, sizeof(data)); start.delete(&pid); return 0; } """ b = BPF(text=prog) #b.attach_kprobe(event="huge_pte_alloc", fn_name="trace_hugepte") b.attach_kprobe(event="__alloc_pages_nodemask", fn_name="do_entry") b.attach_kretprobe(event="__alloc_pages_nodemask", fn_name="do_return") # b.detach_kprobe(event="__alloc_pages_nodemask") # b.detach_kretprobe(event="__alloc_pages_nodemask") time = [ ] pid = [ ] comm = [ ] latns = [ ] host = [ ] tsp = [ ] order = [ ]
for addr in stack[1:args.stacks]: print("%40s" % b.ksym(addr, show_offset=True)) if args.tid: # TID trumps PID program = program.replace('FILTER', 'if (tid != %s) { return 0; }' % args.tid) elif args.pid: program = program.replace('FILTER', 'if (pid != %s) { return 0; }' % args.pid) else: program = program.replace('FILTER', '') program = program.replace('STACK_STORAGE_SIZE', str(args.stack_storage_size)) b = BPF(text=program) b.attach_kprobe(event="mutex_unlock", fn_name="mutex_unlock_enter") b.attach_kretprobe(event="mutex_lock", fn_name="mutex_lock_return") b.attach_kprobe(event="mutex_lock", fn_name="mutex_lock_enter") enabled = b.get_table("enabled") stack_traces = b.get_table("stack_traces") aq_counts = b.get_table("aq_report_count") aq_maxs = b.get_table("aq_report_max") aq_totals = b.get_table("aq_report_total") hl_counts = b.get_table("hl_report_count") hl_maxs = b.get_table("hl_report_max") hl_totals = b.get_table("hl_report_total")
from bcc import BPF BPF(text=''' int kprobe__sys_clone(void *ctx) { bpf_trace_printk("%llu\\n", bpf_get_smp_processor_id()); return 0; }''').trace_print()
bpf_text = bpf_text.replace("FILTER_STRING", this_filter) if this_filter: bpf_text = bpf_text.replace( "FILTER", "if (!filter(start_data.input)) { return 0; }") else: bpf_text = bpf_text.replace("FILTER", "") # Create USDT context print("Attaching probes to pid %d" % this_pid) usdt_ctx = USDT(pid=this_pid) usdt_ctx.enable_probe(probe="operation_start", fn_name="trace_operation_start") usdt_ctx.enable_probe(probe="operation_end", fn_name="trace_operation_end") # Create BPF context, load BPF program bpf_ctx = BPF(text=bpf_text, usdt_contexts=[usdt_ctx], debug=debugLevel) # Define latency event and print function class OperationEventData(ct.Structure): _fields_ = [("operation_id", ct.c_ulonglong), ("input", ct.c_char * 64), ("output", ct.c_char * 64), ("start", ct.c_ulonglong), ("end", ct.c_ulonglong), ("duration", ct.c_ulonglong)] start = 0 def print_event(cpu, data, size): global start event = ct.cast(data, ct.POINTER(OperationEventData)).contents
def bench_redis(repeat=3, n=1000000): # type: (int, int) -> pandas.DataFrame def read_result(name, file): # type: (str, Optional[IO[Any]]) -> pandas.DataFrame df = pandas.read_csv(file, names=["Type", "Req/s"]) df["Name"] = name return df bench_cmd = [ "redis-benchmark", "-r", "100000", "-t", "set,lpush", "-n", str(n), "--csv", "-p", ] init_port = 10000 results = [] syscalls, bpf_prog = read_syscall() with open(os.devnull, "w") as fnull: for i in range(repeat): print("Record {}th performance without bpf".format(i)) while check_port_inuse(init_port): init_port += 1 serv = subprocess.Popen(server_cmd + [str(init_port)], stdout=fnull) sleep(1) # for setup bench = subprocess.Popen(bench_cmd + [str(init_port)], stdout=subprocess.PIPE) bench.wait() serv.terminate() results.append(read_result("no-bpf", bench.stdout)) b = BPF(text=bpf_prog) for sysc in syscalls: try: b.attach_kprobe(event=sysc, fn_name="dump") b.attach_kretprobe(event=sysc, fn_name="dump") except Exception as e: print(str(e) + ", syscall: {}".format(sysc)) for i in range(repeat): print("Record {}th performance with bpf".format(i)) while check_port_inuse(init_port): init_port += 1 serv = subprocess.Popen(server_cmd + [str(init_port)], stdout=fnull) sleep(1) # for setup bench = subprocess.Popen(bench_cmd + [str(init_port)], stdout=subprocess.PIPE) bench.wait() serv.terminate() results.append(read_result("bpf", bench.stdout)) df = pandas.concat(results) path = os.path.join(os.path.dirname(__file__), "results", "syscall.tsv") print("wrote %s" % path) df.to_csv(path, sep="\t")
def test_default(self): b = BPF(text=self.gpl_only_text) self.load_bpf_code(b)
def test_char_array_probe(self): BPF(text="""#include <linux/blkdev.h> int kprobe__blk_update_request(struct pt_regs *ctx, struct request *req) { bpf_trace_printk("%s\\n", req->rq_disk->disk_name); return 0; }""")
def test_gpl_compatible_macro(self): b = BPF(text=self.gpl_only_text + self.license('Dual BSD/GPL')) self.load_bpf_code(b)
def test_complex(self): b = BPF(src_file="test_clang_complex.c", debug=0) fn = b.load_func("handle_packet", BPF.SCHED_CLS)
def test_cflags_fail(self): b = BPF(text=self.gpl_only_text, cflags=["-DBPF_LICENSE=GPL"]) self.load_bpf_code(b)
def main(): # # Don't like these globals, but ctx passing does not seem to work with the # existing open_ring_buffer() API :( # global b global options # # Argument parsing # parser = argparse.ArgumentParser() parser.add_argument("--buffer-page-count", help="Number of BPF ring buffer pages, default 1024", type=int, default=1024, metavar="NUMBER") parser.add_argument("-D", "--debug", help="Enable eBPF debugging", type=int, const=0x3f, default=0, nargs='?') parser.add_argument('-d', '--packet-decode', help='Display packet content in selected mode, ' 'default none', choices=['none', 'hex', 'decode'], default='none') parser.add_argument("-f", "--flow-key-size", help="Set maximum flow key size to capture, " "default 64", type=buffer_size_type, default=64, metavar="[64-2048]") parser.add_argument('-k', '--flow-key-decode', help='Display flow-key content in selected mode, ' 'default none', choices=['none', 'hex', 'nlraw'], default='none') parser.add_argument("-p", "--pid", metavar="VSWITCHD_PID", help="ovs-vswitch's PID", type=int, default=None) parser.add_argument("-s", "--packet-size", help="Set maximum packet size to capture, " "default 64", type=buffer_size_type, default=64, metavar="[64-2048]") parser.add_argument("-w", "--pcap", metavar="PCAP_FILE", help="Write upcall packets to specified pcap file.", type=str, default=None) options = parser.parse_args() # # Find the PID of the ovs-vswitchd daemon if not specified. # if options.pid is None: for proc in psutil.process_iter(): if 'ovs-vswitchd' in proc.name(): if options.pid is not None: print("ERROR: Multiple ovs-vswitchd daemons running, " "use the -p option!") sys.exit(-1) options.pid = proc.pid # # Error checking on input parameters # if options.pid is None: print("ERROR: Failed to find ovs-vswitchd's PID!") sys.exit(-1) if options.pcap is not None: if exists(options.pcap): print("ERROR: Destination capture file \"{}\" already exists!". format(options.pcap)) sys.exit(-1) options.buffer_page_count = next_power_of_two(options.buffer_page_count) # # Attach the usdt probe # u = USDT(pid=int(options.pid)) try: u.enable_probe(probe="recv_upcall", fn_name="do_trace") except USDTException as e: print("ERROR: {}" "ovs-vswitchd!".format( (re.sub('^', ' ' * 7, str(e), flags=re.MULTILINE)).strip().replace( "--with-dtrace or --enable-dtrace", "--enable-usdt-probes"))) sys.exit(-1) # # Uncomment to see how arguments are decoded. # print(u.get_text()) # # # Attach probe to running process # source = ebpf_source.replace("<MAX_PACKET_VAL>", str(options.packet_size)) source = source.replace("<MAX_KEY_VAL>", str(options.flow_key_size)) source = source.replace("<BUFFER_PAGE_CNT>", str(options.buffer_page_count)) b = BPF(text=source, usdt_contexts=[u], debug=options.debug) # # Print header # print("{:<18} {:<4} {:<16} {:<10} {:<32} {:<4} {:<10} {:<10}".format( "TIME", "CPU", "COMM", "PID", "DPIF_NAME", "TYPE", "PKT_LEN", "FLOW_KEY_LEN")) # # Dump out all events # b['events'].open_ring_buffer(print_event) while 1: try: b.ring_buffer_poll() time.sleep(0.5) except KeyboardInterrupt: break dropcnt = b.get_table("dropcnt") for k in dropcnt.keys(): count = dropcnt.sum(k).value if k.value == 0 and count > 0: print("\nWARNING: Not all upcalls were captured, {} were dropped!" "\n Increase the BPF ring buffer size with the " "--buffer-page-count option.".format(count))