Make installation prefixes more realistic
authorBrenden Blanco <bblanco@plumgrid.com>
Wed, 10 Jun 2015 00:43:27 +0000 (17:43 -0700)
committerBrenden Blanco <bblanco@plumgrid.com>
Wed, 10 Jun 2015 00:43:27 +0000 (17:43 -0700)
* 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>
17 files changed:
CMakeLists.txt
README.md
examples/hello_world.py
scripts/README.md [new file with mode: 0644]
scripts/bpf_demo.ks.erb
src/cc/CMakeLists.txt
src/cc/bpf_module.cc
src/cc/export/helpers.h [moved from src/cc/bpf_helpers.h with 100% similarity]
src/cc/export/proto.h [new file with mode: 0644]
src/cc/proto.h [deleted file]
src/python/CMakeLists.txt
tests/cc/test_call1.c
tests/cc/test_stat1.c
tests/cc/test_trace2.c
tests/cc/test_trace2.py
tests/cc/test_trace3.c
tests/cc/test_xlate1.c

index 7e82f10..88ce021 100644 (file)
@@ -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")
index 166b84d..05cf2ec 100644 (file)
--- a/README.md
+++ b/README.md
@@ -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
index 39dc85c..dcecc70 100755 (executable)
@@ -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";
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644 (file)
index 0000000..fbcc2ce
--- /dev/null
@@ -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
+```
index 5f3d2c5..8cddf10 100644 (file)
@@ -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
index 804204f..f0a97c2 100644 (file)
@@ -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")
index 93029cd..32bdca4 100644 (file)
@@ -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());
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 (file)
index 0000000..c6de80e
--- /dev/null
@@ -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 (file)
index d23fe2b..0000000
+++ /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));
index 891693e..f62048e 100644 (file)
@@ -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})")
index 38d221a..4b6b653 100644 (file)
@@ -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);
index 92c85d4..970bb72 100644 (file)
@@ -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;
index ead26d5..e4f5db1 100644 (file)
@@ -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);
index 64ed192..35db950 100755 (executable)
@@ -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);
index 543135e..1058be2 100644 (file)
@@ -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);
index 2492122..a7f0635 100644 (file)
@@ -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;