meta-facebook: fix ipv6-ll address
The correct MAC address of NCSI managerd ethernet interface is obtained
during NCSI config process. It will need run extra workaround to
regenerated IPv6-LL address based on new MAC address from NCSI.
Add service for checking the MAC address is correctly get from NIC card
via NCSI, then regenerate the IPv6-LL address.
Tested on Harma:
```
root@harma:~# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 10:70:FD:E4:3F:63
inet addr:10.10.12.110 Bcast:10.10.255.255 Mask:255.255.0.0
inet6 addr: fe80::1270:fdff:fee4:3f63/64 Scope:Link
inet6 addr: 2018:5::e52e/128 Scope:Global
inet6 addr: 2019:7::1270:fdff:fee4:3f63/64 Scope:Global
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:97642 errors:0 dropped:539 overruns:0 frame:0
TX packets:1625 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:15804387 (15.0 MiB) TX bytes:140035 (136.7 KiB)
Interrupt:42
root@harma:~# systemctl status network-wait-ipv6-ll@eth0.service
* network-wait-ipv6-ll@eth0.service - Wait IPv6 link-local initialization
Loaded: loaded (/usr/lib/systemd/system/network-wait-ipv6-ll@.service; static)
Active: active (exited) since Tue 2024-01-09 03:33:43 PST; 38s ago
Process: 271 ExecStart=/usr/libexec/check-ipv6-ll eth0 (code=exited, status=0/SUCCESS)
Main PID: 271 (code=exited, status=0/SUCCESS)
CPU: 148ms
Jan 09 03:33:41 harma systemd[1]: Starting Wait IPv6 link-local initialization...
Jan 09 03:33:41 harma check-ipv6-ll[271]: non-global mac address, start fix eth0 ipv6-ll
Jan 09 03:33:43 harma check-ipv6-ll[271]: eth0 mac: 10:70:fd:e4:3f:63
Jan 09 03:33:43 harma check-ipv6-ll[271]: expected ipv6-ll: fe80::1270:fdff:fee4:3f63
Jan 09 03:33:43 harma systemd[1]: Finished Wait IPv6 link-local initialization.
```
Signed-off-by: Potin Lai <potin.lai@quantatw.com>
Change-Id: Id3c40beda9f290d36565f0e8e146be772c9a9983
diff --git a/meta-facebook/conf/machine/include/facebook-ncsi-nic.inc b/meta-facebook/conf/machine/include/facebook-ncsi-nic.inc
new file mode 100644
index 0000000..2e93a14
--- /dev/null
+++ b/meta-facebook/conf/machine/include/facebook-ncsi-nic.inc
@@ -0,0 +1,2 @@
+MACHINE_FEATURES:append = " fb-ncsi-nic"
+MACHINEOVERRIDES:append = ":mf-fb-ncsi-nic"
diff --git a/meta-facebook/meta-harma/conf/machine/harma.conf b/meta-facebook/meta-harma/conf/machine/harma.conf
index 1599d0c..83f22a1 100644
--- a/meta-facebook/meta-harma/conf/machine/harma.conf
+++ b/meta-facebook/meta-harma/conf/machine/harma.conf
@@ -17,6 +17,7 @@
require conf/machine/include/ast2600.inc
require conf/machine/include/obmc-bsp-common.inc
require conf/machine/include/facebook-tpm2.inc
+require conf/machine/include/facebook-ncsi-nic.inc
FLASH_SIZE = "131072"
diff --git a/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/check-ipv6-ll b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/check-ipv6-ll
new file mode 100644
index 0000000..154943e
--- /dev/null
+++ b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/check-ipv6-ll
@@ -0,0 +1,71 @@
+#!/bin/bash -e
+
+eth_intf="$1"
+exp_ll=""
+ll=""
+
+is_local_mac() {
+ if [ "$((0x${1:0:2} & 0x2))" -gt 0 ]; then
+ return 0
+ fi
+ return 1
+}
+
+mac_to_ll() {
+ IFS=':' read -r -a oct <<< "$1"
+ echo "fe80::$(printf %x $((0x${oct[0]} ^ 2)))${oct[1]}:${oct[2]}ff:fe${oct[3]}:${oct[4]}${oct[5]}" | \
+ sed -E 's/:0+/:/g; s/:{3,}/::/; s/:$/:0/'
+}
+
+get_ll() {
+ ip -6 addr show dev "$eth_intf" scope link | sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'
+}
+
+if ! is_local_mac "$(cat /sys/class/net/"$eth_intf"/address)"; then
+ echo "global mac address found"
+ exit 0;
+else
+ echo "non-global mac address, start fix $eth_intf ipv6-ll"
+fi
+
+# bring up ethernet interface to start NCSI init process
+ifconfig "$eth_intf" up
+
+for _ in {1..30}; do
+ # wait getting address from NC-SI
+ mac=$(cat /sys/class/net/"$eth_intf"/address)
+ if ! is_local_mac "$mac"; then
+ exp_ll=$(mac_to_ll "$mac")
+ echo "$eth_intf mac: $mac"
+ echo "expected ipv6-ll: $exp_ll"
+ ll=$(get_ll)
+ if [ "$ll" == "$exp_ll" ]; then
+ break
+ fi
+ # re-generate link-local address
+ ip -6 addr flush dev "$eth_intf" scope link
+ echo 1 > /proc/sys/net/ipv6/conf/"$eth_intf"/addr_gen_mode
+ echo 0 > /proc/sys/net/ipv6/conf/"$eth_intf"/addr_gen_mode
+ break;
+ fi
+ sleep 1
+done
+
+# exp_ll is not assigned if global mac address not found
+if [ -z "$exp_ll" ]; then
+ echo "no global mac address found"
+ exit 1
+fi
+
+# wait for ipv6-ll to be generated
+if [ "$ll" != "$exp_ll" ]; then
+ for _ in {1..100}; do
+ usleep 10000
+ ll=$(get_ll)
+ if [ "$ll" == "$exp_ll" ]; then
+ break;
+ fi
+ done
+fi
+
+exit 0;
diff --git a/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/network-wait-ipv6-ll@.service b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/network-wait-ipv6-ll@.service
new file mode 100644
index 0000000..3ebcd21
--- /dev/null
+++ b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll/network-wait-ipv6-ll@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Wait IPv6 link-local initialization
+Before=systemd-networkd.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/libexec/check-ipv6-ll %i
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll_0.1.bb b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll_0.1.bb
new file mode 100644
index 0000000..28e016e
--- /dev/null
+++ b/meta-facebook/recipes-fb/network-wait-ipv6-ll/network-wait-ipv6-ll_0.1.bb
@@ -0,0 +1,24 @@
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+inherit obmc-phosphor-systemd
+
+RDEPENDS:${PN} += " bash"
+
+SRC_URI += " \
+ file://check-ipv6-ll \
+ file://network-wait-ipv6-ll@.service \
+ "
+
+do_install() {
+ install -d ${D}${libexecdir}
+ install -m 0755 ${WORKDIR}/check-ipv6-ll ${D}${libexecdir}
+}
+
+NCSI_ETH_INTF ?= "eth0"
+
+TGT = "${SYSTEMD_DEFAULT_TARGET}"
+NCSI_WAIT_IPV6_LL_INSTFMT="../network-wait-ipv6-ll@.service:${TGT}.wants/network-wait-ipv6-ll@{0}.service"
+
+SYSTEMD_SERVICE:${PN} += "network-wait-ipv6-ll@.service"
+SYSTEMD_LINK:${PN} += "${@compose_list(d, 'NCSI_WAIT_IPV6_LL_INSTFMT', 'NCSI_ETH_INTF')}"
diff --git a/meta-facebook/recipes-phosphor/images/fb-phosphor-image.inc b/meta-facebook/recipes-phosphor/images/fb-phosphor-image.inc
index 1c2281e..7172028 100644
--- a/meta-facebook/recipes-phosphor/images/fb-phosphor-image.inc
+++ b/meta-facebook/recipes-phosphor/images/fb-phosphor-image.inc
@@ -25,6 +25,9 @@
mmc-utils \
util-linux-blkdiscard \
"
+OBMC_IMAGE_EXTRA_INSTALL:append:mf-fb-ncsi-nic = " \
+ network-wait-ipv6-ll \
+ "
IMAGE_LINGUAS="en-us"