diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 435781a774..5ed75852cb 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -206,8 +206,7 @@ write_boot_configs() { elif [ ! -f "$cmdline_base" ]; then # some systems were started with other versions of this script and therefore # do not have the $cmdline_base file. we assume that we are on Sonic or EOS. - cat /proc/cmdline > $cmdline_base - sed -Ei 's/^(.*) rw .*$/\1/' $cmdline_base + cat /proc/cmdline | sed -E 's/^(.*) rw .*$/\1/' | tr ' ' '\n' > $cmdline_base fi cp $cmdline_base /tmp/append @@ -215,6 +214,10 @@ write_boot_configs() { platform_specific echo "rw loop=$image_name/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >> /tmp/append + # Pass the MAC address to the new kernel as a command line parameter. This makes it + # possible to restore the MAC address in the new kernel without requiring driver modifications. + [ "${NETDEV}" ] || NETDEV=ma1 + echo "hwaddr_${NETDEV}=$(cat /sys/class/net/${NETDEV}/address)" >> /tmp/append # use extra parameters from kernel-params hook if the file exists if [ -f "$target_path/$kernel_params" ]; then diff --git a/files/initramfs-tools/arista-net b/files/initramfs-tools/arista-net index 1fbe4838ad..8759746458 100644 --- a/files/initramfs-tools/arista-net +++ b/files/initramfs-tools/arista-net @@ -26,20 +26,72 @@ for x in "$@"; do esac done -arista_net_rename() { - local device_path="$1" - local new_name="$2" - local from_name="$3" - for path in $(ls -d /sys/class/net/$from_name* 2>/dev/null); do +random() { + echo $(od -vAn -N1 -tu1 < /dev/urandom) +} + +arista_net_devname() { + local pciaddr="$1" + local devname_prefix="$2" + for path in $(ls -d /sys/class/net/${devname_prefix}* 2>/dev/null); do local devid="$(realpath "$path/device")" - if echo "$devid" | grep -q "$device_path"; then - local cur_name="${path##*/}" - ip link set "$cur_name" name "$new_name" + if echo "$devid" | grep -q "$pciaddr"; then + echo "${path##*/}" return fi done } +arista_net_rename() { + local device_path="$1" + local new_name="$2" + local from_name="$3" + devname=$(arista_net_devname "$device_path" "$from_name") + [ -n "$devname" ] && ip link set "$devname" name "$new_name" +} + +# Sets the MAC address to the value passed by Aboot through /proc/cmdline +tg3fixhwaddr() +{ + local default_tg3_hwaddr="00:10:18:00:00:00" + local pciaddr="$1" + local hwaddr="$2" + + devname=$(arista_net_devname "$pciaddr") + if [ -z "$devname" ]; then + return + fi + + driver=$(basename $(readlink "/sys/class/net/$devname/device/driver")) + if [ "$driver" != "tg3" ]; then + return 0 + fi + + if [ "$hwaddr" = "$default_tg3_hwaddr" ]; then + hwaddr=$(cat /sys/class/net/$devname/address) + fi + + if [ "$hwaddr" = "$default_tg3_hwaddr" ]; then + hwaddr=$(printf "%02x" "$(($(random) & 0xfe | 0x02))") + for i in 1 2 3 4 5; do + hwaddr=$(printf "$hwaddr:%02x" "$(($(random) & 0xfe | 0x02))") + done + fi + + ip link set dev "$devname" addr "$hwaddr" +} + +if [ -n "$aboot_flag" ]; then + for item in $items; do + key="${item%=*}" + value="${item#*=}" + hwaddr=$(eval echo \${hwaddr_${key}}) + if [ -n "$hwaddr" ]; then + tg3fixhwaddr "$value" "$hwaddr" + fi + done +fi + # Iterate over all the net_maX items found in the cmdline two times. # First time renaming the interfaces to maX. # The second time renaming them to their final name ethX.