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