LinuxマシンにUSB接続したMilk-v duoをInternetに接続する

## はじめに
秋葉原ロボット部の有志で、milk-v Duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v Duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの1. 速度でイーサーネットに接続可能

このボードのUSB-C端子をUSBケーブルで、LinuxマシンやWindowsマシンに接続すると、RNDISと表示されるLANモジュールとして認識されます。
USBケーブルで接続したマシン同士では、Ethernetに対応したアプリケーションで通信できますが、そのままでは、Milk-v DuoはInternetに接続されません。
この記事では、Linuxマシンに接続したMilk-v DuoをInternetに接続する設定を紹介します。
Linuxマシンとして、Raspberry pi OSをインストールしたRaspberry pi 4を使用しています。
Milk-v Duoで使用しているイメージファイルのバージョンは1.0.5です。
## Linuxマシン上でのMilk-v Duo
Milk-v DuoとLinuxマシンをUSBケーブルで接続した後に、Linuxマシンのコマンドプロンプトに「dmesg」を入力すると、Milk-v DuoがRNDISで接続されていることがわかります。
```
[   71.883752] usb 1-1.3: new high-speed USB device number 3 using xhci_hcd
[   71.985050] usb 1-1.3: New USB device found, idVendor=3346, idProduct=1009, b                                        cdDevice= 5.10
[   71.985078] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber                                        =3
[   71.985095] usb 1-1.3: Product: RNDIS
[   71.985110] usb 1-1.3: Manufacturer: Cvitek
[   71.985123] usb 1-1.3: SerialNumber: 0123456789
[   72.078021] usbcore: registered new interface driver cdc_ether
[   72.083816] rndis_host 1-1.3:1.0 usb0: register 'rndis_host' at usb-0000:01:0                                        0.0-1.3, RNDIS device, e2:e8:cf:87:0b:b2
[   72.083981] usbcore: registered new interface driver rndis_host
[   72.091112] usbcore: registered new interface driver rndis_wlan
```
「ip」で、ネットワークインターフェースカード（以降、NIC）を確認します。
```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether dc:a6:32:b4:72:a6 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether dc:a6:32:b4:72:a7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.11/24 brd 192.168.0.255 scope global dynamic noprefixroute wlan0
       valid_lft 85507sec preferred_lft 74707sec
    inet6 240b:251:9700:9f00:6b4:6669:3d35:4bd5/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591944sec preferred_lft 604744sec
    inet6 fe80::c72d:e687:de6d:d75c/64 scope link
       valid_lft forever preferred_lft forever
4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether e2:e8:cf:87:0b:b2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.1/24 brd 192.168.42.255 scope global dynamic noprefixroute usb0
       valid_lft 2763sec preferred_lft 2313sec
    inet6 fe80::bb91:b894:d916:b3ff/64 scope link
       valid_lft forever preferred_lft forever
```
「wlan0」がLinuxマシンのNICで、「usb0」がMilk-v DuoのNICです。
異なったネットワークに所属していることがわかります。

## Linuxマシン側のネットワーク設定
```
$ sudo sysctl net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
$ sudo iptables -P FORWARD ACCEPT
$ sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
```
設定がどのように反映されているかを、「ifconfig」で確認します。
ここでは、変更された部分のみ表示します。
```
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.141  netmask 255.255.255.0  broadcast 192.168.42.255
        inet6 fe80::bb91:b894:d916:b3ff  prefixlen 64  scopeid 0x20<link>
        ether e2:e8:cf:87:0b:b2  txqueuelen 1000  (Ethernet)
        RX packets 20  bytes 1648 (1.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27  bytes 4890 (4.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.11  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::c72d:e687:de6d:d75c  prefixlen 64  scopeid 0x20<link>
        inet6 240b:251:9700:9f00:6b4:6669:3d35:4bd5  prefixlen 64  scopeid 0x0<global>
        ether dc:a6:32:b4:72:a7  txqueuelen 1000  (Ethernet)
        RX packets 2332  bytes 518352 (506.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 509  bytes 105256 (102.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```
「usb0」のIPアドレスが「192.168.42.141」に変更されました。
## Milk-v Duo側のネットワーク設定
先ほど調べた「192.168.42.141」を使って設定します。
「8.8.8.8」はDNSサーバーのアドレスです。
```
[root@milkv-duo]~# ip r add default via 192.168.42.141
[root@milkv-duo]~#echo "nameserver 8.8.8.8" >> /etc/resolv.conf
```
早速、Internetに接続されているか確認します。
```
[root@milkv-duo]~# ping www.yahoo.co.jp
PING www.yahoo.co.jp (182.22.31.252): 56 data bytes
64 bytes from 182.22.31.252: seq=0 ttl=56 time=35.350 ms
64 bytes from 182.22.31.252: seq=1 ttl=56 time=22.402 ms
64 bytes from 182.22.31.252: seq=2 ttl=56 time=21.581 ms
64 bytes from 182.22.31.252: seq=3 ttl=56 time=21.462 ms
^C
--- www.yahoo.co.jp ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 21.462/25.198/35.350 ms
[root@milkv-duo]~#
```
「www.yahoo.co.jp」につながりました。
wgetコマンドでファイルのダウンロードを試みます。
```
[root@milkv-duo]~# wget www.yahoo.co.jp
Connecting to www.yahoo.co.jp (182.22.16.251:80)
wget: not an http or ftp url: https://www.yahoo.co.jp:443/
[root@milkv-duo]~#
```
Milk-v Duo用の「wget」は「http」と「ftp」のみに対応しているようです。

## おわりに
Millk-v duoをインターネットに接続する方法には、専用のLANアダプタやIOボードを利用する方法があります。
Linuxマシンが手元にある場合、今回の設定を採用することにより、追加投資なくmilk-v Duoをインターネットに接続できることになります。

参考　https://community.milkv.io/t/linux-iptables-nat/542