# 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.

[ -n "${gbmc_ncsi_br_deprecated_ips_lib-}" ] && return

source /usr/share/network/lib.sh || exit
source /usr/share/gbmc-net-lib.sh || exit

gbmc_ncsi_br_deprecated_ips_init=
gbmc_ncsi_br_deprecated_ips_confip=
gbmc_ncsi_br_deprecated_ips_lastip=
gbmc_ncsi_br_deprecated_ips_lastncsi=
gbmc_ncsi_br_deprecated_ips_confncsi=

GBMC_NCSI_ROUTE_TABLE=900

gbmc_ncsi_br_deprecated_ips_update() {
  [ -n "$gbmc_ncsi_br_deprecated_ips_init" ] || return
  [ "$gbmc_ncsi_br_deprecated_ips_confip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ] || \
    [ "$gbmc_ncsi_br_deprecated_ips_confncsi" != "$gbmc_ncsi_br_deprecated_ips_lastncsi" ] || return
  gbmc_ncsi_br_deprecated_ips_confip="$gbmc_ncsi_br_deprecated_ips_lastip"
  gbmc_ncsi_br_deprecated_ips_confncsi="$gbmc_ncsi_br_deprecated_ips_lastncsi"

  printf 'gBMC NCSI Deprecated Addrs: %s\n' \
    "${gbmc_ncsi_br_deprecated_ips_lastip:-(deleted)}" >&2

  local contents=
  local nfcontents=
  if [ -n "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
    local pfx_bytes=()
    ip_to_bytes pfx_bytes "$gbmc_ncsi_br_deprecated_ips_lastip"

    local pfx="$(ip_bytes_to_str pfx_bytes)"
    (( pfx_bytes[9] &= 0xf0 ))
    local stateless_pfx="$(ip_bytes_to_str pfx_bytes)"
    local stateless_ip=
    if [ -e /sys/class/net/gbmcbr ]; then
      local gbmcbr_mac="$(ip link show gbmcbr | tail -n 1 | awk '{print $2}')"
      local gbmcbr_eui48="$(mac_to_eui48 "$gbmcbr_mac")"
      stateless_ip="$(ip_pfx_concat "$stateless_pfx/80" "$gbmcbr_eui48")"
      stateless_ip="${stateless_ip%/*}"
    fi
    pfx_bytes[8]=0
    pfx_bytes[9]=0
    local host_pfx=
    if [ -n "${gbmc_ncsi_br_deprecated_ips_confncsi}" ]; then
      # Only impersonate the host if we have an NCSI state machine
      host_pfx="$(ip_bytes_to_str pfx_bytes)"
    fi
    read -r -d '' contents <<EOF
[Network]
IPv6ProxyNDP=yes
IPv6ProxyNDPAddress=$pfx
IPv6ProxyNDPAddress=$stateless_pfx
${host_pfx:+IPv6ProxyNDPAddress=}$host_pfx
${stateless_ip:+IPv6ProxyNDPAddress=}$stateless_ip
[RoutingPolicyRule]
From=$pfx/76
Table=$GBMC_NCSI_ROUTE_TABLE
Priority=$GBMC_NCSI_ROUTE_TABLE
EOF
    read -r -d '' nfcontents <<EOF
table inet filter {
  chain ncsi_input {
    ip6 saddr != $pfx/76 ip6 daddr $pfx/76 goto ncsi_gbmc_br_pub_input
    ${host_pfx:+ip6 daddr $host_pfx/64 goto ncsi_legacy_input}
  }
  chain ncsi_forward {
    ip6 saddr != $pfx/76 ip6 daddr $pfx/76 accept
  }
}
EOF
  fi

  local file
  for file in /run/systemd/network/{00,}-bmc-@NCSI_IF@.network.d/50-deprecated.conf; do
    mkdir -p -m 755 "$(dirname "$file")"
    if [ -z "$contents" ]; then
      rm -f "$file"
    else
      printf '%s' "$contents" >"$file"
    fi
  done

  # Remove all old ncsi neighbor proxied entries, since we solely
  # manage all of these entries and we don't want any that are stale
  local entry
  while read -r entry; do
    ip -6 neigh del proxy ${entry%% *} dev @NCSI_IF@ || true
  done < <(ip -6 neigh show proxy dev @NCSI_IF@)
  ip -6 rule del pref $GBMC_NCSI_ROUTE_TABLE 2>/dev/null || true

  local st=0
  if [ -n "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
    sysctl net.ipv6.conf.@NCSI_IF@.proxy_ndp=1 >/dev/null || st=$?
    ip -6 neigh add proxy $pfx dev @NCSI_IF@ || st=$?
    ip -6 neigh add proxy $stateless_pfx dev @NCSI_IF@ || st=$?
    if [ -n "$host_pfx" ]; then
      ip -6 neigh add proxy $host_pfx dev @NCSI_IF@ || st=$?
    fi
    if [ -n "$stateless_ip" ]; then
      ip -6 neigh add proxy $stateless_ip dev @NCSI_IF@ || st=$?
    fi
    ip -6 rule add pref $GBMC_NCSI_ROUTE_TABLE from $pfx/76 \
      lookup $GBMC_NCSI_ROUTE_TABLE || st=$?
  fi

  (( st == 0 )) || gbmc_net_networkd_reload @NCSI_IF@

  local rfile=/run/nftables/40-gbmc-ncsi-br.rules
  mkdir -p -m 755 "$(dirname "$rfile")"
  if [ -z "$nfcontents" ]; then
    rm -f "$rfile"
  else
    printf '%s' "$nfcontents" >"$rfile"
  fi
  systemctl reset-failed nftables && systemctl --no-block reload-or-restart nftables || true
}

gbmc_ncsi_br_deprecated_ips_hook() {
  if [ "$change" = 'init' ]; then
    gbmc_ncsi_br_deprecated_ips_init=1
    gbmc_ip_monitor_defer
  elif [ "$change" = 'defer' ]; then
    gbmc_ncsi_br_deprecated_ips_update
  elif [ "$change" = 'addr' -a "$scope" = 'global' -a "$fam" = 'inet6' ] &&
      [ "$intf" = 'gbmcbr' -o "$intf" = '@NCSI_IF@' ] &&
      [[ "$flags" != *deprecated* ]]; then
    local pfx_bytes=()
    ip_to_bytes pfx_bytes "$ip" || return
    # No ULA Addresses
    if (( (pfx_bytes[0] & 0xfe) == 0xfc )); then
      return
    fi
    # We only want to allow a <pfx>::fd0x address, where x>0
    if (( pfx_bytes[8] != 0xfd || (pfx_bytes[9] & 0xf) == 0 )); then
      return
    fi
    for (( i = 10; i < 16; ++i )); do
      if (( pfx_bytes[i] != 0 )); then
        return
      fi
    done
    if [ "$action" = 'add' -a "$ip" != "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
      gbmc_ncsi_br_deprecated_ips_lastip="$ip"
      gbmc_ip_monitor_defer
    fi
    if [ "$action" = 'del' -a "$ip" = "$gbmc_ncsi_br_deprecated_ips_lastip" ]; then
      gbmc_ncsi_br_deprecated_ips_lastip=
      gbmc_ip_monitor_defer
    fi
  elif [ "$change" = 'link' -a "$action" = 'add' -a "$intf" = '@NCSI_IF@' ]; then
    if ip link show '@NCSI_IF@' | grep -q '^ *alias ncsi$'; then
      gbmc_ncsi_br_deprecated_ips_lastncsi=1
      gbmc_ip_monitor_defer
    else
      gbmc_ncsi_br_deprecated_ips_lastncsi=
      gbmc_ip_monitor_defer
    fi
  fi
}

GBMC_IP_MONITOR_HOOKS+=(gbmc_ncsi_br_deprecated_ips_hook)

gbmc_ncsi_br_deprecated_ips_lib=1
