はじめに
せっかく通信キャリアのモバイルコア部門のエンジニアになったので、自宅でもコア設備を再現してみようと思いました。とは言っても私はモバイルコアの基盤開発担当なので、3GPPや設備については概要程度しか知りません。
一部曖昧な説明があるかもしれませんがご了承ください。
今回作っていくものは自宅のWiFiで端末やユーザーごとに通信速度制限をするものです。
簡単に説明すると、ルーターと無線APの間にラズパイをかまして、無線APを介す通信に対して速度制限をラズパイでかけるというものです。
今回作ったシステムはgithubで公開しています↓(継続開発中)
3GPPの超簡略説明
4G LTE のコアネットワーク(EPC)は 3GPPによって機能とインターフェイスが標準化されており、世界中のキャリアはこの仕様に基づいてネットワークを構築しています。
スマホが基地局につながってから、インターネットに接続するまでの過程を超簡略で説明します。
※本当はさらに大量の設備がありますが、大体以下を理解しておけば十分です。

①UE(User Equipment)
ユーザが利用する端末(スマホなど)であり、通信の起点となる
②eNodeB(enhanced NodeB)
もともと3Gの一方式であるW-CDMAの基地局をNodeBと呼んでいたそうで、4Gの基地局はその発展形でeNodeB(enhanced NodeB)、5GはgNodeB(next Generation NodeB)と言うそうです。
(LTEのLong Term Evolutionとか5GのNew Radio,Next Generationみたいな呼び方は、名前が時間に対して不変じゃないと思うので私はすごく嫌いです...ネーミングしてるの誰だよ...)
③MME(Mobility Management Entity)
端末の認証(HSSと連携)やどこの基地局に繋いでいるかなどの位置管理、接続制御などを担う。
④HSS(Home Subscriber Server)
加入者情報(認証情報・契約情報など)を保持するデータベース。
⑤SGW(Serving Gateway)
パケットの中継を行い、移動時のデータ経路の維持を担う
⑥PCRF(Policy and Charging Rules Function)
QoSや帯域制御などのポリシーを決定する制御機能
通信量などをリアルタイムに監視し、課金をする
⑦PGW(Packet Gateway)
外部ネットワークとの接続点となり、IPアドレスの割当や通信出口として機能する
PCRFで決定したポリシーを実行する。
システムアーキテクチャ
tcコマンドをベースに、通信制御の設定を自動で維持する仕組みを構築していきます。
tcコマンドのインストールや使い方はこの辺の記事 ↓ を参考にしてください
アーキテクチャは Kubernetes を参考にしています。
まず、通信の理想状態(Desired State)をデータベースに定義します。
このDBには、以下の二つのテーブルを用意しておいて、通信ポリシーを設定します。
- filter_pocily : ユーザーAの端末は通信速度100Mbps etc...
- device_info : MACアドレスが「1A:2B:3C」の端末はユーザーAのiphone etc...
一方で、実際にLinuxに設定されている状態(Actual State)は、tcコマンドで設定されたフィルタやqdiscの内容になります。
この2つの状態を定期的に比較(ポーリング)し、差分があれば修正するreconciliation loopとして実装しています。
この処理をsystemdでデーモン化し、reconciler daemon として常時動作させます。
システム内でのパケットの流れ
通信制御の流れは以下のようになります。3GPPのノードも当てはめてみました。
基地局の移動などは考えなくてよいのでMMEとSGWは不要です。また、このシステムではPGWがHSS、PCRFを内包している形になる(※本来は別ノード)ので図のようになります。
ラズベリーパイをルーターとアクセスポイントの間に配置し、内部ではブリッジ(br0)を構成して通信を中継します。
eth0:ルーター側
eth1:アクセスポイント側
br0:2つを接続するブリッジ
1.パケット受信(ingress)
ルーター側(eth0)からパケットが入ってくると、まず ingressとして受信されます。
2.ifbによる変換(ingress → egress)
Linuxではingressでは高度な帯域制御(shaping)ができないため、一度 ifb0(仮想NIC)にリダイレクトして、ingressのパケットをegressとして扱えるように変換します
3.tcによる振り分け
ifb0上では通常のegressトラフィックとして扱えるため、tcのフィルタを用いてパケットを分類します。
→宛先MACアドレスを元に端末を判定し、ユーザーの通信ポリシーごとに異なるクラスへ振り分けます。
(3GPP):HSSに誰の端末かを問い合わせ、PCRFにユーザーごとの通信ポリシーを聞いて、PGWで帯域制御をかけています。
4.キューイングと帯域制御
各クラスにはそれぞれキュー(qdisc)が設定されており、
高速通信(例:1Gbps)
低速通信(例:1Kbps)
のように、ポリシーごとに帯域制御を行います。
パケットはそれぞれのキューに蓄えられ、スケジューラによって順次送信されます。
さいごに
キャリアのモバイルコア設備も中核は今回作ったような仕組みで動いています。
今回はラズパイの直にシステムの構築をしましたが、現在KubernetesやOpenShiftといったコンテナ基盤でモバイルコア設備は作られることが一般的なので、そのうちKubernetes上にこのシステムをデプロイしてみたいと思います。
また、現代はスマホやゲーム機、家電など何でもインターネットに接続するのが当たり前の時代です。子供などが好き勝手にインターネットを使うのが悪影響な場合もあると思います。ある程度はインターネットへの接続の制限が必要なこともあると思うのでぜひこのシステムを参考にしてみてください。

