blob: d7c0f023b7c346ba77d064dbff6d8b330fe5bae0 [file] [log] [blame]
William A. Kennington III031f6a62024-09-05 02:22:15 -07001#!/bin/bash
2# Copyright 2024 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_nic_neigh_lib-} ]] && return
17
18# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh
19source /usr/share/network/lib.sh || exit
William A. Kennington IIIa108fcd2024-09-12 14:39:38 -070020# shellcheck source=meta-google/recipes-google/networking/gbmc-net-common/gbmc-net-lib.sh
21source /usr/share/gbmc-net-lib.sh || exit
William A. Kennington III031f6a62024-09-05 02:22:15 -070022
23gbmc_nic_neigh_intfs=(@IFS@)
24gbmc_nic_neigh_addr=
25
26gbmc_nic_neigh_set() {
27 local act="$1"
28 local ip="$2"
29
30 echo "gBMC NIC Neigh $act $ip: ${gbmc_nic_neigh_intfs[*]}" >&2
31
32 local intf
33 local failed_intfs=()
34 for intf in "${gbmc_nic_neigh_intfs[@]}"; do
35 # In case we don't have a base network file, make one
36 # this is intentionally 00- as it will not preceed /etc/systemd/network/00-*
37 # or /lib/systemd/network/-* files.
38 local file=/run/systemd/network/00-bmc-$intf.network
39 printf '[Match]\nName=%s\n[Network]\nDHCP=false\nIPv6AcceptRA=false\nLinkLocalAddressing=yes' \
40 "$intf" >"$file"
41
42 # Override any existing gateway information within files
43 # Make sure we cover `00-*` and `-*` files
44 for file in /run/systemd/network/{00,}-bmc-"$intf".network; do
45 mkdir -p "$file.d"
46 if [[ "$act" == add ]]; then
47 printf '[Network]\nIPv6ProxyNDP=yes\nIPv6ProxyNDPAddress=%s\n' \
48 "$ip" >"$file.d"/10-nic-neigh.conf
49 else
50 rm -f "$file.d"/10-nic-neigh.conf
51 fi
52 done
53
54 sysctl net.ipv6.conf."$intf".proxy_ndp=1 >/dev/null && \
55 ip -6 neigh "$act" proxy "$ip" dev "$intf" || \
56 failed_intfs+=("$intf")
57 done
58 [[ "$act" == del ]] && return
59 if (( "${#failed_intfs[@]}" > 0 )); then
William A. Kennington IIIa108fcd2024-09-12 14:39:38 -070060 gbmc_net_networkd_reload "${failed_intfs[@]}"
William A. Kennington III031f6a62024-09-05 02:22:15 -070061 fi
William A. Kennington III031f6a62024-09-05 02:22:15 -070062}
63
64gbmc_nic_neigh_hook() {
65 # shellcheck disable=SC2154
66 if [[ $change == addr && $intf == gbmcbr && $scope == global ]] &&
67 [[ $fam == inet6 && $flags != *tentative* ]]; then
68 local ip_bytes=()
69 if ! ip_to_bytes ip_bytes "$ip"; then
70 echo "gBMC Bridge Ensure RA Invalid IP: $ip" >&2
71 return 1
72 fi
73 # Ignore ULAs
74 if (( (ip_bytes[0] & 0xfe) == 0xfc )); then
75 return 0
76 fi
77 # Addresses must be /64 to the upstack switch
78 for (( i = 8; i < 16; ++i )); do
79 if (( ip_bytes[i] != 0 )); then
80 return 0
81 fi
82 done
83 if [[ $action == add && "$gbmc_nic_neigh_addr" != "$ip" ]]; then
84 if [ -n "$gbmc_nic_neigh_addr" ]; then
85 gbmc_nic_neigh_set del "$gbmc_nic_neigh_addr"
86 fi
87 gbmc_nic_neigh_addr="$ip"
88 gbmc_nic_neigh_set add "$ip"
89 elif [[ $action == del && "$gbmc_nic_neigh_addr" == "$ip" ]]; then
90 gbmc_nic_neigh_addr=
91 gbmc_nic_neigh_set del "$ip"
92 fi
93 fi
94}
95
96GBMC_IP_MONITOR_HOOKS+=(gbmc_nic_neigh_hook)
97
98gbmc_nic_neigh_lib=1