概述
BPF是作为内核报文传输--数据包处理位于非常底层(在网卡的驱动程序处),避免了很多内核skb处理开销(socket buffer, 数据包的管理结构);可以将很多处理逻辑offload到网卡硬件。
eBPF 程序并不像常规的线程那样,启动后就一直运行在那里,它需要事件触发后才会执行。这些事件包括系统调用、内核跟踪点、内核函数和用户态函数的调用退出、网络事件,等等。借助于强大的内核态插桩(kprobe)和用户态插桩(uprobe),eBPF 程序几乎可以在内核和应用的任意位置进行插桩。
eBPF
1.eBPF是最新加入linux内核模块,源于bpf,后来加入了JIT, 使得它实际上成了一个虚拟机。
2.eBPF 程序支持自己的字节码语言,基于该字节码语言编译成内核原生代码,就像 BPF 程序一样。
3.eBPF在内核中运行。
4.eBPF 程序对内核内存访问是有限制的。只能通过内核提供的函数去获取严格限制的必须的内存。
5.eBPF可以和User空间的程序通过 BPF Map进行通讯。
6.eBPF 必须编译成字节码才能使用。
BPF_PROG_LOAD的BPF程序类型决定了四件事:
1.可以在何处附加程序
2.可以调用验证程序的内核内辅助函数
3.是否可以直接访问网络数据包
4.以及作为第一个传递的对象的类型该程序的参数。
bpf_prog_type枚举
enum bpf_prog_type:定义了eBPF程序的类型,包括以下几种类型:
BPF_PROG_TYPE_SOCKET_FILTER:用于过滤套接字数据包的eBPF程序。
BPF_PROG_TYPE_KPROBE:用于内核探查的eBPF程序。
BPF_PROG_TYPE_SCHED_CLS:用于流量分类的eBPF程序。
BPF_PROG_TYPE_SCHED_ACT:用于流量处理的eBPF程序。
BPF_PROG_TYPE_XDP:用于处理数据包的eBPF程序。
BPF_PROG_TYPE_PERF_EVENT:用于性能事件的eBPF程序。
BPF_PROG_TYPE_CGROUP_SKB:用于控制组的eBPF程序。
BPF_PROG_TYPE_CGROUP_SOCK:用于控制组的eBPF程序。
BPF_PROG_TYPE_LWT_IN:用于网络路径的eBPF程序。
BPF_PROG_TYPE_LWT_OUT:用于网络路径的eBPF程序。
BPF_PROG_TYPE_LWT_XMIT:用于网络路径的eBPF程序。
BPF_PROG_TYPE_SOCK_OPS:用于套接字操作的eBPF程序。
BPF_PROG_TYPE_SK_SKB:用于套接字的eBPF程序。
__u32:用于存储eBPF程序的类型的值。
BPF attach 类型
enum bpf_attach_type {
BPF_CGROUP_INET_INGRESS,
BPF_CGROUP_INET_EGRESS,
BPF_CGROUP_INET_SOCK_CREATE,
...........
............
__MAX_BPF_ATTACH_TYPE};
具体说明如下:
BPF_CGROUP_INET_INGRESS:将eBPF程序附加到指定的网络控制组,在数据包进入网络堆栈之前执行程序。
BPF_CGROUP_INET_EGRESS:将eBPF程序附加到指定的网络控制组,在数据包离开网络堆栈之前执行程序。
BPF_CGROUP_INET_SOCK_CREATE:将eBPF程序附加到指定的网络控制组,当创建新的套接字时执行程序。
BPF_CGROUP_INET4_BIND:将eBPF程序附加到指定的网络控制组,在IPv4套接字绑定时执行程序。
BPF_CGROUP_INET6_BIND:将eBPF程序附加到指定的网络控制组,在IPv6套接字绑定时执行程序。
BPF_CGROUP_INET4_CONNECT:将eBPF程序附加到指定的网络控制组,在IPv4套接字连接时执行程序。
BPF_CGROUP_INET6_CONNECT:将eBPF程序附加到指定的网络控制组,在IPv6套接字连接时执行程序。
总结起来,bpf_attach_type结构体用于定义eBPF程序的附加类型,而bpf_prog_type枚举用于定义eBPF程序的类型。这些类型和枚举提供了一种机制,可以根据具体需求将eBPF程序附加到特定的功能点或事件上,以实现对内核或网络的控制和处理。