diff options
Diffstat (limited to 'meta-google/recipes-google/networking')
3 files changed, 142 insertions, 0 deletions
diff --git a/meta-google/recipes-google/networking/files/gbmc-mac-config.service b/meta-google/recipes-google/networking/files/gbmc-mac-config.service new file mode 100644 index 000000000..fd9247d27 --- /dev/null +++ b/meta-google/recipes-google/networking/files/gbmc-mac-config.service @@ -0,0 +1,10 @@ +[Unit] +Before=systemd-networkd.service + +[Service] +Restart=on-failure +Type=oneshot +ExecStart=/usr/libexec/gbmc-mac-config.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-google/recipes-google/networking/files/gbmc-mac-config.sh.in b/meta-google/recipes-google/networking/files/gbmc-mac-config.sh.in new file mode 100644 index 000000000..a3430a65e --- /dev/null +++ b/meta-google/recipes-google/networking/files/gbmc-mac-config.sh.in @@ -0,0 +1,82 @@ +#!/bin/bash +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source /usr/share/ipmi-fru/lib.sh || exit + +eeprom="$(of_name_to_eeprom '@EEPROM@')" || exit + +header=() +read_header "$eeprom" header || exit +internal_offset=${header[$IPMI_FRU_COMMON_HEADER_INTERNAL_OFFSET_IDX]} +if (( internal_offset == 0 )); then + echo "Internal offset invalid for eeprom" >&2 + exit 1 +fi + +# Our MAC Address configuration lives in the internal area with a format +# Offset Data +# 0 Version (Always 1) +# 1 Type (Always 1 for MAC Address) +# 2 Area Length in bytes (Always 32 bytes or 4 IPMI FRU sectors) +# 3-8 MAC Address Base Octets +# 9 Num Allocate MACs from Base +# 10-30 Padding (Always 0xFF) +# 31 IPMI FRU Checksum +internal=() +read_area "$eeprom" "$internal_offset" internal 4 || exit +if (( internal[1] != 1 || internal[2] != 32 )); then + echo "Not a MAC internal region" >&2 + exit 1 +fi +mac=("${internal[@]:3:6}") +num="${internal[@]:9:1}" +macstr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' "${mac[@]}") +echo "Base MAC $macstr num $num" >&2 + +rc=0 + +# Pre-Determine if we will miss an allocation due to the number of +# addresses the FRU actually supports. +declare -A num_to_if=(@NUM_TO_IF@) +for key in "${!num_to_if[@]}"; do + if (( key >= num )); then + echo "${num_to_if[$key]} at $key is out of range" >&2 + rc=1 + fi +done + +# Write out each MAC override to the runtime networkd configuration +for (( i=0; i<num; i++ )); do + intf="${num_to_if[$i]}" + if [ -n "$intf" ]; then + macstr=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' "${mac[@]}") + echo "Setting $intf to $macstr" >&2 + for override in /run/systemd/network/{00,}-bmc-$intf.network.d; do + mkdir -p "$override" + printf '[Link]\nMACAddress=%s\n' "$macstr" >"$override"/50-mac.conf + done + for override in /run/systemd/network/{00,}-bmc-$intf.netdev.d; do + mkdir -p "$override" + printf '[NetDev]\nMACAddress=%s\n' "$macstr" >"$override"/50-mac.conf + done + fi + if (( ++mac[5] > 0xff )); then + echo "MAC assignment too large: ${mac[@]}" >&2 + rc=2 + break + fi +done + +exit $rc diff --git a/meta-google/recipes-google/networking/gbmc-mac-config.bb b/meta-google/recipes-google/networking/gbmc-mac-config.bb new file mode 100644 index 000000000..6ca4c798b --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-mac-config.bb @@ -0,0 +1,50 @@ +SUMMARY = "Configures MAC addresses on a gBMC system" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +SRC_URI += " \ + file://gbmc-mac-config.service \ + file://gbmc-mac-config.sh.in \ + " + +S = "${WORKDIR}" + +RDEPENDS_${PN} += " \ + bash \ + ipmi-fru-sh \ + " + +FILES_${PN} += "${systemd_unitdir}" + +SYSTEMD_SERVICE_${PN} += "gbmc-mac-config.service" + +GBMC_MAC_EEPROM_OF_NAME ?= "" + +# Maps the MAC address offset from the base address to an interface name +# in bash associative array syntax. +# Ex. "[0]=eth0 [2]=eth2" +GBMC_MAC_IF_MAP ?= "" + +do_install_append() { + if [ -z '${GBMC_MAC_EEPROM_OF_NAME}' ]; then + echo 'Missing GBMC_MAC_EEPROM_OF_NAME' >&2 + exit 1 + fi + + # Build time dictionary sanity check + bash -c 'declare -A dict=(${GBMC_MAC_IF_MAP})' + + sed gbmc-mac-config.sh.in \ + -e 's#@EEPROM@#${GBMC_MAC_EEPROM_OF_NAME}#' \ + -e 's#@NUM_TO_IF@#${GBMC_MAC_IF_MAP}#' \ + >gbmc-mac-config.sh + + install -d -m0755 ${D}${libexecdir} + install -m0755 gbmc-mac-config.sh ${D}${libexecdir}/ + + install -d -m0755 ${D}${systemd_system_unitdir} + install -m0644 gbmc-mac-config.service ${D}${systemd_system_unitdir}/ +} |