William A. Kennington III | 5206f66 | 2023-06-05 16:31:37 -0700 | [diff] [blame] | 1 | #!/bin/bash |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 2 | # 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 III | 5206f66 | 2023-06-05 16:31:37 -0700 | [diff] [blame] | 16 | [[ -n ${gbmc_br_ula_lib-} ]] && return |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 17 | |
William A. Kennington III | 5206f66 | 2023-06-05 16:31:37 -0700 | [diff] [blame] | 18 | # shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 19 | source /usr/share/network/lib.sh || exit |
| 20 | |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 21 | declare -A gbmc_br_ulas=() |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 22 | |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 23 | # BITs set for address suffixes |
| 24 | GBMC_BR_ULA_SFX_HAS_LL=1 |
| 25 | GBMC_BR_ULA_SFX_HAS_ULA=2 |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 26 | |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 27 | gbmc_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 III | 6ca7033 | 2021-05-10 03:14:42 -0700 | [diff] [blame] | 34 | fi |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 35 | done |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 36 | } |
William A. Kennington III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 37 | |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 38 | gbmc_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 III | 8fb9258 | 2021-05-10 03:15:56 -0700 | [diff] [blame] | 45 | |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 46 | gbmc_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 III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | gbmc_br_ula_hook() { |
William A. Kennington III | 5206f66 | 2023-06-05 16:31:37 -0700 | [diff] [blame] | 55 | # shellcheck disable=SC2154 |
| 56 | if [[ $change == init ]]; then |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 57 | 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 III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 68 | fi |
William A. Kennington III | edc0c49 | 2024-09-05 02:17:45 -0700 | [diff] [blame] | 69 | # 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 III | b08a9e6 | 2021-04-26 12:43:43 -0700 | [diff] [blame] | 96 | fi |
| 97 | fi |
| 98 | } |
| 99 | |
| 100 | GBMC_IP_MONITOR_HOOKS+=(gbmc_br_ula_hook) |
| 101 | |
| 102 | gbmc_br_ula_lib=1 |