GoBGPコトハジメ

この記事は[SFC-RG Advent Calendar 2019](https://qiita.com/advent-calendar/2019/sfc-rg)の4日目です。

# 何
このドキュメントでは入門者から見たGoBGPの基本的な利用方法(iBGPによる簡単な経路交換)について記述する。



## 0. GoBGPについて
- GitHub: https://github.com/osrg/gobgp
- 公式WEBサイト: https://osrg.github.io/gobgp/
![GoBGP](https://i.imgur.com/PaetTRB.png)
(公式WEBサイトより引用)

### 概要
GoBGPとはNTT発のOSSのBGPコントロールプレーンである。
開発コミュニティが強力で、新しい標準・ドラフトへの追従も活発だ。

### 脱線


ちなみにデータセンターネットワークでの活用も意識されている。

例えば[RFC5549](https://tools.ietf.org/html/rfc5549)を利用した**IPv6 Link-Local Addressを利用したBGP Peerの確立とIPv4 NLRI(経路情報)の交換**は、近年大規模事業者のDC[^1]で採用が進むBGPを利用したIPファブリックトポロジーの構築[^2]で大いに役に立つ機能だし、[RFC8365](https://tools.ietf.org/html/rfc8365)で述べられているEVPNのテーブルを交換する技術である所謂[**EVPN VXLAN**への対応](GoBGPでEVPN/VXLANを試す)も早くから行われてきた[^3]。

[^1]: 国内では[ヤフー](janog.gr.jp/meeting/janog38/download_file/clos.pdf)や[LINE](https://www.slideshare.net/linecorp/ss-116867631)など。海外では日本に5年ほど先立って採用されはじめていたと風のうわさで聞いた。

[^2]: [RFC 7938](https://tools.ietf.org/html/rfc7938)ではCLOS ネットワークを採用している。ちなみにCLOSネットワークは1951年にすでに理論が[定式化](https://worldwide.espacenet.com/publicationDetails/biblio?CC=US&NR=2244004&KC=&FT=E&locale=en_EP)されていた。すごいですね。

[^3]: RGの偉大な先輩であるskjune12先生はだいぶ早くから検証なさっている。すごいですね。 [GoBGPでEVPN/VXLANを試す](http://skjune12.hatenadiary.com/entry/2017/12/09/235550)


加えて[RouteReflector](https://github.com/osrg/gobgp/blob/master/docs/sources/route-reflector.md)や[RPKIの活用](https://github.com/osrg/gobgp/blob/master/docs/sources/rpki.md)、運用にそのまま利用できそうな楽しそうな機能も簡単に動かせる。


### "コントロールプレーン"

あくまでGoBGP自体はコントロールプレーンである。実際にLinuxのルーティングテーブル(所謂FIB)に落とし込むためには、何かしらつなぎこみを行なうツールが必要だ。


記事執筆時現在、開発コミュニティではZebra[^4]及びそのAPIを利用してFIB操作を行なうことが推奨されている。

[FIB manipulation](https://github.com/osrg/gobgp/blob/master/docs/sources/zebra.md)


[^3]: [FRRouting](https://frrouting.org/)もしくは少し古いが[quagga](https://www.quagga.net/)で利用するのが手っ取り早い。 最近はdebianパッケージで提供されてすごく簡単にFRRが[インストールできるようになっている](https://deb.frrouting.org/)。うれしい。

### GoBGPの構成


GoBGPは[gRPC](https://www.grpc.io/)を利用した疎結合な構成を採用している。

その気になれば自身の好きな言語・アプリケーションから[自由にGoBGPの機能を利用する](https://github.com/osrg/gobgp/blob/master/docs/sources/grpc-client.md)ことが出来る。

がはじめからそんな事言われても取っつきにくいと思うので、本ドキュメントでは公式のデーモンである`gobgpd`と、その操作用コマンドである`gobgp`の２つの利用を推奨する。





### 検証環境

OS: Ubuntu 18.04.2 LTS
Platform: amd64
GoBGP: version 2.11.0

```
root@siit-br:~/# uname -r
4.15.0-70-generic
root@siit-br:~/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"

```

## 1. インストール

Goを頑張ってインストールして`go get`する方法がよく紹介されているが、最近ではコンパイル済みバイナリイメージをそのまま持ってくる方法がお手軽で良い[^4]。
[^4]: 開発コミュニティもバイナリ版の使用を推奨している。https://github.com/osrg/gobgp/issues/1994



執筆時時点の最も新しいリリースは以下である。利用可能な最も新しいバージョンの利用すると良いだろう。

[GoBGP v2.11.0](https://github.com/osrg/gobgp/releases/tag/v2.11.0)

バイナリイメージをダウンロードして適当な場所に置く。

```bash
mkdir /opt/gobgp
cd /opt/gobgp
wget https://github.com/osrg/gobgp/releases/download/v2.11.0/gobgp_2.11.0_linux_amd64.tar.gz
tar xvf gobgp_2.11.0_linux_amd64.tar.gz

ls /opt/gobgp/
gobgp  gobgpd  LICENSE  README.md

```

`/usr/local/bin`にシンボリックリンクを作っておく。パスが通るはずだ。

```bash
ln -s /opt/gobgp/gobgpd /usr/local/bin/gobgpd
ln -s /opt/gobgp/gobgp /usr/local/bin/gobgp

```



実行できることを確認する。

```bash
$ gobgp --version
gobgp version 2.11.0
```


## 2. デーモンの起動

`gobgpd`を起動する前に、設定ファイルを作成しておく。
[TOML記法](https://github.com/toml-lang/toml)を利用する[^5]。

[^5]: 以下の記事が非常に参考になった。[設定ファイル記述言語 TOML](https://qiita.com/b4b4r07/items/77c327742fc2256d6cbe)



```toml:example.conf

[global.config]
  as = 65000
  router-id = "192.0.0.1"
```


デーモンの起動は以下のように行なう。バックグラウンドで起動したければ`screen`などお好みの方法で。

```bash
RouterA# gobgpd -f example.conf 
```




## 3. BGP Neighborの確立

ここまででデーモンの起動の仕方がわかった。

次に2台のPCを用意し、iBGP Neighborの確立を行う。


### 3.1 パラメーターの確認
ここで利用するパラメーターは以下の通り。
ちなみに今回の例ではPeerの確立と交換する経路にIPv6を使っている[^6]。環境と主義信仰に従って読み替えて下さい。お互いのBGP PeerとL3で疎通する必要がある。

[^6]: 一応RGのアドベントカレンダーなので。


| router 名 | router ID(BGP identifier ) | AS番号 | アドレス |
| -------- | -------- | -------- | -------- |
| Router A     | 192.0.0.1  | 65000   | 2001:df8::beaf/64    |
| Router B     | 192.0.0.2  | 65000   | 2001:df8::cafe/64    |


### 3.2 設定ファイルの確認

- Router A

```toml:routerA.conf
[global.config]
  as = 65000
  router-id = "192.0.0.1"
  
[[neighbors]]
  [neighbors.config]
    peer-as = 65000
    neighbor-address = "2001:df8::cafe"
    local-as = 65000

    [[neighbors.afi-safis]]
        [neighbors.afi-safis.config]
        afi-safi-name = "ipv6-unicast"
```

- Router B

```toml:routerB.conf
[global.config]
  as = 65000
  router-id = "192.0.0.2"
  
[[neighbors]]
  [neighbors.config]
    peer-as = 65000
    neighbor-address = "2001:df8::beaf"
    local-as = 65000

    [[neighbors.afi-safis]]
        [neighbors.afi-safis.config]
        afi-safi-name = "ipv6-unicast"
```


### 3.3 デーモンの起動

先程と同じ方法でデーモンを起動する。

- RouterA

```
# gobgpd -f routerA.conf 
```

- RouterB

```
# gobgpd -f routerB.conf 
```


### 3.4 BGP Neighborの確認

フォワグラウンドで起動していると以下のようにログが流れてくる。

```
RouterA# gobgpd -f example.conf
{"level":"info","msg":"gobgpd started","time":"2019-12-03T20:39:25Z"}
{"Topic":"Config","level":"info","msg":"Finished reading the config file","time":"2019-12-03T20:39:25Z"}
2001:df8::cafe is added","time":"2019-12-03T20:39:25Z"}
{"Topic":"Peer","level":"info","msg":"Add a peer configuration for:2001:df8::cafe","time":"2019-12-03T20:39:25Z"}
{"Key":"2001:df8::cafe","State":"BGP_FSM_OPENCONFIRM","Topic":"Peer","level":"info","msg":"Peer Up","time":"2019-12-03T20:39:30Z"}

```

`Peer Up`とあればNeighborの確立成功だ。


ちなみに`gobgp`コマンドを使ってCLIでもNeighborの確認を行なうことが出来る。


```bash
RouterA# gobgp neighbor
Peer                             AS  Up/Down State       |#Received  Accepted
2001:df8::cafe 65000 00:00:12 Establ      |        0         0

```


### 4.1 経路の投入

今回はRouter Aから以下の経路を投入する。

宛先: `2001:df8:100:200::/64`
Nexthop属性: `2001:df8::beaf`


経路の投入には`gobgp`コマンドを利用する。詳しい使い方は[公式ドキュメント](https://github.com/osrg/gobgp/blob/master/docs/sources/cli-command-syntax.md)が非常にわかりやすい。


- 経路の追加

```
# gobgp global rib add -a ipv6 2001:df8:100:200::/64 nexthop  2001:df8::beaf
```

- 経路の削除

```
# gobgp global rib del -a ipv6 2001:df8:100:200::/64 nexthop  2001:df8::beaf
```

- 自分が広告している経路の確認

```
# gobgp nei 2001:df8:: adj-out
   ID  Network               Next Hop             AS_PATH              Attrs
   1   2001:df8:100:200::/64 2001:df8::cafe                            [{Origin: ?} {LocalPref: 100}]

```


### 4.2 経路(Loc-RIBs)の確認

CLIから経路表(Loc-RIBs)を確認できる。
先述したように、Linuxのルーティングテーブルに入れるためにはFIB操作の各種アプリケーションを利用する必要がある。

- RouterBより

```
# gobgp global rib -a ipv6
   Network               Next Hop             AS_PATH              Age        Attrs
*> 2001:df8:100:200::/64 2001:df8::beaf                         00:05:46   [{Origin: ?} {LocalPref: 100}]
```