BESSの開発メモその01：BESSのインストールと基本的な使用方法

## はじめに
これはBESS(Berkeley Extensible Software Switch)の開発に関するガイドブックである。公式Wikiには英語版にしかない上、内容も少ない、だからこのメモを書く。このメモには、公式Wikiにある重要な内容も含めて、自分が開発、ソースコードを読むときの理解や発見などが含めている。
もし誰かの助けになれば、それは幸いなことになる。

公式ページ -> [BESS](http://span.cs.berkeley.edu/bess.html)
公式WikiとRepo -> [BESS Wiki](https://github.com/NetSys/bess/wiki)

## 開発環境
Ubuntu 18.04 LTS 推奨

VMwareでUbuntuをインストールのはおすすめする。スナップショット機能を活用し、システムに回復不可能なダメージが出れば、簡単に正常状態に戻れる。  
決してVMに十分なメモリを設置すること、2~4GBのは目安。

## 依存関係のインストール
BESSには次のソフトパッケージが必要：

```
sudo apt install make apt-transport-https ca-certificates g++ make pkg-config libunwind8-dev liblzma-dev zlib1g-dev libpcap-dev libssl-dev libnuma-dev git python python-pip python-scapy libgflags-dev libgoogle-glog-dev libgraph-easy-perl libgtest-dev libgrpc++-dev libprotobuf-dev libc-ares-dev libbenchmark-dev libgtest-dev protobuf-compiler-grpc
pip install --user protobuf grpcio scapy
```

## ビルド
Repoからクローンとスクリプトを実行：

```
git clone https://github.com/NetSys/bess.git
cd bess/
sudo ./build.py
```

次の出力ならビルド成功：

```
> sudo ./build.py
Configuring DPDK...
 - "Mellanox OFED" is not available. Disabling MLX4 and MLX5 PMDs...
Building DPDK...
Generating protobuf codes for pybess...
Building BESS daemon...
Building BESS kernel module (4.15.0-74-generic - running kernel) ...
Done.
```

### 注意事項
1. もしビルドの途中でDPDKのダウンロードをできなくなれば、出力を従って、マニュアルでダウンロードし、フォルダ```deps```で解凍、そしてもう一度ビルドする。
2. もし```core```のソースコードをかきかえたら、再ビルドの前に関係する```*.o```ファイルを消去するのはおすすめする。
3. フォルダ```core/pb```にあるソースコードはprotobufで生成する、だからビルドの前に何もない。
4. すべてのwarningはerrorとして扱っている。errorがあればビルドは絶対に失敗する。  
5. hugepageの設置は決してビルドのあとにすること。もし順番が間違ったら、次のエーラが発生するかも：

```
Log:
 make: Entering directory '/home/****/bess/core'
[CXX]       opts.o
[CXX]       worker.o
[CXX]       packet_pool.o
[CXX]       task.o
[CXX]       resume_hook.o
[CXX]       memory.o
[CXX]       dpdk.o
[CXX]       event.o
[CXX]       gate.o
[CXX]       port.o
[CXX]       main.o
[CXX]       debug.o
[CXX]       module_graph.o
[CXX]       bessctl.o
g++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
Error: bessctl.o
g++ -o bessctl.o -c bessctl.cc -std=c++17 -g3 -ggdb3 -march=native -isystem /home/****/bess/deps/dpdk-17.11/build/include -isystem /home/****/bess/core -isystem ./.. -isystem /home/****/bess/core/modules -D_GNU_SOURCE -Werror -Wall -Wextra -Wcast-align -Wno-error=deprecated-declarations -pthread -I/usr/include/x86_64-linux-gnu -fno-gnu-unique -O3 -DNDEBUG -MT bessctl.o -MMD -MP -MF .deps/bessctl.d
Makefile:439: recipe for target 'bessctl.o' failed
make: *** [bessctl.o] Error 1
make: Leaving directory '/home/****/bess/core'

Error has occured running command: make -j1 -C core
```

## hugepageの設置
毎回のリブートにはこの設置が必要。
  
次のコマンドを実行する（システムによってコマンドが異なる）：

```
# For single-node systems
sudo sysctl vm.nr_hugepages=1024

# For multi-node (NUMA) systems
echo 1024 | sudo tee /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 | sudo tee /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
```

## BESSを起動し、テストスクリプトを実行する
次のコマンドを実行する

```
> sudo bessctl/bessctl
Type "help" for more information.
Connection to localhost:10514 failed
Perhaps bessd daemon is not running locally? Try "daemon start".
<disconnected> $
```
その後```daemon start```を実行：

```
Done.
localhost:10514 $
```
このときBESSはすでに起動された。

あるテストスクリプトを実行してみよう：

```
$ run samples/acl
```
その結果：

```
Done.
localhost:10514 $
```
なんの出力もない。その原因は、このスクリプトにはなんの出力コマンドも含めていない。
コマンド```monitor pipeline```を入力し、次の出力が出る：  

<img width="610" alt="success.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434909/7d12ef63-d1c6-62be-fa09-3433ecaf2214.jpeg">

これはテストスクリプトを成功に実行する証である。

### 注意事項

今LinuxにはPython3を使用をしているが、BESSにはPython2で書くので、もし次のエラーメッセージが出た場合：

```
Traceback (most recent call last):
  File "bessctl/bessctl", line 186, in <module>
    main()
  File "bessctl/bessctl", line 170, in main
    run_cli()
  File "bessctl/bessctl", line 159, in run_cli
    cli.loop()
  File "bessctl/bessctl", line 134, in loop
    super(BESSCLI, self).loop()
  File "/home/****/bess/bessctl/cli.py", line 528, in loop
    self.process_one_line()
  File "/home/****/bess/bessctl/cli.py", line 440, in process_one_line
    self.call_func(func, args)
  File "bessctl/bessctl", line 95, in call_func
    super(BESSCLI, self).call_func(func, args)
  File "/home/****/bess/bessctl/cli.py", line 411, in call_func
    func(*args)
  File "/home/****/bess/bessctl/commands.py", line 1720, in monitor_pipeline
    _monitor_pipeline(cli, 'pkts', '', graph_args=opts)
  File "/home/****/bess/bessctl/commands.py", line 1711, in _monitor_pipeline
    graph_args=graph_args))
  File "/home/****/bess/bessctl/commands.py", line 1389, in _draw_pipeline
    node_labels[gate.name]), file=f.stdin)
TypeError: a bytes-like object is required, not 'str
```
Python2でbessctlを実行する：
```python2 bessctl/bessctl```

## 続き
次には、BESSのスクリプトを書き方を紹介する。BESSが持っているモジュールを使う方法も理解できるはず。