blob: 6ec624fa7f33f69e315e4ba272c4fe7ff2ca50db [file] [log] [blame] [view]
Brendenc3c4fc12015-05-03 08:33:53 -07001# BPF Compiler Collection (BCC)
2
3This directory contains source code for BCC, a toolkit for creating small
4programs that can be dynamically loaded into a Linux kernel.
5
6The compiler relies upon eBPF (Extended Berkeley Packet Filters), which is a
7feature in Linux kernels starting from 3.19. Currently, this compiler leverages
8features which are mostly available in Linux 4.1 and above.
9
10## Motivation
11
12BPF guarantees that the programs loaded into the kernel cannot crash, and
Brenden Blanco452de202015-05-03 10:43:07 -070013cannot run forever, but yet BPF is general purpose enough to perform many
14arbitrary types of computation. Currently, it is possible to write a program in
Brendenc3c4fc12015-05-03 08:33:53 -070015C that will compile into a valid BPF program, yet it is vastly easier to
16write a C program that will compile into invalid BPF (C is like that). The user
Brenden Blanco452de202015-05-03 10:43:07 -070017won't know until trying to run the program whether it was valid or not.
Brendenc3c4fc12015-05-03 08:33:53 -070018
19With a BPF-specific frontend, one should be able to write in a language and
20receive feedback from the compiler on the validity as it pertains to a BPF
21backend. This toolkit aims to provide a frontend that can only create valid BPF
22programs while still harnessing its full flexibility.
23
Brenden Blanco46176a12015-07-07 13:05:22 -070024Furthermore, current integrations with BPF have a kludgy workflow, sometimes
25involving compiling directly in a linux kernel source tree. This toolchain aims
26to minimize the time that a developer spends getting BPF compiled, and instead
27focus on the applications that can be written and the problems that can be
28solved with BPF.
29
Brendenc3c4fc12015-05-03 08:33:53 -070030The features of this toolkit include:
31* End-to-end BPF workflow in a shared library
Brenden Blanco46176a12015-07-07 13:05:22 -070032 * A modified C language for BPF backends
Brenden Blanco452de202015-05-03 10:43:07 -070033 * Integration with llvm-bpf backend for JIT
Brendenc3c4fc12015-05-03 08:33:53 -070034 * Dynamic (un)loading of JITed programs
35 * Support for BPF kernel hooks: socket filters, tc classifiers,
36 tc actions, and kprobes
37* Bindings for Python
38* Examples for socket filters, tc classifiers, and kprobes
Brenden Blanco46176a12015-07-07 13:05:22 -070039
40In the future, more bindings besides python will likely be supported. Feel free
41to add support for the language of your choice and send a pull request!
42
43## Examples
44
45This toolchain is currently composed of two parts: a C wrapper around LLVM, and
46a Python API to interact with the running program. Later, we will go into more
47detail of how this all works.
48
49### Hello, World
50
51First, we should include the BPF class from the bpf module:
52```python
53from bpf import BPF
54```
55
56Since the C code is so short, we will embed it inside the python script.
57
58The BPF program always takes at least one argument, which is a pointer to the
59context for this type of program. Different program types have different calling
60conventions, but for this one we don't care so `void *` is fine.
61```python
62prog = """
63int hello(void *ctx) {
64 bpf_trace_printk("Hello, World!\\n");
65 return 0;
66};
67"""
68b = BPF(text=prog)
69```
70
71For this example, we will call the program every time `fork()` is called by a
72userspace process. Underneath the hood, fork translates to the `clone` syscall,
73so we will attach our program to the kernel symbol `sys_clone`.
74```python
75fn = b.load_func("hello", BPF.KPROBE)
76BPF.attach_kprobe(fn, "sys_clone")
77```
78
79The python process will then print the trace printk circular buffer until ctrl-c
80is pressed. The BPF program is removed from the kernel when the userspace
81process that loaded it closes the fd (or exits).
82```python
83from subprocess import call
84try:
85 call(["cat", "/sys/kernel/debug/tracing/trace_pipe"])
86except KeyboardInterrupt:
87 pass
88```
89
90Output:
91```
92bcc/examples$ sudo python hello_world.py
93 python-7282 [002] d... 3757.488508: : Hello, World!
94```
95
96[Source code listing](examples/hello_world.py)
97
98### Networking
99
100Walkthrough TBD, see
101[Neighbor Sharing example](examples/tc_neighbor_sharing.py) for longer
102example.
103
104### Tracing
Brendenc3c4fc12015-05-03 08:33:53 -0700105
106## Requirements
107
Brenden Blanco46176a12015-07-07 13:05:22 -0700108To get started using this toolchain in binary format, one needs:
Brendenc3c4fc12015-05-03 08:33:53 -0700109* Linux kernel 4.1 or newer, with these flags enabled:
Brenden Blanco83102912015-06-09 17:43:27 -0700110 * `CONFIG_BPF=y`
111 * `CONFIG_BPF_SYSCALL=y`
112 * `CONFIG_NET_CLS_BPF=m` [optional, for tc filters]
113 * `CONFIG_NET_ACT_BPF=m` [optional, for tc actions]
114 * `CONFIG_BPF_JIT=y`
115 * `CONFIG_HAVE_BPF_JIT=y`
116 * `CONFIG_BPF_EVENTS=y` [optional, for kprobes]
Brenden Blanco46176a12015-07-07 13:05:22 -0700117* Headers for the above kernel
118* gcc, make, python
119* python-pyroute2 (for some networking features only)
Brendenc3c4fc12015-05-03 08:33:53 -0700120
Brenden Blanco452de202015-05-03 10:43:07 -0700121## Getting started
122
Brenden Blanco46176a12015-07-07 13:05:22 -0700123As of this writing, binary packages for the above requirements are available
124in unstable formats. Both Ubuntu and Fedora have 4.2-rcX builds with the above
125flags defaulted to on. LLVM provides 3.7 Ubuntu packages (but not Fedora yet).
Brenden Blanco452de202015-05-03 10:43:07 -0700126
Brenden Blanco46176a12015-07-07 13:05:22 -0700127### Ubuntu - Docker edition
Brenden Blanco452de202015-05-03 10:43:07 -0700128
Brenden Blanco46176a12015-07-07 13:05:22 -0700129The build dependencies are captured in a [Dockerfile](Dockerfile.ubuntu), the
130output of which is a .deb for easy installation.
Brenden Blanco452de202015-05-03 10:43:07 -0700131
Brenden Blanco46176a12015-07-07 13:05:22 -0700132* Start with a recent Ubuntu install (tested with 14.04 LTS)
133* Install a [>= 4.2 kernel](http://kernel.ubuntu.com/~kernel-ppa/mainline/)
134 with headers
135* Reboot
136* Install [docker](https://docs.docker.com/installation/ubuntulinux/)
137 (`wget -qO- https://get.docker.com/ | sh`)
138* Run the Dockerfile for Ubuntu - results in an installable .deb
139 * `git clone https://github.com/iovisor/bcc; cd bcc`
140 * `docker build -t bcc -f Dockerfile.ubuntu .`
141 * `docker run --rm -v /tmp:/mnt bcc sh -c "cp /root/bcc/build/*.deb /mnt"`
142 * `sudo dpkg -i /tmp/libbcc*.deb`
143* Run the example
144 * `sudo python /usr/share/bcc/examples/hello_world.py`
Brenden Blanco452de202015-05-03 10:43:07 -0700145
Brenden Blanco46176a12015-07-07 13:05:22 -0700146### Fedora - Docker edition
Brenden Blanco452de202015-05-03 10:43:07 -0700147
Brenden Blanco46176a12015-07-07 13:05:22 -0700148The build dependencies are captured in a [Dockerfile](Dockerfile.fedora), the
149output of which is a .rpm for easy installation. This version takes longer since
150LLVM needs to be compiled from source.
Brenden Blanco452de202015-05-03 10:43:07 -0700151
Brenden Blanco46176a12015-07-07 13:05:22 -0700152* Start with a recent Fedora install (tested with F22)
153* Install a [>= 4.2 kernel](http://alt.fedoraproject.org/pub/alt/rawhide-kernel-nodebug/x86_64/)
154 with headers
155* Reboot
156* Install [docker](https://docs.docker.com/installation/fedora/)
157* Run the Dockerfile for Fedora - results in an installable .rpm
158 * `git clone https://github.com/iovisor/bcc; cd bcc`
159 * `docker build -t bcc -f Dockerfile.fedora .`
160 * `docker run --rm -v /tmp:/mnt bcc sh -c "cp /root/bcc/build/*.rpm /mnt"`
161 * `sudo rpm -ivh /tmp/libbcc*.rpm`
162* Run the example
163 * `sudo python /usr/share/bcc/examples/hello_world.py`
Brenden Blanco83102912015-06-09 17:43:27 -0700164
Brenden Blanco46176a12015-07-07 13:05:22 -0700165### Ubuntu - From source
Brenden Blanco83102912015-06-09 17:43:27 -0700166
Brenden Blanco46176a12015-07-07 13:05:22 -0700167To build the toolchain from source, one needs:
168* LLVM 3.7 or newer, compiled with BPF support (default=on)
169* Clang 3.7, built from the same tree as LLVM
170* cmake, gcc (>=4.7), flex, bison
Brenden Blanco452de202015-05-03 10:43:07 -0700171
Brenden Blanco46176a12015-07-07 13:05:22 -0700172* Add the [LLVM binary repo](http://llvm.org/apt/) to your apt sources
Brenden Blanco34aafe92015-07-07 13:10:21 -0700173 * `echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty main" | sudo tee /etc/apt/sources.list.d/llvm.list`
Brenden Blanco46176a12015-07-07 13:05:22 -0700174 * `wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -`
175 * `sudo apt-get update`
176* Install build dependencies
Brenden Blanco34aafe92015-07-07 13:10:21 -0700177 * `sudo apt-get -y install bison build-essential cmake flex git libedit-dev python zlib1g-dev`
Brenden Blanco46176a12015-07-07 13:05:22 -0700178* Install LLVM and Clang development libs
179 * `sudo apt-get -y install libllvm3.7 llvm-3.7-dev libclang-3.7-dev`
180* Install and compile BCC
181 * `git clone https://github.com/iovisor/bcc.git`
182 * `mkdir bcc/build; cd bcc/build`
183 * `cmake .. -DCMAKE_INSTALL_PREFIX=/usr`
184 * `make -j$(grep -c ^process /proc/cpuinfo)`
185 * `sudo make install`
Brenden Blanco452de202015-05-03 10:43:07 -0700186
Brendenc3c4fc12015-05-03 08:33:53 -0700187## Release notes
188
189* 0.1
190 * Initial commit