blob: dbf215794a285d350a2670b6ad943cfb295034eb [file] [log] [blame]
William A. Kennington III5206f662023-06-05 16:31:37 -07001#!/bin/bash
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -07002# Copyright 2021 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
William A. Kennington III5206f662023-06-05 16:31:37 -070016[[ -n ${gbmc_br_gw_src_lib-} ]] && return
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070017
William A. Kennington III5206f662023-06-05 16:31:37 -070018# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh
William A. Kennington III4f233cd2021-05-07 03:25:25 -070019source /usr/share/network/lib.sh || exit
20
William A. Kennington III3b127c42022-05-20 13:30:21 -070021gbmc_br_gw_src_ip_stateful=
22gbmc_br_gw_src_ip_stateless=
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070023declare -A gbmc_br_gw_src_routes=()
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070024gbmc_br_gw_defgw=
25
26gbmc_br_set_router() {
27 local defgw=
28 local route
29 for route in "${!gbmc_br_gw_src_routes[@]}"; do
William A. Kennington III5206f662023-06-05 16:31:37 -070030 if [[ $route != *' dev gbmcbr '* ]]; then
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070031 defgw=1
32 break
33 fi
34 done
William A. Kennington III5206f662023-06-05 16:31:37 -070035 [[ $defgw == "$gbmc_br_gw_defgw" ]] && return
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070036 gbmc_br_gw_defgw="$defgw"
37
38 local files=(/run/systemd/network/{00,}-bmc-gbmcbr.network.d/50-defgw.conf)
William A. Kennington III5206f662023-06-05 16:31:37 -070039 if [[ -n $defgw ]]; then
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070040 local file
41 for file in "${files[@]}"; do
42 mkdir -p "$(dirname "$file")"
43 printf '[IPv6PrefixDelegation]\nRouterLifetimeSec=30\n' >"$file"
44 done
45 else
46 rm -f "${files[@]}"
47 fi
48
William A. Kennington III5206f662023-06-05 16:31:37 -070049 if [[ $(systemctl is-active systemd-networkd) != inactive ]]; then
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070050 networkctl reload && networkctl reconfigure gbmcbr
51 fi
52}
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070053
54gbmc_br_gw_src_update() {
William A. Kennington III3b127c42022-05-20 13:30:21 -070055 local gbmc_br_gw_src_ip="${gbmc_br_gw_src_ip_stateful:-$gbmc_br_gw_src_ip_stateless}"
William A. Kennington III5206f662023-06-05 16:31:37 -070056 [[ -n $gbmc_br_gw_src_ip ]] || return
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070057
58 local route
59 for route in "${!gbmc_br_gw_src_routes[@]}"; do
William A. Kennington III5206f662023-06-05 16:31:37 -070060 [[ $route != *" src $gbmc_br_gw_src_ip "* ]] || continue
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070061 echo "gBMC Bridge Updating GW source [$gbmc_br_gw_src_ip]: $route" >&2
William A. Kennington III5206f662023-06-05 16:31:37 -070062 # shellcheck disable=SC2086
William A. Kennington III06ff3042022-05-20 10:40:48 -070063 ip route change $route src "$gbmc_br_gw_src_ip" && \
64 unset 'gbmc_br_gw_src_routes[$route]'
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070065 done
66}
67
68gbmc_br_gw_src_hook() {
69 # We only want to match default gateway routes that are dynamic
70 # (have an expiration time). These will be updated with our preferred
71 # source.
William A. Kennington III5206f662023-06-05 16:31:37 -070072 # shellcheck disable=SC2154
73 if [[ $change == route && $route == 'default '*':'* ]]; then
74 if [[ $route =~ ^(.*)( +expires +[^ ]+)(.*)$ ]]; then
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070075 route="${BASH_REMATCH[1]}${BASH_REMATCH[3]}"
76 fi
William A. Kennington III5206f662023-06-05 16:31:37 -070077 if [[ $action == add && -z ${gbmc_br_gw_src_routes["$route"]} ]]; then
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070078 gbmc_br_gw_src_routes["$route"]=1
79 gbmc_br_gw_src_update
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070080 gbmc_br_set_router
William A. Kennington III5206f662023-06-05 16:31:37 -070081 elif [[ $action == del && -n "${gbmc_br_gw_src_routes["$route"]}" ]]; then
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070082 unset 'gbmc_br_gw_src_routes[$route]'
83 gbmc_br_gw_src_update
William A. Kennington IIIe70461f2022-05-20 10:11:57 -070084 gbmc_br_set_router
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -070085 fi
86 # Match only global IP addresses on the bridge that match the BMC stateless
87 # prefix (<mpfx>:fd00:). So 2002:af4:3480:2248:fd00:6345:3069:9186 would be
88 # matched as the preferred source IP for outoging traffic.
William A. Kennington III5206f662023-06-05 16:31:37 -070089 elif [[ $change == addr && $intf == gbmcbr && $scope == global ]] &&
90 [[ $fam == inet6 && $flags != *tentative* ]]; then
William A. Kennington III4f233cd2021-05-07 03:25:25 -070091 local ip_bytes=()
92 if ! ip_to_bytes ip_bytes "$ip"; then
93 echo "gBMC Bridge Ensure RA Invalid IP: $ip" >&2
94 return 1
95 fi
William A. Kennington III3b127c42022-05-20 13:30:21 -070096 # Ignore ULAs and non-gBMC addresses
Yuxiao Zhang4b1216d2024-02-21 12:14:12 -080097 if (( (ip_bytes[0] & 0xfe) == 0xfc || ip_bytes[8] != 0xfd )); then
William A. Kennington III4f233cd2021-05-07 03:25:25 -070098 return 0
99 fi
Yuxiao Zhang4b1216d2024-02-21 12:14:12 -0800100 if (( (ip_bytes[9] & 0x0f) != 0 )); then
William A. Kennington III3b127c42022-05-20 13:30:21 -0700101 local -n gbmc_br_gw_src_ip=gbmc_br_gw_src_ip_stateful
102 else
103 local -n gbmc_br_gw_src_ip=gbmc_br_gw_src_ip_stateless
104 fi
William A. Kennington III5206f662023-06-05 16:31:37 -0700105 if [[ $action == add && $ip != "$gbmc_br_gw_src_ip" ]]; then
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -0700106 gbmc_br_gw_src_ip="$ip"
107 gbmc_br_gw_src_update
108 fi
William A. Kennington III5206f662023-06-05 16:31:37 -0700109 if [[ $action == del && $ip == "$gbmc_br_gw_src_ip" ]]; then
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -0700110 gbmc_br_gw_src_ip=
111 fi
112 fi
113}
114
115GBMC_IP_MONITOR_HOOKS+=(gbmc_br_gw_src_hook)
116
117gbmc_br_gw_src_lib=1