L-02C で qmi 接続できるようになった ので、少し足を延ばしてIPv6接続を頑張ってみた。SIMはみおふぉんを使っているので、IPv6も使えることになっている。
Raspbian jessie-lite をベースにします。下に行くにしたがって重装備になっていきます。
libqmi
まずモデムはqcserial
とqmi_wwan
で認識されている状態にする。すると /dev/cdc-wwan0
で qmi プロトコルで通信できるようになっている。libqmi を使って、コマンドラインからqmiプロトコルで操作できる。前回使った qmi-network はこの形。
実は qmi-network
は shell script で、実体は qmicli
がやっている。中身を抜き出すとこんな感じになっている。
# qmicli -d /dev/cdc-wdm0 --wds-start-network=iijmio.jp,auth=CHAP,mio@iij,iij --client-no-release-cid
[/dev/cdc-wdm0] Network started
Packet data handle: '28388580'
[/dev/cdc-wdm0] Client ID not released:
Service: 'wds'
CID: '3'
# qmicli -d /dev/cdc-wdm0 --wds-stop-network=28388580 --client-cid=3
Network cancelled... releasing resources
[/dev/cdc-wdm0] Network stopped
IPv6 PDP
IPv6 接続を明示的に行いたい場合はPDP typeを指定することになる。本家の開発repositoryだと、--wds-start-network-apn
の引数が拡張されて、ip-type
を指定できるようになっている。(libqmi リリース済みのものは今のところ無い)。こんな感じでビルドする。
# apt-get install gtk-doc-tools libglib2.0-dev
# git clone https://anongit.freedesktop.org/git/libqmi.git
# cd libqmi
# ./autogen.sh
# make install
--wds-start-network
の引数の形が変わっていることに注意して、ip-type
を指定した場合は、こんな感じになる。
# /usr/local/bin/qmicli -d /dev/cdc-wdm0 --wds-start-network=apn=iijmio.jp,auth=CHAP,username=mio@iij,password=iij,ip-type=6 --client-no-release-cid
[/dev/cdc-wdm0] Network started
Packet data handle: '28388580'
[/dev/cdc-wdm0] Client ID not released:
Service: 'wds'
CID: '3'
IPv6 割り当て
そんなこんなでIPv6アドレスが割り当てられたことは --wds-get-current-settings
というコマンド引数を使って確認する。この引数は 1.14.2 や 1.16.0 に入っている(残念ながら raspbian jessie の 1.10.2 には入っていない)。
# /usr/local/bin/qmicli -d /dev/cdc-wdm0 --wds-get-current-settings
[/dev/cdc-wdm0] Current settings retrieved:
IP Family: IPv6
IPv6 address: 2001:240:2401:e6de:74a5:fb54:ee07:d515/64
IPv6 gateway address: 6ce8:84f1:945a:a678::/64
IPv6 primary DNS: 2001:240::13
IPv6 secondary DNS: 2001:240::14
MTU: 1500
Domains: none
ログに書いてあるように、この値を使って wwam0
の IP アドレスや DNS 登録を更新するのが、通信コストの最も安い方法のようだ。
qmicli
自体には自動的に wwan0
に割り当てる仕組みはない。想像だけれども、理由は PPP pdp の場合は pppd
がアドレス設定を行うので、そことの整合性を取って自動設定しない、ということではないだろうか。dhcpcd
などで割り当てを行うのが良いだろう。
ちなみに L-02C では wwan0
を通じて IPv6 RA を取得すると値がおかしかった(原因未調査)ので、この値を使うべし。てくろぐに「L-02Cでは機器の仕様上、IPv6のDNSサーバを自動的に取得することができない」と書いてあるのと関係があるのかもしれない。UX302NC では正常な値で取得されたので、そうなのだろう。この場合でも、上位が DHCPv6 で配布している IIJmio みおふぉんの環境では、dhcpcd
6.9.4 以降で使える inform6
を使うと、L-02C でも wwan0
に global scope の IPv6 アドレスを自動的に割り当てられた。この割り当ては qmi 上での割り当てとは別に wwan0
リンク上で行われるもので、異なるアドレスが割当たる。
interface wwan0
inform6
ModemManager
qmi 接続よりももう少し抽象度を上げて、qmi や mbim もひっくるめて扱える便利なプログラム ModemManager というものがある。raspbian jessie ではmodemmanager
というパッケージで入る(libqmi-proxy
とpolicykit-1
パッケージも入れておく)。
ModemManager は daemon が常駐していて、その daemon が /dev/cdc-wwan0
を管理する。ModemManager も qmicli と同様に libqmi を使って QMI プロトコル通信する。コマンドライン mmcli
からは D-BUS 経由で ModemManager と通信する。
L-02C --(USB)-- qmi_wwan -- /dev/cdc-wwan0 --(qmi)-- ModemManager --(D-Bus)-- mmcli
mmcli
からは D-Bus 経由になるので、少し雰囲気が変わる。マニュアルを参照しながら使う。具体的な操作例はこんな感じになる。
# mmcli -L
Found 1 modems:
/org/freedesktop/ModemManager1/Modem/0 [LG Electronics Inc] docomo L02C
マニュアルに -m, --modem=[PATH|INDEX]
と書いてあるけれど、PATH というのは「D-Bus の PATH」で、例えば上の /org/freedesktop/ModemManager1/Modem/0
ですね。INDEX のほうは、最後の 0
だけを指しています。どちらで指定しても大丈夫。接続~切断までの簡単な流れは次の通り。
# mmcli -m 0 -e
# mmcli -m 0 --simple-connect=apn=iijmio.jp,user=mio@iij,password=iij
successfully connected the modem
# mmcli -m 0 --list-bearers
Found 1 bearers:
/org/freedesktop/ModemManager1/Bearer/0
# mmcli -b 0
Bearer '/org/freedesktop/ModemManager1/Bearer/0'
-------------------------
Status | connected: 'yes'
| suspended: 'no'
| interface: 'wwan0'
| IP timeout: '20'
-------------------------
Properties | apn: 'iijmio.jp'
| roaming: 'allowed'
| IP type: 'none'
| user: 'mio@iij'
| password: 'iij'
| number: 'none'
| Rm protocol: 'unknown'
-------------------------
IPv4 configuration | method: 'dhcp'
| address: 'unknown'
| prefix: '0'
| gateway: 'unknown'
| DNS: none
| MTU: '1500'
-------------------------
IPv6 configuration | method: 'unknown'
# mmcli -b 0 -x
successfully disconnected the bearer
# mmcli -m 0 -d
--simple-connect
は --create-bearer
と -b [PATH|INDEX] --connect
を一気に実行するショートカット。もちろん別々にやってもいい。
IPv4 の設定は qmi 経由では取れたり取れなかったりする様子で、dhcpcd
が wwan0
上で自動取得するのに任せるのが良さそう。単に mmcli -m 0
とやると、モデムの情報が取得できる。
IPv6 PDP
接続する際に次のようにすると、明示的に IPv6 になる。
# mmcli -m 0 --simple-connect=apn=iijmio.jp,user=mio@iij,password=iij,ip-type=ipv6
successfully connected the modem
IPv6 割り当て
# mmcli -b 1
Bearer '/org/freedesktop/ModemManager1/Bearer/1'
-------------------------
Status | connected: 'yes'
| suspended: 'no'
| interface: 'wwan0'
| IP timeout: '20'
-------------------------
Properties | apn: 'iijmio.jp'
| roaming: 'allowed'
| IP type: 'ipv6'
| user: 'mio@iij'
| password: 'iij'
| number: 'none'
| Rm protocol: 'unknown'
-------------------------
IPv4 configuration | method: 'unknown'
-------------------------
IPv6 configuration | method: 'dhcp'
| address: '2001:240:2401:2bfd:189f:2fdf:b0c3:8b'
| prefix: '64'
| gateway: 'e03f:496e:14a1:762e::'
| DNS: '2001:240::13', '2001:240::14'
| MTU: '1500'
IPv6 のときは qmi でアドレスが入っている。こちらも wwan0
に自動的にアドレスが割当たったり、DNS 設定がされたりとかはしないので、この値をみて手動で割り当てるべし。
繰り返しになるけれども L-02C では DHCPv6 で情報が取れないので、この値に頼るしかない様子です。
NetworkManager
実は NetworkManager は最近では ModemManager と連携するようになっている。raspbian jessie に network-manager
パッケージをインストールする。
L-02C --(USB)-- qmi_wwan -- /dev/cdc-wwan0 --(qmi)-- ModemManager --(D-Bus)-- NetworkManager --(D-Bus)-- nmcli
接続~切断は次のようなコマンドになる。
# nmcli connection add autoconnect no type gsm ifname cdc-wdm0 apn iijmio.jp user mio@iij password iij
Connection 'gsm-cdc-wdm0' (b518ef13-8c72-45bb-ac1a-588db73ab1f3) successfully added.
# nmcli c up b518ef13-8c72-45bb-ac1a-588db73ab1f3
# nmcli c down b518ef13-8c72-45bb-ac1a-588db73ab1f3
IPv6 PDP
NetworkManager 1.0.0 から IPv6 接続がサポートされるので、別途コンパイルしてインストールする。Raspbian jessie のパッケージは 0.9 なので。NetworkManager 1.2.4 (stable) をインストールする際には libmm-glib-dev
, libreadline6-dev
, libndp-dev
, ppp-dev
, libnss3-dev
, uuid-dev
, libnl-3-dev
, libgudev-1.0-dev
, libdbus-glib-1-dev
パッケージをインストールしておく。
インストール後 ln -s /etc/NetworkManager /usr/local/etc
しておくと簡単。
systemctl unmask NetworkManager
systemctl unmask NetworkManager-dispatcher
明示的に PDP は指定できないけれども、モデムがサポートしていれば IPv6 を自動的に有効にしている。NetworkManager 側で IPv4 を無効化すれば IPv6 専用となる。
IPv6 割り当て
NetworkManager が D-Bus 経由で ModemManager の情報をシステムに反映してくれる。全自動。
接続~切断はこんな感じになる。
# nmcli d
DEVICE TYPE STATE CONNECTION
cdc-wdm0 gsm disconnected --
eth0 ethernet unmanaged --
lo loopback unmanaged --
wlan0 wifi unmanaged --
# nmcli c add autoconnect no type gsm ifname cdc-wdm0 apn iijmio.jp user mio@iij password iij
Connection 'gsm-cdc-wdm0' (23ac16f0-5f8f-4080-969b-43a4ed13aa4e) successfully added.
# nmcli c modify 23ac16f0-5f8f-4080-969b-43a4ed13aa4e ipv4.method Disabled
# nmcli c up 23ac16f0-5f8f-4080-969b-43a4ed13aa4e
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1)
# ip addr show dev wwan0
4: wwan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
link/ether 76:b0:b5:85:6d:ee brd ff:ff:ff:ff:ff:ff
inet6 2001:240:2403:8213:94dd:bfe:8a47:154f/64 scope global
valid_lft forever preferred_lft forever
# nmcli c show 23ac16f0-5f8f-4080-969b-43a4ed13aa4e
connection.id: gsm-cdc-wdm0
connection.uuid: 23ac16f0-5f8f-4080-969b-43a4ed13aa4e
connection.interface-name: cdc-wdm0
connection.type: gsm
connection.autoconnect: yes
connection.autoconnect-priority: 0
connection.timestamp: 1471871592
connection.read-only: no
connection.permissions:
connection.zone: --
connection.master: --
connection.slave-type: --
connection.autoconnect-slaves: -1 (default)
connection.secondaries:
connection.gateway-ping-timeout: 0
connection.metered: unknown
connection.lldp: -1 (default)
ipv4.method: disabled
ipv4.dns:
ipv4.dns-search:
ipv4.dns-options: (default)
ipv4.dns-priority: 0
ipv4.addresses:
ipv4.gateway: --
ipv4.routes:
ipv4.route-metric: -1
ipv4.ignore-auto-routes: no
ipv4.ignore-auto-dns: no
ipv4.dhcp-client-id: --
ipv4.dhcp-timeout: 0
ipv4.dhcp-send-hostname: yes
ipv4.dhcp-hostname: --
ipv4.dhcp-fqdn: --
ipv4.never-default: no
ipv4.may-fail: yes
ipv4.dad-timeout: -1 (default)
ipv6.method: auto
ipv6.dns:
ipv6.dns-search:
ipv6.dns-options: (default)
ipv6.dns-priority: 0
ipv6.addresses:
ipv6.gateway: --
ipv6.routes:
ipv6.route-metric: -1
ipv6.ignore-auto-routes: no
ipv6.ignore-auto-dns: no
ipv6.never-default: no
ipv6.may-fail: yes
ipv6.ip6-privacy: -1 (unknown)
ipv6.addr-gen-mode: stable-privacy
ipv6.dhcp-send-hostname: yes
ipv6.dhcp-hostname: --
gsm.number: *99#
gsm.username: mio@iij
gsm.password: <hidden>
gsm.password-flags: 0 (none)
gsm.apn: iijmio.jp
gsm.network-id: --
gsm.pin: <hidden>
gsm.pin-flags: 0 (none)
gsm.home-only: no
gsm.device-id: --
gsm.sim-id: --
gsm.sim-operator-id: --
GENERAL.NAME: gsm-cdc-wdm0
GENERAL.UUID: 23ac16f0-5f8f-4080-969b-43a4ed13aa4e
GENERAL.DEVICES: cdc-wdm0
GENERAL.STATE: activated
GENERAL.DEFAULT: no
GENERAL.DEFAULT6: yes
GENERAL.VPN: no
GENERAL.ZONE: --
GENERAL.DBUS-PATH: /org/freedesktop/NetworkManager/ActiveConnection/1
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/Settings/3
GENERAL.SPEC-OBJECT: /
GENERAL.MASTER-PATH: --
IP4.ADDRESS[1]: 169.254.136.188/16
IP4.GATEWAY:
IP6.ADDRESS[1]: 2001:240:2403:8213:94dd:bfe:8a47:154f/64
IP6.GATEWAY: 345e:3437:1252:9881::
IP6.DNS[1]: 2001:240::13
IP6.DNS[2]: 2001:240::14
# nmcli c down 23ac16f0-5f8f-4080-969b-43a4ed13aa4e
Connection 'gsm-cdc-wdm0' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1)
Ubuntu Mate
もういっそここまで来たら Raspbian jessie じゃなくて Ubuntu Mate 使ったほうが手っ取り早いかも。NetworkManager で QMI ですぐに繋がるし、IPv6 も wwan0
に反映される。DNS登録も入るし、経路も入る。
IPv6 のみの接続が最初うまくいかないときは、IPv4v6 で一度接続してから、IPv6 にするといけたりするみたい(未調査)。
まとめ
方法がいくつかあるのをまとめると、こんな選択肢になるだろう。
- libqmi master HEAD をインストール + ネットワーク設定手動反映
- ModemManager + ネットワーク設定手動反映
- NetworkManager 1.2.4 をインストール
- (Raspbian ではなく)Ubuntu Mate をインストール
私は libqmi を Raspbian に入れて使おうかなぁ…
libqmi
, ModemManager
を作り上げた Aleksander Morgado さんに感謝!