summaryrefslogtreecommitdiff
path: root/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-dhcp.sh
blob: 42a077d09315ef9146f07130fa4275dba11c05bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/bin/bash
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# A list of functions which get executed for each bound DHCP lease.
# These are configured by the files included below.
GBMC_BR_DHCP_HOOKS=()

# Load configurations from a known location in the filesystem to populate
# hooks that are executed after each event.
shopt -s nullglob
for conf in /usr/share/gbmc-br-dhcp/*.sh; do
  # SC doesn't like dynamic source loading
  # shellcheck disable=SC1090
  source "$conf"
done

gbmc_br_dhcp_run_hooks() {
  local hook
  for hook in "${GBMC_BR_DHCP_HOOKS[@]}"; do
    "$hook" || continue
  done
}

# SC can't find this path during repotest
# shellcheck disable=SC1091
source /usr/share/network/lib.sh || exit

if [ "$1" = bound ]; then
  # Variable is from the environment via udhcpc6
  # shellcheck disable=SC2154
  echo "DHCPv6(gbmcbr): $ipv6/128" >&2

  pfx_bytes=()
  ip_to_bytes pfx_bytes "$ipv6"
  # Ensure we are a BMC and have a suffix nibble, the 0th index is reserved
  if (( pfx_bytes[8] != 0xfd || pfx_bytes[9] & 0xf == 0 )); then
    echo "Invalid address" >&2
    exit
  fi
  # Ensure we don't have more than a /80 address
  for (( i = 10; i < 16; ++i )); do
    if (( pfx_bytes[i] != 0 )); then
      echo "Invalid address" >&2
      exit
    fi
  done

  pfx="$(ip_bytes_to_str pfx_bytes)"
  (( pfx_bytes[9] &= 0xf0 ))
  stateless_pfx="$(ip_bytes_to_str pfx_bytes)"
  read -r -d '' contents <<EOF
[Network]
Address=$pfx/128
IPv6PrefixDelegation=yes
[IPv6PrefixDelegation]
RouterLifetimeSec=60
[IPv6Prefix]
Prefix=$stateless_pfx/80
PreferredLifetimeSec=60
ValidLifetimeSec=60
[IPv6RoutePrefix]
Route=$pfx/80
LifetimeSec=60
[Route]
Destination=$stateless_pfx/76
Type=unreachable
Metric=1024
EOF

  for file in /etc/systemd/network/{00,}-bmc-gbmcbr.network.d/50-public.conf; do
    mkdir -p "$(dirname "$file")"
    printf '%s' "$contents" >"$file"
  done

  # Ensure that systemd-networkd performs a reconfiguration as it doesn't
  # currently check the mtime of drop-in files.
  touch -c /lib/systemd/network/*-bmc-gbmcbr.network

  if [ "$(systemctl is-active systemd-networkd)" != 'inactive' ]; then
    networkctl reload && networkctl reconfigure gbmcbr
  fi

  if [ -n "${fqdn-}" ]; then
    echo "Using hostname $fqdn" >&2
    hostnamectl set-hostname "$fqdn" || true
  fi

  gbmc_br_dhcp_run_hooks
fi