LTEを自作してみる(Part3)

# はじめに

前回と前々回はOAI CoreとOAI SIMをセットアップして、それらを接続して呼処理のシミュレーションを行いました。

OAI以外のOSS LTE(NextEPC, srsLTE)も試そう！ということで、
今回はNextEPCをセットアップして、OAI Coreと同様にOAI SIMと接続して呼処理のシミュレーションを行います。

# NextEPC

* NextEPC INCが提供する3GPPに準拠したEPCのアプリケーション
* ソースコード : https://github.com/nextepc/nextepc
* C++ 製
* 機能
    * EPC
    * MME
    * HSS
    * SGW
    * PGW
    * PCRF
* ベアメタル、仮想化およびコンテナ化(Docker)に対応している
* Subscribe情報などを格納するデータベースとしてMongoDBを使用

名前の通りEPCのアプリケーションであるため、EUTRAN側は実装されていないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/f55bbba6-85b2-f4d8-c446-70b728d5a5fd.png)


# セットアップ(NextEPC)

NextEPCのインストールはソースファイルからとパッケージからの2通りの方法があります。どちらも試してみましたが、設定ファイルの構成や起動方法に若干の違いがありました。今回はソースファイルからインストールする手順について記載します。


## 1.VM作成
以下の通りUbuntu VMを作成します。

* ホスト名 : nepc01
* OS : Ubuntu 16.04.5 LTS
* Spec
    * CPU : 4vcore
    * Memory : 4GB
    * Disk : 100GB
* Network
    * ens3 : 管理用インターフェース
    * ens9 :　内部通信(EUTRAN-EPC)用インターフェース
    * ens10 : インターネット接続用インターフェース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354136/4f232c4e-bdab-d094-8ee9-3cec593db6a0.png)

