OpenWRT(LEDE)で HUAWEIのモバイルルーターを使用する
はじめに
家には光ファイバーによる固定回線があるんですが、 公開サーバーを建てるにあたってその固定回線に迷惑がかからないように、 ゲートウェイからセグメントを変えてネット環境を構築したいなと思いました。
そこで目をつけたのが、モバイル回線です。今回はモバイルルーターである、 HUAWEIの「504HW」を使用できるようにしていきます。
LinuxからのHUAWEI製モバイルルーターの利用
基本的にソフトバンク系のPocket WiFiなどで使用されてきた HUAWEI製のLTEモバイルルーターは対応OSがWindows, Macとされていて、 Linux用のドライバは明に公開されていません。
しかし、どうもグローバル版のLinux用ドライバを使用することができるようで、 ググってみると結構情報が出てきます。
500番台のモバイルルーターはどうも「GL04P」などと同じように、 「HUAWEI Data Cards Linux Driver」を使用することでLinux側からも利用可能みたいです。
調べてみるとWiMAXのモバイルルーターはつなぐとRNDISでつながるらしく、 (つまりスマホでテザリングしているのと同じ繋がり方)挿すだけで使えるようになるらしいです。羨ましい。
OpenWRTでスマホのテザリングを使用するのはRNDISのドライバをopkg入れるだけみたいですね。 HUAWEI P9でやってみましたが、ちゃんと使えました。
HUAWEI Data Cards Linux Driverのビルド
ここが鬼門です。今回使用する「WZR-HP-AG300H」という機材はCPUのアーキテクチャがMIPSで、 (気合で突破する方法を除き、)クロスコンパイルする必要があります。 どうも過去の自分の記事を読むとこれを実施しているようですが
手順を残しておらず、呆れ果てました。今回はちゃんと書きます。
使えるKernelのバージョンに制限がある
今回色々と試してみた結果、使えるLinux Kernelのバージョンが4.4あたりまでということです。 つまり、LEDE 17.01.6が限度のようでした。
OpenWRT 18, 19 では Kernel 4.9 や 4.14 を使用しているのでそもそもビルドすることができませんでした。
具体的には、net_deviceの仕様が変わっており、net_device has no member named trans_start
エラーを突破できません。
ググって軽く見つかるワークアラウンドを試してみるとビルドは通るものの、kernel panicでOSごと落ちてしまいました。 カーネルの非互換恐ろしや・・・
LEDE 17.01.6用にビルドする
というわけで、Kernel 4.4を採用しているLEDE 17.01.6用にビルドしていきます。 前回の記事でも確かLEDE 17.01.6を使用していた気がします。
SDKの準備
OpenWRT(LEDE)用のクロスコンパイル環境を整えるのは簡単です。 OpenWRTがすでにビルド済みの環境を提供してくれていて、対応するバージョンのSDKをダウンロードして展開するだけです。
OpenWrt Project: Using the SDK
今回は上記サイトより、
lede-sdk-17.01.6-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz
をダウンロードしました。
使用する機材が WZR-HP-AG300H
なので ar71xx
のsdkをダウンロードしましたが、
ここは機材によって変える必要があります。適宜読み替えてください。
展開する
私はWindowsユーザーなのでWSL2上に環境を構築しました。
tar xvf lede-sdk-17.01.6-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz
として、適当なフォルダに展開しました。この先展開先を /path/to/sdk/
と表します。適宜読み替えてください。
HUAWEIドライバのダウンロード
適当なサイトから「HUAWEI Data Cards Linux Driver」をダウンロードしてください。 もう公式サイトからは提供されていないため、2次配布されているサイトからダウンロードする他ありません。
tar zxf Linux\ Driver\ 4.19.19.00.tar.xz
として、ダウンロードしたドライバを展開します。
すると中に driver/ndis_driver/ndis_src
というフォルダがあるので、
cp -r Linux\ Driver\ 4.19.19.00.tar/driver/ndis_driver/ndis_src ~/
として適当な作業フォルダにコピーします。 今後の作業はこのフォルダにて行います。
cd ~/ndis_src
ソースコードの修正
このままだとクロスコンパイルできないので、クロスコンパイル用に修正していきます。
まずは src/Makefile
KVER := $(shell uname -r) # KDIR := /lib/modules/$(KVER)/build # KDIR := /path/to/sdk/lede-sdk-17.01.6-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/build_dir/target-mips_24kc_musl-1.1.16/linux-ar71xx_generic/linux-4.4.153 KMISC := /lib/modules/$(KVER)/kernel/drivers/usb/net KEXT := $(shell echo $(KVER) | sed -ne 's/^2\.[567]\..*/k/p')o
Makefile冒頭のmake用の変数を修正していきます。どうせ一度しかビルドしないので直書きしてしまいましたw
modules: #$(PWD)/src/add_header.sh "modules" "$(KDIR)/include/linux/usb" # $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)/src modules $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)/src ARCH=mips CROSS_COMPILE=mips-openwrt-linux- modules strip --strip-debug hw_cdc_driver.$(KEXT)
Makefileのmodules ターゲットを修正しました。
具体的には make を実行する際に ARCH=mips CROSS_COMPILE=mips-openwrt-linux-
オプションを指定します。
次にソースコードです。 src/hw_cdc_driver.c
を修正します。
135行目
// #include <linux/unaligned/access_ok.h>
2718行目
// dbg ("can't kmalloc dev");
それぞれコメントアウトします。
ビルドの実行
ビルドを実行する前に、クロスコンパイル用のgccにPATHを通します。
export PATH=/path/to/sdk/lede-sdk-17.01.6-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/bin:$PATH export STAGING_DIR=/path/to/sdk/lede-sdk-17.01.6-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/
これでビルドできるはずです。 makeしてみましょう
make modules
LEDEへのカーネルモジュールコピー
そして出来上がったカーネルモジュールをコピーします。
scp src/hw_cdc_driver.ko root@XXX.XXX.XXX.XXX:/root/
で、コピーされたファイルを /lib/modules/カーネルバージョン/
フォルダに配置します。(私の場合は /lib/modules/4.4.153/
)
配置が完了したら、
modprobe hw_cdc_driver
でモジュールがロードできたら完了です。
もしかすると mii
が足りないと言われるので、 opkg install kmod-mii
で miiをインストールしてください。
あとは、モバイルルーターが接続されたときにCDROMとしてマウントされてしまうのを防ぐために、
usb_modeswitch
を導入します。
opkg install usb-modeswitch
で導入できます。これでモバイルルーターを接続すると eth2
として認識されるはずです。
完成!モバイルネットワーク環境
こんな感じになりました。 504HWがソフトバンクの4G回線を拾い、LEDEにIPが振られローカルネットワークから出られるようになりました。
2重ルーター(NAT)になるのが気持ち悪いですが、まぁ仕方ない。 (事業者から振られているのがプライベートIPなので更に段数は増えるか?)
終わりに
以前はこの方法でいけたので今回もなぞってやってみました。 ちょっと不安なのがLinuxのカーネルのバージョンの都合上、 サポート切れのLEDEを使用しなければならないことです。
OpenWRTの19系を使用したかったのですが、Linux力が足りず、カーネルモジュールをうまくビルドできませんでした。 (モジュール自体はビルドできたが、使用しようとするとカーネルパニックで落ちる)
まぁあくまで一時的な利用に控えようと思います。
それはそれとして、2年前構築したときはグローバルIPが降ってきてた気がするんですが、 最近ではプライベートIPしか降ってこないんだろうか・・・? 困る・・・