1#!/bin/bash 2# Copyright 2021 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# A list of functions which get executed for each bound DHCP lease. 17# These are configured by the files included below. 18# Shellcheck does not understand how this gets referenced 19# shellcheck disable=SC2034 20GBMC_BR_DHCP_HOOKS=() 21 22# A dict of outstanding items that should prevent DHCP completion 23declare -A GBMC_BR_DHCP_OUTSTANDING=() 24 25# SC can't find this path during repotest 26# shellcheck disable=SC1091 27source /usr/share/network/lib.sh || exit 28# SC can't find this path during repotest 29# shellcheck disable=SC1091 30source /usr/share/gbmc-br-lib.sh || exit 31 32# Load configurations from a known location in the filesystem to populate 33# hooks that are executed after each event. 34gbmc_br_source_dir /usr/share/gbmc-br-dhcp || exit 35 36# We don't want to allow 2 simultaneous sessions. Check for a pidfile 37PID_FILE=/run/gbmc-br-dhcp.pid 38exec {PID_FD}<>$PID_FILE 39# If we can't acquire the lock we already have a successful DHCP process in the works 40flock -xn $PID_FD || exit 0 41 42# Write out the current PID and cleanup when complete 43trap 'rm -f $PID_FILE' EXIT 44echo "$$" >&$PID_FD 45 46if [ "$1" = bound ]; then 47 # Variable is from the environment via udhcpc6 48 # shellcheck disable=SC2154 49 echo "DHCPv6(gbmcbr): $ipv6/128" >&2 50 51 update-dhcp-status 'ONGOING' "Received dhcp response ${ipv6}" 52 pfx_bytes=() 53 ip_to_bytes pfx_bytes "$ipv6" 54 # Ensure we are a BMC and have a suffix nibble, the 0th index is reserved 55 # Alternatively, we may also have received a /64 for the OOB address 56 if (( pfx_bytes[8] != 0xfd || (pfx_bytes[9] & 0xf) == 0 )) && 57 (( pfx_bytes[8] != 0 || pfx_bytes[9] != 0 )); then 58 echo "Invalid address prefix ${ipv6}" >&2 59 update-dhcp-status 'ONGOING' "Invalid address prefix ${ipv6}" 60 exit 1 61 fi 62 # Ensure we don't have more than a /80 address 63 for (( i = 10; i < 16; ++i )); do 64 if (( pfx_bytes[i] != 0 )); then 65 echo "Invalid address ${ipv6}" >&2 66 update-dhcp-status 'ONGOING' "Invalid address ${ipv6}" 67 exit 1 68 fi 69 done 70 71 update-dhcp-status 'ONGOING' "Setting hostname ${fqdn} and ip ${ipv6}" 72 73 pfx="$(ip_bytes_to_str pfx_bytes)" 74 gbmc_br_set_ip "$pfx" || exit 75 76 if [ -n "${fqdn-}" ]; then 77 echo "Using hostname $fqdn" >&2 78 hostnamectl set-hostname "$fqdn" || true 79 fi 80 81 gbmc_br_run_hooks GBMC_BR_DHCP_HOOKS || exit 82 83 # If any of our hooks had expectations we should fail here 84 if [ "${#GBMC_BR_DHCP_OUTSTANDING[@]}" -gt 0 ]; then 85 echo "Not done with DHCP process: ${!GBMC_BR_DHCP_OUTSTANDING[*]}" >&2 86 update-dhcp-status 'ONGOING' "Outstanding DHCP hooks ${!GBMC_BR_DHCP_OUTSTANDING[*]}" 87 exit 1 88 fi 89 90 # Ensure that the installer knows we have completed processing DHCP by 91 # running a service that reports completion 92 echo 'Signaling dhcp done' >&2 93 update-dhcp-status 'DONE' "Netboot finished" 94fi 95