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
|
||||
Reference in New Issue
Block a user