Android Automotive OS(AAOS)でネットワークをシミュレートする

このページでは、Android Automotive ハードウェア デバイスのさまざまなネットワーク状態を、スケーラブルでメンテナンスが少なくてすむ方法でシミュレートする方法について説明します。環境に依存しないこのネットワーク シミュレーションでは、Android Automotive ハードウェア デバイス上で実行できる、一般的に利用可能な Linux ツールを使用します。

以下のセクションでは、Android Automotive ハードウェア デバイスでネットワーク シミュレーションを設定して実行する方法について説明します。

カーネルの要件

テスト対象デバイス(DUT)でネットワーク シミュレーションを有効にするには、Linux の ifb モジュールと netem モジュールをカーネル構成ファイルで次のように設定する必要があります。

# Network simulation config fragment start
CONFIG_NET_SCH_NETEM=y
CONFIG_IFB=y
CONFIG_NET_ACT_MIRRED=y
# Network simulation config fragment end

シミュレーションを設定する

すべてのネットワーク シミュレーションまたはスロットリング シミュレーションは、テスト対象デバイス(DUT)で実施する必要があります。このシミュレーションでは、Linux の tc および NetEm ユーティリティを使用し、制御ポリシーおよびルールに基づいてネットワーク インターフェース コントローラ(NIC)のネットワーク トラフィックを制御します。

シミュレーションを設定する手順は次のとおりです。

  1. DUT とホストサーバーをインターネットに接続します。
  2. NetworkSimulation.sh スクリプトのセクションにあるコードからコピーして NetworkSimulation.sh スクリプトを作成し、ホストサーバーにダウンロードします。
  3. ホストサーバーを DUT に接続します。adb devices -l を実行して、接続済みのデバイスのリストに DUT が表示されていることを確認します。

以下に、セットアップ アーキテクチャの図を示します。

nw-sim

図 1. アーキテクチャの設定

NetworkSimulation.sh スクリプト

NetworkSimulation.sh スクリプト ファイルには、ネットワーク シミュレーションを実行する adb コマンドが含まれています。以下を NetworkSimulation.sh というファイルにコピーします。

  #!/bin/bash

  latency=$1
  bandwidth=$2
  packetloss=$3

  # root device and set it to permissive mode
  adb root
  adb shell setenforce 0

  #Clear the current tc control
  adb shell tc qdisc del dev ifb0 root
  adb shell ip link set dev ifb0 down
  adb shell tc qdisc del dev wlan0 ingress
  adb shell tc qdisc del dev wlan0 root

  # Create a virtual device for ingress
  adb shell ip link set dev wlan0 up
  adb shell ip link set dev ifb0 up
  adb shell tc qdisc del dev wlan0 clsact
  adb shell tc qdisc add dev wlan0 handle ffff: ingress
  adb shell tc filter add dev wlan0 parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb0

  # Throttle upload bandwidth / latency / packet loss
  adb shell tc qdisc add dev wlan0 root handle 1: htb default 11
  adb shell tc class add dev wlan0 parent 1: classid 1:1 htb rate "$bandwidth"
  adb shell tc class add dev wlan0 parent 1:1 classid 1:11 htb rate "$bandwidth"
  adb shell tc qdisc add dev wlan0 parent 1:11 handle 10: netem delay "$latency" loss "$packetloss"

  # Throttle download bandwidth
  adb shell tc qdisc add dev ifb0 root handle 1: htb default 10
  adb shell tc class add dev ifb0 parent 1: classid 1:1 htb rate "$bandwidth"
  adb shell tc class add dev ifb0 parent 1:1 classid 1:10 htb rate "$bandwidth"

シミュレーションを実行する

ネットワーク シミュレーションを実行する際、NetworkSimulation.sh スクリプト ファイルの adb コマンドは、コマンドライン引数を使用して必要な値を設定します。

シミュレートするレイテンシ、帯域幅、パケットロスを指定するには、次のコマンドライン引数を指定して NetworkSimulation.sh スクリプトを実行します。

  • レイテンシ(ミリ秒単位)
  • 帯域幅(kbit または mbit 単位)
  • パケットロス(パーセント単位)

たとえば、レイテンシ 300 ms、帯域幅 100 kbit、パケットロス 50% を設定するには、次のコマンドを実行します。

bash NetworkSimulation.sh 300ms 100kbit 50%

レイテンシ 100 ms、帯域幅 1 mbit、パケットロス 0% を設定するには、次のコマンドを実行します。

bash NetworkSimulation.sh 100ms 1mbit 0%

シミュレーションを検証する

NetworkSimulation.sh スクリプトを実行した後、Linux の ping コマンドと curl コマンドを使用して、ネットワーク シミュレーションが正しく設定されていることと、想定どおりに実行されていることを確認します。レイテンシを確認するには ping コマンドを使用し、帯域幅を確認するには curl コマンドを使用します。

たとえば、bash NetworkSimulation.sh 100ms 500kbit 10% の設定で実行したシミュレーションで想定される ping の出力は次のとおりです。

BUILD:/ # ping -c 20 www.google.com
PING www.google.com (172.217.5.100) 56(84) bytes of data.
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=1 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=2 ttl=119 time=105 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=3 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=5 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=6 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=7 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=9 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=10 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=11 ttl=119 time=185 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=12 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=13 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=14 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=15 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=16 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=17 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=18 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=19 ttl=119 time=103 ms
64 bytes from sfo03s07-in-f4.1e100.net (172.217.5.100): icmp_seq=20 ttl=119 time=103 ms

--- www.google.com ping statistics ---
20 packets transmitted, 18 received, 10% packet loss, time 19040ms
rtt min/avg/max/mdev = 103.394/108.307/185.756/18.791 ms

この例では、パケットロスが 10% であり、平均レイテンシが約 108 ミリであることが ping によりレポートされています。これは、シミュレーションで指定された 100ms の値に対して想定されていたとおりの出力です。レポートされるレイテンシが、指定された値と多少異なることは異常ではありません。

同じ例で curl コマンドを実行した場合に想定される出力は次のとおりです。

BUILD:/sdcard/DCIM # curl https://images-assets.nasa.gov/image/PIA15416/PIA15416~orig.jpg -o foo.jpg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 6598k  100 6598k    0     0  49220      0  0:02:17  0:02:17 --:--:-- 47574

この例では、平均ダウンロード速度が 49,220 Bps であることが curl によりレポートされています。これは、シミュレーションで指定された 500kbit の値に対して想定されていたとおりの出力です。レポートされる帯域幅が、指定された値と多少異なることは異常ではありません。