Skip to content

Commit

Permalink
Add socket-tracer
Browse files Browse the repository at this point in the history
Signed-off-by: Tomoki Sugiura <[email protected]>
  • Loading branch information
chez-shanpu committed Jan 15, 2024
1 parent 422cfa3 commit a397685
Show file tree
Hide file tree
Showing 16 changed files with 592 additions and 0 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
24 changes: 24 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: main
on:
pull_request:
push:
branches:
- 'main'
jobs:
build:
name: Build Container Image
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
push: false
tags: ghcr.io/cybozu-go/neco-bpftools:dev
50 changes: 50 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: release
on:
push:
tags:
- 'v*'
jobs:
image:
name: Push container image
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set Tag
id: set-tag
run: echo "RELEASE_TAG=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT # Remove "v" prefix.
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/cybozu-go/neco-bpftools:${{ steps.set-tag.output.RELEASE_TAG }}
release:
name: Release on GitHub
needs: image
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
See [CHANGELOG.md](./CHANGELOG.md) for details.
draft: false
prerelease: ${{ contains(github.ref, '-') }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ go.work
### Custom
.idea
*.o
bin/
**/vmlinux.h
**/*bpfeb.go
**/*bpfel.go
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Change Log

All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]


[Unreleased]: https://github.com/cybozu-go/neco-bpftools/compare/6082b8a847fef66103a84bde4a051c1870710970...HEAD
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM ghcr.io/cybozu/golang:1.21-jammy AS build

COPY . /work/neco-bpftools
WORKDIR /work/neco-bpftools

RUN apt-get update -y && \
apt-get install -y llvm clang libbpf-dev

RUN make build

FROM ghcr.io/cybozu/ubuntu:22.04
LABEL org.opencontainers.image.source="https://github.com/cybozu-go/neco-bpftools"

COPY --from=build /work/neco-bpftools/bin/* /usr/local/bin
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
BPFTOOL := /usr/local/bin/bpftool

.PHONY: build
build: bpftool
$(MAKE) -C socket-tracer build

.PHONY: bpftool
bpftool: $(BPFTOOL)
$(BPFTOOL):
git clone --recurse-submodules https://github.com/libbpf/bpftool.git
cd bpftool && \
git submodule update --init && \
cd src && \
$(MAKE) && \
$(SUDO) $(MAKE) install
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Neco-bpftools

Neco-bpftools contains utility tools using eBPF.

## Available tools

### socket-tracer

Socket-tracer traces `socket` system call by specified socket family.
Please see [socket(2)](https://man7.org/linux/man-pages/man2/socket.2.html).

```console
$ socket-tracer -h
trace socket syscall

Usage:
socket-tracer [flags]

Flags:
-f, --family man socket Family value for socket system call. See man socket. Accepts AF_* or number
-h, --help help for socket-tracer
```

## License

Neco-bpftools licensed under GNU General Public License, Version 2.
76 changes: 76 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
Release procedure
=================

This document describes how to release a new version.

## Versioning

Follow [semantic versioning 2.0.0][semver] to choose the new version number.

## Prepare change log entries

Add notable changes since the last release to [CHANGELOG.md](CHANGELOG.md).
It should look like:

```markdown
(snip)
## [Unreleased]

### Added
- Implement ... (#35)

### Changed
- Fix a bug in ... (#33)

### Removed
- Deprecated `-option` is removed ... (#39)

(snip)
```

## Bump version

1. Determine a new version number. Then set `VERSION` variable.

```console
# Set VERSION and confirm it. It should not have "v" prefix.
$ VERSION=x.y.z
$ echo $VERSION
```

2. Make a branch to release

```console
$ git neco dev "bump-$VERSION"
```

3. Edit `CHANGELOG.md` for the new version ([example][]).
4. Commit the change and push it.

```console
$ git commit -a -m "Bump version to $VERSION"
$ git neco review
```

5. Merge this branch.
6. Add a git tag to the main HEAD, then push it.

```console
# Set VERSION again.
$ VERSION=x.y.z
$ echo $VERSION

$ git checkout main
$ git pull
$ git tag -a -m "Release v$VERSION" "v$VERSION"

# Make sure the release tag exists.
$ git tag -ln | grep $VERSION

$ git push origin "v$VERSION"
```

GitHub actions will build and push artifacts such as container images and
create a new GitHub release.

[semver]: https://semver.org/spec/v2.0.0.html
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/cybozu-go/neco-bpftools

go 1.21.4

require (
github.com/cilium/ebpf v0.12.3
github.com/spf13/cobra v1.8.0
golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c
)

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect
)
26 changes: 26 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
github.com/cilium/ebpf v0.12.3 h1:8ht6F9MquybnY97at+VDZb3eQQr8ev79RueWeVaEcG4=
github.com/cilium/ebpf v0.12.3/go.mod h1:TctK1ivibvI3znr66ljgi4hqOT8EYQjz1KWBfb1UVgM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c h1:3kC/TjQ+xzIblQv39bCOyRk8fbEeJcDHwbyxPUU2BpA=
golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
22 changes: 22 additions & 0 deletions socket-tracer/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PROJECT := socket-tracer

BIN_DIR := ../bin
HEADER_DIR := ./bpf/include
VMLINUX := $(HEADER_DIR)/vmlinux.h

.PHONY: build
build: vmlinux
go generate ./...
CGO_ENABLED=0 go build -o -ldflags="-w -s" -o $(BIN_DIR)/$(PROJECT)

.PHONY: clean
clean:
rm $(BIN_DIR)/$(PROJECT)
go clean


.PHONY: vmlinux
vmlinux: $(VMLINUX)
$(VMLINUX):
mkdir -p $(HEADER_DIR)
bpftool btf dump file /sys/kernel/btf/vmlinux format c > $(VMLINUX)
69 changes: 69 additions & 0 deletions socket-tracer/bpf/trace_enter_socket.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//go:build ignore

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

#define TASK_COMM_LEN 16

char __license[] SEC("license") = "Dual MIT/GPL";

struct bpf_map_def SEC("maps") event_rb = {
.type = BPF_MAP_TYPE_RINGBUF,
.max_entries = 256 * 1024,
};

struct bpf_map_def SEC("maps") target_family = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(u32),
.value_size = sizeof(u32),
.max_entries = 1,
};

// ref /sys/kernel/debug/tracing/events/syscalls/sys_enter_socket/format
struct enter_socket_ctx {
/* The first 8 bytes is not allowed to read */
unsigned long pad;

int __syscall_nr;
u64 family;
u64 type;
u64 protocol;
};

struct event {
u32 pid;
u8 comm[TASK_COMM_LEN];
};

// Force emitting struct event into the ELF.
const struct event *unused __attribute__((unused));

SEC("tracepoint/syscalls/sys_enter_socket")
int trace_enter_socket(struct enter_socket_ctx *ctx) {
int zero = 0;

int *valp;
valp = bpf_map_lookup_elem(&target_family, &zero);
if (!valp) {
return 0;
}

if (ctx->family != *valp) {
return 0;
}

struct event *e;
e = bpf_ringbuf_reserve(&event_rb, sizeof(struct event), 0);
if (!e) {
return 0;
}
u64 res;
u64 id = bpf_get_current_pid_tgid();

e->pid = (u32)(id >> 32);
res = bpf_get_current_comm(&e->comm, sizeof(e->comm));

bpf_ringbuf_submit(e, 0);

return 0;
}
Loading

0 comments on commit a397685

Please sign in to comment.