※OAI SIMは[その2](https://qiita.com/keiusukematsuda/private/d8b772cab2584558baa5)でセットアップしたものと同一のものです。

## 2.MongoDBのインストール

NextEPCではデータベースとしてMongoDBを使用します。

```
# apt-get update
# apt-get -y install mongodb
# systemctl start mongodb
# systemctl status mongodb <- check service status is active
```

## 3.TUNの作成

NextEPCではPGWのIFとしてTUNを使用します。
そのためTUNを事前に作成しておく必要があります。

```
# sh -c "cat << EOF > /etc/systemd/network/99-nextepc.netdev
[NetDev]
Name=pgwtun
Kind=tun
EOF"

# sh -c "cat << EOF > /etc/systemd/network/99-nextepc.network
[Match]
Name=pgwtun
[Network]
Address=45.45.0.1/16
Address=cafe::1/64
EOF"

# systemctl enable systemd-networkd
# systemctl restart systemd-networkd
```

作成するTUNのアドレスですが、後述するPGWのIPプールアドレスの範囲内である必要があります。

## 4.依存パッケージのインストール

```
apt-get -y install autoconf libtool gcc pkg-config git flex bison libsctp-dev libgnutls28-dev libgcrypt-dev libssl-dev libidn11-dev libmongoc-dev libbson-dev libyaml-dev
```

## 5.ビルド

```
# git clone https://github.com/nextepc/nextepc
# cd nextepc
# autoreconf -iv
# ./configure --prefix=`pwd`/install
# make -j `nproc`
# make install
```

## 6.Node.jsのインストール

```
# apt-get -y install curl
# curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
# apt-get -y install nodejs
```

## 7.WebUIのインストールと起動

```
# cd webui
# npm install
# npm run dev
```
起動後、https://[IPアドレス]:3000 でWebUIにアクセスすることが可能です。

## 8.NextEPCの設定

ソースからインストールした場合とパッケージからインストールした場合で設定ファイルの置き場所が異なるようです。

* ソース : <ソースのディレクトリ>/install/etc/nextepc
* パッケージ : /etc/nextepc

以下の通り、設定ファイルを編集します。
※理由は後述しますがgummeiはOAI SIMに合わせて設定します。

```
db_uri: mongodb://localhost/nextepc

logger:
    file: /root/nextepc/install/var/log/nextepc/nextepc.log
    trace:
        app: 1
        s1ap: 1
        nas: 1
        diameter: 1
        gtpv2: 1
        gtp: 1

parameter:
    no_ipv6: true

mme:
    freeDiameter: mme.conf


    s1ap:
      - addr: 172.16.0.54
    gtpc:

    gummei:
      plmn_id:
        mcc: 208
        mnc: 93
      mme_gid: 2
      mme_code: 1

    tai:
      plmn_id:
        mcc: 208
        mnc: 93
      tac: 1

    security:
        integrity_order : [ EIA1, EIA2, EIA0 ]
        ciphering_order : [ EEA0, EEA1, EEA2 ]


    network_name:
        full: NextEPC

hss:
    freeDiameter: hss.conf

sgw:
    gtpc:
      addr: 127.0.0.2


    gtpu:
     - addr: 172.16.0.54

pgw:
    freeDiameter: pgw.conf

    gtpc:
      addr:
        - 127.0.0.3
        - ::1

    gtpu:
      - addr: 127.0.0.3
      - addr: ::1

    ue_pool:
      - addr: 45.45.0.1/16
      - addr: cafe::1/64

    dns:
      - 8.8.8.8
      - 8.8.4.4
      - 2001:4860:4860::8888
      - 2001:4860:4860::8844


pcrf:
    freeDiameter: pcrf.conf
```

## 9.NATの有効化

このままだとUE(OAI SIM)がSGi(インターネット)と接続する際にNATされません。そのためインターネットに接続しているIFにてNATを有効化する必要があります。

```
sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
iptables -t nat -A POSTROUTING -o ens10 -j MASQUERADE
iptables -I INPUT -i pgwtun -j ACCEPT
```

## 10.起動

ソースでインストールした場合はスクリプトでNextEPCを起動します。(パッケージでインストールした場合はサービスとして登録されるため、systemctlコマンドで起動することが可能です。)

```
# cd <ソースのディレクトリ>/install/bin
# ./nextepc-epcd
```

上記のスクリプトを実行すると、MME/HSS/SGW/PGW/PCRFすべてが起動します。
※プロセス毎の起動スクリプトも用意されています。


NextEPC VMは以下のように稼働しています。(多分)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354136/ad7139ad-a2b9-ccad-eedd-6a017fcd54e4.png)

OAIと違って、SGWとPGWが異なるプロセスとなっています。またPCRFも実装されています。デフォルトではPCRFは機能しませんが、設定次第では帯域制御なども可能になるようですね。

# OAI SIMとの接続

接続する前にSubscriber情報の登録を行う必要があります。

## 1. Subscriber情報をMongoDBに登録

Subscriber情報をWebUI経由でMongoDBに登録します。(mongoDBに直接登録することも可能です。)登録するSubscriber情報はOAI coreと同じものにします。というのもOAI SIMでIMSIなどのSubscribe情報を変更する方法がわからないためです。。だれか教えてください。。。

### ログイン

ブラウザ(chrome、Firefoxがおすすめです)からhttp://[ IPアドレス ]:3000にアクセスします。
Username : admin
Password : 1423
でログインします。(デフォルトのユーザ/パスワードです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/ac0088ff-7f01-f76b-938e-ea76d563c7b7.png)

### Subscriberの登録

ログイン後、画面右下の赤い+をクリックします。

その後、Subscriber情報の入力を行います。

※先ほども言いましたが、接続するOAI SIM側のSubscriber情報をいじることができないので、NextEPC側にOAI SIMのSubscriber情報を登録していきます。

* Subscriber Configuration
    * IMSI : 208930100001111
    * Subscribe Key : 8baf473f2f8fd09487cccbd7097c6862
    * USIM Type : OP
    * OPc/OP : 1006020f0a478bf6b699f15c062e42b3
