2022年3月3日木曜日

Zynq Linuxの2つ目(サブ・増設)のEthernetのMACアドレスを設定する(1つ目と関連付けさせる)

現在使用しているZynq7020ボードにはなぜかLANポートが2つ(Zynq PSのEthernet0、1どっちも使っている。いわゆるNIC2枚挿し状態)あり、メインで使用するポート(eth0)はEEPROMに書き込まれた値をMACアドレスとして使用している。
なお、EEPROMの値からMACアドレスを設定する方法はこちらを参考にした。(http://nahitafu.cocolog-nifty.com/nahitafu/2018/01/zynq.html)
もう片方のポート(eth1)はローカルでしか使用せず、同じローカルネットワーク内(正確に言えばブロードキャストドメイン内)に複数の同Zynqボードが存在する=MACアドレスが重複する状況は想定していなかったため特に設定していなかった。
しかし状況が変わりeth1側のネットワークにも複数のZynqボードが存在しMACアドレスが重複する可能性が出てきた。そのためeth1側のMACアドレスも重複しないような対策をしなければならなくなった。


対策案としては、
案1.eth0のようにEEPROMにMACアドレスを書き込んでおいて使用する
案2.デバイスツリーに「local-mac-address = [11 22 33 44 55 66]」を記載する
案3.「ifconfig eth1 hw ether 11:22:33:44:55:66」等のコマンドをsystemdで起動時に実行する
案4.u-bootにeth1のMACアドレスも定義しておく
が考えられたがどうやら案2はu-bootがデバイスツリーの値を上書きしてしまうし、案3も変更後すぐに元のMACアドレスに戻ってしまうらしい。案4は基板毎にu-bootをビルドしなければならず大変。しかも案2と3、4はMACアドレスが基板依存ではなくSDカード依存になってしまう。
かといって案1はEEPROMに書き込む手間も増えるし(eth0のを書くついでにできなくもなさそうだけど)、既に手元にないZynqボードのEEPROMは書き換えられない。
既にeth0用のMACアドレスはEEPROMに書いてあり一意のものであることから、eth0のMACアドレスをチョイ変したものをeth1のMACアドレスとして設定することにした。

上記のu-bootによるデバイスツリー上書きやすぐに元のMACアドレスに戻ってしまう問題により、実質u-bootでしかMACアドレスを設定できないのでu-bootのソースを少し書き換えることにした。
EEPROMの値からMACアドレスを設定する方法で参考にしたページによると、u-boot-xlnx/common/fdt_support.cの関数fdt_fixup_ethernet()内にてデバイスツリーへMACアドレスを追加・上書きしているようだ。この関数内をいじれば設定できそうだ。
具体的に書き換えた場所は
if (i != -1) {
if (i == 0)
strcpy(mac, "ethaddr");
else
sprintf(mac, "eth%daddr", i);
} else {
continue;
}
if (i != -1) {
if (i == 0 || i == 1)
strcpy(mac, "ethaddr");
else
sprintf(mac, "eth%daddr", i);
} else {
continue;
}

for (j = 0; j < 6; j++) {
mac_addr[j] = tmp ?
      simple_strtoul(tmp, &end, 16) : 0;
if (tmp)
tmp = (*end) ? end + 1 : end;
}
for (j = 0; j < 6; j++) {
if (i == 1 && j == 5) {
mac_addr[j] = tmp ?
      simple_strtoul(tmp, &end, 16) + 1 : 0;
} else {
mac_addr[j] = tmp ?
      simple_strtoul(tmp, &end, 16) : 0;
}
if (tmp)
tmp = (*end) ? end + 1 : end;
}
に変えた。
最初の変更箇所はethernet1(eth1)のときもethernet0(eth0)のMACアドレスを変数macに取得するようにし、(変数iにはethernetXのXの値が入るようだ)
次の変更箇所はiが1(=ethernet1)のとき最初の変更箇所で変数macに取得したethernet0のMACアドレスを少し加工するようにした。この変更の場合はベンダ独自管理部分の最下位バイトに+1するようになっている。
このようにeth1はeth0のMACアドレスの最下位バイトに1足すようにして、MACアドレスは2づつインクリメントするように払い出していけば比較的楽に管理できる。(アドレスに+1したときのオーバーフローに注意)
jはMACアドレスのバイト目を表しているのでjが0~2がOUI(ベンダID)、3~5がベンダ独自管理部分となる。
ちなみに安易な考えでj=0にして最上位バイトに1を加えるようにしたらうまく反映されなかった。MACアドレスの最上位バイトの0ビット目は特殊ビットだからかもしれない。

0 件のコメント:

コメントを投稿