eBPF 程序使用 C 语言的一个子集(restricted C)编写,然后通过 LLVM 编译成字节码注入到 内核执行。bcc是 eBPF 的一个外围工具集,使得 “编 写 BPF 代码-编译成字节码-注入内核-获取结果-展示” 整个过程更加便捷。

下面我们将搭建一个基础环境,通过几个例子展示如何编写 bcc/eBPF 程序,感受它们的强大功能。

准备工作

环境需要以下几方面满足要求:内核、docker、bcc。

内核版本

eBPF 需要较新的 Linux kernel 支持。 因此首先要确保你的内核版本足够新,至少要在 4.1 以上,最好在 4.10 以上:

1
2
$ uname -r
4.10.13-1.el7.elrepo.x86_64

阅读更多

前言

虽然 Linux 内核很早就已经支持了 eBPF,但很多新特性都是在 4.x 版本中逐步增加的。所以,想要稳定运行 eBPF 程序,内核至少需要 4.9 或者更新的版本。而在开发和学习 eBPF 时,为了体验和掌握最新的 eBPF 特性,我推荐使用更新的 5.x 内核。

作为 eBPF 最重大的改进之一,一次编译到处执行(简称 CO-RE)解决了内核数据结构在不同版本差异导致的兼容性问题。不过,在使用 CO-RE 之前,内核需要开启 CONFIG_DEBUG_INFO_BTF=yCONFIG_DEBUG_INFO=y 这两个编译选项。为了避免你在首次学习 eBPF 时就去重新编译内核,我推荐使用已经默认开启这些编译选项的发行版,作为你的开发环境,比如:

  • Ubuntu 20.10+
  • Fedora 31+
  • RHEL 8.2+
  • Debian 11+

阅读更多

主要介绍wireshark中的length计算方法,主要涉及MTU、MSS、常见协议头大小。

length含义

Wireshark is showing you the length of the Ethernet frame that is handed to it, which may or may not include the FCS.

wireshark显示的长度为以太网帧的长度,不包括FCS(Frame check sequence)[帧校验序列]

阅读更多

前言

网上关于 net.ipv4.ip_local_port_range 的值的效果众说纷纭(下面所说的连接都假定使用的是相同的协议(都是 TCP 或 UDP)):

  • 大部分文章都说这个值决定了客户端的一个 ip 可用的端口数量,即一个 ip 最多只能创建 60K 多一点的连接(1025-65535),如果要突破这个限制需要客户端机器绑定多个 ip。
  • 还有部分文章说的是这个值决定的是 socket 四元组中的本地端口数量,即一个 ip 对同一个目标 ip+port 最多可以创建 60K 多一点连接,只要目标 ip 或端口不一样就可以使用相同的本地端口,不一定需要多个客户端 ip 就可以突破端口数量限制。

阅读更多

用户态与内核态交互通信的方法不止一种,sockopt是比较方便的一个,写法也简单.

缺点就是使用 copy_from_user()/copy_to_user()完成内核和用户的通信, 效率其实不高, 多用在传递控制 选项 信息,不适合做大量的数据传输。

用户态函数:

  • 发送:int setsockopt ( int sockfd, int proto, int cmd, void *data, int datelen);
  • 接收:int getsockopt(int sockfd, int proto, int cmd, void *data, int datalen)
    • 第一个参数是socket描述符;
    • 第二个参数proto是sock协议,IP RAW的就用SOL_SOCKET/SOL_IP等,TCP/UDP socket的可用SOL_SOCKET/SOL_IP/SOL_TCP/SOL_UDP等,即高层的socket是都可以使用低层socket的命令字 的,IPPROTO_IP;
    • 第三个参数cmd是操作命令字,由自己定义;
    • 第四个参数是数据缓冲区起始位置指针,set操作时是将缓冲区数据写入内核,get的时候是将内核中的数 据读入该缓冲区;
    • 第五个参数数据长度

阅读更多