15d074370SPatrick Williams#!/bin/bash 21285115cSWilliam A. Kennington III# Copyright 2021 Google LLC 31285115cSWilliam A. Kennington III# 41285115cSWilliam A. Kennington III# Licensed under the Apache License, Version 2.0 (the "License"); 51285115cSWilliam A. Kennington III# you may not use this file except in compliance with the License. 61285115cSWilliam A. Kennington III# You may obtain a copy of the License at 71285115cSWilliam A. Kennington III# 81285115cSWilliam A. Kennington III# http://www.apache.org/licenses/LICENSE-2.0 91285115cSWilliam A. Kennington III# 101285115cSWilliam A. Kennington III# Unless required by applicable law or agreed to in writing, software 111285115cSWilliam A. Kennington III# distributed under the License is distributed on an "AS IS" BASIS, 121285115cSWilliam A. Kennington III# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131285115cSWilliam A. Kennington III# See the License for the specific language governing permissions and 141285115cSWilliam A. Kennington III# limitations under the License. 151285115cSWilliam A. Kennington III 161285115cSWilliam A. Kennington III# Internal handler used for signalling child processes that they should 171285115cSWilliam A. Kennington III# terminate. 1859486679SPatrick Williamsfunction HandleTerm() { 191285115cSWilliam A. Kennington III GOT_TERM=1 201285115cSWilliam A. Kennington III if ShouldTerm && (( ${#CHILD_PIDS[@]} > 0 )); then 21d7989581SWilliam A. Kennington III kill -s TERM "${!CHILD_PIDS[@]}" 221285115cSWilliam A. Kennington III fi 231285115cSWilliam A. Kennington III} 241285115cSWilliam A. Kennington III 251285115cSWilliam A. Kennington III# Sets up the signal handler and global variables needed to run interruptible 261285115cSWilliam A. Kennington III# services that can be killed gracefully. 2759486679SPatrick Williamsfunction InitTerm() { 281285115cSWilliam A. Kennington III declare -g -A CHILD_PIDS=() 291285115cSWilliam A. Kennington III declare -g GOT_TERM=0 301285115cSWilliam A. Kennington III declare -g SUPPRESS_TERM=0 311285115cSWilliam A. Kennington III trap HandleTerm TERM 321285115cSWilliam A. Kennington III} 331285115cSWilliam A. Kennington III 341285115cSWilliam A. Kennington III# Used to suppress the handling of SIGTERM for critical components that should 351285115cSWilliam A. Kennington III# not respect SIGTERM. To finish suppressing, use UnsuppressTerm() 3659486679SPatrick Williamsfunction SuppressTerm() { 371285115cSWilliam A. Kennington III SUPPRESS_TERM=$((SUPPRESS_TERM + 1)) 381285115cSWilliam A. Kennington III} 391285115cSWilliam A. Kennington III 401285115cSWilliam A. Kennington III# Stops suppressing SIGTERM for a single invocation of SuppresssTerm() 4159486679SPatrick Williamsfunction UnsuppressTerm() { 421285115cSWilliam A. Kennington III SUPPRESS_TERM=$((SUPPRESS_TERM - 1)) 431285115cSWilliam A. Kennington III} 441285115cSWilliam A. Kennington III 451285115cSWilliam A. Kennington III# Determines if we got a SIGTERM and should respect it 4659486679SPatrick Williamsfunction ShouldTerm() { 471285115cSWilliam A. Kennington III (( GOT_TERM == 1 && SUPPRESS_TERM == 0 )) 481285115cSWilliam A. Kennington III} 491285115cSWilliam A. Kennington III 501285115cSWilliam A. Kennington III# Internal, ensures that functions called in a subprocess properly initialize 511285115cSWilliam A. Kennington III# their SIGTERM handling logic 5259486679SPatrick Williamsfunction RunInterruptibleFunction() { 531285115cSWilliam A. Kennington III CHILD_PIDS=() 541285115cSWilliam A. Kennington III trap HandleTerm TERM 551285115cSWilliam A. Kennington III "$@" 561285115cSWilliam A. Kennington III} 571285115cSWilliam A. Kennington III 581285115cSWilliam A. Kennington III# Runs the provided commandline in the background, and passes any received 591285115cSWilliam A. Kennington III# SIGTERMS to the child. Can be waited on using WaitInterruptibleBg 6059486679SPatrick Williamsfunction RunInterruptibleBg() { 611285115cSWilliam A. Kennington III if ShouldTerm; then 621285115cSWilliam A. Kennington III return 143 631285115cSWilliam A. Kennington III fi 641285115cSWilliam A. Kennington III if [ "$(type -t "$1")" = "function" ]; then 651285115cSWilliam A. Kennington III RunInterruptibleFunction "$@" & 661285115cSWilliam A. Kennington III else 671285115cSWilliam A. Kennington III "$@" & 681285115cSWilliam A. Kennington III fi 691285115cSWilliam A. Kennington III CHILD_PIDS["$!"]=1 701285115cSWilliam A. Kennington III} 711285115cSWilliam A. Kennington III 721285115cSWilliam A. Kennington III# Runs the provided commandline to completion, and passes any received 731285115cSWilliam A. Kennington III# SIGTERMS to the child. 7459486679SPatrick Williamsfunction RunInterruptible() { 751285115cSWilliam A. Kennington III RunInterruptibleBg "$@" || return 761285115cSWilliam A. Kennington III local child_pid="$!" 771285115cSWilliam A. Kennington III wait "$child_pid" || true 781285115cSWilliam A. Kennington III unset CHILD_PIDS["$child_pid"] 791285115cSWilliam A. Kennington III wait "$child_pid" 801285115cSWilliam A. Kennington III} 811285115cSWilliam A. Kennington III 821285115cSWilliam A. Kennington III# Waits until all of the RunInterruptibleBg() jobs have terminated 8359486679SPatrick Williamsfunction WaitInterruptibleBg() { 841285115cSWilliam A. Kennington III local wait_on=("${!CHILD_PIDS[@]}") 851285115cSWilliam A. Kennington III if (( ${#wait_on[@]} > 0 )); then 861285115cSWilliam A. Kennington III wait "${wait_on[@]}" || true 871285115cSWilliam A. Kennington III CHILD_PIDS=() 881285115cSWilliam A. Kennington III local rc=0 891285115cSWilliam A. Kennington III local id 901285115cSWilliam A. Kennington III for id in "${wait_on[@]}"; do 911285115cSWilliam A. Kennington III wait "$id" || rc=$? 921285115cSWilliam A. Kennington III done 931285115cSWilliam A. Kennington III return $rc 941285115cSWilliam A. Kennington III fi 951285115cSWilliam A. Kennington III} 961285115cSWilliam A. Kennington III 97d7989581SWilliam A. Kennington III# Runs the provided commandline to completion, capturing stdout 98d7989581SWilliam A. Kennington III# into a variable 9959486679SPatrick Williamsfunction CaptureInterruptible() { 100d7989581SWilliam A. Kennington III local var="$1" 101d7989581SWilliam A. Kennington III shift 102d7989581SWilliam A. Kennington III if ShouldTerm; then 103d7989581SWilliam A. Kennington III return 143 104d7989581SWilliam A. Kennington III fi 105d7989581SWilliam A. Kennington III coproc "$@" || return 106d7989581SWilliam A. Kennington III local child_pid="$COPROC_PID" 107d7989581SWilliam A. Kennington III CHILD_PIDS["$child_pid"]=1 108d7989581SWilliam A. Kennington III exec {COPROC[1]}>&- 109d7989581SWilliam A. Kennington III read -d $'\0' -ru "${COPROC[0]}" "$var" || true 110d7989581SWilliam A. Kennington III wait "$child_pid" || true 111d7989581SWilliam A. Kennington III unset CHILD_PIDS[$child_pid] 112d7989581SWilliam A. Kennington III wait "$child_pid" 113d7989581SWilliam A. Kennington III} 114d7989581SWilliam A. Kennington III 1151285115cSWilliam A. Kennington III# Determines if an address could be a valid IPv4 address 1161285115cSWilliam A. Kennington III# NOTE: this doesn't sanitize invalid IPv4 addresses 11759486679SPatrick Williamsfunction IsIPv4() { 1181285115cSWilliam A. Kennington III local ip="$1" 1191285115cSWilliam A. Kennington III 1201285115cSWilliam A. Kennington III [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] 1211285115cSWilliam A. Kennington III} 1221285115cSWilliam A. Kennington III 1231285115cSWilliam A. Kennington III# Takes lines of text from an application on stdin and parses out a single 1241285115cSWilliam A. Kennington III# MAC address per line of input. 12559486679SPatrick Williamsfunction ParseMACFromLine() { 1261285115cSWilliam A. Kennington III sed -n 's,.*\(\([0-9a-fA-F]\{2\}:\)\{5\}[0-9a-fA-F]\{2\}\).*,\1,p' 1271285115cSWilliam A. Kennington III} 1281285115cSWilliam A. Kennington III 1291285115cSWilliam A. Kennington III# Looks up the MAC address of the IPv4 neighbor using ARP 13059486679SPatrick Williamsfunction DetermineNeighbor4() { 1311285115cSWilliam A. Kennington III local netdev="$1" 1321285115cSWilliam A. Kennington III local ip="$2" 1331285115cSWilliam A. Kennington III 1341285115cSWilliam A. Kennington III # Grep intentionally prevented from returning an error to preserve the error 1351285115cSWilliam A. Kennington III # value of arping 1361285115cSWilliam A. Kennington III RunInterruptible arping -f -c 5 -w 5 -I "$netdev" "$ip" | \ 1371285115cSWilliam A. Kennington III { grep 'reply from' || true; } | ParseMACFromLine 1381285115cSWilliam A. Kennington III} 1391285115cSWilliam A. Kennington III 1401285115cSWilliam A. Kennington III# Looks up the MAC address of the IPv6 neighbor using ICMPv6 ND 14159486679SPatrick Williamsfunction DetermineNeighbor6() { 1421285115cSWilliam A. Kennington III local netdev="$1" 1431285115cSWilliam A. Kennington III local ip="$2" 1441285115cSWilliam A. Kennington III 1451285115cSWilliam A. Kennington III RunInterruptible ndisc6 -1 -r 5 -w 1000 -q "$ip" "$netdev" 1461285115cSWilliam A. Kennington III} 1471285115cSWilliam A. Kennington III 1481285115cSWilliam A. Kennington III# Looks up the MAC address of the neighbor regardless of type 14959486679SPatrick Williamsfunction DetermineNeighbor() { 1501285115cSWilliam A. Kennington III local netdev="$1" 1511285115cSWilliam A. Kennington III local ip="$2" 1521285115cSWilliam A. Kennington III 1531285115cSWilliam A. Kennington III if IsIPv4 "$ip"; then 1541285115cSWilliam A. Kennington III DetermineNeighbor4 "$netdev" "$ip" 1551285115cSWilliam A. Kennington III else 1561285115cSWilliam A. Kennington III DetermineNeighbor6 "$netdev" "$ip" 1571285115cSWilliam A. Kennington III fi 1581285115cSWilliam A. Kennington III} 1591285115cSWilliam A. Kennington III 1601285115cSWilliam A. Kennington III# Performs a mapper call to get the subroot for the object root 1611285115cSWilliam A. Kennington III# with a maxdepth and list of required interfaces. Returns a streamed list 1621285115cSWilliam A. Kennington III# of JSON objects that contain an { object, service }. 16359486679SPatrick Williamsfunction GetSubTree() { 1641285115cSWilliam A. Kennington III local root="$1" 1651285115cSWilliam A. Kennington III shift 1661285115cSWilliam A. Kennington III local max_depth="$1" 1671285115cSWilliam A. Kennington III shift 1681285115cSWilliam A. Kennington III 1691285115cSWilliam A. Kennington III busctl --json=short call \ 1701285115cSWilliam A. Kennington III 'xyz.openbmc_project.ObjectMapper' \ 1711285115cSWilliam A. Kennington III '/xyz/openbmc_project/object_mapper' \ 1721285115cSWilliam A. Kennington III 'xyz.openbmc_project.ObjectMapper' \ 1731285115cSWilliam A. Kennington III 'GetSubTree' sias "$root" "$max_depth" "$#" "$@" | \ 1741285115cSWilliam A. Kennington III jq -c '.data[0] | to_entries[] | { object: .key, service: (.value | keys[0]) }' 1751285115cSWilliam A. Kennington III} 1761285115cSWilliam A. Kennington III 1771285115cSWilliam A. Kennington III# Returns all of the properties for a DBus interface on an object as a JSON 1781285115cSWilliam A. Kennington III# object where the keys are the property names 17959486679SPatrick Williamsfunction GetProperties() { 1801285115cSWilliam A. Kennington III local service="$1" 1811285115cSWilliam A. Kennington III local object="$2" 1821285115cSWilliam A. Kennington III local interface="$3" 1831285115cSWilliam A. Kennington III 1841285115cSWilliam A. Kennington III busctl --json=short call \ 1851285115cSWilliam A. Kennington III "$service" \ 1861285115cSWilliam A. Kennington III "$object" \ 1871285115cSWilliam A. Kennington III 'org.freedesktop.DBus.Properties' \ 1881285115cSWilliam A. Kennington III 'GetAll' s "$interface" | \ 1891285115cSWilliam A. Kennington III jq -c '.data[0] | with_entries({ key, value: .value.data })' 1901285115cSWilliam A. Kennington III} 1911285115cSWilliam A. Kennington III 1921285115cSWilliam A. Kennington III# Returns the property for a DBus interface on an object 19359486679SPatrick Williamsfunction GetProperty() { 1941285115cSWilliam A. Kennington III local service="$1" 1951285115cSWilliam A. Kennington III local object="$2" 1961285115cSWilliam A. Kennington III local interface="$3" 1971285115cSWilliam A. Kennington III local property="$4" 1981285115cSWilliam A. Kennington III 1991285115cSWilliam A. Kennington III busctl --json=short call \ 2001285115cSWilliam A. Kennington III "$service" \ 2011285115cSWilliam A. Kennington III "$object" \ 2021285115cSWilliam A. Kennington III 'org.freedesktop.DBus.Properties' \ 2031285115cSWilliam A. Kennington III 'Get' ss "$interface" "$property" | \ 2041285115cSWilliam A. Kennington III jq -r '.data[0].data' 2051285115cSWilliam A. Kennington III} 2061285115cSWilliam A. Kennington III 2071285115cSWilliam A. Kennington III# Deletes any OpenBMC DBus object from a service 20859486679SPatrick Williamsfunction DeleteObject() { 2091285115cSWilliam A. Kennington III local service="$1" 2101285115cSWilliam A. Kennington III local object="$2" 2111285115cSWilliam A. Kennington III 2121285115cSWilliam A. Kennington III busctl call \ 2131285115cSWilliam A. Kennington III "$service" \ 2141285115cSWilliam A. Kennington III "$object" \ 2151285115cSWilliam A. Kennington III 'xyz.openbmc_project.Object.Delete' \ 2161285115cSWilliam A. Kennington III 'Delete' 2171285115cSWilliam A. Kennington III} 2181285115cSWilliam A. Kennington III 2191285115cSWilliam A. Kennington III# Transforms the given JSON dictionary into bash local variable 2201285115cSWilliam A. Kennington III# statements that can be directly evaluated by the interpreter 22159486679SPatrick Williamsfunction JSONToVars() { 2221285115cSWilliam A. Kennington III jq -r 'to_entries[] | @sh "local \(.key)=\(.value)"' 2231285115cSWilliam A. Kennington III} 2241285115cSWilliam A. Kennington III 2251285115cSWilliam A. Kennington III# Returns the DBus object root for the ethernet interface 22659486679SPatrick Williamsfunction EthObjRoot() { 2271285115cSWilliam A. Kennington III local netdev="$1" 2281285115cSWilliam A. Kennington III 2291285115cSWilliam A. Kennington III echo "/xyz/openbmc_project/network/$netdev" 2301285115cSWilliam A. Kennington III} 2311285115cSWilliam A. Kennington III 2321285115cSWilliam A. Kennington III# Returns the DBus object root for the static neighbors of an intrerface 23359486679SPatrick Williamsfunction StaticNeighborObjRoot() { 2341285115cSWilliam A. Kennington III local netdev="$1" 2351285115cSWilliam A. Kennington III 2361285115cSWilliam A. Kennington III echo "$(EthObjRoot "$netdev")/static_neighbor" 2371285115cSWilliam A. Kennington III} 2381285115cSWilliam A. Kennington III 2391285115cSWilliam A. Kennington III# Returns all of the neighbor { service, object } data for an interface as if 2401285115cSWilliam A. Kennington III# a call to GetSubTree() was made 24159486679SPatrick Williamsfunction GetNeighborObjects() { 2421285115cSWilliam A. Kennington III local netdev="$1" 2431285115cSWilliam A. Kennington III 2441285115cSWilliam A. Kennington III GetSubTree "$(StaticNeighborObjRoot "$netdev")" 0 \ 2451285115cSWilliam A. Kennington III 'xyz.openbmc_project.Network.Neighbor' 2461285115cSWilliam A. Kennington III} 2471285115cSWilliam A. Kennington III 2481285115cSWilliam A. Kennington III# Returns the neighbor properties as a JSON object 24959486679SPatrick Williamsfunction GetNeighbor() { 2501285115cSWilliam A. Kennington III local service="$1" 2511285115cSWilliam A. Kennington III local object="$2" 2521285115cSWilliam A. Kennington III 2531285115cSWilliam A. Kennington III GetProperties "$service" "$object" 'xyz.openbmc_project.Network.Neighbor' 2541285115cSWilliam A. Kennington III} 2551285115cSWilliam A. Kennington III 2561285115cSWilliam A. Kennington III# Adds a static neighbor to the system network daemon 25759486679SPatrick Williamsfunction AddNeighbor() { 2581285115cSWilliam A. Kennington III local service="$1" 2591285115cSWilliam A. Kennington III local netdev="$2" 2601285115cSWilliam A. Kennington III local ip="$3" 2611285115cSWilliam A. Kennington III local mac="$4" 2621285115cSWilliam A. Kennington III 2631285115cSWilliam A. Kennington III busctl call \ 2641285115cSWilliam A. Kennington III "$service" \ 2651285115cSWilliam A. Kennington III "$(EthObjRoot "$netdev")" \ 2661285115cSWilliam A. Kennington III 'xyz.openbmc_project.Network.Neighbor.CreateStatic' \ 2671285115cSWilliam A. Kennington III 'Neighbor' ss "$ip" "$mac" >/dev/null 2681285115cSWilliam A. Kennington III} 2691285115cSWilliam A. Kennington III 2701285115cSWilliam A. Kennington III# Returns all of the IP { service, object } data for an interface as if 2711285115cSWilliam A. Kennington III# a call to GetSubTree() was made 27259486679SPatrick Williamsfunction GetIPObjects() { 2731285115cSWilliam A. Kennington III local netdev="$1" 2741285115cSWilliam A. Kennington III 2751285115cSWilliam A. Kennington III GetSubTree "$(EthObjRoot "$netdev")" 0 \ 2761285115cSWilliam A. Kennington III 'xyz.openbmc_project.Network.IP' 2771285115cSWilliam A. Kennington III} 2781285115cSWilliam A. Kennington III 2791285115cSWilliam A. Kennington III# Returns the IP properties as a JSON object 28059486679SPatrick Williamsfunction GetIP() { 2811285115cSWilliam A. Kennington III local service="$1" 2821285115cSWilliam A. Kennington III local object="$2" 2831285115cSWilliam A. Kennington III 2841285115cSWilliam A. Kennington III GetProperties "$service" "$object" 'xyz.openbmc_project.Network.IP' 2851285115cSWilliam A. Kennington III} 2861285115cSWilliam A. Kennington III 287b163a2c1SWilliam A. Kennington III# Returns the Gateway address for the interface and type 28859486679SPatrick Williamsfunction GetGateways() { 289b163a2c1SWilliam A. Kennington III local service="$1" 290b163a2c1SWilliam A. Kennington III local netdev="$2" 291b163a2c1SWilliam A. Kennington III 292b163a2c1SWilliam A. Kennington III # We fetch both the system properties and the netdev specific properties 293b163a2c1SWilliam A. Kennington III # as OpenBMC is in the process of transitioning these to the netdev object 294b163a2c1SWilliam A. Kennington III # but the migration is not yet complete. 295b163a2c1SWilliam A. Kennington III { 296b163a2c1SWilliam A. Kennington III GetProperties "$service" '/xyz/openbmc_project/network/config' \ 297b163a2c1SWilliam A. Kennington III 'xyz.openbmc_project.Network.SystemConfiguration' 298b163a2c1SWilliam A. Kennington III GetProperties "$service" "$(EthObjRoot "$netdev")" \ 299b163a2c1SWilliam A. Kennington III 'xyz.openbmc_project.Network.EthernetInterface' 300b163a2c1SWilliam A. Kennington III } | jq -s ' 301b163a2c1SWilliam A. Kennington III . | map( 302b163a2c1SWilliam A. Kennington III if .DefaultGateway != "" then 303b163a2c1SWilliam A. Kennington III {DefaultGateway: .DefaultGateway} 304b163a2c1SWilliam A. Kennington III else 305b163a2c1SWilliam A. Kennington III {} 306b163a2c1SWilliam A. Kennington III end + 307b163a2c1SWilliam A. Kennington III if .DefaultGateway6 != "" then 308b163a2c1SWilliam A. Kennington III {DefaultGateway6: .DefaultGateway6} 309b163a2c1SWilliam A. Kennington III else 310b163a2c1SWilliam A. Kennington III {} 311b163a2c1SWilliam A. Kennington III end 312b163a2c1SWilliam A. Kennington III ) | {DefaultGateway: "", DefaultGateway6: ""} + add' 313b163a2c1SWilliam A. Kennington III} 314b163a2c1SWilliam A. Kennington III 3151285115cSWilliam A. Kennington III# Adds a static IP to the system network daemon 31659486679SPatrick Williamsfunction AddIP() { 3171285115cSWilliam A. Kennington III local service="$1" 3181285115cSWilliam A. Kennington III local netdev="$2" 3191285115cSWilliam A. Kennington III local ip="$3" 3201285115cSWilliam A. Kennington III local prefix="$4" 3211285115cSWilliam A. Kennington III 3221285115cSWilliam A. Kennington III local protocol='xyz.openbmc_project.Network.IP.Protocol.IPv4' 3231285115cSWilliam A. Kennington III if ! IsIPv4 "$ip"; then 3241285115cSWilliam A. Kennington III protocol='xyz.openbmc_project.Network.IP.Protocol.IPv6' 3251285115cSWilliam A. Kennington III fi 3261285115cSWilliam A. Kennington III 3271285115cSWilliam A. Kennington III busctl call \ 3281285115cSWilliam A. Kennington III "$service" \ 3291285115cSWilliam A. Kennington III "$(EthObjRoot "$netdev")" \ 3301285115cSWilliam A. Kennington III 'xyz.openbmc_project.Network.IP.Create' \ 3311285115cSWilliam A. Kennington III 'IP' ssys "$protocol" "$ip" "$prefix" '' >/dev/null 3321285115cSWilliam A. Kennington III} 3331285115cSWilliam A. Kennington III 3341285115cSWilliam A. Kennington III# Determines if two IP addresses have the same address family 3351285115cSWilliam A. Kennington III# IE: Both are IPv4 or both are IPv6 33659486679SPatrick Williamsfunction MatchingAF() { 3371285115cSWilliam A. Kennington III local rc1=0 rc2=0 3381285115cSWilliam A. Kennington III IsIPv4 "$1" || rc1=$? 3391285115cSWilliam A. Kennington III IsIPv4 "$2" || rc2=$? 3401285115cSWilliam A. Kennington III (( rc1 == rc2 )) 3411285115cSWilliam A. Kennington III} 3421285115cSWilliam A. Kennington III 3431285115cSWilliam A. Kennington III# Checks to see if the machine has the provided IP address information 3441285115cSWilliam A. Kennington III# already configured. If not, it deletes all of the information for that 3451285115cSWilliam A. Kennington III# address family and adds the provided IP address. 34659486679SPatrick Williamsfunction UpdateIP() { 3471285115cSWilliam A. Kennington III local service="$1" 3481285115cSWilliam A. Kennington III local netdev="$2" 349*1e5029b4SWilliam A. Kennington III local ip="$(normalize_ip $3)" 3501285115cSWilliam A. Kennington III local prefix="$4" 3511285115cSWilliam A. Kennington III 3521285115cSWilliam A. Kennington III local should_add=1 3531285115cSWilliam A. Kennington III local delete_services=() 3541285115cSWilliam A. Kennington III local delete_objects=() 3551285115cSWilliam A. Kennington III local entry 3561285115cSWilliam A. Kennington III while read entry; do 3571285115cSWilliam A. Kennington III eval "$(echo "$entry" | JSONToVars)" || return $? 3581285115cSWilliam A. Kennington III eval "$(GetIP "$service" "$object" | JSONToVars)" || return $? 359*1e5029b4SWilliam A. Kennington III if [ "$(normalize_ip "$Address")" = "$ip" ] && \ 3601285115cSWilliam A. Kennington III [ "$PrefixLength" = "$prefix" ]; then 3611285115cSWilliam A. Kennington III should_add=0 3621285115cSWilliam A. Kennington III elif MatchingAF "$ip" "$Address"; then 3631285115cSWilliam A. Kennington III echo "Deleting spurious IP: $Address/$PrefixLength" >&2 3641285115cSWilliam A. Kennington III delete_services+=("$service") 3651285115cSWilliam A. Kennington III delete_objects+=("$object") 3661285115cSWilliam A. Kennington III fi 3671285115cSWilliam A. Kennington III done < <(GetIPObjects "$netdev") 3681285115cSWilliam A. Kennington III 3691285115cSWilliam A. Kennington III local i 3701285115cSWilliam A. Kennington III for (( i=0; i<${#delete_objects[@]}; ++i )); do 3712be0536cSWilliam A. Kennington III DeleteObject "${delete_services[$i]}" "${delete_objects[$i]}" || true 3721285115cSWilliam A. Kennington III done 3731285115cSWilliam A. Kennington III 374*1e5029b4SWilliam A. Kennington III # The default address is treated as a delete only request 375*1e5029b4SWilliam A. Kennington III if [ "$ip" = :: -o "$ip" = 0.0.0.0 ]; then 376*1e5029b4SWilliam A. Kennington III return 377*1e5029b4SWilliam A. Kennington III fi 378*1e5029b4SWilliam A. Kennington III 3791285115cSWilliam A. Kennington III if (( should_add == 0 )); then 3801285115cSWilliam A. Kennington III echo "Not adding IP: $ip/$prefix" >&2 3811285115cSWilliam A. Kennington III else 3821285115cSWilliam A. Kennington III echo "Adding IP: $ip/$prefix" >&2 3831285115cSWilliam A. Kennington III AddIP "$service" "$netdev" "$ip" "$prefix" || return $? 3841285115cSWilliam A. Kennington III fi 3851285115cSWilliam A. Kennington III} 3861285115cSWilliam A. Kennington III 3871285115cSWilliam A. Kennington III# Sets the system gateway property to the provided IP address if not already 3881285115cSWilliam A. Kennington III# set to the current value. 38959486679SPatrick Williamsfunction UpdateGateway() { 3901285115cSWilliam A. Kennington III local service="$1" 3912d6858ddSWilliam A. Kennington III local netdev="$2" 3922d6858ddSWilliam A. Kennington III local ip="$3" 3931285115cSWilliam A. Kennington III 3942d6858ddSWilliam A. Kennington III local object="$(EthObjRoot "$netdev")" 3952d6858ddSWilliam A. Kennington III local interface='xyz.openbmc_project.Network.EthernetInterface' 3961285115cSWilliam A. Kennington III local property='DefaultGateway' 3971285115cSWilliam A. Kennington III if ! IsIPv4 "$ip"; then 3981285115cSWilliam A. Kennington III property='DefaultGateway6' 3991285115cSWilliam A. Kennington III fi 4001285115cSWilliam A. Kennington III 4011285115cSWilliam A. Kennington III local current_ip 4021285115cSWilliam A. Kennington III current_ip="$(GetProperty "$service" "$object" "$interface" "$property")" || \ 4031285115cSWilliam A. Kennington III return $? 4041285115cSWilliam A. Kennington III if [ -n "$current_ip" ] && \ 4051285115cSWilliam A. Kennington III [ "$(normalize_ip "$ip")" = "$(normalize_ip "$current_ip")" ]; then 4061285115cSWilliam A. Kennington III echo "Not reconfiguring gateway: $ip" >&2 4071285115cSWilliam A. Kennington III return 0 4081285115cSWilliam A. Kennington III fi 4091285115cSWilliam A. Kennington III 4101285115cSWilliam A. Kennington III echo "Setting gateway: $ip" >&2 4111285115cSWilliam A. Kennington III busctl set-property "$service" "$object" "$interface" "$property" s "$ip" 4121285115cSWilliam A. Kennington III} 4131285115cSWilliam A. Kennington III 4141285115cSWilliam A. Kennington III# Checks to see if the machine has the provided neighbor information 4151285115cSWilliam A. Kennington III# already configured. If not, it deletes all of the information for that 4161285115cSWilliam A. Kennington III# address family and adds the provided neighbor entry. 41759486679SPatrick Williamsfunction UpdateNeighbor() { 4181285115cSWilliam A. Kennington III local service="$1" 4191285115cSWilliam A. Kennington III local netdev="$2" 4201285115cSWilliam A. Kennington III local ip="$3" 4211285115cSWilliam A. Kennington III local mac="$4" 4221285115cSWilliam A. Kennington III 4231285115cSWilliam A. Kennington III local should_add=1 4241285115cSWilliam A. Kennington III local delete_services=() 4251285115cSWilliam A. Kennington III local delete_objects=() 4261285115cSWilliam A. Kennington III local entry 4271285115cSWilliam A. Kennington III while read entry; do 4281285115cSWilliam A. Kennington III eval "$(echo "$entry" | JSONToVars)" || return $? 4291285115cSWilliam A. Kennington III eval "$(GetNeighbor "$service" "$object" | JSONToVars)" || return $? 4301285115cSWilliam A. Kennington III if [ "$(normalize_ip "$IPAddress")" = "$(normalize_ip "$ip")" ] && \ 4311285115cSWilliam A. Kennington III [ "$(normalize_mac "$MACAddress")" = "$(normalize_mac "$mac")" ]; then 4321285115cSWilliam A. Kennington III should_add=0 4331285115cSWilliam A. Kennington III elif MatchingAF "$ip" "$IPAddress"; then 4341285115cSWilliam A. Kennington III echo "Deleting spurious neighbor: $IPAddress $MACAddress" >&2 4351285115cSWilliam A. Kennington III delete_services+=("$service") 4361285115cSWilliam A. Kennington III delete_objects+=("$object") 4371285115cSWilliam A. Kennington III fi 4381285115cSWilliam A. Kennington III done < <(GetNeighborObjects "$netdev" 2>/dev/null) 4391285115cSWilliam A. Kennington III 4401285115cSWilliam A. Kennington III local i 4411285115cSWilliam A. Kennington III for (( i=0; i<${#delete_objects[@]}; ++i )); do 4422be0536cSWilliam A. Kennington III DeleteObject "${delete_services[$i]}" "${delete_objects[$i]}" || true 4431285115cSWilliam A. Kennington III done 4441285115cSWilliam A. Kennington III 4451285115cSWilliam A. Kennington III if (( should_add == 0 )); then 4461285115cSWilliam A. Kennington III echo "Not adding neighbor: $ip $mac" >&2 4471285115cSWilliam A. Kennington III else 4481285115cSWilliam A. Kennington III echo "Adding neighbor: $ip $mac" >&2 4491285115cSWilliam A. Kennington III AddNeighbor "$service" "$netdev" "$ip" "$mac" || return $? 4501285115cSWilliam A. Kennington III fi 4511285115cSWilliam A. Kennington III} 452b163a2c1SWilliam A. Kennington III 453b163a2c1SWilliam A. Kennington III# Determines the ip and mac of the IPv6 router 45459486679SPatrick Williamsfunction DiscoverRouter6() { 455b163a2c1SWilliam A. Kennington III local netdev="$1" 456b163a2c1SWilliam A. Kennington III local retries="$2" 457b163a2c1SWilliam A. Kennington III local timeout="$3" 458b163a2c1SWilliam A. Kennington III local router="${4-}" 459b163a2c1SWilliam A. Kennington III 460b163a2c1SWilliam A. Kennington III local output 461b163a2c1SWilliam A. Kennington III local st=0 462b163a2c1SWilliam A. Kennington III local args=(-1 -w "$timeout" -n $router "$netdev") 463b163a2c1SWilliam A. Kennington III if (( retries < 0 )); then 464b163a2c1SWilliam A. Kennington III args+=(-d) 465b163a2c1SWilliam A. Kennington III else 466b163a2c1SWilliam A. Kennington III args+=(-r "$retries") 467b163a2c1SWilliam A. Kennington III fi 468d7989581SWilliam A. Kennington III CaptureInterruptible output rdisc6 "${args[@]}" || st=$? 469b163a2c1SWilliam A. Kennington III if (( st != 0 )); then 470b163a2c1SWilliam A. Kennington III echo "rdisc6 failed with: " >&2 471b163a2c1SWilliam A. Kennington III echo "$output" >&2 472b163a2c1SWilliam A. Kennington III return $st 473b163a2c1SWilliam A. Kennington III fi 474b163a2c1SWilliam A. Kennington III 475b163a2c1SWilliam A. Kennington III local ip="$(echo "$output" | grep 'from' | awk '{print $2}')" 476b163a2c1SWilliam A. Kennington III local mac="$(echo "$output" | grep 'Source link-layer' | ParseMACFromLine)" 477379b061fSWilliam A. Kennington III local staddr="$(echo "$output" | grep 'Stateful address conf.*Yes')" 478379b061fSWilliam A. Kennington III printf '{"router_ip":"%s","router_mac":"%s","stateful_address":"%s"}\n' \ 479379b061fSWilliam A. Kennington III "$ip" "$mac" "$staddr" 480b163a2c1SWilliam A. Kennington III} 481a7af2e08SWilliam A. Kennington III 482a7af2e08SWilliam A. Kennington III# Sets the network configuration of an interface to be static 48359486679SPatrick Williamsfunction SetStatic() { 484a7af2e08SWilliam A. Kennington III local service="$1" 485a7af2e08SWilliam A. Kennington III local netdev="$2" 486a7af2e08SWilliam A. Kennington III 487a7af2e08SWilliam A. Kennington III echo "Disabling DHCP" >&2 488a7af2e08SWilliam A. Kennington III busctl set-property "$service" "$(EthObjRoot "$netdev")" \ 489a7af2e08SWilliam A. Kennington III xyz.openbmc_project.Network.EthernetInterface DHCPEnabled \ 490a7af2e08SWilliam A. Kennington III s xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none 491a7af2e08SWilliam A. Kennington III} 492