@@ -18,6 +18,7 @@ declare ether
1818declare unitdir
1919declare lockdir
2020declare reload_flag
21+ declare runtimeroot
2122
2223# Version information - substituted during installation
2324declare PACKAGE_VERSION=" AMAZON_EC2_NET_UTILS_VERSION"
@@ -549,6 +550,16 @@ _get_device_number() {
549550# NOTE: On many instance types, this value is not defined. This
550551# function will print the empty string on those instances. On
551552# instances where it is defined, it will be a numeric value.
553+ #
554+ # The value, like device-number, may not have propagated to IMDS
555+ # when a hot-plugged interface first appears. We can't tell
556+ # "undefined for this instance type" from "not yet propagated" from
557+ # a single query, so we retry on empty. Once the first ENI on this
558+ # boot has exhausted the retry loop with no value, we touch a marker
559+ # so subsequent ENIs skip the retry entirely. Without
560+ # this retry we can silently substitute 0 for a real network-card
561+ # index on multi-card instances, colliding route metrics and
562+ # routing-table IDs across interfaces.
552563_get_network_card () {
553564 local iface ether network_card
554565 iface=" $1 "
@@ -557,8 +568,26 @@ _get_network_card() {
557568 if _is_primary_interface " $ether " ; then
558569 echo 0 ; return 0
559570 fi
560- network_card=$( get_iface_imds " $ether " network-card)
571+
572+ local marker=" ${runtimeroot} /.no-network-card"
573+ if [ -e " $marker " ]; then
574+ echo ${network_card}
575+ return 0
576+ fi
577+
578+ local -i maxtries=40 ntries=0
579+ for (( ntries = 0 ; ntries < maxtries; ntries++ )) ; do
580+ network_card=$( get_iface_imds " $ether " network-card 1)
581+ if [ -n " $network_card " ]; then
582+ echo " $network_card "
583+ return 0
584+ fi
585+ sleep 0.1
586+ done
587+
588+ touch " $marker "
561589 echo ${network_card}
590+ return 0
562591}
563592
564593
0 commit comments