Skip to content

Commit

Permalink
add tcp ping based on ebpf (linuxkerneltravel#356)
Browse files Browse the repository at this point in the history
* add tcp ping based on ebpf

* add ci for ebp tcp ping
  • Loading branch information
IfanTsai authored Sep 21, 2022
1 parent b3a961d commit 1dc1777
Show file tree
Hide file tree
Showing 107 changed files with 28,332 additions and 1 deletion.
69 changes: 69 additions & 0 deletions .github/workflows/ebpf_tcp_ping.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Test for ebpf_tcp_ping build and run

on:
push:
branches: [ "*" ]
paths:
- 'eBPF_Supermarket/eBPF_TCP_Ping/**'
- '.github/workflows/ebpf_tcp_ping.yml'
pull_request:
branches: [ "*" ]
paths:
- 'eBPF_Supermarket/eBPF_TCP_Ping/**'
- '.github/workflows/ebpf_tcp_ping.yml'

jobs:
run-test:
name: Build and run
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16

- name: Install build dependencies
run: |
sudo apt update
sudo apt install -y bison build-essential flex curl libedit-dev \
libllvm12 llvm-12-dev libclang-12-dev python python3 python3-distutils zlib1g-dev libelf-dev libfl-dev \
bpfcc-tools linux-headers-$(uname -r) libelf-dev libpcap-dev gcc-multilib build-essential
sudo ln -sf /usr/bin/llc-12 /usr/bin/llc
- name: Cache bcc
id: cache-bcc
uses: actions/cache@v3
with:
path: bcc
key: ${{ runner.os }}-bcc-0.24.0

- name: Build bcc
if: steps.cache-bcc.outputs.cache-hit != 'true'
run: |
git clone -b v0.24.0 https://github.com/iovisor/bcc.git
export LLVM_ROOT="/usr/lib/llvm-12"
mkdir bcc/build; cd bcc/build
cmake ..
make -j2
- name: Install bcc
run: |
cd bcc/build
sudo make install
- name: Compile and install xdp
run: |
cd eBPF_Supermarket/eBPF_TCP_Ping
make && sudo make install
- name: Test run ebpf ping
run: |
cd eBPF_Supermarket/eBPF_TCP_Ping
go build -o tcp_ping tcp_ping.go
# help
./tcp_ping -h
# sudo ./telescope 127.0.0.1
sudo timeout -s SIGINT 20 ./tcp_ping 127.0.0.1 || pwd
2 changes: 1 addition & 1 deletion eBPF_Supermarket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ eBPF工具集散地
| | Filesystem_Subsystem | | |
| | LSM_BPF | | |
| | Memory_Subsystem | | |
| |
| 基于 eBPF 和 XDP 的 tcp ping |eBPF_TCP_Ping|基于 eBPF 的 tcp ping,通过 kprobe 在内核态计算 RTT。并提供 XDP 来加速回包|[@IfanTsai](https://github.com/IfanTSai)|

59 changes: 59 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Prerequisites
*.d

# Object files
*.o
*.ko
*.obj
*.elf

# Linker output
*.ilk
*.map
*.exp

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo

# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

# Debug files
*.dSYM/
*.su
*.idb
*.pdb

# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
!go.mod

*.ll
cscope*
tags

ping
29 changes: 29 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.PHONY: all clean install uninstall

CLANG ?= clang
LLC ?= llc
NIC ?= eth0
XDP_OBJ := xdp_ping.o
XDP_SEC ?= xdp-ping

INCLUDES ?= -I./include -I./lib -I./
CLANG_FLAGS ?= -D__NR_CPUS__=4 -O2 -target bpf -nostdinc -emit-llvm
CLANF_FLAGS += -Wall -Wextra -Wshadow -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-gnu-variable-sized-type-not-at-end -Wdeclaration-after-statement
LLC_FLAGS ?= -march=bpf -mcpu=probe -mattr=dwarfris -filetype=obj

all: $(XDP_OBJ)

$(XDP_OBJ): %.o: %.ll
$(LLC) $(LLC_FLAGS) -o $@ $^

%.ll: %.c
$(CLANG) $(INCLUDES) $(CLANG_FLAGS) -c $^ -o $@

clean:
-rm -rf *.ll *.o

install: $(XDP_OBJ)
sudo ip -force link set dev $(NIC) xdpgeneric obj $^ sec $(XDP_SEC)

uninstall:
sudo ip link set dev $(NIC) xdpgeneric off
49 changes: 49 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[中文](./README_CN.md)

# eBPF-TCP-Ping

## Introduction

TCP ping command tool based on ebpf, using kprobe to calculate RTT in the kernel space rather than user space. In addition, we can speed up the packet return through XDP.

- tcp_ping.go: TCP ping command tool, it can send a TCP SYN packet to other server, and use the eBPF to hook kernel tcp status function to calculate RTT.

- xdp_ping.c: XDP program, it will be loaded to kernel or NIC. Before SYN packet enter the kernel protocol stack, it can rewrite the packet into RST and return the original way.

## Quick Start
### load XDP program to NIC

**The loading of XDP is optional and is only used to speed up the packet return. You can choose to use the return packet that comes with the kernel instead of XDP.**

Please check your NIC in Makefile

```Makefile
NIC ?= eth0
```

install or uninstall XDP program
```
make
sudo make install
sudo make uninstall
```

### ping other server

help

```
➜ sudo go run tcp_ping.go -h
tcp_ping version: 0.0.1
Usage: tcp_ping 172.217.194.106 [-d 500] [-c 100] [-s]
Options:
-c Number
Number connections to keep ping (default 1)
-d duration
Ping duration ms (default 1000)
-h Show help
-s Do not show information of each ping
```

The tool detects port 65532, noted that port 65532 of other server needs to be opened
50 changes: 50 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[English](./README.md)

# eBPF-TCP-Ping

## 介绍

基于 ebpf 的 tcp ping 命令行工具,通过 kprobe 来在内核态而非用户态计算 RTT。并且可使用 XDP 做回包的加速

- tcp_ping.go: TCP ping 命令行工具,它会发送 TCP SYN 包给指定的服务器,并且使用 eBPF 去 hook 内核 TCP 状态转换的函数来计算 RTT

- xdp_ping.c: XDP 程序, 将会被加载到内核或网卡中。在 TCP SYN 包进入内核协议栈之前,它会原地修改数据包为 RST 后原路返回


## 快速开始

### 加载 XDP 程序到 NIC

**XDP 的加载是可选的,仅仅只是用于加速回包。可以选择使用 kernel 自带的回包而不是 XDP**

请检查 Makefile 中的 NIC 变量
```Makefile
NIC ?= eth0
```

安装和卸载 XDP 程序
```
make
sudo make install
sudo make uninstall
```

### ping 其他服务器

帮助命令

```
➜ sudo go run tcp_ping.go -h
tcp_ping version: 0.0.1
Usage: tcp_ping 172.217.194.106 [-d 500] [-c 100] [-s]
Options:
-c Number
Number connections to keep ping (default 1)
-d duration
Ping duration ms (default 1000)
-h Show help
-s Do not show information of each ping
```

该工具探测的是 65532 端口,所以务必注意被 ping 的服务器需要开放 65532 端口
5 changes: 5 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module ping

go 1.16

require github.com/iovisor/gobpf v0.2.0
2 changes: 2 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/iovisor/gobpf v0.2.0 h1:34xkQxft+35GagXBk3n23eqhm0v7q0ejeVirb8sqEOQ=
github.com/iovisor/gobpf v0.2.0/go.mod h1:WSY9Jj5RhdgC3ci1QaacvbFdQ8cbrEjrpiZbLHLt2s4=
37 changes: 37 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/include/bpf/access.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2020 Authors of Cilium */

#ifndef __BPF_ACCESS_H_
#define __BPF_ACCESS_H_

#include "compiler.h"

#if !defined(__non_bpf_context) && defined(__bpf__)
static __always_inline __maybe_unused __u16
map_array_get_16(const __u16 *array, __u32 index, const __u32 limit)
{
__u16 datum = 0;

if (__builtin_constant_p(index) ||
!__builtin_constant_p(limit))
__throw_build_bug();

/* LLVM tends to optimize code away that is needed for the verifier to
* understand dynamic map access. Input constraint is that index < limit
* for this util function, so we never fail here, and returned datum is
* always valid.
*/
asm volatile("%[index] <<= 1\n\t"
"if %[index] > %[limit] goto +1\n\t"
"%[array] += %[index]\n\t"
"%[datum] = *(u16 *)(%[array] + 0)\n\t"
: [datum]"=r"(datum)
: [limit]"i"(limit), [array]"r"(array), [index]"r"(index)
: /* no clobbers */ );

return datum;
}
#else
# define map_array_get_16(array, index, limit) __throw_build_bug()
#endif /* !__non_bpf_context && __bpf__ */
#endif /* __BPF_ACCESS_H_ */
22 changes: 22 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/include/bpf/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2016-2020 Authors of Cilium */

#ifndef __BPF_API__
#define __BPF_API__

#include <linux/types.h>
#include <linux/byteorder.h>
#include <linux/bpf.h>
#include <linux/if_packet.h>

#include "compiler.h"
#include "section.h"
#include "helpers.h"
#include "builtins.h"
#include "tailcall.h"
#include "errno.h"
#include "loader.h"
#include "csum.h"
#include "access.h"

#endif /* __BPF_API__ */
10 changes: 10 additions & 0 deletions eBPF_Supermarket/eBPF_TCP_Ping/include/bpf/bpf_features.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2016-2020 Authors of Cilium */
#ifndef BPF_FEATURES_H_
#define BPF_FEATURES_H_

#define HAVE_PROG_TYPE_HELPER(prog_type, helper) \
BPF__PROG_TYPE_ ## prog_type ## __HELPER_ ## helper
#define BPF__PROG_TYPE_sched_cls__HELPER_bpf_skb_change_tail 1

#endif /* BPF_FEATURES_H_ */
Loading

0 comments on commit 1dc1777

Please sign in to comment.