* APN Configurations
    * APN : nextepc.ipv4

上記以外デフォルトで問題ありません。

## 2. OAI SIMの設定変更

NextEPcに登録したSubscriber情報はOAI SIMに合わせているので、インターフェース設定(141行目)のみ変更します。

```text:SIM
# vi /root/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf

141     mme_ip_address      = ( { ipv4       = "172.16.0.54"; 
142                               ipv6       = "192:168:30::17";
143                               active     = "yes";
144                               preference = "ipv4";
145                             }
146                           );

148     NETWORK_INTERFACES :
149     {
150         ENB_INTERFACE_NAME_FOR_S1_MME            = "ens9";
151         ENB_IPV4_ADDRESS_FOR_S1_MME              = "172.16.0.115/24";
152
153         ENB_INTERFACE_NAME_FOR_S1U               = "ens9";
154         ENB_IPV4_ADDRESS_FOR_S1U                 = "172.16.0.115/24";
155         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
```


## 3.OAI SIMの起動


```Text:SIM
# cd /root/openairinterface5g/cmake_targets/tools
# ./run_enb_ue_virt_s1
```

## 4. 接続確認

NextEPCにはOAI EPCのようなAttachしているUE(Subscriber)の統計を出力するテーブルはありません。
OAI SIMとNextEPCが接続できたかを確認するためにはOAI SIMのIFステータスを確認して、NextEPCのPGWからIPアドレスが払い出されているか確認します。

```Text:SIM
# ifconfig 

～省略～

oip1      Link encap:AMPR NET/ROM  HWaddr   
          inet addr:45.45.0.2  Bcast:45.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
```

## 5. インターネットへの接続

このoip1 IFからPINGを8.8.8.8(Google Public DNSサーバ)に送信して、インターネットとの接続を確認します。ただ今のままではインターネットへのルーティング情報がないため、デフォルトゲートウェイをPGWに向ける必要があります。
以下の通り、NextEPCのPGWにデフォルトゲートウェイを向けるようにします。

```text:SIM
# route add default gw 45.45.0.1

# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         45.45.0.1       0.0.0.0         UG        0 0          0 oip1
10.0.0.0        0.0.0.0         255.255.255.0   U         0 0          0 em1
45.0.0.0        0.0.0.0         255.0.0.0       U         0 0          0 oip1
172.16.0.0      0.0.0.0         255.255.255.0   U         0 0          0 em49
```

これで準備が整いました。それではPINGを送信します。

```text:SIM
# ping 8.8.8.8 -I oip1
PING 8.8.8.8 (8.8.8.8) from 45.45.0.2 oip1: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=49 time=205 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=49 time=154 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=49 time=112 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=49 time=171 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=49 time=160 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=49 time=152 ms
64 bytes from 8.8.8.8: icmp_seq=7 ttl=49 time=208 ms
64 bytes from 8.8.8.8: icmp_seq=8 ttl=49 time=217 ms
64 bytes from 8.8.8.8: icmp_seq=9 ttl=49 time=116 ms
```

oip1 IF経由でインターネットと接続することができました！

パケットキャプチャを確認してみると、GTPトンネルを通りインターネットと接続できていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/a1e4771b-4496-b79a-5207-c4dc9550ba47.png)


# 最後に
これでNextEPCをセットアップしてOAI SIMと接続することができました。

NextEPCとOAI EPCを比べてみて、NextEPCの方が

* インストール/セットアップが楽
* PCRFも実装している(今回は機能していないですが)

という点でOAIに比べて良さげな印象を持ちました。
ただEUTRANは実装されていないという欠点があるので、OAI EUTRANと組み合わせて使うなどもありなのかなと思ったり。。

次はまたsrsLTEをセットアップして、OAI・NextEPCと比較できればと思います。