diff --git a/addons/common/utils.sh b/addons/common/utils.sh index 4fc74395..1be0d666 100644 --- a/addons/common/utils.sh +++ b/addons/common/utils.sh @@ -31,3 +31,61 @@ use_addon_manifest() { use_manifest_result="$?" rm "${tmp_manifest}" } + +# Function to convert an IP address to a decimal number +ip_to_decimal() { + local ip="$1" + echo $(( $(echo "$ip" | awk -F'.' '{print ($1*256^3)+($2*256^2)+($3*256^1)+$4}') )) +} + +# Function to convert a decimal number to an IP address +decimal_to_ip() { + local decimal="$1" + echo "$(( (decimal >> 24) & 255 )).$(( (decimal >> 16) & 255 )).$(( (decimal >> 8) & 255 )).$(( decimal & 255 ))" +} + +# Function to validate if an IP address is within the CIDR range +ip_in_cidr() { + local ip="$1" + local cidr="$2" + + local cidr_ip=$(echo "$cidr" | cut -d'/' -f1) + local cidr_mask=$(echo "$cidr" | cut -d'/' -f2) + + local ip_decimal=$(ip_to_decimal "$ip") + local cidr_ip_decimal=$(ip_to_decimal "$cidr_ip") + + local bitmask=$((2**(32-cidr_mask)-1)) + local network_ip_decimal=$((cidr_ip_decimal & ~bitmask)) + + local cidr_start_decimal=$((network_ip_decimal + 1)) + local cidr_end_decimal=$((network_ip_decimal + bitmask - 1)) + + [ $ip_decimal -ge $cidr_start_decimal ] && [ $ip_decimal -le $cidr_end_decimal ] +} + +# Function to choose a random valid IP address from the CIDR range +choose_random_ip() { + local cidr="$1" + local ip + local count=0 + local max_attempts=100 + + local cidr_ip=$(echo "$cidr" | cut -d'/' -f1) + local base_ip="${cidr_ip%.*}." + + while [ "$count" -lt "$max_attempts" ]; do + ip=$(shuf -i 1-254 -n 1) + chosen_ip="${base_ip}$ip" + + if ip_in_cidr "$chosen_ip" "$cidr"; then + echo "$chosen_ip" + return 0 + fi + + ((count++)) + done + + echo "Failed to find a valid IP address after $max_attempts attempts." + return 1 +} diff --git a/addons/dns/enable b/addons/dns/enable index 83ee4129..f0748f30 100755 --- a/addons/dns/enable +++ b/addons/dns/enable @@ -47,7 +47,12 @@ else echo "Will use ${nameserver_str} as upstream nameservers" fi -DNSIP="10.152.183.10" +if [ -e "${SNAP_DATA}/args/cni-env" ]; then + source "${SNAP_DATA}/args/cni-env" +fi +# Choose a random IP address from the service cidr. +DNSIP=$(choose_random_ip "$IPv4_SERVICE_CIDR" || true) +echo "Will use ${DNSIP} as dns service ip address" DNSIPARG=$2 if [[ -n "$DNSIPARG" ]]; then