diff --git a/templates/common/gcp/files/gcp-routes-sh.yaml b/templates/common/gcp/files/gcp-routes-sh.yaml new file mode 100644 index 0000000000..3edf079003 --- /dev/null +++ b/templates/common/gcp/files/gcp-routes-sh.yaml @@ -0,0 +1,96 @@ +filesystem: "root" +mode: 0744 +path: "/usr/local/bin/gcp-routes.sh" +contents: + inline: | + #!/bin/bash + + declare -A routes + curler() { + curl --silent -L -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/${1}" + } + + get_ifname() { + sysfs_path="/sys/class/net" + for dev in $(find ${sysfs_path} -maxdepth 1 -mindepth 1); + do + local mac=$(<${dev}/address); + local name="$(basename ${dev})" + if [ "${mac}" == "${1}" ]; + then + echo "${name}" + return; + fi + done + } + + set_routes() { + local dev="${1}" + read -a dev_routes <<< "${routes[$dev]}" + for cur_route in $(ip route show dev ${dev} table local proto 66 | awk '{print$2}'); + do + if [[ ! "${dev_routes[@]}" =~ "${cur_route}" ]]; + then + echo "Removing stale forwarded IP ${cur_route}/32" + ip route del ${cur_route}/32 dev ${dev} table local proto 66 + fi + done + for route in ${dev_routes[@]} + do + ip route replace to local ${route} dev $dev proto 66 + done + unset dev_routes + } + + del_routes() { + local dev="${1}" + read -a dev_routes <<< "${routes[$dev]}" + for cur_route in $(ip route show dev ${dev} table local proto 66 | awk '{print$2}'); + do + if [[ "${dev_routes[@]}" =~ "${cur_route}" ]]; + then + echo "Removing forwarded IP ${cur_route}/32" + ip route del ${cur_route}/32 dev ${dev} table local proto 66 + fi + done + unset dev_routes + } + + run() { + net_path="network-interfaces/" + for vif in $(curler ${net_path}); do + hw_addr=$(curler "${net_path}${vif}mac") + fwip_path="${net_path}${vif}forwarded-ips/" + dev_name="$(get_ifname ${hw_addr})" + for level in $(curler ${fwip_path}) + do + for fwip in $(curler ${fwip_path}${level}) + do + echo "Processing route for NIC ${vif}${hw_addr} as ${dev_name} for ${fwip}" + routes[$dev_name]+="${fwip} " + done + done + $"${1}" ${dev_name} + + routes[$dev_name]="" + unset hw_addr + unset fwip_path + unset dev_name + done + } + + case "$1" in + start) + while :; do + run set_routes + sleep 30 + done + ;; + cleanup) + run del_routes + ;; + *) + echo $"Usage: $0 {start|cleanup}" + exit 1 + + esac diff --git a/templates/common/gcp/units/gcp-routes-service.yaml b/templates/common/gcp/units/gcp-routes-service.yaml new file mode 100644 index 0000000000..1d02c5c41b --- /dev/null +++ b/templates/common/gcp/units/gcp-routes-service.yaml @@ -0,0 +1,19 @@ +name: "gcp-routes.service" +enabled: true +contents: | + [Unit] + Description=Update GCP routes for forwarded IPs. + ConditionKernelCommandLine=|ignition.platform.id=gce + ConditionKernelCommandLine=|ignition.platform.id=gcp + After=network.target + + [Service] + Type=simple + ExecStart=/bin/bash /usr/local/bin/gcp-routes.sh start + ExecStopPost=/bin/bash /usr/local/bin/gcp-routes.sh cleanup + User=root + RestartSec=30 + Restart=always + + [Install] + WantedBy=multi-user.target