【BPF EBPF】

简介: 【BPF EBPF】

linu 4.14内核

tcp.bt

#include <linux/socket.h>
#include <net/sock.h>
BEGIN
{
  printf("Tracing tcp state.\n");
  @tcp_states[1] = "ESTABLISHED";
  @tcp_states[2] = "SYN_SENT";
  @tcp_states[3] = "SYN_RECV";
  @tcp_states[4] = "FIN_WAIT1";
  @tcp_states[5] = "FIN_WAIT2";
  @tcp_states[6] = "TIME_WAIT";
  @tcp_states[7] = "CLOSE";
  @tcp_states[8] = "CLOSE_WAIT";
  @tcp_states[9] = "LAST_ACK";
  @tcp_states[10] = "LISTEN";
  @tcp_states[11] = "CLOSING";
  @tcp_states[12] = "NEW_SYN_RECV"; 
}
// 
kretprobe:inet_csk_accept
{
  $sk = (struct sock*)retval;
  $inet_family = $sk->__sk_common.skc_family;
  $daddr = ntop(0);
  $saddr = ntop(0);
  if ($inet_family == AF_INET) {
    $daddr = ntop($sk->__sk_common.skc_daddr);
    $saddr = ntop($sk->__sk_common.skc_rcv_saddr);    
  }
  $sport = $sk->__sk_common.skc_num;
  $dport = $sk->__sk_common.skc_dport;
  printf(" tcp_accept: %-16s:%d --> %-16s:%d\n", $daddr, $dport, $saddr, $sport);
}
kprobe:tcp_connect 
{
  $sk = ((struct sock*)arg0);
  $inet_family = $sk->__sk_common.skc_family;
  $daddr = ntop(0);
        $saddr = ntop(0);
        if ($inet_family == AF_INET) {
                $daddr = ntop($sk->__sk_common.skc_daddr);
                $saddr = ntop($sk->__sk_common.skc_rcv_saddr);
        }
        $sport = $sk->__sk_common.skc_num;
        $dport = $sk->__sk_common.skc_dport;
        printf(" tcp_connect: %-16s:%d --> %-16s:%d\n", $daddr, $dport, $saddr, $sport);
}
tracepoint:syscalls:sys_enter_connect
{
  @start[tid] = nsecs;
  printf("sys_enter_connect: %s --> %ld\n", comm, @start[tid]);
}
tracepoint:syscalls:sys_exit_connect
{
  @ms[comm] = sum(nsecs - @start[tid]);
  delete(@start[tid]);
  printf("sys_exit_connect: %s ", comm);
  print(@ms);
}
kprobe:tcp_fin
{
  $sk = ((struct sock*)arg0);
  $state = $sk->__sk_common.skc_state;
  $statestr = @tcp_states[$state];
  printf(" tcp_fin ");
  time("%H:%M:%S ");
  printf("%-8d %-16s %-16s\n", pid, comm, $statestr); 
}
END
{
  clear(@tcp_states);
  clear(@ms);
  clear(@start);
}

bpftrace 命令

