blob: b79e25fe4ac80f0e02d65735dfd60244fa842688 [file] [log] [blame]
William A. Kennington III5206f662023-06-05 16:31:37 -07001#!/bin/bash
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -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_ula_lib-} ]] && return
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -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 IIIb08a9e62021-04-26 12:43:43 -070019source /usr/share/network/lib.sh || exit
20
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070021declare -A gbmc_br_ulas=()
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070022
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070023# BITs set for address suffixes
24GBMC_BR_ULA_SFX_HAS_LL=1
25GBMC_BR_ULA_SFX_HAS_ULA=2
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070026
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070027gbmc_br_ula_cleanup() {
28 local addr
29 for addr in "${!gbmc_br_ulas[@]}"; do
30 local val="${gbmc_br_ulas["$addr"]}"
31 if (( val & GBMC_BR_ULA_SFX_HAS_LL == 0 )); then
32 echo "Removing Stale ULA: $addr" >&2
33 ip addr del "$addr"/64 dev gbmcbr || true
William A. Kennington III6ca70332021-05-10 03:14:42 -070034 fi
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070035 done
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070036}
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070037
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070038gbmc_br_ula_is_ll() {
39 # shellcheck disable=SC2178
40 local -n bytes="$1"
41 (( bytes[0] == 0xfe && bytes[1] == 0x80 && bytes[2] == 0x00 &&
42 bytes[3] == 0x00 && bytes[4] == 0x00 && bytes[5] == 0x00 &&
43 bytes[6] == 0x00 && bytes[7] == 0x00 ))
44}
William A. Kennington III8fb92582021-05-10 03:15:56 -070045
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070046gbmc_br_ula_is_ula() {
47 # shellcheck disable=SC2178
48 local -n bytes="$1"
49 (( bytes[0] == 0xfd && bytes[1] == 0xb5 && bytes[2] == 0x04 &&
50 bytes[3] == 0x81 && bytes[4] == 0x10 && bytes[5] == 0xce &&
51 bytes[6] == 0x00 && bytes[7] == 0x00 ))
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070052}
53
54gbmc_br_ula_hook() {
William A. Kennington III5206f662023-06-05 16:31:37 -070055 # shellcheck disable=SC2154
56 if [[ $change == init ]]; then
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070057 gbmc_br_ula_cleanup
58 elif [[ $change == addr && $intf == gbmcbr && $fam == inet6 ]]; then
59 local pfx_bytes=()
60 ip_to_bytes pfx_bytes "$ip" || return
61 local val=0
62 if gbmc_br_ula_is_ll pfx_bytes; then
63 val="$GBMC_BR_ULA_SFX_HAS_LL"
64 elif gbmc_br_ula_is_ula pfx_bytes; then
65 val="$GBMC_BR_ULA_SFX_HAS_ULA"
66 else
67 return 0
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070068 fi
William A. Kennington IIIedc0c492024-09-05 02:17:45 -070069 # Force all addresses into what they would be as a ULA so that we can
70 # store bits about the assigned addresses on the interface
71 pfx_bytes[0]=0xfd
72 pfx_bytes[1]=0xb5
73 pfx_bytes[2]=0x04
74 pfx_bytes[3]=0x81
75 pfx_bytes[4]=0x10
76 pfx_bytes[5]=0xce
77 addr="$(ip_bytes_to_str pfx_bytes)"
78 local old=${gbmc_br_ulas["$addr"]-0}
79 if [[ $action == add ]]; then
80 val=$((old | val))
81 elif [[ $action == del ]]; then
82 val=$((old & ~val))
83 fi
84 gbmc_br_ulas["$addr"]=$val
85 if (( val == GBMC_BR_ULA_SFX_HAS_LL )); then
86 # We have a link local address but no ULA, so we need to add the ULA
87 echo "Adding ULA: $addr" >&2
88 ip addr replace "$addr"/64 dev gbmcbr
89 elif (( val == GBMC_BR_ULA_SFX_HAS_ULA )); then
90 # We have a ULA without a link local, so we should not longer have this ULA
91 echo "Removing ULA: $addr" >&2
92 ip addr del "$addr"/64 dev gbmcbr || true
93 elif (( val == 0 )); then
94 # Cleanup the map if we no longer have any addresses for the suffix
95 unset 'gbmc_br_ulas[$addr]'
William A. Kennington IIIb08a9e62021-04-26 12:43:43 -070096 fi
97 fi
98}
99
100GBMC_IP_MONITOR_HOOKS+=(gbmc_br_ula_hook)
101
102gbmc_br_ula_lib=1