Commit 83102918 authored by Brenden Blanco's avatar Brenden Blanco

Make installation prefixes more realistic

* Add/document cmake variables that control various installation path
  options. See README.md for examples.
* Updated README a bit
* Hide helpers.h from include requirements
* Install things to real paths in a proper way. Header files will go
  into <prefix>/share/bcc/include.
* Move the kickstart script readme to its own directory.
Signed-off-by: default avatarBrenden Blanco <bblanco@plumgrid.com>
parent c765d244
......@@ -29,6 +29,9 @@ find_library(libclangParse NAMES clangParse HINTS ${CLANG_SEARCH})
find_library(libclangRewrite NAMES clangRewrite HINTS ${CLANG_SEARCH})
find_library(libclangSema NAMES clangSema HINTS ${CLANG_SEARCH})
find_library(libclangSerialization NAMES clangSerialization HINTS ${CLANG_SEARCH})
if(libclangBasic STREQUAL "libclangBasic-NOTFOUND")
message(FATAL_ERROR "Unable to find clang libraries")
endif()
set(CMAKE_C_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall")
......
......@@ -36,89 +36,69 @@ The features of this toolkit include:
To get started using this toolchain, one needs:
* Linux kernel 4.1 or newer, with these flags enabled:
* CONFIG_BPF=y
* CONFIG_BPF_SYSCALL=y
* CONFIG_NET_CLS_BPF=m [optional, for tc filters]
* CONFIG_NET_ACT_BPF=m [optional, for tc actions]
* CONFIG_BPF_JIT=y
* CONFIG_HAVE_BPF_JIT=y
* CONFIG_BPF_EVENTS=y [optional, for kprobes]
* `CONFIG_BPF=y`
* `CONFIG_BPF_SYSCALL=y`
* `CONFIG_NET_CLS_BPF=m` [optional, for tc filters]
* `CONFIG_NET_ACT_BPF=m` [optional, for tc actions]
* `CONFIG_BPF_JIT=y`
* `CONFIG_HAVE_BPF_JIT=y`
* `CONFIG_BPF_EVENTS=y` [optional, for kprobes]
* LLVM 3.7 or newer, compiled with BPF support (currently experimental)
* Clang 3.5 or newer (this requirement is orthoganal to the LLVM requirement,
and the versions do not necessarily need to match)
* cmake, gcc-4.9, flex, bison, xxd, libstdc++-static, libmnl-devel
* Clang 3.7, built from the same tree as LLVM
* pyroute2, version X.X (currently master, tag TBD) or newer
* cmake, gcc-4.7, flex, bison
## Getting started
Included in the scripts/ directory of this project is a VM kickstart script that
captures the above requirements inside a Fedora VM. Before running the script,
ensure that virt-install is available on the system.
### Demo VM
`./build_bpf_demo.sh -n bpf-demo -k bpf_demo.ks.erb`
See https://github.com/iovisor/bcc/scripts/README.md for a script that can
be used to set up a libvirt VM with the required dependencies.
After setting up the initial VM, log in (the default password is 'iovisor')
and determine the DHCP IP. SSH to this IP as root.
### Quick Setup
To set up a kernel with the right options, run `bpf-kernel-setup`.
If the LLVM and Linux kernel requirements are satisfied, testing out this
package should be as simple as:
```
[root@bpf-demo ~]# bpf-kernel-setup
Cloning into 'net-next'...
git clone https://github.com/iovisor/bcc.git
cd bcc; mkdir build; cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH=/opt/local/llvm
make -j$(grep -c ^processor /proc/cpuinfo)
sudo make install
cd ../../
sudo python examples/hello_world.py
<ctrl-C>
```
After pulling the net-next branch, the kernel config menu should pop up. Ensure
that the below settings are proper.
```
General setup --->
[*] Enable bpf() system call
Networking support --->
Networking options --->
QoS and/or fair queueing --->
<M> BPF-based classifier
<M> BPF based action
[*] enable BPF Just In Time compiler
```
Once the .config is saved, the build will proceed and install the resulting
kernel. This kernel has updated userspace headers (e.g. the bpf() syscall) which
install into /usr/local/include...proper packaging for this will be
distro-dependent.
Next, run `bpf-llvm-setup` to pull and compile LLVM with BPF support enabled.
```
[root@bpf-demo ~]# bpf-llvm-setup
Cloning into 'llvm'...
```
The resulting libraries will be installed into /opt/local/llvm.
Change `CMAKE_PREFIX_PATH` if llvm is installed elsewhere.
### Cleaning up
Since packaging is currently not available, one can cleanup the collateral of
bcc by doing:
Next, reboot into the new kernel, either manually or by using the kexec helper.
```
[root@bpf-demo ~]# kexec-4.1.0-rc1+
Connection to 192.168.122.247 closed by remote host.
Connection to 192.168.122.247 closed.
sudo rm -rf /usr/{lib/libbpf.prog.so,include/bcc,share/bcc}
sudo pip uninstall bpf
```
Reconnect and run the final step, building and testing bcc.
### Building LLVM
See http://llvm.org/docs/GettingStarted.html for the full guide.
The short version:
```
[root@bpf-demo ~]# bcc-setup
Cloning into 'bcc'...
...
Linking CXX shared library libbpfprog.so
[100%] Built target bpfprog
...
Running tests...
Test project /root/bcc/build
Start 1: py_test1
1/4 Test #1: py_test1 ......................... Passed 0.24 sec
Start 2: py_test2
2/4 Test #2: py_test2 ......................... Passed 0.53 sec
Start 3: py_trace1
3/4 Test #3: py_trace1 ........................ Passed 0.09 sec
Start 4: py_trace2
4/4 Test #4: py_trace2 ........................ Passed 1.06 sec
100% tests passed, 0 tests failed out of 4
git clone https://github.com/llvm-mirror/llvm.git llvm
git clone https://github.com/llvm-mirror/clang.git llvm/tools/clang
mkdir llvm/build/
cd llvm/build/
cmake .. -DCMAKE_INSTALL_PREFIX=/opt/local/llvm
make -j$(grep -c ^processor /proc/cpuinfo)
sudo make install
```
## Release notes
* 0.1
......
......@@ -9,7 +9,6 @@ from bpf import BPF
from subprocess import call
prog = """
#include "src/cc/bpf_helpers.h"
BPF_EXPORT(hello)
int hello(void *ctx) {
char fmt[] = "Hello, World!\\n";
......
## Fedora Demo VM
Before running the script, ensure that virt-install is available on the system.
`./build_bpf_demo.sh -n bpf-demo -k bpf_demo.ks.erb`
After setting up the initial VM, log in (the default password is 'iovisor')
and determine the DHCP IP. SSH to this IP as root.
To set up a kernel with the right options, run `bpf-kernel-setup`.
```
[root@bpf-demo ~]# bpf-kernel-setup
Cloning into 'net-next'...
```
After pulling the net-next branch, the kernel config menu should pop up. Ensure
that the below settings are proper.
```
General setup --->
[*] Enable bpf() system call
Networking support --->
Networking options --->
QoS and/or fair queueing --->
<M> BPF-based classifier
<M> BPF based action
[*] enable BPF Just In Time compiler
```
Once the .config is saved, the build will proceed and install the resulting
kernel. This kernel has updated userspace headers (e.g. the bpf() syscall) which
install into /usr/local/include...proper packaging for this will be
distro-dependent.
Next, run `bpf-llvm-setup` to pull and compile LLVM with BPF support enabled.
```
[root@bpf-demo ~]# bpf-llvm-setup
Cloning into 'llvm'...
```
The resulting libraries will be installed into /opt/local/llvm.
Next, reboot into the new kernel, either manually or by using the kexec helper.
```
[root@bpf-demo ~]# kexec-4.1.0-rc1+
Connection to 192.168.122.247 closed by remote host.
Connection to 192.168.122.247 closed.
```
Reconnect and run the final step, building and testing bcc.
```
[root@bpf-demo ~]# bcc-setup
Cloning into 'bcc'...
...
Linking CXX shared library libbpfprog.so
[100%] Built target bpfprog
...
Running tests...
Test project /root/bcc/build
Start 1: py_test1
1/4 Test #1: py_test1 ......................... Passed 0.24 sec
Start 2: py_test2
2/4 Test #2: py_test2 ......................... Passed 0.53 sec
Start 3: py_trace1
3/4 Test #3: py_trace1 ........................ Passed 0.09 sec
Start 4: py_trace2
4/4 Test #4: py_trace2 ........................ Passed 1.06 sec
100% tests passed, 0 tests failed out of 4
```
......@@ -85,6 +85,7 @@ set -e -x
numcpu=$(grep -c ^processor /proc/cpuinfo)
git clone https://github.com/llvm-mirror/llvm.git
git clone https://github.com/llvm-mirror/clang.git llvm/tools/clang
mkdir llvm/build/
cd llvm/build/
......@@ -93,7 +94,6 @@ cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_TERMINFO=OFF \
-DLLVM_TARGETS_TO_BUILD="ARM;CppBackend;X86;BPF" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=BPF \
-DCMAKE_INSTALL_PREFIX=/opt/local/llvm
make -j$numcpu
......
......@@ -9,10 +9,20 @@ BISON_TARGET(Parser parser.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.yy.cc COMPILE_F
FLEX_TARGET(Lexer lexer.ll ${CMAKE_CURRENT_BINARY_DIR}/lexer.ll.cc COMPILE_FLAGS "--c++ --o lexer.ll.cc")
ADD_FLEX_BISON_DEPENDENCY(Lexer Parser)
# if gcc 4.9 or higher is used, static libstdc++ is a good option
#set(CMAKE_SHARED_LINKER_FLAGS "-static-libstdc++ -Wl,--exclude-libs=ALL")
# prune unused llvm static library stuff when linking into the new .so
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--exclude-libs=ALL")
# if gcc 4.9 or higher is used, static libstdc++ is a good option
if (CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++")
endif()
endif()
# tell the shared library where it is being installed so it can find shared header files
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBCC_INSTALL_PREFIX='\"${CMAKE_INSTALL_PREFIX}\"'")
add_library(bpfprog SHARED bpf_common.cc bpf_module.cc codegen_llvm.cc
node.cc parser.cc printer.cc type_check.cc libbpf.c b_frontend_action.cc
kbuild_helper.cc
......@@ -30,3 +40,5 @@ set(clang_libs ${libclangFrontend} ${libclangSerialization} ${libclangDriver} ${
target_link_libraries(bpfprog ${clang_libs} ${llvm_libs} LLVMBPFCodeGen)
install(TARGETS bpfprog LIBRARY DESTINATION lib)
install(DIRECTORY export/ DESTINATION share/bcc/include/bcc
FILES_MATCHING PATTERN "*.h")
......@@ -151,6 +151,10 @@ int BPFModule::load_file_module(unique_ptr<llvm::Module> *mod, const string &fil
vector<string> kflags;
if (kbuild_helper.get_flags(un.release, &kflags))
return -1;
kflags.push_back("-include");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h");
kflags.push_back("-I");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include");
for (auto it = kflags.begin(); it != kflags.end(); ++it)
flags_cstr.push_back(it->c_str());
......@@ -329,8 +333,7 @@ int BPFModule::parse() {
return -1;
}
// TODO: clean this
if (load_includes("../../src/cc/bpf_helpers.h") < 0)
if (load_includes(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h") < 0)
return -1;
codegen_ = ebpf::make_unique<ebpf::cc::CodegenLLVM>(mod_, parser_->scopes_.get(), proto_parser_->scopes_.get());
......
......@@ -13,73 +13,72 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <linux/types.h>
struct ethernet_t {
u64 dst:48;
u64 src:48;
u32 type:16;
unsigned long long dst:48;
unsigned long long src:48;
unsigned int type:16;
} __attribute__((packed));
struct dot1q_t {
u16 pri:3;
u16 cfi:1;
u16 vlanid:12;
u16 type;
unsigned short pri:3;
unsigned short cfi:1;
unsigned short vlanid:12;
unsigned short type;
} __attribute__((packed));
struct arp_t {
u16 htype;
u16 ptype;
u8 hlen;
u8 plen;
u16 oper;
u64 sha:48;
u64 spa:32;
u64 tha:48;
u32 tpa;
unsigned short htype;
unsigned short ptype;
unsigned char hlen;
unsigned char plen;
unsigned short oper;
unsigned long long sha:48;
unsigned long long spa:32;
unsigned long long tha:48;
unsigned int tpa;
} __attribute__((packed));
struct ip_t {
u8 ver:4; // byte 0
u8 hlen:4;
u8 tos;
u16 tlen;
u16 identification; // byte 4
u16 ffo_unused:1;
u16 df:1;
u16 mf:1;
u16 foffset:13;
u8 ttl; // byte 8
u8 nextp;
u16 hchecksum;
u32 src; // byte 12
u32 dst; // byte 16
unsigned char ver:4; // byte 0
unsigned char hlen:4;
unsigned char tos;
unsigned short tlen;
unsigned short identification; // byte 4
unsigned short ffo_unused:1;
unsigned short df:1;
unsigned short mf:1;
unsigned short foffset:13;
unsigned char ttl; // byte 8
unsigned char nextp;
unsigned short hchecksum;
unsigned int src; // byte 12
unsigned int dst; // byte 16
} __attribute__((packed));
struct udp_t {
u16 sport;
u16 dport;
u16 length;
u16 crc;
unsigned short sport;
unsigned short dport;
unsigned short length;
unsigned short crc;
} __attribute__((packed));
struct tcp_t {
u16 src_port; // byte 0
u16 dst_port;
u32 seq_num; // byte 4
u32 ack_num; // byte 8
u8 offset:4; // byte 12
u8 reserved:4;
u8 flag_cwr:1;
u8 flag_ece:1;
u8 flag_urg:1;
u8 flag_ack:1;
u8 flag_psh:1;
u8 flag_rst:1;
u8 flag_syn:1;
u8 flag_fin:1;
u16 rcv_wnd;
u16 cksum; // byte 16
u16 urg_ptr;
unsigned short src_port; // byte 0
unsigned short dst_port;
unsigned int seq_num; // byte 4
unsigned int ack_num; // byte 8
unsigned char offset:4; // byte 12
unsigned char reserved:4;
unsigned char flag_cwr:1;
unsigned char flag_ece:1;
unsigned char flag_urg:1;
unsigned char flag_ack:1;
unsigned char flag_psh:1;
unsigned char flag_rst:1;
unsigned char flag_syn:1;
unsigned char flag_fin:1;
unsigned short rcv_wnd;
unsigned short cksum; // byte 16
unsigned short urg_ptr;
} __attribute__((packed));
......@@ -7,13 +7,14 @@ endmacro()
symlink_file(${CMAKE_CURRENT_SOURCE_DIR}/bpf ${CMAKE_CURRENT_BINARY_DIR}/bpf)
set(PIP_INSTALLABLE "${CMAKE_CURRENT_BINARY_DIR}/dist/bpf-${REVISION}.tar.gz")
configure_file(setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py @ONLY)
# build the pip installable
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dist/bpf-${REVISION}.tar.gz
add_custom_command(OUTPUT ${PIP_INSTALLABLE}
COMMAND python setup.py sdist
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bpf/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/setup.py
)
add_custom_target(bpf_py ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dist/bpf-${REVISION}.tar.gz)
add_custom_target(bpf_py ALL DEPENDS ${PIP_INSTALLABLE})
install(CODE "execute_process(COMMAND python setup.py install -f
--prefix=${CMAKE_INSTALL_PREFIX} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
// Copyright (c) PLUMgrid, Inc.
// Licensed under the Apache License, Version 2.0 (the "License")
#include "../../src/cc/bpf_helpers.h"
BPF_TABLE("prog", int, int, jump, 64);
BPF_TABLE("array", int, u64, stats, 64);
......
// Copyright (c) PLUMgrid, Inc.
// Licensed under the Apache License, Version 2.0 (the "License")
#include "../../src/cc/bpf_helpers.h"
#include "../../src/cc/proto.h"
#include <bcc/proto.h>
struct IPKey {
u32 dip;
......
// Copyright (c) PLUMgrid, Inc.
// Licensed under the Apache License, Version 2.0 (the "License")
#include <linux/ptrace.h>
#include "../../src/cc/bpf_helpers.h"
struct Ptr { u64 ptr; };
struct Counters { u64 stat1; };
BPF_TABLE("hash", struct Ptr, struct Counters, stats, 1024);
......
......@@ -10,7 +10,6 @@ from unittest import main, TestCase
text = """
#include <linux/ptrace.h>
#include "../../src/cc/bpf_helpers.h"
struct Ptr { u64 ptr; };
struct Counters { u64 stat1; };
BPF_TABLE("hash", struct Ptr, struct Counters, stats, 1024);
......
......@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0 (the "License")
#include <linux/ptrace.h>
#include <linux/blkdev.h>
#include "../../src/cc/bpf_helpers.h"
struct Request { u64 rq; };
struct Time { u64 start; };
BPF_TABLE("hash", struct Request, struct Time, requests, 1024);
......
// Copyright (c) PLUMgrid, Inc.
// Licensed under the Apache License, Version 2.0 (the "License")
#include "../../src/cc/bpf_helpers.h"
#include "../../src/cc/proto.h"
#include <bcc/proto.h>
struct IPKey {
u32 dip;
u32 sip;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment