blob: d6bc9eb77cf91a45a41a9dbd8008ae592320a99c [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 III21e9a742022-05-10 10:52:09 -070042gbmc_ncsi_br_deprecated_ips_host_contents() {
43 local addr="$1"
44
45 cat <<EOF
46[Network]
47IPv6ProxyNDP=yes
48IPv6ProxyNDPAddress=$addr
49EOF
50}
51
William A. Kennington III21e7e452021-11-05 01:31:59 -070052gbmc_ncsi_br_deprecated_ips_update() {
53 [ -n "$gbmc_ncsi_br_deprecated_ips_init" ] || return
54 [ "$gbmc_ncsi_br_deprecated_ips_confip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ] || return
55 gbmc_ncsi_br_deprecated_ips_confip="$gbmc_ncsi_br_deprecated_ips_lastip"
56
57 printf 'gBMC Bridge NCSI Deprecated Addrs: %s\n' \
58 "${gbmc_ncsi_br_deprecated_ips_lastip:-(deleted)}" >&2
59
60 local contents=
William A. Kennington IIIb823f892021-11-23 20:54:56 -080061 local nfcontents=
William A. Kennington III21e7e452021-11-05 01:31:59 -070062 if [ -n "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
63 local pfx_bytes=()
64 ip_to_bytes pfx_bytes "$gbmc_ncsi_br_deprecated_ips_lastip"
65
66 local pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III3dbea932021-11-05 01:31:59 -070067 (( pfx_bytes[9] &= 0xf0 ))
68 local stateless_pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III51def642022-02-13 23:11:59 -080069 local gbmcbr_mac="$(ip link show gbmcbr | tail -n 1 | awk '{print $2}')"
70 local gbmcbr_eui48="$(mac_to_eui48 "$gbmcbr_mac")"
71 local stateless_ip="$(ip_pfx_concat "$stateless_pfx/80" "$gbmcbr_eui48")"
72 stateless_ip="${stateless_ip%/*}"
William A. Kennington III21e7e452021-11-05 01:31:59 -070073 pfx_bytes[8]=0
74 pfx_bytes[9]=0
75 local host_pfx="$(ip_bytes_to_str pfx_bytes)"
William A. Kennington III7d346b72022-04-29 14:26:05 -070076 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$pfx")"$'\n'
77 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$stateless_pfx")"$'\n'
78 contents+="$(gbmc_ncsi_br_deprecated_ips_addr_contents "$stateless_ip")"$'\n'
William A. Kennington III21e9a742022-05-10 10:52:09 -070079 contents+="$(gbmc_ncsi_br_deprecated_ips_host_contents "$host_pfx")"$'\n'
William A. Kennington IIIb823f892021-11-23 20:54:56 -080080 read -r -d '' nfcontents <<EOF
81table inet filter {
82 chain ncsi_input {
83 ip6 saddr != $pfx/76 ip6 daddr $pfx/76 goto ncsi_gbmc_br_pub_input
84 }
85 chain ncsi_forward {
86 ip6 saddr != $pfx/76 ip6 daddr $pfx/76 accept
87 }
88}
89EOF
William A. Kennington III21e7e452021-11-05 01:31:59 -070090 fi
91
92 local file
93 for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/50-deprecated.conf; do
94 mkdir -p -m 755 "$(dirname "$file")"
95 if [ -z "$contents" ]; then
96 rm -f "$file"
97 else
98 printf '%s' "$contents" >"$file"
99 fi
100 done
101
102 # Ensure that systemd-networkd performs a reconfiguration as it doesn't
103 # currently check the mtime of drop-in files.
104 touch -c /etc/systemd/network/*-bmc-@NCSI_IF@.network
105
106 if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then
107 networkctl reload && networkctl reconfigure @NCSI_IF@
108 fi
109
William A. Kennington IIIb823f892021-11-23 20:54:56 -0800110 local rfile=/run/nftables/40-gbmc-ncsi-br.rules
William A. Kennington III21e7e452021-11-05 01:31:59 -0700111 mkdir -p -m 755 "$(dirname "$rfile")"
William A. Kennington IIIb823f892021-11-23 20:54:56 -0800112 if [ -z "$nfcontents" ]; then
113 rm -f "$rfile"
114 else
115 printf '%s' "$nfcontents" >"$rfile"
116 fi
William A. Kennington III7356f8e2021-12-15 02:21:52 -0800117 systemctl reset-failed nftables && systemctl --no-block reload-or-restart nftables || true
William A. Kennington III21e7e452021-11-05 01:31:59 -0700118}
119
120gbmc_ncsi_br_deprecated_ips_hook() {
121 if [ "$change" = 'init' ]; then
122 gbmc_ncsi_br_deprecated_ips_init=1
123 gbmc_ip_monitor_defer
124 elif [ "$change" = 'defer' ]; then
125 gbmc_ncsi_br_deprecated_ips_update
126 elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' ] &&
127 [ "$scope" = 'global' -a "$fam" = 'inet6' ]; then
128 local pfx_bytes=()
129 ip_to_bytes pfx_bytes "$ip" || return
130 # No ULA Addresses
131 if (( pfx_bytes[0] & 0xfe == 0xfc )); then
132 return
133 fi
134 # We only want to allow a <pfx>::fd0x address, where x>0
135 if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] & 0xf == 0 )); then
136 return
137 fi
138 for (( i = 10; i < 16; ++i )); do
139 if (( pfx_bytes[i] != 0 )); then
140 return
141 fi
142 done
143 if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
144 gbmc_ncsi_br_deprecated_ips_lastip="$ip"
145 gbmc_ip_monitor_defer
146 fi
147 if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
148 gbmc_ncsi_br_deprecated_ips_lastip=
149 gbmc_ip_monitor_defer
150 fi
151 fi
152}
153
154GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_deprecated_ips_hook)
155
156gbmc_ncsi_br_deprecated_ips_lib=1