meta-google: gbmc-bridge: Migrate RA script to new common RA handler

Tested: Ran on a CN and Tray system to verify that the behavior of the
RA is as expected. Also ran on a tray system with the RA handler in
place.

Change-Id: I863c89a2f7118489febc17b621ad14248141b60a
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/meta-google/recipes-google/networking/gbmc-bridge.bb b/meta-google/recipes-google/networking/gbmc-bridge.bb
index 95c3737..e23ee57 100644
--- a/meta-google/recipes-google/networking/gbmc-bridge.bb
+++ b/meta-google/recipes-google/networking/gbmc-bridge.bb
@@ -19,9 +19,8 @@
   file://gbmc-br-ensure-ra.service \
   file://gbmc-br-hostname.sh \
   file://gbmc-br-hostname.service \
-  file://gbmc-ip-from-ra.sh \
-  file://gbmc-br-ip-from-ra.sh.in \
-  file://gbmc-br-ip-from-ra.service \
+  file://gbmc-br-ra.sh.in \
+  file://gbmc-br-ra.service \
   file://gbmc-br-gw-src.sh \
   file://gbmc-br-nft.sh \
   file://gbmc-br-dhcp.sh \
@@ -40,7 +39,6 @@
   ${datadir}/gbmc-ip-monitor \
   ${datadir}/gbmc-br-dhcp \
   ${datadir}/gbmc-br-lib.sh \
-  ${datadir}/gbmc-ip-from-ra.sh \
   ${systemd_unitdir}/network \
   ${sysconfdir}/nftables \
   "
@@ -49,6 +47,7 @@
   bash \
   dhcp-done \
   gbmc-ip-monitor \
+  gbmc-net-common \
   network-sh \
   ndisc6-rdisc6 \
   nftables-systemd \
@@ -60,7 +59,7 @@
   gbmc-br-dhcp.service \
   gbmc-br-dhcp-term.service \
   gbmc-br-load-ip.service \
-  ${@"gbmc-br-ip-from-ra.service" if d.getVar('GBMC_BR_FIXED_OFFSET') != "" else ""} \
+  gbmc-br-ra.service \
   "
 
 GBMC_BR_MAC_ADDR ?= ""
@@ -70,7 +69,8 @@
 # This is intended only to be used when there is a single expansion tray
 # on the BMC network. If more than one machine uses this feature with the
 # same offset in the same machine network, it will collide with others.
-GBMC_BR_FIXED_OFFSET ?= ""
+# A value of 0 implies that this feature is disabled.
+GBMC_BR_FIXED_OFFSET ?= "0"
 
 # Generated via https://cd34.com/rfc4193/ based on a MAC from a machine I own
 # and we allocated it downstream. Intended to only be used within a complete
@@ -158,16 +158,13 @@
   install -m0644 ${WORKDIR}/51-gbmc-reboot.sh ${D}${datadir}/gbmc-br-dhcp/
 
   install -m0644 ${WORKDIR}/gbmc-br-lib.sh ${D}${datadir}/
-  install -m0644 ${WORKDIR}/gbmc-ip-from-ra.sh ${D}${datadir}/
 
   install -d ${D}/${bindir}
   install -m0755 ${WORKDIR}/gbmc-start-dhcp.sh ${D}${bindir}/
 
