diff options
author | William A. Kennington III <wak@google.com> | 2021-11-04 00:54:51 +0300 |
---|---|---|
committer | William A. Kennington III <wak@google.com> | 2021-12-04 04:20:45 +0300 |
commit | b174c185f31bf14d430e68bb868ccf14ff7d4be3 (patch) | |
tree | fda5ab522fc60af118cd4e286b195ba1fcc851ab | |
parent | 21e7e45b77e026689b72f182aca4ba2ffd5e0a36 (diff) | |
download | openbmc-b174c185f31bf14d430e68bb868ccf14ff7d4be3.tar.xz |
meta-google: gbmc-bridge: Implement DHCP
This makes it possible for a BMC to acquire a public address via DHCP
provisioning.
None of the update processes are included yet.
Change-Id: I51ca2aa4859bcd2b9e909dd5a0d9e66cfbd648af
Signed-off-by: William A. Kennington III <wak@google.com>
6 files changed, 153 insertions, 1 deletions
diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in index 5adc41328..793403348 100644 --- a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in @@ -63,6 +63,8 @@ Destination=$stateless_pfx/76 Type=unreachable Metric=1024 EOF + # Delete DHCP configured addresses if we have a host published address + rm -f /etc/systemd/network/{00,}-bmc-gbmcbr.network.d/50-public.conf fi local file diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-clear-ip.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-clear-ip.sh.in new file mode 100644 index 000000000..e17a5e200 --- /dev/null +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-clear-ip.sh.in @@ -0,0 +1,26 @@ +# 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. + +[ -z "${gbmc_ncsi_clear_ip-}" ] || exit + +source /usr/libexec/ncsid_lib.sh || exit + +gbmc_ncsi_clear_ip_hook() { + UpdateIP xyz.openbmc_project.Network '@NCSI_IF@' '0.0.0.0' '0' || true + UpdateIP xyz.openbmc_project.Network '@NCSI_IF@' '::' '0' || true +} + +GBMC_BR_DHCP_HOOKS+=(gbmc_ncsi_clear_ip_hook) + +gbmc_ncsi_clear_ip=1 diff --git a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb index 0074a3172..6e2582495 100644 --- a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb +++ b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb @@ -20,6 +20,7 @@ SRC_URI += " \ file://gbmc-ncsi-br-pub-addr.sh.in \ file://gbmc-ncsi-br-deprecated-ips.sh.in \ file://gbmc-ncsi-set-nicenabled.service.in \ + file://gbmc-ncsi-clear-ip.sh.in \ " S = "${WORKDIR}" @@ -36,6 +37,7 @@ RDEPENDS:${PN} += " \ " FILES:${PN} += " \ + ${datadir}/gbmc-br-dhcp \ ${datadir}/gbmc-ip-monitor \ ${systemd_unitdir} \ " @@ -105,6 +107,12 @@ do_install:append() { >${WORKDIR}/gbmc-ncsi-br-deprecated-ips.sh install -m644 ${WORKDIR}/gbmc-ncsi-br-deprecated-ips.sh $mondir + dhcpdir=${D}${datadir}/gbmc-br-dhcp/ + install -d -m0755 $dhcpdir + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-clear-ip.sh.in \ + >${WORKDIR}/gbmc-ncsi-clear-ip.sh + install -m644 ${WORKDIR}/gbmc-ncsi-clear-ip.sh $dhcpdir + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-set-nicenabled.service.in \ >${D}${systemd_system_unitdir}/gbmc-ncsi-set-nicenabled.service diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index dea14f00b..5f79d468a 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -20,6 +20,8 @@ SRC_URI += " \ file://gbmc-br-ensure-ra.service \ file://gbmc-br-gw-src.sh \ file://gbmc-br-nft.sh \ + file://gbmc-br-dhcp.sh \ + file://gbmc-br-dhcp.service \ " FILES:${PN}:append = " \ @@ -37,7 +39,10 @@ RDEPENDS:${PN}:append = " \ ndisc6-rdisc6 \ " -SYSTEMD_SERVICE:${PN} += "gbmc-br-ensure-ra.service" +SYSTEMD_SERVICE:${PN} += " \ + gbmc-br-ensure-ra.service \ + gbmc-br-dhcp.service \ + " GBMC_BR_MAC_ADDR ?= "" @@ -94,8 +99,10 @@ do_install() { install -d -m0755 ${D}${libexecdir} install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.sh ${D}${libexecdir}/ + install -m0755 ${WORKDIR}/gbmc-br-dhcp.sh ${D}${libexecdir}/ install -d -m0755 ${D}${systemd_system_unitdir} install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.service ${D}${systemd_system_unitdir}/ + install -m0755 ${WORKDIR}/gbmc-br-dhcp.service ${D}${systemd_system_unitdir}/ } do_rm_work:prepend() { diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.service b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.service new file mode 100644 index 000000000..145f84b93 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.service @@ -0,0 +1,13 @@ +[Unit] +Description=gBMC DHCP Client +After=network.target +StartLimitIntervalSec=10 +StartLimitBurst=3 + +[Service] +Restart=always +RestartSec=5 +ExecStart=/usr/bin/udhcpc6 -f -q -O bootfile_url -O bootfile_param -i gbmcbr -s /usr/libexec/gbmc-br-dhcp.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.sh new file mode 100644 index 000000000..beccc8658 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.sh @@ -0,0 +1,96 @@ +#!/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. + +# A list of functions which get executed for each bound DHCP lease. +# These are configured by the files included below. +GBMC_BR_DHCP_HOOKS=() + +# Load configurations from a known location in the filesystem to populate +# hooks that are executed after each event. +shopt -s nullglob +for conf in /usr/share/gbmc-br-dhcp/*.sh; do + # SC doesn't like dynamic source loading + # shellcheck disable=SC1090 + source "$conf" +done + +gbmc_br_dhcp_run_hooks() { + local hook + for hook in "${GBMC_BR_DHCP_HOOKS[@]}"; do + "$hook" || continue + done +} + +# SC can't find this path during repotest +# shellcheck disable=SC1091 +source /usr/share/network/lib.sh || exit + +if [ "$1" = bound ]; then + # Variable is from the environment via udhcpc6 + # shellcheck disable=SC2154 + echo "DHCPv6(gbmcbr): $ipv6/128" >&2 + + pfx_bytes=() + ip_to_bytes pfx_bytes "$ipv6" + # Ensure we are a BMC and have a suffix nibble, the 0th index is reserved + if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] & 0xf == 0 )); then + echo "Invalid address" >&2 + exit + fi + # Ensure we don't have more than a /80 address + for (( i = 10; i < 16; ++i )); do + if (( pfx_bytes[i] != 0 )); then + echo "Invalid address" >&2 + exit + fi + done + + pfx="$(ip_bytes_to_str pfx_bytes)" + (( pfx_bytes[9] &= 0xf0 )) + stateless_pfx="$(ip_bytes_to_str pfx_bytes)" + read -r -d '' contents <<EOF +[Network] +Address=$pfx/128 +IPv6PrefixDelegation=yes +[IPv6PrefixDelegation] +RouterLifetimeSec=60 +[IPv6Prefix] +Prefix=$stateless_pfx/80 +PreferredLifetimeSec=60 +ValidLifetimeSec=60 +[IPv6RoutePrefix] +Route=$pfx/80 +LifetimeSec=60 +[Route] +Destination=$stateless_pfx/76 +Type=unreachable +Metric=1024 +EOF + + for file in /etc/systemd/network/{00,}-bmc-gbmcbr.network.d/50-public.conf; do + mkdir -p "$(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 + + if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then + networkctl reload && networkctl reconfigure gbmcbr + fi + + gbmc_br_dhcp_run_hooks +fi |