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[ ! -e /usr/share/gbmc-br-lib.sh ] && exit 17 18# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh 19source /usr/share/network/lib.sh || exit 20# shellcheck source=meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-lib.sh 21source /usr/share/gbmc-br-lib.sh || exit 22 23NCSI_IF='@NCSI_IF@' 24 25old_pfx= 26old_fqdn= 27old_rtr= 28 29set_host() { 30 [[ -n "$host" && -n "$domain" && -n "$hextet" ]] || return 31 32 local fqdn="$host-n$hextet.$domain" 33 [ "$fqdn" != "$old_fqdn" ] || return 34 old_fqdn="$fqdn" 35 36 echo "Found hostname $fqdn" >&2 37 hostnamectl set-hostname "$fqdn" || true 38} 39 40set_net() { 41 [[ -n "$pfx" && -n "$rtr" ]] || return 42 [[ "$pfx" != "$old_pfx" || "$rtr" != "$old_rtr" ]] || return 43 old_pfx="$pfx" 44 old_rtr="$rtr" 45 46 echo "Found prefix $pfx from $rtr" >&2 47 48 # We no longer need NCSId if we are in this configuration 49 systemctl stop --no-block ncsid@"$NCSI_IF" || true 50 51 # Save the IP address for the interface 52 gbmc_br_set_ip "$pfx" || true 53 54 # DHCP Relay workaround until alternate source port is supported 55 # TODO: Remove this once internal relaying cleanups land 56 gbmc-ncsi-smartnic-wa.sh || true 57} 58 59w=60 60while true; do 61 start=$SECONDS 62 while read -r line; do 63 if [ -z "$line" ]; then 64 hextet= 65 pfx= 66 host= 67 domain= 68 elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then 69 t_pfx="${BASH_REMATCH[1]}" 70 t_pfx_len="${BASH_REMATCH[2]}" 71 ip_to_bytes t_pfx_b "$t_pfx" || continue 72 (( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue 73 (( t_pfx_b[9] |= 1 )) 74 hextet="fd$(printf '%02x' "${t_pfx_b[9]}")" 75 pfx="$(ip_bytes_to_str t_pfx_b)" 76 elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.]+)(.*[.]google[.]com)$ ]]; then 77 # Ideally, we use PCRE and with lookahead and can do this in a single regex 78 # ^([a-zA-Z0-9-]+(?=-n[a-fA-F0-9]{1,4})|[a-zA-Z0-9-]+(?!-n[a-fA-F0-9]{1,4}))[^.]*[.]((?:[a-zA-Z0-9]*[.])*google[.]com)$ 79 # Instead we do multiple steps to extract the needed info 80 host="${BASH_REMATCH[1]}" 81 domain="${BASH_REMATCH[2]#.}" 82 if [[ "$host" =~ (-n[a-fA-F0-9]{1,4})$ ]]; then 83 host="${host%"${BASH_REMATCH[1]}"}" 84 fi 85 elif [[ "$line" =~ ^from' '(.*)$ ]]; then 86 rtr="${BASH_REMATCH[1]}" 87 set_net || true 88 set_host || true 89 fi 90 done < <(rdisc6 -d -m "$NCSI_IF" -w $(( w * 1000 )) 2>/dev/null) 91 # If rdisc6 exits early we still want to wait the full `w` time before 92 # starting again. 93 (( timeout = start + w - SECONDS )) 94 sleep $(( timeout < 0 ? 0 : timeout )) 95done 96