From 593f2bd8afb67661ab1d399c7d7d3d436e8ebac4 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 26 Apr 2021 13:31:45 -0700 Subject: meta-google: gbmc-ip-monitor: Fix missing variable Change-Id: I3cc51f3d5885e983ca6f901c103eec4e64c9943c Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/files/gbmc-ip-monitor.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/files/gbmc-ip-monitor.sh b/meta-google/recipes-google/networking/files/gbmc-ip-monitor.sh index baeff9a85..e64c8675e 100755 --- a/meta-google/recipes-google/networking/files/gbmc-ip-monitor.sh +++ b/meta-google/recipes-google/networking/files/gbmc-ip-monitor.sh @@ -114,7 +114,7 @@ trap cleanup HUP INT QUIT ABRT TERM EXIT return 0 2>/dev/null while read line; do - gbmc_ip_monitor_parse_line || continue + gbmc_ip_monitor_parse_line "$line" || continue gbmc_ip_monitor_run_hooks || continue if [ "$change" = 'init' ]; then systemd-notify --ready -- cgit v1.2.3 From 832f02b111487b37e71c0170795cb0db6ce1732a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 23 Apr 2021 12:53:36 -0700 Subject: meta-google: gbmc-bridge: Add package This adds a machine local ethernet network which allows BMCs to communicate with one another. Change-Id: I5e0ace231af02d84f7678b8241b5ec71823e86af Signed-off-by: William A. Kennington III --- .../avahi/files/avahi-daemon.conf | 2 +- .../recipes-core/dropbear/dropbear_%.bbappend | 4 +- .../recipes-google/networking/gbmc-bridge.bb | 75 ++++++++++++++++++++++ .../networking/gbmc-bridge/+-bmc-gbmcbrusb.network | 8 +++ .../networking/gbmc-bridge/-bmc-gbmcbr.netdev.in | 7 ++ .../networking/gbmc-bridge/-bmc-gbmcbr.network | 8 +++ .../networking/gbmc-bridge/-bmc-gbmcbrdummy.netdev | 3 + .../gbmc-bridge/-bmc-gbmcbrdummy.network | 4 ++ .../networking/gbmc-bridge/50-gbmc-br.rules | 27 ++++++++ .../networking/gbmc-bridge/ipmi.service.in | 11 ++++ .../recipes-google/networking/gbmc-iperf3.bb | 4 +- 11 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge.bb create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/+-bmc-gbmcbrusb.network create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.netdev create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.network create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/50-gbmc-br.rules create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/ipmi.service.in (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-connectivity/avahi/files/avahi-daemon.conf b/meta-google/recipes-connectivity/avahi/files/avahi-daemon.conf index 9688ffb39..57520df7f 100644 --- a/meta-google/recipes-connectivity/avahi/files/avahi-daemon.conf +++ b/meta-google/recipes-connectivity/avahi/files/avahi-daemon.conf @@ -1,5 +1,5 @@ [server] -allow-interfaces=mgmt +allow-interfaces=mgmt,gbmcbr [publish] disable-user-service-publishing=yes diff --git a/meta-google/recipes-core/dropbear/dropbear_%.bbappend b/meta-google/recipes-core/dropbear/dropbear_%.bbappend index e93eba8b6..0b4349e00 100644 --- a/meta-google/recipes-core/dropbear/dropbear_%.bbappend +++ b/meta-google/recipes-core/dropbear/dropbear_%.bbappend @@ -5,13 +5,13 @@ SYSTEMD_AUTO_ENABLE_${PN}_prod = "disable" FILESEXTRAPATHS_remove_gbmc_bandaid := "${THISDIR}/${PN}:" SYSTEMD_AUTO_ENABLE_${PN}_bandaid_prod = "enable" -# Allow SSH to the mgmt node on DEV builds +# Allow SSH to the gbmc-bridge node on DEV builds do_install_append_gbmc_dev() { nftables_dir=${D}${sysconfdir}/nftables rules=$nftables_dir/50-dropbear-dev.rules install -d -m0755 $nftables_dir echo 'table inet filter {' >"$rules" - echo ' chain mgmt_pub_input {' >>"$rules" + echo ' chain gbmc_br_pub_input {' >>"$rules" echo ' tcp dport 22 accept' >>"$rules" echo ' }' >>"$rules" echo '}' >>"$rules" diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb new file mode 100644 index 000000000..1358ac543 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -0,0 +1,75 @@ +SUMMARY = "Configures the gbmc bridge and filter rules" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" +SRC_URI += " \ + file://-bmc-gbmcbr.netdev.in \ + file://-bmc-gbmcbr.network \ + file://-bmc-gbmcbrdummy.netdev \ + file://-bmc-gbmcbrdummy.network \ + file://+-bmc-gbmcbrusb.network \ + file://ipmi.service.in \ + file://50-gbmc-br.rules \ + " + +FILES_${PN}_append = " \ + ${systemd_unitdir}/network \ + ${sysconfdir}/nftables \ + ${sysconfdir}/avahi/services \ + " + +RDEPENDS_${PN}_append = " \ + mstpd-mstpd \ + " + +GBMC_BR_MAC_ADDR ?= "" + +# Generated via https://cd34.com/rfc4193/ based on a MAC from a machine I own +# and we allocated it downstream. Intended to only be used within a complete +# system of multiple network endpoints. +GBMC_ULA_PREFIX = "fdb5:0481:10ce:0" + +def mac_to_eui64(mac): + if not mac: + return '' + b = [int(c, 16) for c in mac.split(':')] + b[0] ^= 2 + b.insert(3, 0xfe) + b.insert(3, 0xff) + idx = range(0, len(b)-1, 2) + return ':'.join([format((b[i] << 8) + b[i+1], '04x') for i in idx]) + +do_install() { + netdir=${D}${systemd_unitdir}/network + install -d -m0755 $netdir + + if [ ! -z "${GBMC_BR_MAC_ADDR}" ]; then + sed -i 's,@MAC@,MACAddress=${GBMC_BR_MAC_ADDR},' ${WORKDIR}/-bmc-gbmcbr.netdev.in + addr=${GBMC_ULA_PREFIX}:${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64 + sed -i "s,@ADDR@,Address=$addr," ${WORKDIR}/-bmc-gbmcbr.netdev.in + else + sed -i '/@MAC@/d' ${WORKDIR}/-bmc-gbmcbr.netdev.in + sed -i '/@ADDR@/d' ${WORKDIR}/-bmc-gbmcbr.netdev.in + fi + + install -m0644 ${WORKDIR}/-bmc-gbmcbr.netdev.in $netdir/-bmc-gbmcbr.netdev + install -m0644 ${WORKDIR}/-bmc-gbmcbr.network $netdir/ + install -m0644 ${WORKDIR}/-bmc-gbmcbrdummy.netdev $netdir/ + install -m0644 ${WORKDIR}/-bmc-gbmcbrdummy.network $netdir/ + install -m0644 ${WORKDIR}/+-bmc-gbmcbrusb.network $netdir/ + + nftables_dir=${D}${sysconfdir}/nftables + install -d -m0755 "$nftables_dir" + install -m0644 ${WORKDIR}/50-gbmc-br.rules $nftables_dir/ + + avahi_dir=${D}${sysconfdir}/avahi/services + install -d -m 0755 "$avahi_dir" + sed -i 's,@MACHINE@,${MACHINE},g' ${WORKDIR}/ipmi.service.in + sed -i 's,@EXTRA_ATTRS@,,g' ${WORKDIR}/ipmi.service.in + sed 's,@NAME@,bmc,g' ${WORKDIR}/ipmi.service.in >${avahi_dir}/bmc.ipmi.service + sed 's,@NAME@,${MACHINE}-bmc,g' ${WORKDIR}/ipmi.service.in >${avahi_dir}/${MACHINE}-bmc.ipmi.service +} diff --git a/meta-google/recipes-google/networking/gbmc-bridge/+-bmc-gbmcbrusb.network b/meta-google/recipes-google/networking/gbmc-bridge/+-bmc-gbmcbrusb.network new file mode 100644 index 000000000..e403334b4 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/+-bmc-gbmcbrusb.network @@ -0,0 +1,8 @@ +[Match] +Name=usb* +[Network] +Bridge=gbmcbr +[Bridge] +# USB speeds tend to be better than 100mbit (100 cost) but worse +# than 1gbit (10 cost). Generally around 200mbit. +Cost=85 diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in new file mode 100644 index 000000000..a7e91332c --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in @@ -0,0 +1,7 @@ +[NetDev] +Name=gbmcbr +Kind=bridge +@MAC@ +@ADDR@ +[Bridge] +STP=true diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network new file mode 100644 index 000000000..18d208a3b --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network @@ -0,0 +1,8 @@ +[Match] +Name=gbmcbr +[Network] +DHCP=false +IPv6AcceptRA=false +LLMNR=true +MulticastDNS=true +LinkLocalAddressing=ipv6 diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.netdev b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.netdev new file mode 100644 index 000000000..97c725812 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.netdev @@ -0,0 +1,3 @@ +[NetDev] +Name=gbmcbrdummy +Kind=dummy diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.network b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.network new file mode 100644 index 000000000..7d3f07197 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbrdummy.network @@ -0,0 +1,4 @@ +[Match] +Name=gbmcbrdummy +[Network] +Bridge=gbmcbr diff --git a/meta-google/recipes-google/networking/gbmc-bridge/50-gbmc-br.rules b/meta-google/recipes-google/networking/gbmc-bridge/50-gbmc-br.rules new file mode 100644 index 000000000..1a5e6331d --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/50-gbmc-br.rules @@ -0,0 +1,27 @@ +table bridge filter { + chain gbmc_br_prerouting { + type filter hook prerouting priority 0; + iifname != gbmcbr accept + # Sometimes our links are over NCSI and we don't want to broadcast + # those packets over the entire bridge. They are only relevant P2P. + ether type 0x88F8 drop + } +} + +table inet filter { + chain gbmc_br_input { + type filter hook input priority 0; policy drop; + iifname != gbmcbr accept + jump gbmc_br_int_input + jump gbmc_br_pub_input + reject + } + chain gbmc_br_int_input { + ip6 daddr ff00::/8 accept + ip6 daddr fe80::/64 accept + ip6 daddr fdb5:0481:10ce::/64 accept + } + chain gbmc_br_pub_input { + ip6 nexthdr icmpv6 accept + } +} diff --git a/meta-google/recipes-google/networking/gbmc-bridge/ipmi.service.in b/meta-google/recipes-google/networking/gbmc-bridge/ipmi.service.in new file mode 100644 index 000000000..0b940fa2d --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/ipmi.service.in @@ -0,0 +1,11 @@ + + + + @NAME@ + + _ipmi._udp + 623 + Machine=@MACHINE@ + @EXTRA_ATTRS@ + + diff --git a/meta-google/recipes-google/networking/gbmc-iperf3.bb b/meta-google/recipes-google/networking/gbmc-iperf3.bb index 5044e418b..27ebdb7e0 100644 --- a/meta-google/recipes-google/networking/gbmc-iperf3.bb +++ b/meta-google/recipes-google/networking/gbmc-iperf3.bb @@ -17,13 +17,13 @@ do_install() { install -m 0644 ${WORKDIR}/iperf3.service ${D}${systemd_system_unitdir} } -# Allow IPERF3 to the mgmt node on DEV builds +# Allow IPERF3 to run on the gbmcbr node on DEV builds do_install_append_dev() { nftables_dir=${D}${sysconfdir}/nftables rules=$nftables_dir/50-gbmc-iperf3-dev.rules install -d -m0755 $nftables_dir echo 'table inet filter {' >"$rules" - echo ' chain mgmt_pub_input {' >>"$rules" + echo ' chain gbmc_br_pub_input {' >>"$rules" echo ' tcp dport 5201 accept' >>"$rules" echo ' }' >>"$rules" echo '}' >>"$rules" -- cgit v1.2.3 From b08a9e64a8c373bc4023663e5fccf05521d188f1 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 26 Apr 2021 12:43:43 -0700 Subject: meta-google: gbmc-bridge: Discover ULA addresses at runtime If the bridge interface is assigned a MAC at runtime then it needs to add the appropriate ULA address for that MAC. Change-Id: Ia109c36320a78bb02ba9b54038ca23b0d3e2c948 Signed-off-by: William A. Kennington III --- .../recipes-google/networking/gbmc-bridge.bb | 8 +++ .../networking/gbmc-bridge/gbmc-br-ula.sh | 67 ++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index 1358ac543..202522a86 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -14,16 +14,20 @@ SRC_URI += " \ file://+-bmc-gbmcbrusb.network \ file://ipmi.service.in \ file://50-gbmc-br.rules \ + file://gbmc-br-ula.sh \ " FILES_${PN}_append = " \ + ${datadir}/gbmc-ip-monitor \ ${systemd_unitdir}/network \ ${sysconfdir}/nftables \ ${sysconfdir}/avahi/services \ " RDEPENDS_${PN}_append = " \ + gbmc-ip-monitor \ mstpd-mstpd \ + network-sh \ " GBMC_BR_MAC_ADDR ?= "" @@ -72,4 +76,8 @@ do_install() { sed -i 's,@EXTRA_ATTRS@,,g' ${WORKDIR}/ipmi.service.in sed 's,@NAME@,bmc,g' ${WORKDIR}/ipmi.service.in >${avahi_dir}/bmc.ipmi.service sed 's,@NAME@,${MACHINE}-bmc,g' ${WORKDIR}/ipmi.service.in >${avahi_dir}/${MACHINE}-bmc.ipmi.service + + mondir=${D}${datadir}/gbmc-ip-monitor + install -d -m0755 "$mondir" + install -m0644 ${WORKDIR}/gbmc-br-ula.sh "$mondir"/ } diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh new file mode 100644 index 000000000..ac273a395 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh @@ -0,0 +1,67 @@ +# 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_ula_lib-}" ] || return + +source /usr/share/network/lib.sh || exit + +gbmc_br_ula_init= +gbmc_br_ula_mac= + +gbmc_br_ula_update() { + [ -n "$gbmc_br_ula_init" ] || return + + echo "gBMC Bridge ULA MAC: ${gbmc_br_ula_mac:-(deleted)}" >&2 + + local addr= + contents='[Network]'$'\n' + if [ -n "$gbmc_br_ula_mac" ]; then + local eui64 + eui64="$(mac_to_eui64 "$mac")" || return + addr="fdb5:0481:10ce:0:$eui64/64" + contents+="Address=$addr"$'\n' + fi + + local netfile + for netfile in /run/systemd/network/{00,}-bmc-gbmcbr.network.d/60-ula.conf; do + mkdir -p -m 755 "$(dirname "$netfile")" + printf '%s' "$contents" >"$netfile" + done + + # We have to add the address after writing the systemd config to ensure we + # don't race with reconfiguration and drop the address. + if [ -n "$addr" ]; then + ip addr replace "$addr" dev gbmcbr + fi +} + +gbmc_br_ula_hook() { + if [ "$change" = 'init' ]; then + gbmc_br_ula_init=1 + gbmc_br_ula_update + elif [ "$change" = 'link' -a "$intf" = 'gbmcbr' ]; then + if [ "$action" = 'add' -a "$mac" != "$gbmc_br_ula_mac" ]; then + gbmc_br_ula_mac="$mac" + gbmc_br_ula_update + fi + if [ "$action" = 'del' -a "$mac" = "$gbmc_br_ula_mac" ]; then + gbmc_br_ula_mac= + gbmc_br_ula_update + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_br_ula_hook) + +gbmc_br_ula_lib=1 -- cgit v1.2.3 From 7b6d7c90bff2d9ab30ceeb922afb572b7196d61b Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 26 Apr 2021 12:57:42 -0700 Subject: meta-google: gbmc-bridge: Don't hardcode MAC We want to eventually replace the link layer address with an address from an EEPROM. This change keeps the hardcoded address that services depend on, but allows for the MAC to be changed. Change-Id: I748fab21561f0f22ec0790487755e29e9aecd1b0 Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge.bb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index 202522a86..a4e7881ed 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -52,7 +52,8 @@ do_install() { install -d -m0755 $netdir if [ ! -z "${GBMC_BR_MAC_ADDR}" ]; then - sed -i 's,@MAC@,MACAddress=${GBMC_BR_MAC_ADDR},' ${WORKDIR}/-bmc-gbmcbr.netdev.in + sed -i 's,@MAC@,Address=fe80::${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64,' \ + ${WORKDIR}/-bmc-gbmcbr.netdev.in addr=${GBMC_ULA_PREFIX}:${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64 sed -i "s,@ADDR@,Address=$addr," ${WORKDIR}/-bmc-gbmcbr.netdev.in else -- cgit v1.2.3 From 1ef795b90e4d87f58553afbcf5928728ffb86e1b Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 10 Mar 2021 18:59:12 -0800 Subject: meta-google: gbmc-ncsi-config: Restrict NCSI input packets Break down packets by their incoming address and ensure that we don't allow packets to unintended destinations. Right now this is effectively a no-op, but it will be necessary for BMC public addressing. Change-Id: I39c16c3b9cd4c293df42b928674e39677d7834e9 Signed-off-by: William A. Kennington III --- .../ncsi/files/50-gbmc-ncsi.rules.in | 13 +++ .../recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in | 95 ++++++++++++++++++++++ .../recipes-google/ncsi/gbmc-ncsi-config.bb | 17 +++- 3 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in index 33031f0db..4ebe35128 100644 --- a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in +++ b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in @@ -3,10 +3,23 @@ table inet filter { type filter hook input priority 0; policy drop; iifname != @NCSI_IF@ accept ct state established accept + ip6 daddr ff00::/8 goto ncsi_brd_input + ip6 daddr fe80::/64 goto ncsi_legacy_input + } + chain ncsi_gbmc_br_pub_input { + jump gbmc_br_pub_input + reject + } + chain gbmc_br_pub_input { + } + chain ncsi_legacy_input { + jump ncsi_brd_input tcp dport 3959 accept udp dport 3959 accept tcp dport 3967 accept udp dport 3967 accept + } + chain ncsi_brd_input { icmpv6 type nd-neighbor-advert accept icmpv6 type nd-neighbor-solicit accept icmpv6 type nd-router-advert accept diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in new file mode 100644 index 000000000..34ca4e52f --- /dev/null +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in @@ -0,0 +1,95 @@ +# 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_nft_lib-}" ] || return + +gbmc_ncsi_nft_init= +gbmc_ncsi_nft_lastip4= +gbmc_ncsi_nft_lastip6= + +gbmc_ncsi_nft_update() { + [ -n "$gbmc_ncsi_nft_init" ] || return + + printf 'NCSI firewall for IPv4(%s) IPv6(%s)\n' \ + "${gbmc_ncsi_nft_lastip4:-(deleted)}" \ + "${gbmc_ncsi_nft_lastip6:-(deleted)}" >&2 + + local contents= + contents+='table inet filter {'$'\n' + contents+=' chain ncsi_input {'$'\n' + + local ip4="$gbmc_ncsi_nft_lastip4" + if [ -n "$ip4" ]; then + contents+=" ip daddr $ip4 goto ncsi_legacy_input"$'\n' + fi + + local ip6="$gbmc_ncsi_nft_lastip6" + if [ -n "$ip6" ]; then + contents+=" ip6 daddr $ip6/128 goto ncsi_legacy_input"$'\n' + + # Pad out to 4 hextets with no trailing semicolons + local pfx= + pfx="${ip6%::}" + while true; do + # Count `:` in `pfx` by removing them and diffing their lengths + local nos="${pfx//:/}" + (( ${#pfx} - ${#nos} >= 3 )) && break + pfx+=":0" + done + + # If our address has enough spare bits for appending the BMC suffix + # then we add a rule that allows the BMC subnet. That is, we need a /64 + # as input. + if (( ${#pfx} - ${#nos} == 3 )); then + contents+=" ip6 saddr != ${pfx}:fd00::/72 ip6 daddr" + contents+=" ${pfx}:fd00::/72 goto ncsi_gbmc_br_pub_input"$'\n' + fi + fi + + contents+=' }'$'\n' + contents+='}'$'\n' + + local rfile=/run/nftables/40-gbmc-ncsi-in.rules + mkdir -p -m 755 "$(dirname "$rfile")" + printf '%s' "$contents" >"$rfile" + + echo 'Restarting nftables' >&2 + systemctl reset-failed nftables + systemctl --no-block restart nftables +} + +gbmc_ncsi_nft_hook() { + if [ "$change" = 'init' ]; then + gbmc_ncsi_nft_init=1 + gbmc_ncsi_nft_update + elif [ "$change" = 'addr' -a "$intf" = '@NCSI_IF@' -a "$scope" = 'global' ]; then + if [ "$fam" = 'inet6' ]; then + local -n lastip='gbmc_ncsi_nft_lastip6' + else + local -n lastip='gbmc_ncsi_nft_lastip4' + fi + if [ "$action" = 'add' -a "$ip" != "$lastip" ]; then + lastip="$ip" + gbmc_ncsi_nft_update + fi + if [ "$action" = 'del' -a "$ip" = "$lastip" ]; then + lastip= + gbmc_ncsi_nft_update + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_nft_hook) + +gbmc_ncsi_nft_lib=1 diff --git a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb index ecdda2cb6..b833810f1 100644 --- a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb +++ b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb @@ -9,17 +9,22 @@ SRC_URI += " \ file://50-gbmc-ncsi.rules.in \ file://gbmc-ncsi-sslh.socket.in \ file://gbmc-ncsi-sslh.service \ + file://gbmc-ncsi-nft.sh.in \ " S = "${WORKDIR}" RDEPENDS_${PN} += " \ + gbmc-ip-monitor \ ncsid \ nftables-systemd \ sslh \ " -FILES_${PN} += "${systemd_unitdir}" +FILES_${PN} += " \ + ${datadir}/gbmc-ip-monitor \ + ${systemd_unitdir} \ + " SYSTEMD_SERVICE_${PN} += " \ gbmc-ncsi-sslh.service \ @@ -50,7 +55,7 @@ do_install_append() { nftdir=${D}${sysconfdir}/nftables install -d -m0755 "$nftdir" - sed "s,@NCSI_IF@,$if_name," ${WORKDIR}/50-gbmc-ncsi.rules.in \ + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/50-gbmc-ncsi.rules.in \ >"$nftdir"/50-gbmc-ncsi.rules wantdir=${D}${systemd_system_unitdir}/multi-user.target.wants @@ -58,6 +63,12 @@ do_install_append() { ln -sv ../ncsid@.service "$wantdir"/ncsid@$if_name.service install -m 0644 ${WORKDIR}/gbmc-ncsi-sslh.service ${D}${systemd_system_unitdir} - sed "s,@NCSI_IF@,$if_name," ${WORKDIR}/gbmc-ncsi-sslh.socket.in \ + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-sslh.socket.in \ >${D}${systemd_system_unitdir}/gbmc-ncsi-sslh.socket + + mondir=${D}${datadir}/gbmc-ip-monitor/ + install -d -m0755 $mondir + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-nft.sh.in \ + >${WORKDIR}/gbmc-ncsi-nft.sh + install -m644 ${WORKDIR}/gbmc-ncsi-nft.sh $mondir } -- cgit v1.2.3 From e99168aab003bd20a901f40e15823af6637a4abd Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 10 Mar 2021 23:40:47 -0800 Subject: meta-google: gbmc-ncsi-config: Add public address to gbmc-bridge This dynamically detects addresses applied to the NC-SI interface and infers the addreses which should be used explicitly by BMCs. Change-Id: I9036be0a54936aace580746cd1900ee653f43cfd Signed-off-by: William A. Kennington III --- .../ncsi/files/gbmc-ncsi-br-pub-addr.sh.in | 107 +++++++++++++++++++++ .../recipes-google/ncsi/gbmc-ncsi-config.bb | 4 + 2 files changed, 111 insertions(+) create mode 100644 meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in (limited to 'meta-google/recipes-google') 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 new file mode 100644 index 000000000..f51b033d5 --- /dev/null +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in @@ -0,0 +1,107 @@ +# 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_br_pub_addr_lib-}" ] || return + +gbmc_ncsi_br_pub_addr_init= +gbmc_ncsi_br_pub_addr_lastip= + +gbmc_ncsi_br_pub_addr_update() { + [ -n "$gbmc_ncsi_br_pub_addr_init" ] || return + + printf 'gBMC Bridge Pub Addr from NCSI: %s\n' \ + "${gbmc_ncsi_br_pub_addr_lastip:-(deleted)}" >&2 + + local pfx= + if [ -n "$gbmc_ncsi_br_pub_addr_lastip" ]; then + # Pad the address out to a /64 and ensure that it doesn't have extra bits + pfx="${gbmc_ncsi_br_pub_addr_lastip%::}" + while true; do + # Count `:` in `pfx` by removing them and diffing their lengths + local nos="${pfx//:/}" + (( ${#pfx} - ${#nos} >= 3 )) && break + pfx+=":0" + done + # Addresses that have more than 64bits of prefix (more than 3 separators) + # do not work with this scheme. Ignore them. + (( ${#pfx} - ${#nos} == 3 )) || pfx= + fi + + local contents='[Network]'$'\n' + if [ -n "$pfx" ]; then + local here= + read -r -d '' here <"$file" + done + + # We only restart networkd if we know we have a management network available + # on the machine and networkd is already running. + if [ -e /lib/systemd/network/-bmc-gbmcbrdummy.network ] && \ + ! systemctl status systemd-networkd | grep -q inactive; then + echo "Restarting networkd" >&2 + # HACK: We can't restart systemd-networkd without coordinating with + # phosphor-networkd, otherwise it will sometimes detect interfaces as + # unmanaged because it reads administrative state to determine enabled + # status. Adding an IP to phosphor-networkd is guaranteed to trigger the + # restart we want, and systemd-network will never actually accept the + # new value. + local start=$SECONDS + while (( SECONDS - start < 30 )); do + busctl call xyz.openbmc_project.Network \ + /xyz/openbmc_project/network/gbmcbrdummy \ + xyz.openbmc_project.Network.IP.Create IP ssys \ + xyz.openbmc_project.Network.IP.Protocol.IPv6 ff02::1 128 '' && break + sleep 1 + done + fi +} + +gbmc_ncsi_br_pub_addr_hook() { + if [ "$change" = 'init' ]; then + gbmc_ncsi_br_pub_addr_init=1 + gbmc_ncsi_br_pub_addr_update + elif [ "$change" = 'addr' -a "$intf" = '@NCSI_IF@' ] && + [ "$scope" = 'global' -a "$fam" = 'inet6' ]; then + if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_pub_addr_lastip" ]; then + gbmc_ncsi_br_pub_addr_lastip="$ip" + gbmc_ncsi_br_pub_addr_update + fi + if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_pub_addr_lastip" ]; then + gbmc_ncsi_br_pub_addr_lastip= + gbmc_ncsi_br_pub_addr_update + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_pub_addr_hook) + +gbmc_ncsi_br_pub_addr_lib=1 diff --git a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb index b833810f1..098819988 100644 --- a/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb +++ b/meta-google/recipes-google/ncsi/gbmc-ncsi-config.bb @@ -10,6 +10,7 @@ SRC_URI += " \ file://gbmc-ncsi-sslh.socket.in \ file://gbmc-ncsi-sslh.service \ file://gbmc-ncsi-nft.sh.in \ + file://gbmc-ncsi-br-pub-addr.sh.in \ " S = "${WORKDIR}" @@ -71,4 +72,7 @@ do_install_append() { sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-nft.sh.in \ >${WORKDIR}/gbmc-ncsi-nft.sh install -m644 ${WORKDIR}/gbmc-ncsi-nft.sh $mondir + sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-br-pub-addr.sh.in \ + >${WORKDIR}/gbmc-ncsi-br-pub-addr.sh + install -m644 ${WORKDIR}/gbmc-ncsi-br-pub-addr.sh $mondir } -- cgit v1.2.3 From 5ba6d08d7f49d26ae466f6d826ed1d849972ad59 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 10 Mar 2021 19:24:22 -0800 Subject: meta-google: gbmc-systemd-config: Enable packet forwarding This allows gBMCs to route packets, needed for routing packets to the management netowrk. Change-Id: I71f59eeb12607aa9c9d64687fb983938d5d69413 Signed-off-by: William A. Kennington III --- .../ncsi/files/50-gbmc-ncsi.rules.in | 7 ++++++ .../systemd/files/40-gbmc-forward.conf | 5 ++++ .../recipes-google/systemd/gbmc-systemd-config.bb | 29 ++++++++++++---------- 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 meta-google/recipes-google/systemd/files/40-gbmc-forward.conf (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in index 4ebe35128..70f14ae59 100644 --- a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in +++ b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in @@ -24,4 +24,11 @@ table inet filter { icmpv6 type nd-neighbor-solicit accept icmpv6 type nd-router-advert accept } + chain ncsi_forward { + type filter hook forward priority 0; policy accept; + iifname != @NCSI_IF@ accept + oifname != gbmcbr drop + ip6 daddr fdb5:0481:10ce::/64 drop + ip6 saddr fdb5:0481:10ce::/64 drop + } } diff --git a/meta-google/recipes-google/systemd/files/40-gbmc-forward.conf b/meta-google/recipes-google/systemd/files/40-gbmc-forward.conf new file mode 100644 index 000000000..9f8d1eb50 --- /dev/null +++ b/meta-google/recipes-google/systemd/files/40-gbmc-forward.conf @@ -0,0 +1,5 @@ +net.ipv4.ip_forward=1 +net.ipv4.conf.default.forwarding=1 +net.ipv4.conf.all.forwarding=1 +net.ipv6.conf.default.forwarding=1 +net.ipv6.conf.all.forwarding=1 diff --git a/meta-google/recipes-google/systemd/gbmc-systemd-config.bb b/meta-google/recipes-google/systemd/gbmc-systemd-config.bb index 011b62edc..29d81f46a 100644 --- a/meta-google/recipes-google/systemd/gbmc-systemd-config.bb +++ b/meta-google/recipes-google/systemd/gbmc-systemd-config.bb @@ -10,11 +10,13 @@ S = "${WORKDIR}" SRC_URI_append = " \ file://firmware-updates.target \ file://firmware-updates-pre.target \ + file://40-gbmc-forward.conf \ " FILES_${PN}_append = " \ ${systemd_unitdir}/coredump.conf.d/40-gbmc-coredump.conf \ ${systemd_unitdir}/resolved.conf.d/40-gbmc-nomdns.conf \ + ${libdir}/sysctl.d/40-gbmc-forward.conf \ " FILES_${PN}_append_dev = " \ @@ -28,22 +30,23 @@ SYSTEMD_SERVICE_${PN}_append = " \ # Put coredumps in the journal to ensure they stay in ram do_install() { - install -d -m 0755 ${D}${systemd_unitdir}/coredump.conf.d - printf "[Coredump]\nStorage=journal\n" \ - >${D}${systemd_unitdir}/coredump.conf.d/40-gbmc-coredump.conf + install -d -m 0755 ${D}${systemd_unitdir}/coredump.conf.d + printf "[Coredump]\nStorage=journal\n" \ + >${D}${systemd_unitdir}/coredump.conf.d/40-gbmc-coredump.conf - install -d -m 0755 ${D}${systemd_unitdir}/resolved.conf.d - printf "[Resolve]\nLLMNR=no\nMulticastDNS=resolve\n" \ - >${D}${systemd_unitdir}/resolved.conf.d/40-gbmc-nomdns.conf + install -d -m 0755 ${D}${systemd_unitdir}/resolved.conf.d + printf "[Resolve]\nLLMNR=no\nMulticastDNS=resolve\n" \ + >${D}${systemd_unitdir}/resolved.conf.d/40-gbmc-nomdns.conf - install -d -m 0755 ${D}${systemd_system_unitdir} - install -m 0644 ${WORKDIR}/firmware-updates.target ${D}${systemd_system_unitdir}/ - install -m 0644 ${WORKDIR}/firmware-updates-pre.target ${D}${systemd_system_unitdir}/ + install -d -m 0755 ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/firmware-updates.target ${D}${systemd_system_unitdir}/ + install -m 0644 ${WORKDIR}/firmware-updates-pre.target ${D}${systemd_system_unitdir}/ + + install -d -m0755 ${D}${libdir}/sysctl.d + install -m 0644 ${WORKDIR}/40-gbmc-forward.conf ${D}${libdir}/sysctl.d/ } do_install_append_dev() { - install -d -m 0755 ${D}${libdir}/sysctl.d - printf "kernel.sysrq = 1\n" \ - >${D}${libdir}/sysctl.d/40-gbmc-debug.conf - + printf "kernel.sysrq = 1\n" \ + >${D}${libdir}/sysctl.d/40-gbmc-debug.conf } -- cgit v1.2.3 From 24615567082edbe4c287e994f92fb94afcedf185 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 26 Apr 2021 14:10:52 -0700 Subject: 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 --- .../recipes-google/networking/gbmc-bridge.bb | 13 +++ .../networking/gbmc-bridge/-bmc-gbmcbr.network | 2 +- .../gbmc-bridge/gbmc-br-ensure-ra.service | 5 ++ .../networking/gbmc-bridge/gbmc-br-ensure-ra.sh | 27 +++++++ .../networking/gbmc-bridge/gbmc-br-from-ra.sh | 92 ++++++++++++++++++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.service create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ensure-ra.sh create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-from-ra.sh (limited to 'meta-google/recipes-google') 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 -- cgit v1.2.3 From 53527f3f24e5df5d0344f057cdb85dde7e596955 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 27 Apr 2021 13:05:45 -0700 Subject: meta-google: gbmc-bridge: Recognize public addresses internally We want to be able to categorize public addresses being used for internal traffic, and allow them to access internal services. Change-Id: I1f4b8eaa329954f330c3052c0c789b8e5e3b4662 Signed-off-by: William A. Kennington III --- .../recipes-google/networking/gbmc-bridge.bb | 2 + .../networking/gbmc-bridge/gbmc-br-nft.sh | 63 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index 80a42bd17..6c51a2806 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -18,6 +18,7 @@ SRC_URI += " \ file://gbmc-br-from-ra.sh \ file://gbmc-br-ensure-ra.sh \ file://gbmc-br-ensure-ra.service \ + file://gbmc-br-nft.sh \ " FILES_${PN}_append = " \ @@ -89,6 +90,7 @@ do_install() { install -d -m0755 "$mondir" install -m0644 ${WORKDIR}/gbmc-br-ula.sh "$mondir"/ install -m0644 ${WORKDIR}/gbmc-br-from-ra.sh "$mondir"/ + install -m0644 ${WORKDIR}/gbmc-br-nft.sh "$mondir"/ install -d -m0755 ${D}${libexecdir} install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.sh ${D}${libexecdir}/ diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh new file mode 100644 index 000000000..2099185e8 --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh @@ -0,0 +1,63 @@ +# 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_nft_lib-}" ] || return + +gbmc_br_nft_init= +gbmc_br_nft_pfx= + +gbmc_br_nft_update() { + printf 'gBMC Bridge input firewall for %s\n' \ + "${gbmc_br_nft_pfx:-(deleted)}" >&2 + + local contents= + contents+='table inet filter {'$'\n' + contents+=' chain gbmc_br_int_input {'$'\n' + if [ -n "${gbmc_br_nft_pfx-}" ]; then + contents+=" ip6 saddr $gbmc_br_nft_pfx" + contents+=" ip6 daddr $gbmc_br_nft_pfx accept"$'\n' + fi + contents+=' }'$'\n' + contents+='}'$'\n' + + local rfile=/run/nftables/40-gbmc-br-int.rules + mkdir -p -m 755 "$(dirname "$rfile")" + printf '%s' "$contents" >"$rfile" + + echo 'Restarting nftables' >&2 + systemctl reset-failed nftables + systemctl --no-block restart nftables +} + +gbmc_br_nft_hook() { + if [ "$change" = 'init' ]; then + gbmc_br_nft_init=1 + gbmc_br_nft_update + # Match only global IP addresses on the bridge that match the BMC prefix + # (:fdxx:). So 2002:af4:3480:2248:fd02:6345:3069:9186 would become + # a 2002:af4:3480:2248:fd00/72 rule. + elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' -a "$scope" = 'global' ] && + [[ "$fam" == 'inet6' && "$ip" =~ ^(([^:]+:){4}fd)[^:]{2}:.*$ ]] && + [[ "$flags" != *tentative* ]]; then + pfx="${BASH_REMATCH[1]}00::/72" + if [ "$action" = "add" -a "$pfx" != "$gbmc_br_nft_pfx" ]; then + gbmc_br_nft_pfx="$pfx" + gbmc_br_nft_update + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_br_nft_hook) + +gbmc_br_nft_lib=1 -- cgit v1.2.3 From cd40c7e803406f66c45338291c20b3cb6076964b Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 5 May 2021 14:44:41 -0700 Subject: meta-google: gbmc-bridge: Set default route source This change ensures that ULA addresses don't get used as the source when trying to send packets outside the machine. Change-Id: I46413a2587634a79f0c0fc4051587e39a9fdcf50 Signed-off-by: William A. Kennington III --- .../recipes-google/networking/gbmc-bridge.bb | 2 + .../networking/gbmc-bridge/gbmc-br-gw-src.sh | 65 ++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index 6c51a2806..fc7dfbfb3 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -18,6 +18,7 @@ SRC_URI += " \ file://gbmc-br-from-ra.sh \ file://gbmc-br-ensure-ra.sh \ file://gbmc-br-ensure-ra.service \ + file://gbmc-br-gw-src.sh \ file://gbmc-br-nft.sh \ " @@ -90,6 +91,7 @@ do_install() { install -d -m0755 "$mondir" install -m0644 ${WORKDIR}/gbmc-br-ula.sh "$mondir"/ install -m0644 ${WORKDIR}/gbmc-br-from-ra.sh "$mondir"/ + install -m0644 ${WORKDIR}/gbmc-br-gw-src.sh "$mondir"/ install -m0644 ${WORKDIR}/gbmc-br-nft.sh "$mondir"/ install -d -m0755 ${D}${libexecdir} diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh new file mode 100644 index 000000000..1364efd7b --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh @@ -0,0 +1,65 @@ +# 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_gw_src_lib-}" ] || return + +gbmc_br_gw_src_ip= +declare -A gbmc_br_gw_src_routes=() + +gbmc_br_gw_src_update() { + [ -n "$gbmc_br_gw_src_ip" ] || return + + local route + for route in "${!gbmc_br_gw_src_routes[@]}"; do + [[ "$route" != *" src $gbmc_br_gw_src_ip "* ]] || continue + echo "gBMC Bridge Updating GW source [$gbmc_br_gw_src_ip]: $route" >&2 + ip route change $route src "$gbmc_br_gw_src_ip" + unset 'gbmc_br_gw_src_routes[$route]' + done +} + +gbmc_br_gw_src_hook() { + # We only want to match default gateway routes that are dynamic + # (have an expiration time). These will be updated with our preferred + # source. + if [[ "$change" == 'route' && "$route" == 'default '*':'* ]]; then + if [[ "$route" =~ ^(.*)( +expires +[^ ]+)(.*)$ ]]; then + route="${BASH_REMATCH[1]}${BASH_REMATCH[3]}" + fi + if [ "$action" = 'add' -a -z "${gbmc_br_gw_src_routes["$route"]}" ]; then + gbmc_br_gw_src_routes["$route"]=1 + gbmc_br_gw_src_update + elif [ "$action" = 'del' -a -n "${gbmc_br_gw_src_routes["$route"]}" ]; then + unset 'gbmc_br_gw_src_routes[$route]' + gbmc_br_gw_src_update + fi + # Match only global IP addresses on the bridge that match the BMC stateless + # prefix (:fd00:). So 2002:af4:3480:2248:fd00:6345:3069:9186 would be + # matched as the preferred source IP for outoging traffic. + elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' -a "$scope" = 'global' ] && + [[ "$fam" == 'inet6' && "$ip" =~ ^([^:]+:){4}fd00:.*$ ]] && + [[ "$flags" != *tentative* ]]; then + if [ "$action" = 'add' -a "$ip" != "$gbmc_br_gw_src_ip" ]; then + gbmc_br_gw_src_ip="$ip" + gbmc_br_gw_src_update + fi + if [ "$action" = 'del' -a "$ip" = "$gbmc_br_gw_src_ip" ]; then + gbmc_br_gw_src_ip= + fi + fi +} + +GBMC_IP_MONITOR_HOOKS+=(gbmc_br_gw_src_hook) + +gbmc_br_gw_src_lib=1 -- cgit v1.2.3 From 70264b98c0362f850c3122966995db8ce4e8f0e8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 7 May 2021 03:07:31 -0700 Subject: meta-google: network-sh: Add ip_to_bytes function This will be used to compare parts of addresses instead of applying regexes to them. Change-Id: Ide7366cab967e31a74cbb4002bad1046432037e3 Signed-off-by: William A. Kennington III --- .../recipes-google/networking/network-sh/lib.sh | 96 ++++++++++++++++++++++ .../recipes-google/networking/network-sh/test.sh | 73 +++++++++++++++- 2 files changed, 166 insertions(+), 3 deletions(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/network-sh/lib.sh b/meta-google/recipes-google/networking/network-sh/lib.sh index f37f7196d..2dc5103e0 100644 --- a/meta-google/recipes-google/networking/network-sh/lib.sh +++ b/meta-google/recipes-google/networking/network-sh/lib.sh @@ -57,6 +57,102 @@ mac_to_eui64() { printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x\n' "${suffix_bytes[@]}" } +ip_to_bytes() { + local -n bytes_out="$1" + local str="$2" + + local bytes=() + local oldifs="$IFS" + # Heuristic for V4 / V6, validity will be checked as it is parsed + if [[ "$str" == *.* ]]; then + # Ensure we don't start or end with IFS + [ "${str:0:1}" != '.' ] || return 1 + [ "${str: -1}" != '.' ] || return 1 + + local v + # Split IPv4 address into octets + IFS=. + for v in $str; do + # IPv4 digits are always decimal numbers + if ! [[ "$v" =~ ^[0-9]+$ ]]; then + IFS="$oldifs" + return 1 + fi + # Each octet is a single byte, make sure the number isn't larger + if (( v > 0xff )); then + IFS="$oldifs" + return 1 + fi + bytes+=($v) + done + # IPv4 addresses must have all 4 bytes present + if (( "${#bytes[@]}" != 4 )); then + IFS="$oldifs" + return 1 + fi + else + # Ensure we bound the padding in an outer byte for + # IFS splitting to work correctly + [ "${str:0:2}" = '::' ] && str="0$str" + [ "${str: -2}" = '::' ] && str="${str}0" + + # Ensure we don't start or end with IFS + [ "${str:0:1}" != ':' ] || return 1 + [ "${str: -1}" != ':' ] || return 1 + + # Stores the bytes that come before ::, if it exists + local bytesBeforePad=() + local v + # Split the Address into hextets + IFS=: + for v in $str; do + # Handle ::, which translates to an empty string + if [ -z "$v" ]; then + # Only allow a single :: sequence in an address + if (( "${#bytesBeforePad[@]}" > 0 )); then + IFS="$oldifs" + return 1 + fi + # Store the already parsed upper bytes separately + # This allows us to calculate and insert padding + bytesBeforePad=("${bytes[@]}") + bytes=() + continue + fi + # IPv6 digits are always hex + if ! [[ "$v" =~ ^[[:xdigit:]]+$ ]]; then + IFS="$oldifs" + return 1 + fi + # Ensure the number is no larger than a hextet + v="0x$v" + if (( v > 0xffff )); then + IFS="$oldifs" + return 1 + fi + # Split the hextet into 2 bytes + bytes+=($(( v >> 8 ))) + bytes+=($(( v & 0xff ))) + done + # If we have ::, add padding + if (( "${#bytesBeforePad[@]}" > 0 )); then + # Fill the middle bytes with padding and store in `bytes` + while (( "${#bytes[@]}" + "${#bytesBeforePad[@]}" < 16 )); do + bytesBeforePad+=(0) + done + bytes=("${bytesBeforePad[@]}" "${bytes[@]}") + fi + # IPv6 addresses must have all 16 bytes present + if (( "${#bytes[@]}" != 16 )); then + IFS="$oldifs" + return 1 + fi + fi + + IFS="$oldifs" + bytes_out=("${bytes[@]}") +} + ipv6_pfx_concat() { local pfx="$1" local sfx="$2" diff --git a/meta-google/recipes-google/networking/network-sh/test.sh b/meta-google/recipes-google/networking/network-sh/test.sh index 57387c47c..2361cfe3e 100755 --- a/meta-google/recipes-google/networking/network-sh/test.sh +++ b/meta-google/recipes-google/networking/network-sh/test.sh @@ -21,6 +21,21 @@ else fi source lib.sh +expect_array_numeq() { + local -n a1="$1" + local -n a2="$2" + + if (( "${#a1[@]}" != "${#a2[@]}" )); then + echo " Line ${BASH_LINENO[0]} Array Size ${#a1[@]} != ${#a2[@]}" >&2 + test_err=1 + else + local i + for (( i=0; i < ${#a1[@]}; ++i )); do + expect_numeq "${a1[$i]}" "${a2[$i]}" + done + fi +} + test_mac_to_bytes() { out=() expect_err 1 mac_to_bytes out '' @@ -32,9 +47,7 @@ test_mac_to_bytes() { expect_err 0 mac_to_bytes out 'a2:0:f:de:0:29' expected=(0xa2 0 0xf 0xde 0 0x29) - for (( i=0; i < ${#expected[@]}; ++i )); do - expect_numeq "${out[$i]}" "${expected[$i]}" - done + expect_array_numeq out expected } test_mac_to_eui_48() { @@ -47,6 +60,60 @@ test_eui_64() { expect_streq "$str" '1334:56ff:fe78:90af' } +test_ip4_to_bytes() { + out=() + expect_err 1 ip_to_bytes out '' + expect_err 1 ip_to_bytes out '10.0.0.' + expect_err 1 ip_to_bytes out '.0.1.1' + expect_err 1 ip_to_bytes out '10.0.0' + expect_err 1 ip_to_bytes out '10.0..0' + expect_err 1 ip_to_bytes out '.10.0.0.0' + expect_err 1 ip_to_bytes out '10.0.0.0.' + expect_err 1 ip_to_bytes out '10.0.0.256' + expect_err 1 ip_to_bytes out '10.0.0.0.256' + expect_err 1 ip_to_bytes out '10.0.0.0.1' + + expect_err 0 ip_to_bytes out '10.0.0.1' + expected=(10 0 0 1) + expect_array_numeq out expected +} + +test_ip6_to_bytes() { + out=() + expect_err 1 ip_to_bytes out '' + expect_err 1 ip_to_bytes out ':::' + expect_err 1 ip_to_bytes out '::z' + expect_err 1 ip_to_bytes out '1::1::1' + expect_err 1 ip_to_bytes out '1:1:1' + expect_err 1 ip_to_bytes out ':1::1' + expect_err 1 ip_to_bytes out '1::1:' + + expect_err 0 ip_to_bytes out '::' + expected=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + expect_array_numeq out expected + out=() + + expect_err 0 ip_to_bytes out '::1' + expected=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1) + expect_array_numeq out expected + out=() + + expect_err 0 ip_to_bytes out 'fd00::' + expected=(0xfd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + expect_array_numeq out expected + out=() + + expect_err 0 ip_to_bytes out 'fd00:ffee::ddff:22' + expected=(0xfd 0 0xff 0xee 0 0 0 0 0 0 0 0 0xdd 0xff 0 0x22) + expect_array_numeq out expected + out=() + + expect_err 0 ip_to_bytes out '1:2:3:4:5:6:7:8' + expected=(0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8) + expect_array_numeq out expected + out=() +} + test_ipv6_pfx_concat() { # Invalid inputs expect_err 1 ipv6_pfx_concat 'fd/64' '1234:5678:90af' -- cgit v1.2.3 From 4f233cd0f430af2172ec4e596f70181a8c6f62ef Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Fri, 7 May 2021 03:25:25 -0700 Subject: meta-google: gbmc-bridge: Look at IP bytes instead of regex Change-Id: Ie3a20df633346692039103edc882e202b7c3309b Signed-off-by: William A. Kennington III --- .../networking/gbmc-bridge/gbmc-br-gw-src.sh | 13 +++++++++++-- .../recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh index 1364efd7b..f765b0d10 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh @@ -14,6 +14,8 @@ [ -z "${gbmc_br_gw_src_lib-}" ] || return +source /usr/share/network/lib.sh || exit + gbmc_br_gw_src_ip= declare -A gbmc_br_gw_src_routes=() @@ -48,8 +50,15 @@ gbmc_br_gw_src_hook() { # prefix (:fd00:). So 2002:af4:3480:2248:fd00:6345:3069:9186 would be # matched as the preferred source IP for outoging traffic. elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' -a "$scope" = 'global' ] && - [[ "$fam" == 'inet6' && "$ip" =~ ^([^:]+:){4}fd00:.*$ ]] && - [[ "$flags" != *tentative* ]]; then + [[ "$fam" == 'inet6' && "$flags" != *tentative* ]]; then + local ip_bytes=() + if ! ip_to_bytes ip_bytes "$ip"; then + echo "gBMC Bridge Ensure RA Invalid IP: $ip" >&2 + return 1 + fi + if (( ip_bytes[9] != 0xfd || ip_bytes[10] != 0 )); then + return 0 + fi if [ "$action" = 'add' -a "$ip" != "$gbmc_br_gw_src_ip" ]; then gbmc_br_gw_src_ip="$ip" gbmc_br_gw_src_update diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh index 2099185e8..185d78b81 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh @@ -14,6 +14,8 @@ [ -z "${gbmc_br_nft_lib-}" ] || return +source /usr/share/network/lib.sh || exit + gbmc_br_nft_init= gbmc_br_nft_pfx= @@ -48,9 +50,16 @@ gbmc_br_nft_hook() { # (:fdxx:). So 2002:af4:3480:2248:fd02:6345:3069:9186 would become # a 2002:af4:3480:2248:fd00/72 rule. elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' -a "$scope" = 'global' ] && - [[ "$fam" == 'inet6' && "$ip" =~ ^(([^:]+:){4}fd)[^:]{2}:.*$ ]] && - [[ "$flags" != *tentative* ]]; then - pfx="${BASH_REMATCH[1]}00::/72" + [[ "$fam" == 'inet6' && "$flags" != *tentative* ]]; then + local ip_bytes=() + if ! ip_to_bytes ip_bytes "$ip"; then + echo "gBMC Bridge NFT Invalid IP: $ip" >&2 + return 1 + fi + if (( ip_bytes[9] != 0xfd )); then + return 0 + fi + pfx="$(printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x:fd00::/72' "${ip_bytes[@]}")" if [ "$action" = "add" -a "$pfx" != "$gbmc_br_nft_pfx" ]; then gbmc_br_nft_pfx="$pfx" gbmc_br_nft_update -- cgit v1.2.3 From 80776788b1946fbbe0748a54b18cb1b28c03a8ad Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 10 May 2021 03:07:14 -0700 Subject: meta-google: network-sh: Add ip_bytes_to_str This makes it possible to get a human readable address back from a byte array. Change-Id: Ifcc98bcc95b8d75fe7d1aae1c264cbddf3fc5bd0 Signed-off-by: William A. Kennington III --- .../recipes-google/networking/network-sh/lib.sh | 54 ++++++++++++++++++++++ .../recipes-google/networking/network-sh/test.sh | 30 ++++++++++++ 2 files changed, 84 insertions(+) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/network-sh/lib.sh b/meta-google/recipes-google/networking/network-sh/lib.sh index 2dc5103e0..04e1480d7 100644 --- a/meta-google/recipes-google/networking/network-sh/lib.sh +++ b/meta-google/recipes-google/networking/network-sh/lib.sh @@ -153,6 +153,60 @@ ip_to_bytes() { bytes_out=("${bytes[@]}") } +ip_bytes_to_str() { + local -n bytes="$1" + + if (( "${#bytes[@]}" == 4 )); then + printf '%d.%d.%d.%d\n' "${bytes[@]}" + elif (( "${#bytes[@]}" == 16 )); then + # Track the starting position of the longest run of 0 hextets (2 bytes) + local longest_i=0 + # Track the size of the longest run of 0 hextets + local longest_s=0 + # The index of the first 0 byte in the current run of zeros + local first_zero=0 + local i + # Find the location of the longest run of zero hextets, preferring same + # size runs later in the address. + for (( i=0; i<=16; i+=2 )); do + # Terminate the run of zeros if we are at the end of the array or + # have a non-zero hextet + if (( i == 16 || bytes[$i] != 0 || bytes[$((i+1))] != 0 )); then + local s=$((i - first_zero)) + if (( s >= longest_s )); then + longest_i=$first_zero + longest_s=$s + fi + first_zero=$((i+2)) + fi + done + # Build the address string by each hextet + for (( i=0; i<16; i+=2 )); do + # If we encountered a run of zeros, add the necessary :: at the end + # of the string. If not at the end, a single : is added since : is + # printed to subsequent hextets already. + if (( i == longest_i )); then + (( i += longest_s-2 )) + printf ':' + # End of string needs to be :: + if (( i == 14 )); then + printf ':' + fi + else + # Prepend : to all hextets except the first for separation + if (( i != 0 )); then + printf ':' + fi + printf '%x' $(( (bytes[$i]<<8) | bytes[$(($i+1))])) + fi + done + printf '\n' + else + echo "Invalid IP Bytes: ${bytes[*]}" >&2 + return 1 + fi +} + ipv6_pfx_concat() { local pfx="$1" local sfx="$2" diff --git a/meta-google/recipes-google/networking/network-sh/test.sh b/meta-google/recipes-google/networking/network-sh/test.sh index 2361cfe3e..33cab86aa 100755 --- a/meta-google/recipes-google/networking/network-sh/test.sh +++ b/meta-google/recipes-google/networking/network-sh/test.sh @@ -114,6 +114,36 @@ test_ip6_to_bytes() { out=() } +test_ip4_bytes_str() { + in=(10 0 255 1) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" '10.0.255.1' +} + +test_ip6_bytes_str() { + in=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" '::' + in=(0xfd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" 'fd00::' + in=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0xfd) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" '::fd' + in=(0xfd 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" 'fd01::1' + in=(0xfd 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" 'fd01::1:0:0:1' + in=(0xfd 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" 'fd01:0:0:1:1::1' + in=(0 1 0 1 0xdd 0xdd 0 1 0 1 0 1 0 1 0 1) + str="$(ip_bytes_to_str in)" || fail + expect_streq "$str" '1:1:dddd:1:1:1:1:1' +} + test_ipv6_pfx_concat() { # Invalid inputs expect_err 1 ipv6_pfx_concat 'fd/64' '1234:5678:90af' -- cgit v1.2.3 From 6ca7033951727549245d10d599890a49c2ed79f6 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 10 May 2021 03:14:42 -0700 Subject: meta-google: network-sh: Convert to IP bytes Now that we can convert to and from IP bytes, we should use them everywhere to ensure values are parsed correctly. Change-Id: I995091d1eff670db6678b4a2f4a64113e93308f7 Signed-off-by: William A. Kennington III --- .../networking/gbmc-bridge/gbmc-br-from-ra.sh | 8 +- .../networking/gbmc-bridge/gbmc-br-nft.sh | 8 +- .../networking/gbmc-bridge/gbmc-br-ula.sh | 9 ++- .../recipes-google/networking/network-sh/lib.sh | 86 ++++++++++++++++------ .../recipes-google/networking/network-sh/test.sh | 68 +++++++++++------ 5 files changed, 123 insertions(+), 56 deletions(-) (limited to 'meta-google/recipes-google') 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 index 9a5586b8a..18341fefb 100644 --- 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 @@ -27,7 +27,7 @@ gbmc_br_from_ra_update() { local pfx for pfx in "${!gbmc_br_from_ra_pfxs[@]}"; do local cidr - if ! cidr="$(ipv6_pfx_to_cidr "$pfx")"; then + if ! cidr="$(ip_pfx_to_cidr "$pfx")"; then unset 'gbmc_br_from_ra_pfxs[$pfx]' continue fi @@ -38,8 +38,12 @@ gbmc_br_from_ra_update() { continue fi local addr - addr="$(ipv6_pfx_concat "$pfx" "$sfx")" + if ! addr="$(ip_pfx_concat "$pfx" "$sfx")"; then + unset 'gbmc_br_from_ra_pfxs[$pfx]' + continue + fi else + unset 'gbmc_br_from_ra_pfxs[$pfx]' continue fi local valid="${gbmc_br_from_ra_pfxs["$pfx"]}" diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh index 185d78b81..19b8f64a1 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-nft.sh @@ -56,10 +56,14 @@ gbmc_br_nft_hook() { echo "gBMC Bridge NFT Invalid IP: $ip" >&2 return 1 fi - if (( ip_bytes[9] != 0xfd )); then + if (( ip_bytes[8] != 0xfd )); then return 0 fi - pfx="$(printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x:fd00::/72' "${ip_bytes[@]}")" + local i + for (( i=9; i<16; i++ )); do + ip_bytes[$i]=0 + done + pfx="$(ip_bytes_to_str ip_bytes)/72" if [ "$action" = "add" -a "$pfx" != "$gbmc_br_nft_pfx" ]; then gbmc_br_nft_pfx="$pfx" gbmc_br_nft_update diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh index ac273a395..69897100e 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh @@ -27,10 +27,11 @@ gbmc_br_ula_update() { local addr= contents='[Network]'$'\n' if [ -n "$gbmc_br_ula_mac" ]; then - local eui64 - eui64="$(mac_to_eui64 "$mac")" || return - addr="fdb5:0481:10ce:0:$eui64/64" - contents+="Address=$addr"$'\n' + local sfx + if sfx="$(mac_to_eui64 "$gbmc_br_ula_mac")" && + addr="$(ip_pfx_concat "fdb5:0481:10ce::/64" "$sfx")"; then + contents+="Address=$addr"$'\n' + fi fi local netfile diff --git a/meta-google/recipes-google/networking/network-sh/lib.sh b/meta-google/recipes-google/networking/network-sh/lib.sh index 04e1480d7..b5d9382fc 100644 --- a/meta-google/recipes-google/networking/network-sh/lib.sh +++ b/meta-google/recipes-google/networking/network-sh/lib.sh @@ -33,11 +33,11 @@ mac_to_bytes() { } mac_to_eui48() { - local mac_bytes=() + local mac_bytes=(0 0 0 0 0 0 0 0 0 0) mac_to_bytes mac_bytes "$1" || return # Return the EUI-64 bytes in the IPv6 format - printf '%02x%02x:%02x%02x:%02x%02x\n' "${mac_bytes[@]}" + ip_bytes_to_str mac_bytes } mac_to_eui64() { @@ -47,6 +47,7 @@ mac_to_eui64() { # Using EUI-64 conversion rules, create the suffix bytes from MAC bytes # Invert bit-0 of the first byte, and insert 0xfffe in the middle. local suffix_bytes=( + 0 0 0 0 0 0 0 0 $((mac_bytes[0] ^ 1)) ${mac_bytes[@]:1:2} $((0xff)) $((0xfe)) @@ -54,7 +55,7 @@ mac_to_eui64() { ) # Return the EUI-64 bytes in the IPv6 format - printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x\n' "${suffix_bytes[@]}" + ip_bytes_to_str suffix_bytes } ip_to_bytes() { @@ -207,49 +208,86 @@ ip_bytes_to_str() { fi } -ipv6_pfx_concat() { +ip_pfx_concat() { local pfx="$1" local sfx="$2" - # Validate the prefix - if ! [[ "$pfx" =~ ^(([0-9a-fA-F]{1,4}:)+):/([0-9]+)$ ]]; then - echo "Invalid IPv6 prefix: $pfx" >&2 + # Parse the prefix + if ! [[ "$pfx" =~ ^([0-9a-fA-F:.]+)/([0-9]+)$ ]]; then + echo "Invalid IP prefix: $pfx" >&2 return 1 fi local addr="${BASH_REMATCH[1]}" - local cidr="${BASH_REMATCH[3]}" + local cidr="${BASH_REMATCH[2]}" + # Ensure prefix doesn't have too many bytes - local nos="${addr//:/}" - if (( ${#addr} - ${#nos} > (cidr+7)/16 )); then - echo "Too many prefix bytes: $pfx" >&2 + local pfx_bytes=() + if ! ip_to_bytes pfx_bytes "$addr"; then + echo "Invalid IP prefix: $pfx" >&2 return 1 fi + if (( ${#pfx_bytes[@]}*8 < cidr )); then + echo "Prefix CIDR too large" >&2 + return 1 + fi + # CIDR values might partially divide a byte so we need to mask out + # only the part of the byte we want to check for emptiness + if (( (pfx_bytes[cidr/8] & ~(~0 << (8-cidr%8))) != 0 )); then + echo "Invalid byte $((cidr/8)): $pfx" >&2 + return 1 + fi + local i + # Check the rest of the whole bytes to make sure they are empty + for (( i=cidr/8+1; i<${#pfx_bytes[@]}; i++ )); do + if (( pfx_bytes[$i] != 0 )); then + echo "Byte $i not 0: $pfx" >&2 + return 1 + fi + done # Validate the suffix - if ! [[ "$sfx" =~ ^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4})*$ ]]; then + local sfx_bytes=() + if ! ip_to_bytes sfx_bytes "$sfx"; then echo "Invalid IPv6 suffix: $sfx" >&2 return 1 fi - # Ensure suffix doesn't have too many bytes - local nos="${sfx//:/}" - if (( ${#sfx} - ${#nos} >= (128-cidr)/16 )); then - echo "Too many suffix bytes: $sfx" >&2 + if (( "${#sfx_bytes[@]}" != "${#pfx_bytes[@]}" )); then + echo "Suffix not the same family as prefix: $pfx $sfx" >&2 return 1 fi - - local comb="$addr:$sfx" - local nos="${comb//:/}" - if (( ${#comb} - ${#nos} == 8 )); then - comb="$addr$sfx" + # Check potential partially divided bytes for emptiness in the upper part + # based on the division specified in CIDR. + if (( (sfx_bytes[cidr/8] & (~0 << (8-cidr%8))) != 0 )); then + echo "Invalid byte $((cidr/8)): $sfx" >&2 + return 1 fi - echo "$comb/$cidr" + local i + # Check the bytes before the CIDR for emptiness to ensure they don't overlap + for (( i=0; i&2 + return 1 + fi + done + + out_bytes=() + for (( i=0; i<${#pfx_bytes[@]}; i++ )); do + out_bytes+=($(( pfx_bytes[$i] | sfx_bytes[$i] ))) + done + echo "$(ip_bytes_to_str out_bytes)/$cidr" } -ipv6_pfx_to_cidr() { - [[ "$1" =~ ^[0-9a-fA-F:]+/([0-9]+)$ ]] || return +ip_pfx_to_cidr() { + [[ "$1" =~ ^[0-9a-fA-F:.]+/([0-9]+)$ ]] || return echo "${BASH_REMATCH[1]}" } +normalize_ip() { + local ip_bytes=() + ip_to_bytes ip_bytes "$1" || return + ip_bytes_to_str ip_bytes +} + network_init=1 return 0 2>/dev/null echo "network is a library, not executed directly" >&2 diff --git a/meta-google/recipes-google/networking/network-sh/test.sh b/meta-google/recipes-google/networking/network-sh/test.sh index 33cab86aa..2803c0978 100755 --- a/meta-google/recipes-google/networking/network-sh/test.sh +++ b/meta-google/recipes-google/networking/network-sh/test.sh @@ -50,14 +50,14 @@ test_mac_to_bytes() { expect_array_numeq out expected } -test_mac_to_eui_48() { +test_mac_to_eui48() { str="$(mac_to_eui48 '12:34:56:78:90:af')" || fail - expect_streq "$str" '1234:5678:90af' + expect_streq "$str" '::1234:5678:90af' } -test_eui_64() { +test_mac_to_eui64() { str="$(mac_to_eui64 '12:34:56:78:90:af')" || fail - expect_streq "$str" '1334:56ff:fe78:90af' + expect_streq "$str" '::1334:56ff:fe78:90af' } test_ip4_to_bytes() { @@ -144,37 +144,57 @@ test_ip6_bytes_str() { expect_streq "$str" '1:1:dddd:1:1:1:1:1' } -test_ipv6_pfx_concat() { +test_ip_pfx_concat() { # Invalid inputs - expect_err 1 ipv6_pfx_concat 'fd/64' '1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::' '1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01:' '1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/a0' '1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/64' ':1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/64' '::' + expect_err 1 ip_pfx_concat 'fd/64' '::1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::' '::1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01:' '::1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/a0' '::1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/64' ':1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/64' '' + expect_err 1 ip_pfx_concat 'fd01::/129' '::1' # Too many address bits - expect_err 1 ipv6_pfx_concat 'fd01:1:1:1:1::/64' '1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/64' '1:0:1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/65' '1:1234:5678:90af' - expect_err 1 ipv6_pfx_concat 'fd01::/72' '1:1234:5678:90af' - - str="$(ipv6_pfx_concat 'fd01::/64' '1')" || fail + expect_err 1 ip_pfx_concat 'fd01:1:1:1:1::/64' '::1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/64' '::1:0:1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/79' '::3:1234:5678:90af' + expect_err 1 ip_pfx_concat 'fd01::/15' '::3:1234:5678:90af' + expect_err 1 ip_pfx_concat '10.0.0.1/31' '0.0.0.0' + + str="$(ip_pfx_concat '::1/128' '::0')" || fail + expect_streq "$str" '::1/128' + str="$(ip_pfx_concat 'fd01::/64' '::1')" || fail expect_streq "$str" 'fd01::1/64' - str="$(ipv6_pfx_concat 'fd01::/72' '1234:5678:90af')" || fail + str="$(ip_pfx_concat 'fd01::/127' '::1')" || fail + expect_streq "$str" 'fd01::1/127' + str="$(ip_pfx_concat 'fd02::/15' '::1')" || fail + expect_streq "$str" 'fd02::1/15' + str="$(ip_pfx_concat 'fd01::/72' '::1234:5678:90af')" || fail expect_streq "$str" 'fd01::1234:5678:90af/72' - str="$(ipv6_pfx_concat 'fd01:eeee:aaaa:cccc::/64' 'a:1234:5678:90af')" || fail + str="$(ip_pfx_concat 'fd01:eeee:aaaa:cccc::/64' '::a:1234:5678:90af')" || fail expect_streq "$str" 'fd01:eeee:aaaa:cccc:a:1234:5678:90af/64' + str="$(ip_pfx_concat 'fd01::fd00:0:0:0/80' '::1')" || fail + expect_streq "$str" 'fd01::fd00:0:0:1/80' + + str="$(ip_pfx_concat '10.0.0.0/24' '0.0.0.1')" || fail + expect_streq "$str" '10.0.0.1/24' } -test_ipv6_pfx_to_cidr() { - expect_err 1 ipv6_pfx_to_cidr 'z/64' - expect_err 1 ipv6_pfx_to_cidr '64' +test_ip_pfx_to_cidr() { + expect_err 1 ip_pfx_to_cidr 'z/64' + expect_err 1 ip_pfx_to_cidr '64' - cidr="$(ipv6_pfx_to_cidr 'fd01::/64')" || fail + cidr="$(ip_pfx_to_cidr 'fd01::/64')" || fail expect_numeq "$cidr" 64 - cidr="$(ipv6_pfx_to_cidr 'fd01:eeee:aaaa:cccc:a:1234:5678:90af/128')" || fail + cidr="$(ip_pfx_to_cidr 'fd01:eeee:aaaa:cccc:a:1234:5678:90af/128')" || fail expect_numeq "$cidr" 128 + cidr="$(ip_pfx_to_cidr '10.0.0.1/24')" || fail + expect_numeq "$cidr" 24 +} + +test_normalize_ip() { + ip="$(normalize_ip 'fd01:1::0:0:1')" || fail + expect_streq "$ip" 'fd01:1::1' } return 0 2>/dev/null -- cgit v1.2.3 From 8fb92589e9368cff81460e89feb9da4de1f82ab8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 10 May 2021 03:15:56 -0700 Subject: meta-google: gbmc-bridge: Use networkctl reconfigure The other workarounds to try and restart networkd tend to result in flaky behavior. We get much more consistent and fast reconfigurations if we target the bridge directly. Change-Id: I3222eba4a2d2b71e3893f93643f412e5238ee60e Signed-off-by: William A. Kennington III --- .../ncsi/files/gbmc-ncsi-br-pub-addr.sh.in | 26 ++++++---------------- .../networking/gbmc-bridge/gbmc-br-ula.sh | 11 +++++---- 2 files changed, 14 insertions(+), 23 deletions(-) (limited to 'meta-google/recipes-google') 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 f51b033d5..e033fd2a5 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,25 +63,13 @@ EOF printf '%s' "$contents" >"$file" done - # We only restart networkd if we know we have a management network available - # on the machine and networkd is already running. - if [ -e /lib/systemd/network/-bmc-gbmcbrdummy.network ] && \ - ! systemctl status systemd-networkd | grep -q inactive; then - echo "Restarting networkd" >&2 - # HACK: We can't restart systemd-networkd without coordinating with - # phosphor-networkd, otherwise it will sometimes detect interfaces as - # unmanaged because it reads administrative state to determine enabled - # status. Adding an IP to phosphor-networkd is guaranteed to trigger the - # restart we want, and systemd-network will never actually accept the - # new value. - local start=$SECONDS - while (( SECONDS - start < 30 )); do - busctl call xyz.openbmc_project.Network \ - /xyz/openbmc_project/network/gbmcbrdummy \ - xyz.openbmc_project.Network.IP.Create IP ssys \ - xyz.openbmc_project.Network.IP.Protocol.IPv6 ff02::1 128 '' && break - sleep 1 - 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 } diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh index 69897100e..8e28d3956 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ula.sh @@ -40,10 +40,13 @@ gbmc_br_ula_update() { printf '%s' "$contents" >"$netfile" done - # We have to add the address after writing the systemd config to ensure we - # don't race with reconfiguration and drop the address. - if [ -n "$addr" ]; then - ip addr replace "$addr" dev gbmcbr + # 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 } -- cgit v1.2.3 From bdbe7ce8bb2a01f4ed04389d677f3724f0ece044 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 10 May 2021 16:48:43 -0700 Subject: meta-google: gbmc-bridge: Remove custom ip parsing logic Change-Id: I455ab70094cfdc79b38097a838051f51b3c852da Signed-off-by: William A. Kennington III --- .../ncsi/files/gbmc-ncsi-br-pub-addr.sh.in | 32 ++++++++++++---------- .../recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in | 27 +++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) (limited to 'meta-google/recipes-google') 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 e033fd2a5..949f04f45 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 @@ -23,35 +23,37 @@ gbmc_ncsi_br_pub_addr_update() { printf 'gBMC Bridge Pub Addr from NCSI: %s\n' \ "${gbmc_ncsi_br_pub_addr_lastip:-(deleted)}" >&2 - local pfx= + local pfx_bytes=() if [ -n "$gbmc_ncsi_br_pub_addr_lastip" ]; then - # Pad the address out to a /64 and ensure that it doesn't have extra bits - pfx="${gbmc_ncsi_br_pub_addr_lastip%::}" - while true; do - # Count `:` in `pfx` by removing them and diffing their lengths - local nos="${pfx//:/}" - (( ${#pfx} - ${#nos} >= 3 )) && break - pfx+=":0" + ip_to_bytes pfx_bytes "$gbmc_ncsi_br_pub_addr_lastip" + # Ensure we don't have more than a /64 address + local i + for (( i = 8; i < 16; ++i )); do + if (( pfx_bytes[$i] != 0 )); then + pfx_bytes=() + break + fi done - # Addresses that have more than 64bits of prefix (more than 3 separators) - # do not work with this scheme. Ignore them. - (( ${#pfx} - ${#nos} == 3 )) || pfx= fi local contents='[Network]'$'\n' - if [ -n "$pfx" ]; then + if (( ${#pfx_bytes[@]} != 0 )); then + pfx_bytes[8]=0xfd + local stateless_pfx="$(ip_bytes_to_str pfx_bytes)" + pfx_bytes[9]=0x01 + local ncsi_pfx="$(ip_bytes_to_str pfx_bytes)" local here= read -r -d '' here <= 3 )) && break - pfx+=":0" - done - + local ip_bytes=() + ip_to_bytes ip_bytes "$ip6" # If our address has enough spare bits for appending the BMC suffix # then we add a rule that allows the BMC subnet. That is, we need a /64 # as input. - if (( ${#pfx} - ${#nos} == 3 )); then - contents+=" ip6 saddr != ${pfx}:fd00::/72 ip6 daddr" - contents+=" ${pfx}:fd00::/72 goto ncsi_gbmc_br_pub_input"$'\n' + local i + for (( i = 8; i < 16; i++ )); do + if (( ip_bytes[$i] != 0 )); then + ip_bytes=() + break + fi + done + if (( ${#ip_bytes[@]} != 0 )); then + ip_bytes[8]=0xfd + local pfx="$(ip_bytes_to_str ip_bytes)" + contents+=" ip6 saddr != $pfx/72 ip6 daddr" + contents+=" $pfx/72 goto ncsi_gbmc_br_pub_input"$'\n' fi fi -- cgit v1.2.3 From eda6f00c1f0479d4c3aeee59be80b6c7c6a4792c Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Tue, 11 May 2021 03:09:54 -0700 Subject: meta-google: gbmc-bridge: Fix misconfigured MAC The network addresses derived from the MAC address are supposed to go in the .network file instead of the .netdev file. Change-Id: I9e9dc2c213414ae458392beab32334b89a897267 Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge.bb | 19 +++++++++---------- .../networking/gbmc-bridge/-bmc-gbmcbr.netdev | 5 +++++ .../networking/gbmc-bridge/-bmc-gbmcbr.netdev.in | 7 ------- .../networking/gbmc-bridge/-bmc-gbmcbr.network | 8 -------- .../networking/gbmc-bridge/-bmc-gbmcbr.network.in | 9 +++++++++ 5 files changed, 23 insertions(+), 25 deletions(-) create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev delete mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in delete mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network create mode 100644 meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network.in (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index fc7dfbfb3..c132bff5e 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -7,8 +7,8 @@ inherit systemd FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" SRC_URI += " \ - file://-bmc-gbmcbr.netdev.in \ - file://-bmc-gbmcbr.network \ + file://-bmc-gbmcbr.netdev \ + file://-bmc-gbmcbr.network.in \ file://-bmc-gbmcbrdummy.netdev \ file://-bmc-gbmcbrdummy.network \ file://+-bmc-gbmcbrusb.network \ @@ -61,17 +61,16 @@ do_install() { install -d -m0755 $netdir if [ ! -z "${GBMC_BR_MAC_ADDR}" ]; then - sed -i 's,@MAC@,Address=fe80::${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64,' \ - ${WORKDIR}/-bmc-gbmcbr.netdev.in - addr=${GBMC_ULA_PREFIX}:${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64 - sed -i "s,@ADDR@,Address=$addr," ${WORKDIR}/-bmc-gbmcbr.netdev.in + local addr= + addr+='Address=fe80::${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64\n' + addr+='Address=${GBMC_ULA_PREFIX}:${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64' + sed -i "s,@ADDR@,$addr," ${WORKDIR}/-bmc-gbmcbr.network.in else - sed -i '/@MAC@/d' ${WORKDIR}/-bmc-gbmcbr.netdev.in - sed -i '/@ADDR@/d' ${WORKDIR}/-bmc-gbmcbr.netdev.in + sed -i '/@ADDR@/d' ${WORKDIR}/-bmc-gbmcbr.network.in fi - install -m0644 ${WORKDIR}/-bmc-gbmcbr.netdev.in $netdir/-bmc-gbmcbr.netdev - install -m0644 ${WORKDIR}/-bmc-gbmcbr.network $netdir/ + install -m0644 ${WORKDIR}/-bmc-gbmcbr.netdev $netdir/ + install -m0644 ${WORKDIR}/-bmc-gbmcbr.network.in $netdir/-bmc-gbmcbr.network install -m0644 ${WORKDIR}/-bmc-gbmcbrdummy.netdev $netdir/ install -m0644 ${WORKDIR}/-bmc-gbmcbrdummy.network $netdir/ install -m0644 ${WORKDIR}/+-bmc-gbmcbrusb.network $netdir/ diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev new file mode 100644 index 000000000..d890ef9ff --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev @@ -0,0 +1,5 @@ +[NetDev] +Name=gbmcbr +Kind=bridge +[Bridge] +STP=true diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in deleted file mode 100644 index a7e91332c..000000000 --- a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.netdev.in +++ /dev/null @@ -1,7 +0,0 @@ -[NetDev] -Name=gbmcbr -Kind=bridge -@MAC@ -@ADDR@ -[Bridge] -STP=true diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network deleted file mode 100644 index 37aea6c1e..000000000 --- a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network +++ /dev/null @@ -1,8 +0,0 @@ -[Match] -Name=gbmcbr -[Network] -DHCP=false -IPv6AcceptRA=true -LLMNR=true -MulticastDNS=true -LinkLocalAddressing=ipv6 diff --git a/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network.in b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network.in new file mode 100644 index 000000000..c6097bbdb --- /dev/null +++ b/meta-google/recipes-google/networking/gbmc-bridge/-bmc-gbmcbr.network.in @@ -0,0 +1,9 @@ +[Match] +Name=gbmcbr +[Network] +@ADDR@ +DHCP=false +IPv6AcceptRA=true +LLMNR=true +MulticastDNS=true +LinkLocalAddressing=ipv6 -- cgit v1.2.3 From 0f31b96b2e13ffd845d012091e5edae80a7fe9d9 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 12 May 2021 01:25:03 -0700 Subject: meta-google: gbmc-bridge: Fix gw source check The conversion to ip_to_bytes picked the wrong address bytes off by one. This fixes it and verifies that a machine now updates the address. Change-Id: Ifc7bbebc0cf500d51d01d693445aa2533122e9a1 Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh index f765b0d10..cfe993f28 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh +++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-gw-src.sh @@ -56,7 +56,7 @@ gbmc_br_gw_src_hook() { echo "gBMC Bridge Ensure RA Invalid IP: $ip" >&2 return 1 fi - if (( ip_bytes[9] != 0xfd || ip_bytes[10] != 0 )); then + if (( ip_bytes[8] != 0xfd || ip_bytes[9] != 0 )); then return 0 fi if [ "$action" = 'add' -a "$ip" != "$gbmc_br_gw_src_ip" ]; then -- cgit v1.2.3 From cf1e7270226fd27f72d9c70caf422376a8a14404 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 12 May 2021 00:57:41 -0700 Subject: meta-google: gbmc-ncsi-nft: More forward restriction We only want to allow ::fd... traffic info the machine area network from the outside world. Instead of just blocking internal network addresses from the outside, explicitly look at the prefix. Change-Id: Id0afef7c813aef381e81b8fcfb570778f529f5dc Signed-off-by: William A. Kennington III --- meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in | 2 +- meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in index 70f14ae59..938dca34b 100644 --- a/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in +++ b/meta-google/recipes-google/ncsi/files/50-gbmc-ncsi.rules.in @@ -25,7 +25,7 @@ table inet filter { icmpv6 type nd-router-advert accept } chain ncsi_forward { - type filter hook forward priority 0; policy accept; + type filter hook forward priority 0; policy drop; iifname != @NCSI_IF@ accept oifname != gbmcbr drop ip6 daddr fdb5:0481:10ce::/64 drop diff --git a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in index 727c8b643..93d1a4ad2 100644 --- a/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in +++ b/meta-google/recipes-google/ncsi/files/gbmc-ncsi-nft.sh.in @@ -58,6 +58,11 @@ gbmc_ncsi_nft_update() { fi fi + contents+=' }'$'\n' + contents+=' chain ncsi_forward {'$'\n' + if [ -n "$pfx" ]; then + contents+=" ip6 saddr != $pfx/72 ip6 daddr $pfx/72 accept"$'\n' + fi contents+=' }'$'\n' contents+='}'$'\n' -- cgit v1.2.3 From c1a3cc2c804b6d323a20b2652c91cbaacb26d589 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 12 May 2021 13:32:38 -0700 Subject: meta-google: gbmc-ncsi-config: Add unreachable bridge route We don't want traffic being routed back out of the BMC when it is destined for the BMC network. It's nice that unrecognized routes return an obvious unreachable error to the end user. Change-Id: If261faf7b8f2416ee9a802f85db17ed62946625d Signed-off-by: William A. Kennington III --- meta-google/recipes-google/ncsi/files/gbmc-ncsi-br-pub-addr.sh.in | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'meta-google/recipes-google') 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 949f04f45..961da5095 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 @@ -55,6 +55,10 @@ ValidLifetimeSec=60 [IPv6RoutePrefix] Route=$ncsi_pfx/80 LifetimeSec=60 +[Route] +Destination=$stateless_pfx/72 +Type=unreachable +Metric=1024 EOF contents+="$here"$'\n' fi -- cgit v1.2.3 From 8a5853a579d00deff5f68ebfe8705b8960b62752 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 12 May 2021 18:01:22 -0700 Subject: meta-google: gbmc-bridge: Remove bashism Appending strings is a bashism and can't be used in bitbake shell. Change-Id: Ie4f75367cc59000595afc68431ff98dbfc4b16c6 Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge.bb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index c132bff5e..329a8b00d 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -61,9 +61,8 @@ do_install() { install -d -m0755 $netdir if [ ! -z "${GBMC_BR_MAC_ADDR}" ]; then - local addr= - addr+='Address=fe80::${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64\n' - addr+='Address=${GBMC_ULA_PREFIX}:${@mac_to_eui64(GBMC_BR_MAC_ADDR)}/64' + sfx='${@mac_to_eui64(GBMC_BR_MAC_ADDR)}' + addr="Address=${GBMC_ULA_PREFIX}:$sfx/64\nAddress=fe80::$sfx/64" sed -i "s,@ADDR@,$addr," ${WORKDIR}/-bmc-gbmcbr.network.in else sed -i '/@ADDR@/d' ${WORKDIR}/-bmc-gbmcbr.network.in -- cgit v1.2.3 From 16fcffb897451aca5a1ca18090234e22e0f8a877 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Wed, 12 May 2021 18:52:20 -0700 Subject: meta-google: gbmc-bridge: Workaround do_rm_work Otherwise when using a posix shell it will fail with: Step #1: | ERROR: Execution of '/workspace/ci_workspace/gbmc/build/tmp/work/armv7a-openbmc-linux-gnueabi/gbmc-bridge/1.0-r1/temp/run.do_rm_work.40349' failed with exit code 1: Step #1: | grep: invalid max count Step #1: | rm: invalid option -- 'b' Step #1: | Try 'rm ./-bmc-gbmcbr.netdev' to remove the file '-bmc-gbmcbr.netdev'. Step #1: | Try 'rm --help' for more information. Step #1: | WARNING: exit code 1 from a shell command. Change-Id: Ie846810b3c5e187d20c18f843ff8e4b0851ed5df Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge.bb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index 329a8b00d..bacb34958 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -97,3 +97,10 @@ do_install() { install -d -m0755 ${D}${systemd_system_unitdir} install -m0755 ${WORKDIR}/gbmc-br-ensure-ra.service ${D}${systemd_system_unitdir}/ } + +do_rm_work_prepend() { + # HACK: Work around broken do_rm_work not properly calling rm with `--` + # It doesn't like filenames that start with `-` + mkdir -p ${WORKDIR}/done + mv -- ${WORKDIR}/-* ${WORKDIR}/done +} -- cgit v1.2.3 From 67f5063d272576de574ba9210c8c42f0d094fbf8 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Thu, 13 May 2021 11:19:25 -0700 Subject: meta-google: gbmc-bridge: Fix do_rm_work The workdir will be empty if the package is populated from the sstate, fix the command to work for this case. Change-Id: Ie262a69de067e94e9da32ca8a89d1db1a5ab5bf2 Signed-off-by: William A. Kennington III --- meta-google/recipes-google/networking/gbmc-bridge.bb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb index bacb34958..37af84baf 100644 --- a/meta-google/recipes-google/networking/gbmc-bridge.bb +++ b/meta-google/recipes-google/networking/gbmc-bridge.bb @@ -101,6 +101,5 @@ do_install() { do_rm_work_prepend() { # HACK: Work around broken do_rm_work not properly calling rm with `--` # It doesn't like filenames that start with `-` - mkdir -p ${WORKDIR}/done - mv -- ${WORKDIR}/-* ${WORKDIR}/done + rm -rf -- ${WORKDIR}/-* } -- cgit v1.2.3 From 1e64a91859cc5562011f6d4373ddf465515e44f8 Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Tue, 18 May 2021 23:30:17 +0000 Subject: google-misc: srcrev bump 4c68ffb8b0..4a0e2e3c10 Nancy Yuen (1): Add OWNERS plugin to google-misc. Change-Id: I8edec84a9493bf67adb6969f2397666bc63d34d4 Signed-off-by: Andrew Geissler --- meta-google/recipes-google/google-misc/google-misc.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'meta-google/recipes-google') diff --git a/meta-google/recipes-google/google-misc/google-misc.inc b/meta-google/recipes-google/google-misc/google-misc.inc index 95f52613a..85acb9353 100644 --- a/meta-google/recipes-google/google-misc/google-misc.inc +++ b/meta-google/recipes-google/google-misc/google-misc.inc @@ -6,7 +6,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://../../LICENSE;md5=34400b68072d710fecd0a2940a0d1658" SRC_URI += "git://github.com/openbmc/google-misc" -SRCREV = "4c68ffb8b08fa4484824586ef4a981bcfabd38bb" +SRCREV = "4a0e2e3c10327dac1c923d263929be9a20478b24" S = "${WORKDIR}/git/subprojects/${GOOGLE_MISC_PROJ}" inherit meson -- cgit v1.2.3