bpftrace -e 'tracepoint:block:block_rq_i* { @[probe] = count(); } interval:s:1 { print(@); clear(@); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret > 0/ { @bytes = sum(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @ret = hist(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @ret = lhist(args->ret, 0, 1000, 100); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret < 0/ { @[- args->ret] = count(); }'
bpftrace -e 'kprobe:vfs_* { @[probe] = count(); } END { print(@, 5); clear(@); }'
bpftrace -e 'kprobe:vfs_read { @start[tid] =nsecs; } kretprobe:vfs_read /@start[tid]/ { @ms[comm] = sum(nsecs - @start[tid]); delete(@start[tid]); } END { print(@ms, 0, 1000000); clear(@ms); clear(@start); }'
bpftrace -e 'k:vfs_read { @[pid] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %s\n", comm, str(args->filename)); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { join(args->argv); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_* {@[probe] = count(); }'
bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[pid, comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/ { @[comm] = sum(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'
bpftrace -e 'tracepoint:block:block_rq_issue { printf("%d %s %d\n", pid, comm, args->bytes); }'
bpftrace -e 'software:major-faults:1 { @[comm] = count(); }'
bpftrace -e 'software:faults:1 { @[comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_clone { printf("-> clone() by %s PID %d\n", comm, pid); } tracepoint:syscalls:sys_exit_clone { printf("<- clone() return %d, %s PID %d\n", args->ret, comm, pid); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_setuid { printf("setuid by PID %d (%s), UID %d\n", pid, comm, uid); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_setuid { printf("setuid by %s returned %d\n", comm, args->ret); }'
bpftrace -e 'tracepoint:block:block_rq_insert { printf("Block I/O by %s\n", kstack); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_connect /pid == 123/ { printf("PID %d called connect()\n", $1); }'
bpftrace -e 'tracepoint:timer:hrtimer_start { @[ksym(args->function)] = count(); }'
bpftrace -e 't:syscalls:sys_enter_read { @reads = count(); } interval:s:5 { exit(); }'


相关文章
|
2天前
|
Linux 数据安全/隐私保护 Perl
bpf对内核的观测
bpftrace 可以对线上项目的系统调用的函数的进行观测,对观测的结果做出分析
48 0
|
存储 Rust 安全
服务网格eBPF应用探索之(一)eBPF基础知识
1)技术背景在eBPF诞生之前,对内核的调试和开发有着相当高的门槛,不仅要十分熟悉庞大的内核代码及开发流程,同时重新编译内核后若希望生效还需要重启OS,开发效率也相当低下。而eBPF提供了相当友好的内核开发/观测机制,即:由用户编写符合一定规范的代码,编译后加载至内核,内核会在指定的时机执行这段代码,内核同时还会将Hook点相关的上下文传递给这段代码供使用,代码可以修改上下文,或是通过返回值来改变
711 0
服务网格eBPF应用探索之(一)eBPF基础知识
|
2天前
|
存储 安全 Ubuntu
eBPF程序如何跟内核进行交互
【2月更文挑战第4天】 一个完整的 eBPF 程序,通常包含用户态和内核态两部分:用户态程序需要通过 BPF 系统调用跟内核进行交互,进而完成 eBPF 程序加载、事件挂载以及映射创建和更新等任务;而在内核态中,eBPF 程序也不能任意调用内核函数,而是需要通过 BPF 辅助函数完成所需的任务。尤其是在访问内存地址的时候,必须要借助 bpf_probe_read 系列函数读取内存数据,以确保内存的安全和高效访问。
|
2天前
|
存储 安全 编译器
eBPF是如何工作的
【2月更文挑战第1天】
|
2天前
|
编译器
内核编译bpf
内核编译bpf
30 0
|
10月前
|
存储 Kubernetes 监控
Linux eBPF解析
今天,我们来了解下 Linux 系统的革命性通用执行引擎-eBPF,之所以聊着玩意,因为它确实牛逼,作为一项底层技术,在现在的云原生生态领域中起着举足轻重的作用。截至目前,业界使用范围最广的 K8S CNI 网络方案 Calico 已宣布支持 eBPF,而作为第一个实现了Kube-Proxy 所有功能的 K8S 网络方案——Cilium 也是基于 eBPF 技术。因此,只有了解其底层机制,才能有助于更好、更易地融入容器生态中。
184 0
|
5月前
|
Ubuntu Linux
|
监控 安全 网络协议
eBPF 是用来干什么的?
eBPF 是用来干什么的?
|
安全 Anolis 开发者
eBPF技术探索SIG:eBPF Hardware Offloading,今天2点见 | 第53期
了解 eBPF 的基础架构,以及如何进行硬件的卸载。
eBPF技术探索SIG:eBPF Hardware Offloading,今天2点见 | 第53期