blob: 1364efd7b73bd7aa7c0899806fff051fafa17832 [file] [log] [blame]
William A. Kennington IIIcd40c7e2021-05-05 14:44:41 -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_br_gw_src_lib-}" ] || return
16
17gbmc_br_gw_src_ip=
18declare -A gbmc_br_gw_src_routes=()
19
20gbmc_br_gw_src_update() {
21 [ -n "$gbmc_br_gw_src_ip" ] || return
22
23 local route
24 for route in "${!gbmc_br_gw_src_routes[@]}"; do
25 [[ "$route" != *" src $gbmc_br_gw_src_ip "* ]] || continue
26 echo "gBMC Bridge Updating GW source [$gbmc_br_gw_src_ip]: $route" >&2
27 ip route change $route src "$gbmc_br_gw_src_ip"
28 unset 'gbmc_br_gw_src_routes[$route]'
29 done
30}
31
32gbmc_br_gw_src_hook() {
33 # We only want to match default gateway routes that are dynamic
34 # (have an expiration time). These will be updated with our preferred
35 # source.
36 if [[ "$change" == 'route' && "$route" == 'default '*':'* ]]; then
37 if [[ "$route" =~ ^(.*)( +expires +[^ ]+)(.*)$ ]]; then
38 route="${BASH_REMATCH[1]}${BASH_REMATCH[3]}"
39 fi
40 if [ "$action" = 'add' -a -z "${gbmc_br_gw_src_routes["$route"]}" ]; then
41 gbmc_br_gw_src_routes["$route"]=1
42 gbmc_br_gw_src_update
43 elif [ "$action" = 'del' -a -n "${gbmc_br_gw_src_routes["$route"]}" ]; then
44 unset 'gbmc_br_gw_src_routes[$route]'
45 gbmc_br_gw_src_update
46 fi
47 # Match only global IP addresses on the bridge that match the BMC stateless
48 # prefix (<mpfx>:fd00:). So 2002:af4:3480:2248:fd00:6345:3069:9186 would be
49 # matched as the preferred source IP for outoging traffic.
50 elif [ "$change" = 'addr' -a "$intf" = 'gbmcbr' -a "$scope" = 'global' ] &&
51 [[ "$fam" == 'inet6' && "$ip" =~ ^([^:]+:){4}fd00:.*$ ]] &&
52 [[ "$flags" != *tentative* ]]; then
53 if [ "$action" = 'add' -a "$ip" != "$gbmc_br_gw_src_ip" ]; then
54 gbmc_br_gw_src_ip="$ip"
55 gbmc_br_gw_src_update
56 fi
57 if [ "$action" = 'del' -a "$ip" = "$gbmc_br_gw_src_ip" ]; then
58 gbmc_br_gw_src_ip=
59 fi
60 fi
61}
62
63GBMC_IP_MONITOR_HOOKS+=(gbmc_br_gw_src_hook)
64
65gbmc_br_gw_src_lib=1