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: Brenden Blanco <bblanco@plumgrid.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7e82f10..88ce021 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,9 @@
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")
diff --git a/README.md b/README.md
index 166b84d..05cf2ec 100644
--- a/README.md
+++ b/README.md
@@ -36,88 +36,68 @@
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'...
-```
-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.
+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>
```
-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
+Change `CMAKE_PREFIX_PATH` if llvm is installed elsewhere.
-100% tests passed, 0 tests failed out of 4
+### Cleaning up
+
+Since packaging is currently not available, one can cleanup the collateral of
+bcc by doing:
+
+```
+sudo rm -rf /usr/{lib/libbpf.prog.so,include/bcc,share/bcc}
+sudo pip uninstall bpf
```
+### Building LLVM
+
+See http://llvm.org/docs/GettingStarted.html for the full guide.
+
+The short version:
+
+```
+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
diff --git a/examples/hello_world.py b/examples/hello_world.py
index 39dc85c..dcecc70 100755
--- a/examples/hello_world.py
+++ b/examples/hello_world.py
@@ -9,7 +9,6 @@
from subprocess import call
prog = """
-#include "src/cc/bpf_helpers.h"
BPF_EXPORT(hello)
int hello(void *ctx) {
char fmt[] = "Hello, World!\\n";
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 0000000..fbcc2ce
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,68 @@
+
+## 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
+```
diff --git a/scripts/bpf_demo.ks.erb b/scripts/bpf_demo.ks.erb
index 5f3d2c5..8cddf10 100644
--- a/scripts/bpf_demo.ks.erb
+++ b/scripts/bpf_demo.ks.erb
@@ -85,6 +85,7 @@
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 @@
-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
diff --git a/src/cc/CMakeLists.txt b/src/cc/CMakeLists.txt
index 804204f..f0a97c2 100644
--- a/src/cc/CMakeLists.txt
+++ b/src/cc/CMakeLists.txt
@@ -9,10 +9,20 @@
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 @@
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")
diff --git a/src/cc/bpf_module.cc b/src/cc/bpf_module.cc
index 93029cd..32bdca4 100644
--- a/src/cc/bpf_module.cc
+++ b/src/cc/bpf_module.cc
@@ -151,6 +151,10 @@
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 @@
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());
diff --git a/src/cc/bpf_helpers.h b/src/cc/export/helpers.h
similarity index 100%
rename from src/cc/bpf_helpers.h
rename to src/cc/export/helpers.h
diff --git a/src/cc/export/proto.h b/src/cc/export/proto.h
new file mode 100644
index 0000000..c6de80e
--- /dev/null
+++ b/src/cc/export/proto.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 PLUMgrid, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+struct ethernet_t {
+ unsigned long long dst:48;
+ unsigned long long src:48;
+ unsigned int type:16;
+} __attribute__((packed));
+
+struct dot1q_t {
+ unsigned short pri:3;
+ unsigned short cfi:1;
+ unsigned short vlanid:12;
+ unsigned short type;
+} __attribute__((packed));
+
+struct arp_t {
+ 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 {
+ 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 {
+ unsigned short sport;
+ unsigned short dport;
+ unsigned short length;
+ unsigned short crc;
+} __attribute__((packed));
+
+struct tcp_t {
+ 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));
diff --git a/src/cc/proto.h b/src/cc/proto.h
deleted file mode 100644
index d23fe2b..0000000
--- a/src/cc/proto.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2015 PLUMgrid, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * 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;
-} __attribute__((packed));
-
-struct dot1q_t {
- u16 pri:3;
- u16 cfi:1;
- u16 vlanid:12;
- u16 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;
-} __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
-} __attribute__((packed));
-
-struct udp_t {
- u16 sport;
- u16 dport;
- u16 length;
- u16 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;
-} __attribute__((packed));
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 891693e..f62048e 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -7,13 +7,14 @@
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})")
diff --git a/tests/cc/test_call1.c b/tests/cc/test_call1.c
index 38d221a..4b6b653 100644
--- a/tests/cc/test_call1.c
+++ b/tests/cc/test_call1.c
@@ -1,6 +1,5 @@
// 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);
diff --git a/tests/cc/test_stat1.c b/tests/cc/test_stat1.c
index 92c85d4..970bb72 100644
--- a/tests/cc/test_stat1.c
+++ b/tests/cc/test_stat1.c
@@ -1,7 +1,7 @@
// 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;
diff --git a/tests/cc/test_trace2.c b/tests/cc/test_trace2.c
index ead26d5..e4f5db1 100644
--- a/tests/cc/test_trace2.c
+++ b/tests/cc/test_trace2.c
@@ -1,7 +1,6 @@
// 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);
diff --git a/tests/cc/test_trace2.py b/tests/cc/test_trace2.py
index 64ed192..35db950 100755
--- a/tests/cc/test_trace2.py
+++ b/tests/cc/test_trace2.py
@@ -10,7 +10,6 @@
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);
diff --git a/tests/cc/test_trace3.c b/tests/cc/test_trace3.c
index 543135e..1058be2 100644
--- a/tests/cc/test_trace3.c
+++ b/tests/cc/test_trace3.c
@@ -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);
diff --git a/tests/cc/test_xlate1.c b/tests/cc/test_xlate1.c
index 2492122..a7f0635 100644
--- a/tests/cc/test_xlate1.c
+++ b/tests/cc/test_xlate1.c
@@ -1,7 +1,6 @@
// 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;