From c7454fb1c54ec6281a42b7cdb29e746b808eb271 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 14 Sep 2021 16:01:37 -0700 Subject: meta-google: gbmc-ncsi-config: Derive IP from RA Our end2end DHCP solution is not yet working, but we need a way to derive addresses for a BMC from the smart NIC in front of it. This provides a mechanism for detecting the address from RA beacons the NIC is sending. Change-Id: I0cdc8c192974c0b00257ebe58e911e62636e4c81 Signed-off-by: William A. Kennington III --- .../ncsi/files/gbmc-ncsi-ip-from-ra.sh.in | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in (limited to 'meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in') diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in new file mode 100755 index 000000000..e4ee10d49 --- /dev/null +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in @@ -0,0 +1,113 @@ +#!/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/network/lib.sh || exit +source /usr/libexec/ncsid_lib.sh || exit + +old_pfx= +old_rtr= + +w=60 +while true; do + start=$SECONDS + while read line; do + if [ -z "$line" ]; then + pfx= + elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then + t_pfx="${BASH_REMATCH[1]}" + t_pfx_len="${BASH_REMATCH[2]}" + ip_to_bytes t_pfx_b "$t_pfx" || continue + (( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue + (( t_pfx_b[9] |= 1 )) + pfx="$(ip_bytes_to_str t_pfx_b)" + (( t_pfx_b[9] &= 0xf0 )) + stateless_pfx="$(ip_bytes_to_str t_pfx_b)" + elif [[ "$line" =~ ^from' '(.*)$ ]]; then + rtr="${BASH_REMATCH[1]}" + (( "${#pfx}" != 0 )) || continue + [[ "$pfx" != "$old_pfx" || "$old_rtr" != "$rtr" ]] || continue + + echo "Found prefix $pfx from $rtr" >&2 + + # Delete any stale IP Addresses from the primary interface as we won't use them + UpdateIP xyz.openbmc_project.Network @NCSI_IF@ '0.0.0.0' '0' + UpdateIP xyz.openbmc_project.Network @NCSI_IF@ '::' '0' + + read -r -d '' contents <"$file" + done + + contents='[Network]'$'\n' + contents+="Address=$pfx/128"$'\n' + contents+="Gateway=$rtr"$'\n' + for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/49-public-ra.conf; do + mkdir -p -m 755 "$(dirname "$file")" + printf '%s' "$contents" >"$file" + done + + # Ensure that systemd-networkd performs a reconfiguration as it doesn't + # currently check the mtime of drop-in files. + touch -c /lib/systemd/network/*-bmc-gbmcbr.network + touch -c /etc/systemd/network/*-bmc-@NCSI_IF@.network + + if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then + networkctl reload + networkctl reconfigure gbmcbr + fi + + read -r -d '' contents <"$rfile" + systemctl reset-failed nftables + systemctl --no-block restart nftables + + old_pfx="$pfx" + old_rtr="$rtr" + fi + done < <(rdisc6 -d -m @NCSI_IF@ -w $(( w * 1000 )) 2>/dev/null) + # If rdisc6 exits early we still want to wait the full `w` time before + # starting again. + (( timeout = start + w - SECONDS )) + sleep $(( timeout < 0 ? 0 : timeout )) +done -- cgit v1.2.3 From bb9fb95ffc2dcd537ff0a948441700e8812af60b Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 27 Sep 2021 18:10:27 -0700 Subject: meta-google: gbmc-ncsi-config: Parse hostnames from RA We need the hostname to be properly configured in order to login with GLOME. This derives the hostname from the FQDN that is passed via the DNS list in the RA messages from the smart NIC. Change-Id: I4e7a414b6b75bfb227df5763917e9e5d09579d7d Signed-off-by: William A. Kennington III --- .../recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in') diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in index e4ee10d49..7ba159fcf 100755 --- a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in @@ -25,15 +25,20 @@ while true; do while read line; do if [ -z "$line" ]; then pfx= + host= elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then t_pfx="${BASH_REMATCH[1]}" t_pfx_len="${BASH_REMATCH[2]}" ip_to_bytes t_pfx_b "$t_pfx" || continue (( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue (( t_pfx_b[9] |= 1 )) + hextet="fd$(printf '%02x' ${t_pfx_b[9]})" pfx="$(ip_bytes_to_str t_pfx_b)" (( t_pfx_b[9] &= 0xf0 )) stateless_pfx="$(ip_bytes_to_str t_pfx_b)" + elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.-]*)[^.]*[.](.*.google.com)$ ]]; then + host="${BASH_REMATCH[1]}" + domain="${BASH_REMATCH[2]}" elif [[ "$line" =~ ^from' '(.*)$ ]]; then rtr="${BASH_REMATCH[1]}" (( "${#pfx}" != 0 )) || continue @@ -102,6 +107,11 @@ EOF systemctl reset-failed nftables systemctl --no-block restart nftables + # Set the machine hostname if discovered + if [ -n "$host" ]; then + hostnamectl set-hostname "$host-n$hextet.$domain" + fi + old_pfx="$pfx" old_rtr="$rtr" fi -- cgit v1.2.3 From 5b4b4f8529e4b919702f8fb08142d100b2310bbc Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 15 Oct 2021 12:22:08 -0700 Subject: meta-google: gbmc-ncsi-config: Re-organize RA code This make it possible for the hostname or IP information to change independently, in case a mistake is made in a development environment and just the hostname or just the prefix need to be updated. Change-Id: I66169dc6cdee681f77bad4b8638dc6a2c72fca5f Signed-off-by: William A. Kennington III --- .../ncsi/files/gbmc-ncsi-ip-from-ra.sh.in | 136 +++++++++++---------- 1 file changed, 73 insertions(+), 63 deletions(-) (limited to 'meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in') diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in index 7ba159fcf..80bd34f04 100755 --- a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-ip-from-ra.sh.in @@ -16,41 +16,36 @@ source /usr/share/network/lib.sh || exit source /usr/libexec/ncsid_lib.sh || exit +NCSI_IF='@NCSI_IF@' + old_pfx= +old_fqdn= old_rtr= -w=60 -while true; do - start=$SECONDS - while read line; do - if [ -z "$line" ]; then - pfx= - host= - elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then - t_pfx="${BASH_REMATCH[1]}" - t_pfx_len="${BASH_REMATCH[2]}" - ip_to_bytes t_pfx_b "$t_pfx" || continue - (( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue - (( t_pfx_b[9] |= 1 )) - hextet="fd$(printf '%02x' ${t_pfx_b[9]})" - pfx="$(ip_bytes_to_str t_pfx_b)" - (( t_pfx_b[9] &= 0xf0 )) - stateless_pfx="$(ip_bytes_to_str t_pfx_b)" - elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.-]*)[^.]*[.](.*.google.com)$ ]]; then - host="${BASH_REMATCH[1]}" - domain="${BASH_REMATCH[2]}" - elif [[ "$line" =~ ^from' '(.*)$ ]]; then - rtr="${BASH_REMATCH[1]}" - (( "${#pfx}" != 0 )) || continue - [[ "$pfx" != "$old_pfx" || "$old_rtr" != "$rtr" ]] || continue +set_host() { + [ -n "$host" -a -n "$domain" -a -n "$hextet" ] || return + + local fqdn="$host-n$hextet.$domain" + [ "$fqdn" != "$old_fqdn" ] || return + old_fqdn="$fqdn" + + echo "Found hostname $fqdn" >&2 + hostnamectl set-hostname "$fqdn" || true +} - echo "Found prefix $pfx from $rtr" >&2 +set_net() { + [ -n "$pfx" -a -n "$rtr" ] || return + [[ "$pfx" != "$old_pfx" || "$rtr" != "$old_rtr" ]] || return + old_pfx="$pfx" + old_rtr="$rtr" - # Delete any stale IP Addresses from the primary interface as we won't use them - UpdateIP xyz.openbmc_project.Network @NCSI_IF@ '0.0.0.0' '0' - UpdateIP xyz.openbmc_project.Network @NCSI_IF@ '::' '0' + echo "Found prefix $pfx from $rtr" >&2 - read -r -d '' contents <"$file" - done - - contents='[Network]'$'\n' - contents+="Address=$pfx/128"$'\n' - contents+="Gateway=$rtr"$'\n' - for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/49-public-ra.conf; do - mkdir -p -m 755 "$(dirname "$file")" - printf '%s' "$contents" >"$file" - done + for file in /run/systemd/network/{00,}-bmc-gbmcbr.network.d/49-public-ra.conf; do + mkdir -p -m 755 "$(dirname "$file")" + printf '%s' "$contents" >"$file" + done + touch -c /lib/systemd/network/*-bmc-gbmcbr.network || true - # Ensure that systemd-networkd performs a reconfiguration as it doesn't - # currently check the mtime of drop-in files. - touch -c /lib/systemd/network/*-bmc-gbmcbr.network - touch -c /etc/systemd/network/*-bmc-@NCSI_IF@.network + contents='[Network]'$'\n' + contents+="Address=$pfx/128"$'\n' + contents+="Gateway=$rtr"$'\n' + for file in /run/systemd/network/{00,}-bmc-"$NCSI_IF".network.d/49-public-ra.conf; do + mkdir -p -m 755 "$(dirname "$file")" + printf '%s' "$contents" >"$file" + done + touch -c /etc/systemd/network/*-bmc-"$NCSI_IF".network || true - if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then - networkctl reload - networkctl reconfigure gbmcbr - fi + if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then + networkctl reload && networkctl reconfigure gbmcbr "$NCSI_IF" || true + fi - read -r -d '' contents <"$rfile" - systemctl reset-failed nftables - systemctl --no-block restart nftables - - # Set the machine hostname if discovered - if [ -n "$host" ]; then - hostnamectl set-hostname "$host-n$hextet.$domain" - fi + rfile=/run/nftables/40-gbmc-ncsi-ra.rules + mkdir -p -m 755 "$(dirname "$rfile")" + printf '%s' "$contents" >"$rfile" + systemctl reset-failed nftables && systemctl --no-block restart nftables || true +} - old_pfx="$pfx" - old_rtr="$rtr" +w=60 +while true; do + start=$SECONDS + while read line; do + if [ -z "$line" ]; then + hextet= + pfx= + host= + domain= + elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then + t_pfx="${BASH_REMATCH[1]}" + t_pfx_len="${BASH_REMATCH[2]}" + ip_to_bytes t_pfx_b "$t_pfx" || continue + (( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue + (( t_pfx_b[9] |= 1 )) + hextet="fd$(printf '%02x' ${t_pfx_b[9]})" + pfx="$(ip_bytes_to_str t_pfx_b)" + (( t_pfx_b[9] &= 0xf0 )) + stateless_pfx="$(ip_bytes_to_str t_pfx_b)" + elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.-]*)[^.]*[.](.*.google.com)$ ]]; then + host="${BASH_REMATCH[1]}" + domain="${BASH_REMATCH[2]}" + elif [[ "$line" =~ ^from' '(.*)$ ]]; then + rtr="${BASH_REMATCH[1]}" + set_net || true + set_host || true fi - done < <(rdisc6 -d -m @NCSI_IF@ -w $(( w * 1000 )) 2>/dev/null) + done < <(rdisc6 -d -m "$NCSI_IF" -w $(( w * 1000 )) 2>/dev/null) # If rdisc6 exits early we still want to wait the full `w` time before # starting again. (( timeout = start + w - SECONDS )) -- cgit v1.2.3