diff options
author | William A. Kennington III <wak@google.com> | 2021-04-27 00:10:52 +0300 |
---|---|---|
committer | William A. Kennington III <wak@google.com> | 2021-05-07 04:09:53 +0300 |
commit | 24615567082edbe4c287e994f92fb94afcedf185 (patch) | |
tree | de261a0bf0e121f174745518e35497b634ef1582 /meta-google/recipes-google | |
parent | 5ba6d08d7f49d26ae466f6d826ed1d849972ad59 (diff) | |
download | openbmc-24615567082edbe4c287e994f92fb94afcedf185.tar.xz |
meta-google: gbmc-bridge: Assign stable addresses from RAs
We want BMCs to be able to discover their machine prefix and assign a
stable IPv6 based on that prefix combined with the MAC of the BMC.
Change-Id: I67b8c56f50ff3a970175abcb81b429ceb1258b69
Signed-off-by: William A. Kennington III <wak@google.com>
Diffstat (limited to 'meta-google/recipes-google')
5 files changed, 138 insertions, 1 deletions
diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index a4e7881ed..80a42bd17 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -15,6 +15,9 @@ SRC_URI += " \ file://ipmi.service.in \ file://50-gbmc-br.rules \ file://gbmc-br-ula.sh \ + file://gbmc-br-from-ra.sh \ + file://gbmc-br-ensure-ra.sh \ + file://gbmc-br-ensure-ra.service \ " FILES_${PN}_append = " \ @@ -25,11 +28,15 @@ FILES_${PN}_append = " \ " RDEPENDS_${PN}_append = " \ + bash \ gbmc-ip-monitor \ mstpd-mstpd \ network-sh \ + ndisc6-rdisc6 \ " +SYSTEMD_SERVICE_${PN} += "gbmc-br-ensure-ra.service" + GBMC_BR_MAC_ADDR ?= "" # Generated via https://cd34.com/rfc4193/ based on a MAC from a machine I own @@ -81,4 +88,10 @@ do_install() { mondir=${D}${datadir}/gbmc-ip-monitor install -d -m0755 "$mondir" install -m0644 ${WORKDIR}/gbmc-br-ula.sh "$mondir"/ + install -m0644 ${WORKDIR}/gbmc-br-from-ra.sh "$mondir"/ + + install -d -m0755 ${D}${libexecdir} + install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.sh ${D}${libexecdir}/ + install -d -m0755 ${D}${systemd_system_unitdir} + install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.service ${D}${systemd_system_unitdir}/ } diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network index 18d208a3b..37aea6c1e 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network @@ -2,7 +2,7 @@ Name=gbmcbr [Network] DHCP=false -IPv6AcceptRA=false +IPv6AcceptRA=true LLMNR=true MulticastDNS=true LinkLocalAddressing=ipv6 diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.service b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.service new file mode 100644 index 000000000..7f97cea48 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.service @@ -0,0 +1,5 @@ +[Service] +ExecStart=/usr/libexec/gbmc-br-ensure-ra.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.sh new file mode 100644 index 000000000..60e33d89b --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.sh @@ -0,0 +1,27 @@ +#!/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. + +# Every 30 seconds, send out an RA so that the kernel will receive a response. +# This ensures that all BMCs (even ones that think they are routers) get updated +# information from the other systems on the network. +w=30 +while true; do + start=$SECONDS + rdisc6 -m gbmcbr -r 1 -w $(( w * 1000 )) >/dev/null 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 diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-from-ra.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-from-ra.sh new file mode 100644 index 000000000..9a5586b8a --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-from-ra.sh @@ -0,0 +1,92 @@ +# 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_br_from_ra_lib-}" ] || return + +source /usr/share/network/lib.sh || exit + +gbmc_br_from_ra_init= +gbmc_br_from_ra_mac= +declare -A gbmc_br_from_ra_pfxs=() +declare -A gbmc_br_from_ra_prev_addrs=() + +gbmc_br_from_ra_update() { + [ -n "$gbmc_br_from_ra_init" -a -n "$gbmc_br_from_ra_mac" ] || return + + local pfx + for pfx in "${!gbmc_br_from_ra_pfxs[@]}"; do + local cidr + if ! cidr="$(ipv6_pfx_to_cidr "$pfx")"; then + unset 'gbmc_br_from_ra_pfxs[$pfx]' + continue + fi + if (( cidr == 80 )); then + local sfx + if ! sfx="$(mac_to_eui48 "$gbmc_br_from_ra_mac")"; then + unset 'gbmc_br_from_ra_pfxs[$pfx]' + continue + fi + local addr + addr="$(ipv6_pfx_concat "$pfx" "$sfx")" + else + continue + fi + local valid="${gbmc_br_from_ra_pfxs["$pfx"]}" + if (( valid > 0 )); then + if [ -z "${gbmc_br_from_ra_prev_addrs["$addr"]-}" ]; then + echo "gBMC Bridge RA Addr Add: $addr" >&2 + gbmc_br_from_ra_prev_addrs["$addr"]=1 + fi + ip addr replace "$addr" dev gbmcbr noprefixroute + else + if [ -n "${gbmc_br_from_ra_prev_addrs["$addr"]-}" ]; then + echo "gBMC Bridge RA Addr Del: $addr" >&2 + unset 'gbmc_br_from_ra_prev_addrs[$addr]' + fi + ip addr del "$addr" dev gbmcbr + unset 'gbmc_br_from_ra_pfxs[$pfx]' + fi + done +} + +gbmc_br_from_ra_hook() { + if [ "$change" = 'init' ]; then + gbmc_br_from_ra_init=1 + gbmc_br_from_ra_update + elif [[ "$change" == 'route' && "$route" != *' via '* ]] && + [[ "$route" =~ ^(.* dev gbmcbr proto ra .*)( +expires +([^ ]+)sec).*$ ]]; then + pfx="${route%% *}" + if [ "$action" = 'add' ]; then + gbmc_br_from_ra_pfxs["$pfx"]="${BASH_REMATCH[3]}" + gbmc_br_from_ra_update + elif [ "$action" = 'del' ]; then + gbmc_br_from_ra_pfxs["$pfx"]=0 + gbmc_br_from_ra_update + fi + elif [ "$change" = 'link' -a "$intf" = 'gbmcbr' ]; then + rdisc6 -m gbmcbr -r 1 -w 100 >/dev/null 2>&1 + if [ "$action" = 'add' -a "$mac" != "$gbmc_br_from_ra_mac" ]; then + gbmc_br_from_ra_mac="$mac" + gbmc_br_from_ra_update + fi + if [ "$action" = 'del' -a "$mac" = "$gbmc_br_from_ra_mac" ]; then + gbmc_br_from_ra_mac= + gbmc_br_from_ra_update + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_br_from_ra_hook) + +gbmc_br_from_ra_lib=1 |