mirror of
https://github.com/bin456789/reinstall.git
synced 2026-03-22 04:24:17 +08:00
fix: select correct primary IPv6 address whose subnet contains the gateway (#561)
* fix: select correct primary IPv6 address whose subnet contains the gateway When a system has multiple IPv6 addresses with different prefix lengths (e.g., /44 and /96), the script previously selected the first address as primary regardless of whether its subnet contained the default gateway. This caused the gateway to be unreachable after reinstallation. This change: - Adds pure shell expand_ipv6 and ip_addr_contains_gw functions to determine which IPv6 subnet contains the gateway (no python dependency) - Modifies collect_netconf to select the correct primary IPv6 address - Stores remaining addresses as ipv6_extra_addrs - Adds extra IPv6 addresses via post-up in create_ifupdown_config Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address review feedback for IPv6 extra addrs and edge cases - Pass ipv6_extra_addrs through initrd-network.sh (receive as $7, add extra addresses in add_missing_ipv6_config, write to netconf) so that trans.sh can read them via get_netconf_to - Fix cut -c1-0 error when prefix_len < 4 in ip_addr_contains_gw - Use grep -Fxve for exact string matching instead of regex Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use subshell for IFS modification to avoid leaking to outer scope Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: avoid global IFS modification when iterating extra IPv6 addresses Replace subshell IFS trick with tr+while read to split comma-separated ipv6_extra_addrs, avoiding any modification of the IFS variable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use ip route get instead of subnet matching for IPv6 primary address selection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -11,6 +11,7 @@ ipv4_gateway=$3
|
|||||||
ipv6_addr=$4
|
ipv6_addr=$4
|
||||||
ipv6_gateway=$5
|
ipv6_gateway=$5
|
||||||
is_in_china=$6
|
is_in_china=$6
|
||||||
|
ipv6_extra_addrs=$7
|
||||||
|
|
||||||
DHCP_TIMEOUT=15
|
DHCP_TIMEOUT=15
|
||||||
DNS_FILE_TIMEOUT=5
|
DNS_FILE_TIMEOUT=5
|
||||||
@ -171,6 +172,15 @@ add_missing_ipv6_config() {
|
|||||||
ip -6 route add default via "$ipv6_gateway" dev "$ethx" onlink
|
ip -6 route add default via "$ipv6_gateway" dev "$ethx" onlink
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 添加额外的 IPv6 地址(逗号分隔)
|
||||||
|
if [ -n "$ipv6_extra_addrs" ]; then
|
||||||
|
printf '%s\n' "$ipv6_extra_addrs" | tr ',' '\n' | while IFS= read -r addr; do
|
||||||
|
if [ -n "$addr" ]; then
|
||||||
|
ip -6 addr add "$addr" dev "$ethx" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,5 +516,6 @@ echo "$ipv4_addr" >"$netconf/ipv4_addr"
|
|||||||
echo "$ipv4_gateway" >"$netconf/ipv4_gateway"
|
echo "$ipv4_gateway" >"$netconf/ipv4_gateway"
|
||||||
echo "$ipv6_addr" >"$netconf/ipv6_addr"
|
echo "$ipv6_addr" >"$netconf/ipv6_addr"
|
||||||
echo "$ipv6_gateway" >"$netconf/ipv6_gateway"
|
echo "$ipv6_gateway" >"$netconf/ipv6_gateway"
|
||||||
|
echo "$ipv6_extra_addrs" >"$netconf/ipv6_extra_addrs"
|
||||||
$ipv4_has_internet && echo 1 >"$netconf/ipv4_has_internet" || echo 0 >"$netconf/ipv4_has_internet"
|
$ipv4_has_internet && echo 1 >"$netconf/ipv4_has_internet" || echo 0 >"$netconf/ipv4_has_internet"
|
||||||
$ipv6_has_internet && echo 1 >"$netconf/ipv6_has_internet" || echo 0 >"$netconf/ipv6_has_internet"
|
$ipv6_has_internet && echo 1 >"$netconf/ipv6_has_internet" || echo 0 >"$netconf/ipv6_has_internet"
|
||||||
|
|||||||
28
reinstall.sh
28
reinstall.sh
@ -2717,7 +2717,27 @@ collect_netconf() {
|
|||||||
eval ipv${v}_ethx="$ethx" # can_use_cloud_kernel 要用
|
eval ipv${v}_ethx="$ethx" # can_use_cloud_kernel 要用
|
||||||
eval ipv${v}_mac="$(ip link show dev $ethx | grep link/ether | head -1 | awk '{print $2}')"
|
eval ipv${v}_mac="$(ip link show dev $ethx | grep link/ether | head -1 | awk '{print $2}')"
|
||||||
eval ipv${v}_gateway="$gateway"
|
eval ipv${v}_gateway="$gateway"
|
||||||
eval ipv${v}_addr="$(ip -$v -o addr show scope global dev $ethx | grep -v temporary | head -1 | awk '{print $4}')"
|
|
||||||
|
# 获取所有全局地址
|
||||||
|
all_addrs=$(ip -$v -o addr show scope global dev $ethx | grep -v temporary | awk '{print $4}')
|
||||||
|
primary_addr=$(echo "$all_addrs" | head -1)
|
||||||
|
|
||||||
|
# IPv6: 用 ip route get 让内核返回正确的源 IP,指定 dev 避免 tun/warp 干扰
|
||||||
|
if [ "$v" = 6 ] && [ -n "$primary_addr" ]; then
|
||||||
|
route_src=$(ip -6 route get 2001:4860:4860::8888 dev "$ethx" 2>/dev/null | grep -oP 'src \K[^ ]+')
|
||||||
|
if [ -n "$route_src" ]; then
|
||||||
|
for addr in $all_addrs; do
|
||||||
|
if [ "${addr%/*}" = "$route_src" ]; then
|
||||||
|
primary_addr=$addr
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval ipv${v}_addr="$primary_addr"
|
||||||
|
# extra_addrs: 除主地址外的所有地址
|
||||||
|
eval ipv${v}_extra_addrs="$(echo "$all_addrs" | grep -Fxve "$primary_addr" | tr '\n' ',' | sed 's/,$//')"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
@ -3607,13 +3627,13 @@ get_ip_conf_cmd() {
|
|||||||
|
|
||||||
sh=/initrd-network.sh
|
sh=/initrd-network.sh
|
||||||
if is_found_ipv4_netconf && is_found_ipv6_netconf && [ "$ipv4_mac" = "$ipv6_mac" ]; then
|
if is_found_ipv4_netconf && is_found_ipv6_netconf && [ "$ipv4_mac" = "$ipv6_mac" ]; then
|
||||||
echo "'$sh' '$ipv4_mac' '$ipv4_addr' '$ipv4_gateway' '$ipv6_addr' '$ipv6_gateway' '$is_in_china'"
|
echo "'$sh' '$ipv4_mac' '$ipv4_addr' '$ipv4_gateway' '$ipv6_addr' '$ipv6_gateway' '$is_in_china' '$ipv6_extra_addrs'"
|
||||||
else
|
else
|
||||||
if is_found_ipv4_netconf; then
|
if is_found_ipv4_netconf; then
|
||||||
echo "'$sh' '$ipv4_mac' '$ipv4_addr' '$ipv4_gateway' '' '' '$is_in_china'"
|
echo "'$sh' '$ipv4_mac' '$ipv4_addr' '$ipv4_gateway' '' '' '$is_in_china' ''"
|
||||||
fi
|
fi
|
||||||
if is_found_ipv6_netconf; then
|
if is_found_ipv6_netconf; then
|
||||||
echo "'$sh' '$ipv6_mac' '' '' '$ipv6_addr' '$ipv6_gateway' '$is_in_china'"
|
echo "'$sh' '$ipv6_mac' '' '' '$ipv6_addr' '$ipv6_gateway' '$is_in_china' '$ipv6_extra_addrs'"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
10
trans.sh
10
trans.sh
@ -1121,6 +1121,16 @@ EOF
|
|||||||
post-up ip route add default via $ipv6_gateway dev $ethx
|
post-up ip route add default via $ipv6_gateway dev $ethx
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 额外的 IPv6 地址(子网不含网关的地址)
|
||||||
|
get_netconf_to ipv6_extra_addrs
|
||||||
|
if [ -n "$ipv6_extra_addrs" ]; then
|
||||||
|
_old_ifs=$IFS; IFS=','
|
||||||
|
for _addr in $ipv6_extra_addrs; do
|
||||||
|
echo " post-up ip -6 addr add $_addr dev $ethx" >>$conf_file
|
||||||
|
done
|
||||||
|
IFS=$_old_ifs
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# dns
|
# dns
|
||||||
|
|||||||
Reference in New Issue
Block a user