Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
[NetDev]
|
||||
Name=gbmcbrncsidhcp
|
||||
Kind=veth
|
||||
[Peer]
|
||||
Name=gbmcncsidhcp
|
||||
@@ -0,0 +1,4 @@
|
||||
[Match]
|
||||
Name=gbmcbrncsidhcp
|
||||
[Network]
|
||||
Bridge=gbmcbr
|
||||
@@ -0,0 +1,5 @@
|
||||
[NetDev]
|
||||
Name=gbmcncsidhcp
|
||||
Kind=veth
|
||||
[Peer]
|
||||
Name=gbmcbrncsidhcp
|
||||
@@ -0,0 +1,10 @@
|
||||
[Match]
|
||||
Name=gbmcncsidhcp
|
||||
[Network]
|
||||
DHCP=false
|
||||
IPv6AcceptRA=false
|
||||
LLMNR=false
|
||||
MulticastDNS=false
|
||||
LinkLocalAddressing=ipv6
|
||||
# TODO: Change address back to fdb5:0481:10ce::1/64
|
||||
Address=fdb5:0481:10ce::2/64
|
||||
@@ -0,0 +1,33 @@
|
||||
# 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.
|
||||
|
||||
[ -n "${gbmc_ncsi_clear_ip-}" ] && return
|
||||
|
||||
source /usr/libexec/ncsid_lib.sh || exit
|
||||
|
||||
gbmc_ncsi_clear_ip_hook() {
|
||||
local ip="${1-}"
|
||||
|
||||
# We only want to clear our IPs if we are assigning a new IP
|
||||
[ -z "$ip" ] && return
|
||||
|
||||
echo "Removing Persistent NCSI IPs" >&2
|
||||
SetStatic xyz.openbmc_project.Network '@NCSI_IF@' 2>/dev/null || true
|
||||
UpdateIP xyz.openbmc_project.Network '@NCSI_IF@' '0.0.0.0' '0' 2>/dev/null || true
|
||||
UpdateIP xyz.openbmc_project.Network '@NCSI_IF@' '::' '0' 2>/dev/null || true
|
||||
}
|
||||
|
||||
GBMC_BR_LIB_SET_IP_HOOKS+=(gbmc_ncsi_clear_ip_hook)
|
||||
|
||||
gbmc_ncsi_clear_ip=1
|
||||
@@ -0,0 +1,45 @@
|
||||
table inet filter {
|
||||
chain ncsi_input {
|
||||
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
|
||||
jump ncsi_legacy_input
|
||||
reject
|
||||
}
|
||||
chain gbmc_br_pub_input {
|
||||
ip6 nexthdr icmpv6 accept
|
||||
}
|
||||
chain ncsi_legacy_input {
|
||||
jump ncsi_any_input
|
||||
tcp dport 3959 accept
|
||||
udp dport 3959 accept
|
||||
tcp dport 3967 accept
|
||||
udp dport 3967 accept
|
||||
}
|
||||
chain ncsi_brd_input {
|
||||
jump ncsi_any_input
|
||||
}
|
||||
chain ncsi_any_input {
|
||||
icmpv6 type nd-neighbor-advert accept
|
||||
icmpv6 type nd-neighbor-solicit accept
|
||||
icmpv6 type nd-router-advert accept
|
||||
}
|
||||
chain ncsi_forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
iifname != @NCSI_IF@ accept
|
||||
oifname != gbmcbr drop
|
||||
ip6 daddr fdb5:0481:10ce::/64 drop
|
||||
ip6 saddr fdb5:0481:10ce::/64 drop
|
||||
}
|
||||
chain ncsi_dhcp_input {
|
||||
type filter hook input priority 0; policy drop;
|
||||
iifname != ncsigbmc accept
|
||||
ip6 nexthdr icmpv6 accept
|
||||
udp dport 547 accept
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
BindsTo=ncsid@@NCSI_IF@.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/sbin/ip link set @NCSI_IF@ alias ncsi
|
||||
ExecStop=/sbin/ip link set @NCSI_IF@ alias ''
|
||||
|
||||
[Install]
|
||||
WantedBy=nic-hostful@@NCSI_IF@.target
|
||||
WantedBy=nic-hostless@@NCSI_IF@.target
|
||||
@@ -0,0 +1,152 @@
|
||||
# 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.
|
||||
|
||||
[ -n "${gbmc_ncsi_br_deprecated_ips_lib-}" ] && return
|
||||
|
||||
source /usr/share/network/lib.sh || exit
|
||||
|
||||
gbmc_ncsi_br_deprecated_ips_init=
|
||||
gbmc_ncsi_br_deprecated_ips_confip=
|
||||
gbmc_ncsi_br_deprecated_ips_lastip=
|
||||
gbmc_ncsi_br_deprecated_ips_lastncsi=
|
||||
gbmc_ncsi_br_deprecated_ips_confncsi=
|
||||
|
||||
gbmc_ncsi_br_deprecated_ips_update() {
|
||||
[ -n "$gbmc_ncsi_br_deprecated_ips_init" ] || return
|
||||
[ "$gbmc_ncsi_br_deprecated_ips_confip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ] || \
|
||||
[ "$gbmc_ncsi_br_deprecated_ips_confncsi" != "$gbmc_ncsi_br_deprecated_ips_lastncsi" ] || return
|
||||
gbmc_ncsi_br_deprecated_ips_confip="$gbmc_ncsi_br_deprecated_ips_lastip"
|
||||
gbmc_ncsi_br_deprecated_ips_confncsi="$gbmc_ncsi_br_deprecated_ips_lastncsi"
|
||||
|
||||
printf 'gBMC NCSI Deprecated Addrs: %s\n' \
|
||||
"${gbmc_ncsi_br_deprecated_ips_lastip:-(deleted)}" >&2
|
||||
|
||||
local contents=
|
||||
local nfcontents=
|
||||
if [ -n "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
|
||||
local pfx_bytes=()
|
||||
ip_to_bytes pfx_bytes "$gbmc_ncsi_br_deprecated_ips_lastip"
|
||||
|
||||
local pfx="$(ip_bytes_to_str pfx_bytes)"
|
||||
(( pfx_bytes[9] &= 0xf0 ))
|
||||
local stateless_pfx="$(ip_bytes_to_str pfx_bytes)"
|
||||
local stateless_ip=
|
||||
if [ -e /sys/class/net/gbmcbr ]; then
|
||||
local gbmcbr_mac="$(ip link show gbmcbr | tail -n 1 | awk '{print $2}')"
|
||||
local gbmcbr_eui48="$(mac_to_eui48 "$gbmcbr_mac")"
|
||||
stateless_ip="$(ip_pfx_concat "$stateless_pfx/80" "$gbmcbr_eui48")"
|
||||
stateless_ip="${stateless_ip%/*}"
|
||||
fi
|
||||
pfx_bytes[8]=0
|
||||
pfx_bytes[9]=0
|
||||
local host_pfx=
|
||||
if [ -n "${gbmc_ncsi_br_deprecated_ips_confncsi}" ]; then
|
||||
# Only impersonate the host if we have an NCSI state machine
|
||||
host_pfx="$(ip_bytes_to_str pfx_bytes)"
|
||||
fi
|
||||
read -r -d '' contents <<EOF
|
||||
[Network]
|
||||
IPv6ProxyNDP=yes
|
||||
IPv6ProxyNDPAddress=$pfx
|
||||
IPv6ProxyNDPAddress=$stateless_pfx
|
||||
${host_pfx:+IPv6ProxyNDPAddress=}$host_pfx
|
||||
${stateless_ip:+IPv6ProxyNDPAddress=}$stateless_ip
|
||||
EOF
|
||||
read -r -d '' nfcontents <<EOF
|
||||
table inet filter {
|
||||
chain ncsi_input {
|
||||
ip6 saddr != $pfx/76 ip6 daddr $pfx/76 goto ncsi_gbmc_br_pub_input
|
||||
${host_pfx:+ip6 daddr $host_pfx/64 goto ncsi_legacy_input}
|
||||
}
|
||||
chain ncsi_forward {
|
||||
ip6 saddr != $pfx/76 ip6 daddr $pfx/76 accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
local file
|
||||
for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/50-deprecated.conf; do
|
||||
mkdir -p -m 755 "$(dirname "$file")"
|
||||
if [ -z "$contents" ]; then
|
||||
rm -f "$file"
|
||||
else
|
||||
printf '%s' "$contents" >"$file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Ensure that systemd-networkd performs a reconfiguration as it doesn't
|
||||
# currently check the mtime of drop-in files.
|
||||
touch -c /etc/systemd/network/*-bmc-@NCSI_IF@.network
|
||||
|
||||
if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then
|
||||
networkctl reload && networkctl reconfigure @NCSI_IF@
|
||||
fi
|
||||
|
||||
local rfile=/run/nftables/40-gbmc-ncsi-br.rules
|
||||
mkdir -p -m 755 "$(dirname "$rfile")"
|
||||
if [ -z "$nfcontents" ]; then
|
||||
rm -f "$rfile"
|
||||
else
|
||||
printf '%s' "$nfcontents" >"$rfile"
|
||||
fi
|
||||
systemctl reset-failed nftables && systemctl --no-block reload-or-restart nftables || true
|
||||
}
|
||||
|
||||
gbmc_ncsi_br_deprecated_ips_hook() {
|
||||
if [ "$change" = 'init' ]; then
|
||||
gbmc_ncsi_br_deprecated_ips_init=1
|
||||
gbmc_ip_monitor_defer
|
||||
elif [ "$change" = 'defer' ]; then
|
||||
gbmc_ncsi_br_deprecated_ips_update
|
||||
elif [ "$change" = 'addr' -a "$scope" = 'global' -a "$fam" = 'inet6' ] &&
|
||||
[ "$intf" = 'gbmcbr' -o "$intf" = '@NCSI_IF@' ] &&
|
||||
[[ "$flags" != *deprecated* ]]; then
|
||||
local pfx_bytes=()
|
||||
ip_to_bytes pfx_bytes "$ip" || return
|
||||
# No ULA Addresses
|
||||
if (( pfx_bytes[0] & 0xfe == 0xfc )); then
|
||||
return
|
||||
fi
|
||||
# We only want to allow a <pfx>::fd0x address, where x>0
|
||||
if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] & 0xf == 0 )); then
|
||||
return
|
||||
fi
|
||||
for (( i = 10; i < 16; ++i )); do
|
||||
if (( pfx_bytes[i] != 0 )); then
|
||||
return
|
||||
fi
|
||||
done
|
||||
if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
|
||||
gbmc_ncsi_br_deprecated_ips_lastip="$ip"
|
||||
gbmc_ip_monitor_defer
|
||||
fi
|
||||
if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
|
||||
gbmc_ncsi_br_deprecated_ips_lastip=
|
||||
gbmc_ip_monitor_defer
|
||||
fi
|
||||
elif [ "$change" = 'link' -a "$action" = 'add' -a "$intf" = '@NCSI_IF@' ]; then
|
||||
if ip link show '@NCSI_IF@' | grep -q '^ *alias ncsi$'; then
|
||||
gbmc_ncsi_br_deprecated_ips_lastncsi=1
|
||||
gbmc_ip_monitor_defer
|
||||
else
|
||||
gbmc_ncsi_br_deprecated_ips_lastncsi=
|
||||
gbmc_ip_monitor_defer
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_deprecated_ips_hook)
|
||||
|
||||
gbmc_ncsi_br_deprecated_ips_lib=1
|
||||
@@ -0,0 +1,87 @@
|
||||
# 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.
|
||||
|
||||
[ -n "${gbmc_ncsi_br_pub_addr_lib-}" ] && return
|
||||
|
||||
[ ! -e /usr/share/gbmc-br-lib.sh ] && return
|
||||
|
||||
source /usr/share/network/lib.sh || exit
|
||||
source /usr/share/gbmc-br-lib.sh || exit
|
||||
|
||||
gbmc_ncsi_br_pub_addr_init=
|
||||
gbmc_ncsi_br_pub_addr_lastip=
|
||||
gbmc_ncsi_br_pub_addr_confip=
|
||||
|
||||
gbmc_ncsi_br_pub_addr_update() {
|
||||
[ -n "$gbmc_ncsi_br_pub_addr_init" ] || return
|
||||
[ "$gbmc_ncsi_br_pub_addr_confip" != "$gbmc_ncsi_br_pub_addr_lastip" ] || return
|
||||
gbmc_ncsi_br_pub_addr_confip="$gbmc_ncsi_br_pub_addr_lastip"
|
||||
|
||||
printf 'gBMC Bridge Pub Addr from NCSI: %s\n' \
|
||||
"${gbmc_ncsi_br_pub_addr_lastip:-(deleted)}" >&2
|
||||
|
||||
local pfx_bytes=()
|
||||
if [ -n "$gbmc_ncsi_br_pub_addr_lastip" ]; then
|
||||
ip_to_bytes pfx_bytes "$gbmc_ncsi_br_pub_addr_lastip"
|
||||
# Ensure we have a /64 or an fdxx address
|
||||
if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] == 0 )); then
|
||||
local i
|
||||
for (( i = 8; i < 16; ++i )); do
|
||||
if (( pfx_bytes[$i] != 0 )); then
|
||||
pfx_bytes=()
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
local contents=
|
||||
if (( ${#pfx_bytes[@]} != 0 )); then
|
||||
pfx_bytes[8]=0xfd
|
||||
# We never want to use the stateless pfx
|
||||
if (( pfx_bytes[9] == 0 )); then
|
||||
pfx_bytes[9]=0x01
|
||||
fi
|
||||
# Remove any existing persisted IP
|
||||
gbmc_br_set_ip
|
||||
# Load the IP to the bridge non-persistently
|
||||
gbmc_br_reload_ip "$(ip_bytes_to_str pfx_bytes)"
|
||||
else
|
||||
gbmc_br_reload_ip
|
||||
fi
|
||||
}
|
||||
|
||||
gbmc_ncsi_br_pub_addr_hook() {
|
||||
if [ "$change" = 'init' ]; then
|
||||
gbmc_ncsi_br_pub_addr_init=1
|
||||
gbmc_ip_monitor_defer
|
||||
elif [ "$change" = 'defer' ]; then
|
||||
gbmc_ncsi_br_pub_addr_update
|
||||
elif [ "$change" = 'addr' -a "$intf" = '@NCSI_IF@' ] &&
|
||||
[ "$scope" = 'global' -a "$fam" = 'inet6' ] &&
|
||||
[[ "$flags" != *deprecated* ]]; then
|
||||
if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_pub_addr_lastip" ]; then
|
||||
gbmc_ncsi_br_pub_addr_lastip="$ip"
|
||||
gbmc_ip_monitor_defer
|
||||
fi
|
||||
if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_pub_addr_lastip" ]; then
|
||||
gbmc_ncsi_br_pub_addr_lastip=
|
||||
gbmc_ip_monitor_defer
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_pub_addr_hook)
|
||||
|
||||
gbmc_ncsi_br_pub_addr_lib=1
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=gBMC DHCP Relay Agent Daemon
|
||||
After=network.target
|
||||
StartLimitIntervalSec=10
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
ExecStart=/usr/sbin/dhcrelay -d --no-pid -rp 3967 -l gbmcncsidhcp -u ff02::1:2%%@NCSI_IF@
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=gBMC NCSI RA Discovery
|
||||
After=network.target
|
||||
StartLimitIntervalSec=10
|
||||
StartLimitBurst=3
|
||||
Conflicts=nic-hostless@@NCSI_IF@.target
|
||||
Conflicts=nic-hostful@@NCSI_IF@.target
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
ExecStart=/usr/libexec/gbmc-ncsi-ip-from-ra.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,95 @@
|
||||
#!/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.
|
||||
|
||||
[ ! -e /usr/share/gbmc-br-lib.sh ] && exit
|
||||
|
||||
# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh
|
||||
source /usr/share/network/lib.sh || exit
|
||||
# shellcheck source=meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-lib.sh
|
||||
source /usr/share/gbmc-br-lib.sh || exit
|
||||
|
||||
NCSI_IF='@NCSI_IF@'
|
||||
|
||||
old_pfx=
|
||||
old_fqdn=
|
||||
old_rtr=
|
||||
|
||||
set_host() {
|
||||
[[ -n "$host" && -n "$domain" && -n "$hextet" ]] || return
|
||||
|
||||
local fqdn="$host-n$hextet.$domain"
|
||||
[ "$fqdn" != "$old_fqdn" ] || return
|
||||
old_fqdn="$fqdn"
|
||||
|
||||
echo "Found hostname $fqdn" >&2
|
||||
hostnamectl set-hostname "$fqdn" || true
|
||||
}
|
||||
|
||||
set_net() {
|
||||
[[ -n "$pfx" && -n "$rtr" ]] || return
|
||||
[[ "$pfx" != "$old_pfx" || "$rtr" != "$old_rtr" ]] || return
|
||||
old_pfx="$pfx"
|
||||
old_rtr="$rtr"
|
||||
|
||||
echo "Found prefix $pfx from $rtr" >&2
|
||||
|
||||
# We no longer need NCSId if we are in this configuration
|
||||
systemctl stop --no-block ncsid@"$NCSI_IF" || true
|
||||
|
||||
# Save the IP address for the interface
|
||||
gbmc_br_set_ip "$pfx" || true
|
||||
|
||||
# DHCP Relay workaround until alternate source port is supported
|
||||
# TODO: Remove this once internal relaying cleanups land
|
||||
gbmc-ncsi-smartnic-wa.sh || true
|
||||
}
|
||||
|
||||
w=60
|
||||
while true; do
|
||||
start=$SECONDS
|
||||
while read -r line; do
|
||||
if [ -z "$line" ]; then
|
||||
hextet=
|
||||
pfx=
|
||||
host=
|
||||
domain=
|
||||
elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then
|
||||
t_pfx="${BASH_REMATCH[1]}"
|
||||
t_pfx_len="${BASH_REMATCH[2]}"
|
||||
ip_to_bytes t_pfx_b "$t_pfx" || continue
|
||||
(( t_pfx_len == 76 && t_pfx_b[8] & 0xfd == 0xfd )) || continue
|
||||
(( t_pfx_b[9] |= 1 ))
|
||||
hextet="fd$(printf '%02x' "${t_pfx_b[9]}")"
|
||||
pfx="$(ip_bytes_to_str t_pfx_b)"
|
||||
elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.]+)(.*[.]google[.]com)$ ]]; then
|
||||
# Ideally, we use PCRE and with lookahead and can do this in a single regex
|
||||
# ^([a-zA-Z0-9-]+(?=-n[a-fA-F0-9]{1,4})|[a-zA-Z0-9-]+(?!-n[a-fA-F0-9]{1,4}))[^.]*[.]((?:[a-zA-Z0-9]*[.])*google[.]com)$
|
||||
# Instead we do multiple steps to extract the needed info
|
||||
host="${BASH_REMATCH[1]}"
|
||||
domain="${BASH_REMATCH[2]#.}"
|
||||
if [[ "$host" =~ (-n[a-fA-F0-9]{1,4})$ ]]; then
|
||||
host="${host%"${BASH_REMATCH[1]}"}"
|
||||
fi
|
||||
elif [[ "$line" =~ ^from' '(.*)$ ]]; then
|
||||
rtr="${BASH_REMATCH[1]}"
|
||||
set_net || true
|
||||
set_host || true
|
||||
fi
|
||||
done < <(rdisc6 -d -m "$NCSI_IF" -w $(( w * 1000 )) 2>/dev/null)
|
||||
# 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
|
||||
@@ -0,0 +1,85 @@
|
||||
# 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.
|
||||
|
||||
[ -n "${gbmc_ncsi_nft_lib-}" ] && return
|
||||
|
||||
source /usr/share/network/lib.sh || exit
|
||||
|
||||
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 goto ncsi_legacy_input"$'\n'
|
||||
fi
|
||||
|
||||
contents+=' }'$'\n'
|
||||
contents+='}'$'\n'
|
||||
|
||||
local rfile=/run/nftables/30-gbmc-ncsi-in.rules
|
||||
mkdir -p -m 755 "$(dirname "$rfile")"
|
||||
printf '%s' "$contents" >"$rfile"
|
||||
|
||||
systemctl reset-failed nftables && systemctl --no-block reload-or-restart nftables || true
|
||||
}
|
||||
|
||||
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'
|
||||
local pfx_bytes=()
|
||||
ip_to_bytes pfx_bytes "$ip" || return
|
||||
# We only want to allow a <pfx>:: address
|
||||
for (( i = 8; i < 16; ++i )); do
|
||||
if (( pfx_bytes[i] != 0 )); then
|
||||
return
|
||||
fi
|
||||
done
|
||||
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
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Set NICEnabled property to true
|
||||
Wants=xyz.openbmc_project.Network.service
|
||||
After=xyz.openbmc_project.Network.service
|
||||
Wants=mapper-wait@-xyz-openbmc_project-network-@NCSI_IF@.service
|
||||
After=mapper-wait@-xyz-openbmc_project-network-@NCSI_IF@.service
|
||||
StartLimitIntervalSec=10
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=busctl set-property xyz.openbmc_project.Network /xyz/openbmc_project/network/@NCSI_IF@ xyz.openbmc_project.Network.EthernetInterface NICEnabled b true
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/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.
|
||||
|
||||
override=/run/systemd/system/gbmc-ncsi-dhcrelay.service.d/10-nosp.conf
|
||||
mkdir -p "$(dirname "$override")"
|
||||
echo '[Service]' >"$override"
|
||||
echo 'ExecStart=' >>"$override"
|
||||
# Remove the source relay port from the relay, bringing it back to run on
|
||||
# the default port 547. Our relays don't support the source port option needed
|
||||
# to run on 3967 for our legacy NICs.
|
||||
grep '^ExecStart=' /lib/systemd/system/gbmc-ncsi-dhcrelay.service | \
|
||||
sed 's, -rp 3967,,' >>"$override"
|
||||
|
||||
override=/run/systemd/system/gbmc-br-dhcp.service.d/10-direct.conf
|
||||
mkdir -p "$(dirname "$override")"
|
||||
echo '[Service]' >"$override"
|
||||
echo 'ExecStart=' >>"$override"
|
||||
# Switch the gbmcbr interface for the NCSI one to avoid passing the SOLICIT
|
||||
# message through the BMC relay.
|
||||
grep '^ExecStart=' /lib/systemd/system/gbmc-br-dhcp.service | \
|
||||
sed 's, -i gbmcbr, -i @NCSI_IF@,' >>"$override"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl reset-failed gbmc-ncsi-dhcrelay
|
||||
systemctl restart --no-block gbmc-ncsi-dhcrelay
|
||||
systemctl reset-failed gbmc-br-dhcp
|
||||
systemctl restart --no-block gbmc-br-dhcp
|
||||
|
||||
read -r -d '' contents <<EOF
|
||||
table inet filter {
|
||||
chain ncsi_legacy_input {
|
||||
udp dport {546,547} accept
|
||||
}
|
||||
}
|
||||
EOF
|
||||
rfile=/run/nftables/60-gbmc-ncsi-ra.rules
|
||||
mkdir -p "$(dirname "$rfile")"
|
||||
printf '%s' "$contents" >"$rfile"
|
||||
systemctl reset-failed nftables
|
||||
systemctl --no-block reload-or-restart nftables
|
||||
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=SSL/SSH multiplexer
|
||||
Requires=gbmc-ncsi-sslh.socket
|
||||
After=gbmc-ncsi-sslh.socket
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/sslh -n -f --ssh [::1]:22 --http [::1]:80 --tls [::1]:443
|
||||
KillMode=process
|
||||
#Hardening
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectControlGroups=true
|
||||
MountFlags=private
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
MemoryDenyWriteExecute=true
|
||||
DynamicUser=true
|
||||
@@ -0,0 +1,6 @@
|
||||
[Socket]
|
||||
BindToDevice=@NCSI_IF@
|
||||
ListenStream=3967
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
@@ -0,0 +1,149 @@
|
||||
SUMMARY = "Configures ncsi for a gBMC system"
|
||||
PR = "r1"
|
||||
LICENSE = "Apache-2.0"
|
||||
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
|
||||
|
||||
inherit systemd
|
||||
|
||||
SRC_URI += " \
|
||||
file://-bmc-gbmcbrncsidhcp.netdev \
|
||||
file://-bmc-gbmcbrncsidhcp.network \
|
||||
file://-bmc-gbmcncsidhcp.netdev \
|
||||
file://-bmc-gbmcncsidhcp.network \
|
||||
file://50-gbmc-ncsi.rules.in \
|
||||
file://gbmc-ncsi-dhcrelay.service.in \
|
||||
file://gbmc-ncsi-ip-from-ra.service.in \
|
||||
file://gbmc-ncsi-ip-from-ra.sh.in \
|
||||
file://gbmc-ncsi-smartnic-wa.sh.in \
|
||||
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 \
|
||||
file://gbmc-ncsi-br-deprecated-ips.sh.in \
|
||||
file://gbmc-ncsi-set-nicenabled.service.in \
|
||||
file://gbmc-ncsi-alias.service.in \
|
||||
file://50-gbmc-ncsi-clear-ip.sh.in \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}"
|
||||
|
||||
RDEPENDS:${PN} += " \
|
||||
bash \
|
||||
dhcp-relay \
|
||||
gbmc-ip-monitor \
|
||||
ncsid \
|
||||
network-sh \
|
||||
nftables-systemd \
|
||||
sslh \
|
||||
ndisc6-rdisc6 \
|
||||
"
|
||||
|
||||
FILES:${PN} += " \
|
||||
${datadir}/gbmc-br-lib \
|
||||
${datadir}/gbmc-ip-monitor \
|
||||
${systemd_unitdir} \
|
||||
"
|
||||
|
||||
SYSTEMD_SERVICE:${PN} += " \
|
||||
gbmc-ncsi-dhcrelay.service \
|
||||
gbmc-ncsi-sslh.service \
|
||||
gbmc-ncsi-sslh.socket \
|
||||
gbmc-ncsi-set-nicenabled.service \
|
||||
gbmc-ncsi-ip-from-ra.service \
|
||||
"
|
||||
|
||||
do_install:append() {
|
||||
if_name='${GBMC_NCSI_IF_NAME}'
|
||||
if [ -z "$if_name" ]; then
|
||||
echo "Missing if_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install -d -m0755 ${D}${sysconfdir}/sysctl.d
|
||||
echo "net.ipv6.conf.$if_name.accept_dad=0" \
|
||||
>>${D}${sysconfdir}/sysctl.d/25-gbmc-ncsi.conf
|
||||
echo "net.ipv6.conf.$if_name.dad_transmits=0" \
|
||||
>>${D}${sysconfdir}/sysctl.d/25-gbmc-ncsi.conf
|
||||
|
||||
install -d -m0755 ${D}${systemd_unitdir}/network
|
||||
install -m0644 ${WORKDIR}/-bmc-gbmcbrncsidhcp.netdev \
|
||||
${D}${systemd_unitdir}/network/
|
||||
install -m0644 ${WORKDIR}/-bmc-gbmcbrncsidhcp.network \
|
||||
${D}${systemd_unitdir}/network/
|
||||
install -m0644 ${WORKDIR}/-bmc-gbmcncsidhcp.netdev \
|
||||
${D}${systemd_unitdir}/network/
|
||||
install -m0644 ${WORKDIR}/-bmc-gbmcncsidhcp.network \
|
||||
${D}${systemd_unitdir}/network/
|
||||
|
||||
netdir=${D}${systemd_unitdir}/network/00-bmc-$if_name.network.d
|
||||
install -d -m0755 "$netdir"
|
||||
echo '[Network]' >>"$netdir"/gbmc-ncsi.conf
|
||||
echo 'DHCP=false' >>"$netdir"/gbmc-ncsi.conf
|
||||
echo 'IPv6AcceptRA=false' >>"$netdir"/gbmc-ncsi.conf
|
||||
echo 'LLMNR=false' >>"$netdir"/gbmc-ncsi.conf
|
||||
echo 'MulticastDNS=false' >>"$netdir"/gbmc-ncsi.conf
|
||||
echo 'LinkLocalAddressing=ipv6' >>"$netdir"/gbmc-ncsi.conf
|
||||
|
||||
nftdir=${D}${sysconfdir}/nftables
|
||||
install -d -m0755 "$nftdir"
|
||||
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
|
||||
install -d -m0755 "$wantdir"
|
||||
ln -sv ../ncsid@.service "$wantdir"/ncsid@$if_name.service
|
||||
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-alias.service.in \
|
||||
>${D}${systemd_system_unitdir}/gbmc-ncsi-alias.service
|
||||
install -d -m0755 "${D}${systemd_system_unitdir}/nic-hostless@$if_name.target.wants"
|
||||
ln -sv ../gbmc-ncsi-alias.service "${D}${systemd_system_unitdir}/nic-hostless@$if_name.target.wants"/
|
||||
install -d -m0755 "${D}${systemd_system_unitdir}/nic-hostful@$if_name.target.wants"
|
||||
ln -sv ../gbmc-ncsi-alias.service "${D}${systemd_system_unitdir}/nic-hostful@$if_name.target.wants"/
|
||||
|
||||
install -m 0644 ${WORKDIR}/gbmc-ncsi-sslh.service ${D}${systemd_system_unitdir}
|
||||
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
|
||||
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
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-br-deprecated-ips.sh.in \
|
||||
>${WORKDIR}/gbmc-ncsi-br-deprecated-ips.sh
|
||||
install -m644 ${WORKDIR}/gbmc-ncsi-br-deprecated-ips.sh $mondir
|
||||
|
||||
brlibdir=${D}${datadir}/gbmc-br-lib/
|
||||
install -d -m0755 $brlibdir
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/50-gbmc-ncsi-clear-ip.sh.in \
|
||||
>${WORKDIR}/50-gbmc-ncsi-clear-ip.sh
|
||||
install -m644 ${WORKDIR}/50-gbmc-ncsi-clear-ip.sh $brlibdir
|
||||
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-set-nicenabled.service.in \
|
||||
>${D}${systemd_system_unitdir}/gbmc-ncsi-set-nicenabled.service
|
||||
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-dhcrelay.service.in \
|
||||
>${D}${systemd_system_unitdir}/gbmc-ncsi-dhcrelay.service
|
||||
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-ip-from-ra.service.in \
|
||||
>${WORKDIR}/gbmc-ncsi-ip-from-ra.service
|
||||
install -m0644 ${WORKDIR}/gbmc-ncsi-ip-from-ra.service ${D}${systemd_system_unitdir}
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-ip-from-ra.sh.in \
|
||||
>${WORKDIR}/gbmc-ncsi-ip-from-ra.sh
|
||||
install -d -m0755 ${D}${libexecdir}
|
||||
install -m0755 ${WORKDIR}/gbmc-ncsi-ip-from-ra.sh ${D}${libexecdir}/
|
||||
|
||||
sed "s,@NCSI_IF@,$if_name,g" ${WORKDIR}/gbmc-ncsi-smartnic-wa.sh.in \
|
||||
>${WORKDIR}/gbmc-ncsi-smartnic-wa.sh
|
||||
install -d -m0755 ${D}${bindir}
|
||||
install -m0755 ${WORKDIR}/gbmc-ncsi-smartnic-wa.sh ${D}${bindir}/
|
||||
}
|
||||
|
||||
do_rm_work:prepend() {
|
||||
# HACK: Work around broken do_rm_work not properly calling rm with `--`
|
||||
# It doesn't like filenames that start with `-`
|
||||
rm -rf -- ${WORKDIR}/-*
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
SUMMARY = "Google NCSI daemon"
|
||||
DESCRIPTION = "Google NCSI daemon."
|
||||
GOOGLE_MISC_PROJ = "ncsid"
|
||||
|
||||
require ../google-misc/google-misc.inc
|
||||
|
||||
inherit systemd
|
||||
|
||||
EXTRA_OEMESON = " \
|
||||
-Dtests=disabled \
|
||||
"
|
||||
|
||||
SYSTEMD_SERVICE:${PN} += " \
|
||||
dhcp4@.service \
|
||||
dhcp6@.service \
|
||||
ncsid@.service \
|
||||
nic-hostful@.target \
|
||||
nic-hostless@.target \
|
||||
update-ra-gw@.service \
|
||||
update-ra-neighbor@.service \
|
||||
update-ra-neighbor@.timer \
|
||||
update-static-neighbors@.service \
|
||||
update-static-neighbors@.timer \
|
||||
"
|
||||
|
||||
DEPENDS += " \
|
||||
fmt \
|
||||
sdbusplus \
|
||||
stdplus \
|
||||
"
|
||||
|
||||
RDEPENDS:${PN} += " \
|
||||
bash \
|
||||
busybox \
|
||||
iputils-arping \
|
||||
jq \
|
||||
ndisc6-ndisc6 \
|
||||
ndisc6-rdisc6 \
|
||||
systemd \
|
||||
"
|
||||
Reference in New Issue
Block a user