1#!/bin/bash 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 16[[ -n ${gbmc_br_from_ra_lib-} ]] && return 17 18# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh 19source /usr/share/network/lib.sh || exit 20 21gbmc_br_from_ra_init= 22gbmc_br_from_ra_mac= 23declare -A gbmc_br_from_ra_pfxs=() 24declare -A gbmc_br_from_ra_prev_addrs=() 25 26gbmc_br_from_ra_update() { 27 [[ -n $gbmc_br_from_ra_init && -n $gbmc_br_from_ra_mac ]] || return 28 29 local pfx 30 for pfx in "${!gbmc_br_from_ra_pfxs[@]}"; do 31 local cidr 32 if ! cidr="$(ip_pfx_to_cidr "$pfx")"; then 33 unset 'gbmc_br_from_ra_pfxs[$pfx]' 34 continue 35 fi 36 if (( cidr == 80 )); then 37 local sfx 38 if ! sfx="$(mac_to_eui48 "$gbmc_br_from_ra_mac")"; then 39 unset 'gbmc_br_from_ra_pfxs[$pfx]' 40 continue 41 fi 42 local addr 43 if ! addr="$(ip_pfx_concat "$pfx" "$sfx")"; then 44 unset 'gbmc_br_from_ra_pfxs[$pfx]' 45 continue 46 fi 47 else 48 unset 'gbmc_br_from_ra_pfxs[$pfx]' 49 continue 50 fi 51 local valid="${gbmc_br_from_ra_pfxs["$pfx"]}" 52 if (( valid > 0 )); then 53 if [[ -z ${gbmc_br_from_ra_prev_addrs["$addr"]-} ]]; then 54 echo "gBMC Bridge RA Addr Add: $addr" >&2 55 gbmc_br_from_ra_prev_addrs["$addr"]=1 56 fi 57 ip addr replace "$addr" dev gbmcbr noprefixroute 58 else 59 if [[ -n ${gbmc_br_from_ra_prev_addrs["$addr"]-} ]]; then 60 echo "gBMC Bridge RA Addr Del: $addr" >&2 61 unset 'gbmc_br_from_ra_prev_addrs[$addr]' 62 fi 63 ip addr del "$addr" dev gbmcbr 64 unset 'gbmc_br_from_ra_pfxs[$pfx]' 65 fi 66 done 67} 68 69gbmc_br_from_ra_hook() { 70 # shellcheck disable=SC2154 71 if [[ $change == init ]]; then 72 gbmc_br_from_ra_init=1 73 gbmc_ip_monitor_defer 74 elif [[ $change == defer ]]; then 75 gbmc_br_from_ra_update 76 elif [[ $change == route && $route != *' via '* ]] && 77 [[ $route =~ ^(.* dev gbmcbr proto ra .*)( +expires +([^ ]+)sec).*$ ]]; then 78 pfx="${route%% *}" 79 # shellcheck disable=SC2154 80 if [[ $action == add ]]; then 81 gbmc_br_from_ra_pfxs["$pfx"]="${BASH_REMATCH[3]}" 82 gbmc_ip_monitor_defer 83 elif [[ $action == del ]]; then 84 gbmc_br_from_ra_pfxs["$pfx"]=0 85 gbmc_ip_monitor_defer 86 fi 87 elif [[ $change == link && $intf == gbmcbr ]]; then 88 rdisc6 -m gbmcbr -r 1 -w 100 >/dev/null 2>&1 89 if [[ $action == add && $mac != "$gbmc_br_from_ra_mac" ]]; then 90 gbmc_br_from_ra_mac="$mac" 91 gbmc_ip_monitor_defer 92 fi 93 if [[ $action == del && $mac == "$gbmc_br_from_ra_mac" ]]; then 94 gbmc_br_from_ra_mac= 95 gbmc_ip_monitor_defer 96 fi 97 fi 98} 99 100GBMC_IP_MONITOR_HOOKS+=(gbmc_br_from_ra_hook) 101 102gbmc_br_from_ra_lib=1 103