Raspberry Pi の USB-OTG ethernet の MAC address を model B の ethernet と同じ規則で設定する

Raspberry Pi model A/A+/Zero/ZeroW/ZeroHW/Compute Module/Compute module 3ではUSB-OTGが利用できます.(ZeroHW/Compute Module/Compute module 3は自分は未確認)

USB-OTGでUSBをEthernetにしてHostPCからアクセスするようにするとUSBケーブル1本で電源と併用できて便利です.

このときMACアドレスはモジュール読み込み毎に自動生成されます.
以下の例では,接続先(PC等)から見えるMACが HOST MAC 6a:b3:b1:5e:22:89 で,Raspberry Pi の中でのMACが MAC ae:3a:c7:8e:50:38 になっています.

$ sudo modprobe g_ether
$ dmesg | tail -15
[   88.517568] using random self ethernet address
[   88.517590] using random host ethernet address
[   88.519210] usb0: HOST MAC 6a:b3:b1:5e:22:89
[   88.520195] usb0: MAC ae:3a:c7:8e:50:38
[   88.520396] using random self ethernet address
[   88.520412] using random host ethernet address
[   88.520534] g_ether gadget: Ethernet Gadget, version: Memorial Day 2008
[   88.520546] g_ether gadget: g_ether ready
[   88.520580] dwc2 20980000.usb: bound driver g_ether
[   88.866651] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[   94.048758] dwc2 20980000.usb: new device is high-speed
[   94.128837] dwc2 20980000.usb: new device is high-speed
[   94.197523] dwc2 20980000.usb: new address 9
[   96.057234] g_ether gadget: high-speed config #1: CDC Ethernet (ECM)
[   96.095719] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready
$ /sbin/ifconfig usb0
usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.42.0.212  netmask 255.255.255.0  broadcast 10.42.0.255
        inet6 fe80::5855:ab0c:6628:557c  prefixlen 64  scopeid 0x20<link>
        ether ae:3a:c7:8e:50:38  txqueuelen 1000  (Ethernet)
        RX packets 208  bytes 17243 (16.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 67  bytes 7696 (7.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

これは毎回変わるのでふと気づくとホストPCのネットワークの設定が沢山になっていたり…….

$ nmcli connection show | grep ethernet | wc -l
25

MAC addressを固定するにはモジュール読み込み時に指定してあげればOKです.

$ sudo rmmod g_ether
$ sudo modprobe g_ether host_addr=de:ad:fe:ef:00:01 dev_addr=de:ad:fe:ef:00:00
$ dmesg | egrep usb0:.*MAC | tail -2
[ 1067.248443] usb0: HOST MAC de:ad:fe:ef:00:01
[ 1067.248958] usb0: MAC de:ad:fe:ef:00:00

永続化するには,g_etherモジュールを読んでいるところで指定してあげます.

/boot/cmdline.txt の場合 rootwait の前に以下を追加
modules-load=dwc2,g_cdc g_ether.host_addr=de:ad:fe:ef:00:01 g_ether.dev_addr=de:ad:fe:ef:00:00
/etc/modules の場合
g_ether g_ether.host_addr=de:ad:fe:ef:00:01 g_ether.dev_addr=de:ad:fe:ef:00:00
Note

※g_cdcの場合はこんな感じで

g_cdc g_cdc.host_addr=de:ad:fe:ef:00:01 g_cdc.dev_addr=de:ad:fe:ef:00:00

/etc/rc.local の場合 exit より前の行に以下を追加(※model Aの場合 cmdline.txt, modules 共に module は読み込まれるけど動作はうまく行かないことが多いので rc.local が良さそう)
modprobe g_ether host_addr=de:ad:fe:ef:00:01 dev_addr=de:ad:fe:ef:00:00

このときのMAC addressは g_ether が自動生成したものを使うのが無難だとおもうのですが,ランダムとかでいんだろうか?という不安があります.

ベンダーIDに使われていない領域だったら多分問題ないですが,これから埋まることもありそうです.(IPアドレスのプライベートIPアドレスのような領域があるのかもしれ無いけど未確認)

Raspberry Pi model B シリーズのNICには Raspberry Pi Foundation のベンダーコードが使われています.

nmap のMAC addressベンダー情報のファイルから確認
$ grep -i raspberry /usr/share/nmap/nmap-mac-prefixes
B827EB Raspberry Pi Foundation

Raspberry Pi の smsc95xx の MAC address の生成は,上6桁はベンダーIDの b8:27:eb を,下6桁はボードのserialの下6桁を割り当てているようです.

MAC address generation
To have a predetermined MAC address, a given SMSC LAN9512 must be attached to an EEPROM that contains the MAC address. But on the Raspberry Pi Model B, this EEPROM is not present; therefore, this driver must assign a MAC address itself. We do this by generating a MAC address from the board’s serial number. This guarantees that a given Raspberry Pi will always have the same MAC address and that two Raspberry Pis are extremely unlikely to be assigned the same MAC address.

手元の Raspberry Pi 2 Model B を確認すると確かにそうなっているようです.

$ ifconfig | grep ether
		ether b8:27:eb:ff:56:0a  txqueuelen 1000  (Ethernet)
$ grep Serial /proc/cpuinfo
Serial          : 0000000094ff560a
$ sed -n "s/^Serial.*:.*\(..\)\(..\)\(..\)$/b8:27:eb:::/p" /proc/cpuinfo
b8:27:eb:ff:56:0a
$ cat /proc/device-tree/model ;echo
Raspberry Pi 2 Model B Rev 1.1
Note

16進数6桁は 0xFFFFFF → 16777215です,Raspberry Pi は2018年3月時点で190万台出荷しているようなので2周目に入っています.低い確率でしょうが同じMAC addressが割り当てられる可能性が…….

we’ve sold 19 million Raspberry Pis in total

内蔵ネットワークに自分でMAC addressを指定したい場合はこんな感じでいけます.

/boot/cmdline.txt に以下を設定
smsc95xx.macaddr=b8:27:eb:00:00:00
/etc/network/interfaces でも設定できるはずだがRaspbianでは未確認
hwaddress ether b8:27:eb:00:00:00

CPU Serialを詐称する手も?

ということで,Raspberry Pi model A / Zero でもこの MAC address が利用できそうな感じです.外向けの HOST MAC をこのアドレスにしてみます.

$ sed -n "s/^Serial.*:.*\(..\)\(..\)\(..\)$/b8:27:eb:::/p" /proc/cpuinfo | tee ~/macaddress
b8:27:eb:d8:63:18
$ sudo vi /boot/cmdline.txt
$ sudo reboot
  :
  :
$ dmesg | grep usb0
[    4.937660] usb0: HOST MAC b8:27:eb:d8:63:18
[    4.937845] usb0: MAC 86:d7:fe:57:f2:d5

ホストPCでもちゃんと指定したものになっています.

$ /sbin/ifconfig enxb827ebd86318 | grep ether
			 ether b8:27:eb:d8:63:18  txqueuelen 1000  (Ethernet)

とりあえずこれで使ってみようと思います.

環境
$ lsb_release -d
Description:    Raspbian GNU/Linux 9.4 (stretch)
$ uname -m
armv6l
$ cat /proc/device-tree/model ;echo
Raspberry Pi Model A Rev 2