-  if [ -n "${GBMC_BR_FIXED_OFFSET}" ]; then
-    sed 's,@IP_OFFSET@,${GBMC_BR_FIXED_OFFSET},' ${WORKDIR}/gbmc-br-ip-from-ra.sh.in >${WORKDIR}/gbmc-br-ip-from-ra.sh
-    install -m0755 ${WORKDIR}/gbmc-br-ip-from-ra.sh ${D}${libexecdir}/
-    install -m0644 ${WORKDIR}/gbmc-br-ip-from-ra.service ${D}${systemd_system_unitdir}/
-  fi
+  sed 's,@IP_OFFSET@,${GBMC_BR_FIXED_OFFSET},' ${WORKDIR}/gbmc-br-ra.sh.in >${WORKDIR}/gbmc-br-ra.sh
+  install -m0755 ${WORKDIR}/gbmc-br-ra.sh ${D}${libexecdir}/
+  install -m0644 ${WORKDIR}/gbmc-br-ra.service ${D}${systemd_system_unitdir}/
 }
 
 do_rm_work:prepend() {
diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.service b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.service
similarity index 80%
rename from meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.service
rename to meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.service
index 2aaf6a9..08fd15f 100644
--- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.service
+++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.service
@@ -7,7 +7,7 @@
 [Service]
 Restart=always
 RestartSec=5
-ExecStart=/usr/libexec/gbmc-br-ip-from-ra.sh
+ExecStart=/usr/libexec/gbmc-br-ra.sh
 
 [Install]
 WantedBy=multi-user.target
diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.sh.in b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.sh.in
similarity index 62%
rename from meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.sh.in
rename to meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.sh.in
index 8fc4c8e..66d7a7d 100755
--- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ip-from-ra.sh.in
+++ b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-ra.sh.in
@@ -16,17 +16,27 @@
 # shellcheck source=meta-google/recipes-google/networking/gbmc-bridge/gbmc-br-lib.sh
 source /usr/share/gbmc-br-lib.sh || exit
 
+update_rtr() {
+  true
+}
+
 update_fqdn() {
-  hostnamectl set-hostname "$1" || true
+  (( IP_OFFSET == 0 )) && return
+  default_update_fqdn "$@"
 }
 
 update_pfx() {
-  # Save the IP address for the interface
-  gbmc_br_set_ip "$1" || true
+  local pfx="$1"
+  (( IP_OFFSET == 0 )) && return
+  gbmc_br_set_ip "$pfx" || true
+  echo "IP $pfx set on $RA_IF" >&2
 }
 
 RA_IF=gbmcbr
 IP_OFFSET=@IP_OFFSET@
+# Use the lowest priority, except for kernel RA discovered routes.
+# We want closer NICs to provide a default route if existing.
+ROUTE_METRIC=1000
 
-# shellcheck source=meta-google/recipes-google/networking/gbmc-bridge/gbmc-ip-from-ra.sh
-source /usr/share/gbmc-ip-from-ra.sh || exit
+# shellcheck source=meta-google/recipes-google/networking/gbmc-net-common/gbmc-ra.sh
+source /usr/share/gbmc-ra.sh || exit
diff --git a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-ip-from-ra.sh b/meta-google/recipes-google/networking/gbmc-bridge/gbmc-ip-from-ra.sh
deleted file mode 100755
index 7a8dfbe..0000000
--- a/meta-google/recipes-google/networking/gbmc-bridge/gbmc-ip-from-ra.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/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.
-
-# shellcheck source=meta-google/recipes-google/networking/network-sh/lib.sh
-source /usr/share/network/lib.sh || exit
-
-: "${RA_IF:?No RA interface set}"
-: "${IP_OFFSET:?No IP offset set}"
-
-old_pfx=
-old_fqdn=
-
-w=60
-while true; do
-  start=$SECONDS
-  while read -r line; do
-    # `script` terminates all lines with a CRLF, remove it
-    line="${line:0:-1}"
-    if [ -z "$line" ]; then
-      hextet=
-      pfx=
-      host=
-      domain=
-      lifetime=-1
-    elif [[ "$line" =~ ^Prefix' '*:' '*(.*)/([0-9]+)$ ]]; then
-      t_pfx="${BASH_REMATCH[1]}"
-      t_pfx_len="${BASH_REMATCH[2]}"
-      ip_to_bytes t_pfx_b "$t_pfx" || continue
-      (( (t_pfx_len == 76 || t_pfx_len == 80) && (t_pfx_b[8] & 0xfd) == 0xfd )) || continue
-      (( t_pfx_b[9] &= 0xf0 ))
-      (( t_pfx_b[9] |= IP_OFFSET ))
-      hextet="fd$(printf '%02x' "${t_pfx_b[9]}")"
-      pfx="$(ip_bytes_to_str t_pfx_b)"
-    elif [[ "$line" =~ ^'Router lifetime'' '*:' '*([0-9]+)' '+ ]]; then
-      lifetime="${BASH_REMATCH[1]}"
-    elif [[ "$line" =~ ^'DNS search list'' '*:' '*([^.]+)(.*[.]google[.]com)' '*$ ]]; then
-      # Ideally, we use PCRE and with lookahead and can do this in a single regex
-      #   ^([a-zA-Z0-9-]+(?=-n[a-fA-F0-9]{1,4})|[a-zA-Z0-9-]+(?!-n[a-fA-F0-9]{1,4}))[^.]*[.]((?:[a-zA-Z0-9]*[.])*google[.]com)$
-      # Instead we do multiple steps to extract the needed info
-      host="${BASH_REMATCH[1]}"
-      domain="${BASH_REMATCH[2]#.}"
-      if [[ "$host" =~ (-n[a-fA-F0-9]{1,4})$ ]]; then
-        host="${host%"${BASH_REMATCH[1]}"}"
-      fi
-    elif [[ "$line" =~ ^from' '(.*)$ ]]; then
-      # We only want to accept info from gateway providing routers
-      (( lifetime > 0 )) || continue
-      rtr="${BASH_REMATCH[1]}"
-      if [[ -n $pfx && $pfx != "$old_pfx" ]]; then
-        echo "Updating PFX($pfx) from $rtr" >&2
-        old_pfx="$pfx"
-        update_pfx "$pfx" || true
-      fi
-      if [[ -n $host && -n $hextet && -n $domain ]]; then
-        fqdn="$host-n$hextet.$domain"
-        if [[ $fqdn != "$old_fqdn" ]]; then
-          echo "Updating FQDN($fqdn) from $rtr" >&2
-          old_fqdn="$fqdn"
-          update_fqdn "$fqdn" || true
-        fi
-      fi
-    fi
-  done < <(exec script -q -c "rdisc6 -d -m $RA_IF -w $(( w * 1000 ))" /dev/null 2>/dev/null)
-  # If rdisc6 exits early we still want to wait the full `w` time before
-  # starting again.
-  (( timeout = start + w - SECONDS ))
-  sleep $(( timeout < 0 ? 0 : timeout ))
-done