blob: fdfa87803f0922860ef45245e4e7cbdbd22d20de [file] [log] [blame]
William A. Kennington III21e7e452021-11-05 01:31:59 -07001# Copyright 2021 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15[ -z "${gbmc_ncsi_br_deprecated_ips_lib-}" ] || return
16
William A. Kennington III2f5e1692021-11-05 01:31:59 -070017source /usr/share/network/lib.sh || exit
18
William A. Kennington III21e7e452021-11-05 01:31:59 -070019gbmc_ncsi_br_deprecated_ips_init=
20gbmc_ncsi_br_deprecated_ips_confip=
21gbmc_ncsi_br_deprecated_ips_lastip=
22
William A. Kennington III7d346b72022-04-29 14:26:05 -070023gbmc_ncsi_br_deprecated_ips_addr_contents() {
24 local addr="$1"
25
26 # If our address is assigned explicitly, don't mark it deprecated
27 local line
28 for line in $(grep '^Address=' /etc/systemd/network/*-bmc-@NCSI_IF@.network); do
29 # Remove `Address=` on the input line
30 local apfx="$(echo "$line" | sed 's,^[^=]*=,,')"
31 # ip_pfx_concat is used to normalize the address string for comparison
32 [[ "$addr/128" == "$(ip_pfx_concat "$apfx" ::)" ]] && return
33 done
34
35 cat <<EOF
36[Address]
37Address=$addr/128
38PreferredLifetime=0
39EOF
40}
41
William A. Kennington III21e7e452021-11-05 01:31:59 -070042gbmc_ncsi_br_deprecated_ips_update() {
43 [ -n "$gbmc_ncsi_br_deprecated_ips_init" ] || return
44 [ "$gbmc_ncsi_br_deprecated_ips_confip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ] || return
45 gbmc_ncsi_br_deprecated_ips_confip="$gbmc_ncsi_br_deprecated_ips_lastip"
46
47 printf 'gBMC Bridge NCSI Deprecated Addrs: %s\n' \
48 "${gbmc_ncsi_br_deprecated_ips_lastip:-(deleted)}" >&2
49
50 local contents=
William A. Kennington IIIb823f892021-11-23 20:54:56 -080051 local nfcontents=
William A. Kennington III21e7e452021-11-05 01:31:59 -070052 if [ -n "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
53 local pfx_bytes=()
54 ip_to_bytes pfx_bytes "$gbmc_ncsi_br_deprecated_ips_lastip"
55
56 local pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III3dbea932021-11-05 01:31:59 -070057 (( pfx_bytes[9] &= 0xf0 ))
58 local stateless_pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III51def642022-02-13 23:11:59 -080059 local gbmcbr_mac="$(ip link show gbmcbr | tail -n 1 | awk '{print $2}')"
60 local gbmcbr_eui48="$(mac_to_eui48 "$gbmcbr_mac")"
61 local stateless_ip="$(ip_pfx_concat "$stateless_pfx/80" "$gbmcbr_eui48")"
62 stateless_ip="${stateless_ip%/*}"
William A. Kennington III21e7e452021-11-05 01:31:59 -070063 pfx_bytes[8]=0
64 pfx_bytes[9]=0
65 local host_pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III7d346b72022-04-29 14:26:05 -070066 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$pfx")"$'\n'
67 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$stateless_pfx")"$'\n'
68 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$stateless_ip")"$'\n'
69 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$host_pfx")"$'\n'
William A. Kennington IIIb823f892021-11-23 20:54:56 -080070 read -r -d '' nfcontents <<EOF
71table inet filter {
72 chain ncsi_input {
73 ip6 saddr != $pfx/76 ip6 daddr $pfx/76 goto ncsi_gbmc_br_pub_input
74 }
75 chain ncsi_forward {
76 ip6 saddr != $pfx/76 ip6 daddr $pfx/76 accept
77 }
78}
79EOF
William A. Kennington III21e7e452021-11-05 01:31:59 -070080 fi
81
82 local file
83 for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/50-deprecated.conf; do
84 mkdir -p -m 755 "$(dirname "$file")"
85 if [ -z "$contents" ]; then
86 rm -f "$file"
87 else
88 printf '%s' "$contents" >"$file"
89 fi
90 done
91
92 # Ensure that systemd-networkd performs a reconfiguration as it doesn't
93 # currently check the mtime of drop-in files.
94 touch -c /etc/systemd/network/*-bmc-@NCSI_IF@.network
95
96 if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then
97 networkctl reload && networkctl reconfigure @NCSI_IF@
98 fi
99
William A. Kennington IIIb823f892021-11-23 20:54:56 -0800100 local rfile=/run/nftables/40-gbmc-ncsi-br.rules
William A. Kennington III21e7e452021-11-05 01:31:59 -0700101 mkdir -p -m 755 "$(dirname "$rfile")"
William A. Kennington IIIb823f892021-11-23 20:54:56 -0800102 if [ -z "$nfcontents" ]; then
103 rm -f "$rfile"
104 else
105 printf '%s' "$nfcontents" >"$rfile"
106 fi
William A. Kennington III7356f8e2021-12-15 02:21:52 -0800107 systemctl reset-failed nftables && systemctl --no-block reload-or-restart nftables || true
William A. Kennington III21e7e452021-11-05 01:31:59 -0700108}
109
110gbmc_ncsi_br_deprecated_ips_hook() {
111 if [ "$change" = 'init' ]; then
112 gbmc_ncsi_br_deprecated_ips_init=1
113 gbmc_ip_monitor_defer
114 elif [ "$change" = 'defer' ]; then
115 gbmc_ncsi_br_deprecated_ips_update
116 elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' ] &&
117 [ "$scope" = 'global' -a "$fam" = 'inet6' ]; then
118 local pfx_bytes=()
119 ip_to_bytes pfx_bytes "$ip" || return
120 # No ULA Addresses
121 if (( pfx_bytes[0] & 0xfe == 0xfc )); then
122 return
123 fi
124 # We only want to allow a <pfx>::fd0x address, where x>0
125 if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] & 0xf == 0 )); then
126 return
127 fi
128 for (( i = 10; i < 16; ++i )); do
129 if (( pfx_bytes[i] != 0 )); then
130 return
131 fi
132 done
133 if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
134 gbmc_ncsi_br_deprecated_ips_lastip="$ip"
135 gbmc_ip_monitor_defer
136 fi
137 if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
138 gbmc_ncsi_br_deprecated_ips_lastip=
139 gbmc_ip_monitor_defer
140 fi
141 fi
142}
143
144GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_deprecated_ips_hook)
145
146gbmc_ncsi_br_deprecated_ips_lib=1