From 1abe3f70402a7896f1a34c1abce3208f8f323fdc Mon Sep 17 00:00:00 2001 From: Noah Meyerhans Date: Tue, 12 Sep 2023 09:45:06 -0700 Subject: [PATCH 1/2] Preserve the original value of the errexit shell option Previously the code would disable errexit in a certain block, and then unconditionally re-enable it at the end, regardless of whether it had originally been enabled. This change ensures that it's only re-enabled if it originally had been. --- lib/lib.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/lib.sh b/lib/lib.sh index a53d269..347011c 100644 --- a/lib/lib.sh +++ b/lib/lib.sh @@ -35,12 +35,13 @@ get_token() { # invocations we avoid retrying local deadline deadline=$(date -d "now+30 seconds" +%s) + local old_opts=$- while [ "$(date +%s)" -lt $deadline ]; do for ep in "${imds_endpoints[@]}"; do set +e imds_token=$(curl --max-time 5 --connect-timeout 0.15 -s --fail \ -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 60" ${ep}/${imds_token_path}) - set -e + [[ $old_opts = *e* ]] && set -e if [ -n "$imds_token" ]; then debug "Got IMDSv2 token from ${ep}" imds_endpoint=$ep From c04b3e5ae6aa5dbe502ffd3ec34cb4669e0ea0bf Mon Sep 17 00:00:00 2001 From: Noah Meyerhans Date: Fri, 15 Sep 2023 21:33:48 -0700 Subject: [PATCH 2/2] Route configuration simplification Install routes from DHCP in the main table with increasing metrics Install static routes in secondary tables Formatting changes to the generated config drop-in for readability Fixes: 33b68bb15dd2 ("Install prefix routes in private tables") --- lib/lib.sh | 74 +++++++++++++++++++++++++--------- systemd/network/80-ec2.network | 7 ---- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/lib/lib.sh b/lib/lib.sh index 347011c..049437a 100644 --- a/lib/lib.sh +++ b/lib/lib.sh @@ -24,6 +24,11 @@ declare -r imds_token_path="api/token" declare -r syslog_facility="user" declare -r syslog_tag="ec2net" declare -i -r rule_base=10000 + +# Systemd installs routes with a metric of 1024 by default. We +# override to a lower metric to ensure that our fully configured +# interfaces are preferred over those in the process of being +# configured. declare -i -r metric_base=512 declare imds_endpoint imds_token @@ -175,6 +180,23 @@ subnet_supports_ipv6() { ip -6 addr show dev "$iface" scope global | grep -q inet6 } +subnet_prefixroutes() { + local ether=$1 + local family=${2:-ipv4} + if [ -z "$ether" ]; then + err "${FUNCNAME[0]} called without an MAC address" + return 1 + fi + case "$family" in + ipv4) + get_iface_imds "$ether" "subnet-${family}-cidr-block" + ;; + ipv6) + get_iface_imds "$ether" "subnet-${family}-cidr-blocks" + ;; + esac +} + create_rules() { local iface=$1 local ifid=$2 @@ -243,10 +265,7 @@ create_if_overrides() { local cfgdir="${cfgfile}.d" local dropin="${cfgdir}/eni.conf" local -i metric=$((metric_base+10*ifid)) - local -i tableid=0 - if [ $ifid -gt 0 ]; then - tableid=$((rule_base+ifid)) - fi + local -i tableid=$((rule_base+ifid)) mkdir -p "$cfgdir" cat < "${dropin}.tmp" @@ -255,32 +274,51 @@ create_if_overrides() { MACAddress=${ether} [Network] DHCP=yes + [DHCPv4] RouteMetric=${metric} -[DHCPv6] +UseRoutes=true +UseGateway=true + +[IPv6AcceptRA] RouteMetric=${metric} +UseGateway=true + EOF - if [ "$tableid" -gt 0 ]; then - cat <> "${dropin}.tmp" + cat <> "${dropin}.tmp" [Route] Table=${tableid} Gateway=_ipv6ra -[DHCPv4] -RouteTable=${tableid} -[IPv6AcceptRA] -RouteTable=${tableid} + EOF - if subnet_supports_ipv4 "$iface"; then - # if we're not in a v6-only network, add IPv4 routes to the private table - cat <> "${dropin}.tmp" + for dest in $(subnet_prefixroutes "$ether" ipv6); do + cat <> "${dropin}.tmp" +[Route] +Table=${tableid} +Destination=${dest} + +EOF + done + + if subnet_supports_ipv4 "$iface"; then + # if not in a v6-only network, add IPv4 routes to the private table + cat <> "${dropin}.tmp" [Route] Gateway=_dhcp4 Table=${tableid} EOF - fi + local dest + for dest in $(subnet_prefixroutes "$ether" ipv4); do + cat <> "${dropin}.tmp" +[Route] +Table=${tableid} +Destination=${dest} +EOF + done fi + mv "${dropin}.tmp" "$dropin" echo 1 } @@ -396,11 +434,7 @@ setup_interface() { changes+=$(create_interface_config "$iface" "$device_number" "$ether") for family in 4 6; do - if [ "$device_number" -eq 0 ]; then - debug "Skipping ipv$family rules for primary ENI $iface" - else - changes+=$(create_rules "$iface" "$device_number" $family) - fi + changes+=$(create_rules "$iface" "$device_number" $family) done changes+=$(create_ipv4_aliases $iface $ether) diff --git a/systemd/network/80-ec2.network b/systemd/network/80-ec2.network index a926b64..4eb0a73 100644 --- a/systemd/network/80-ec2.network +++ b/systemd/network/80-ec2.network @@ -21,10 +21,3 @@ UseHostname=no UseDNS=yes UseNTP=yes WithoutRA=solicit - -[Route] -Gateway=_ipv6ra - -[IPv6AcceptRA] -UseDomains=yes -