Skip to content
This repository was archived by the owner on Sep 30, 2021. It is now read-only.

Commit c545fd4

Browse files
committed
fix IPv6 address assignment and restoration
1 parent 7811c5c commit c545fd4

1 file changed

Lines changed: 34 additions & 11 deletions

File tree

create_ap

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,28 @@ get_new_macaddr() {
434434
echo $NEWMAC
435435
}
436436

437+
get_ipv6addr() {
438+
ip -6 addr show $1 scope global | sed -e 's/ /\n/g' | sed -ne '/inet6/{n;p}'
439+
}
440+
441+
get_new_ipv6addr() {
442+
local OLDIP NEWIP LAST_CHUNK i
443+
OLDIP=$(get_ipv6addr $INTERNET_IFACE)
444+
OLDIP="${OLDIP%/*}"
445+
mutex_lock
446+
for i in {1..65535}; do
447+
if [[ "$OLDIP" == ::* ]]; then
448+
NEWIP="${OLDIP}::$(printf %04x $i)"
449+
else
450+
LAST_CHUNK=$(printf %d 0x${OLDIP##*:})
451+
NEWIP="${OLDIP%:*}:$(printf %02x $(( ($LAST_CHUNK + $i) % 65536 )))"
452+
ip -6 addr show $1 scope global | sed -e 's/ /\n/g' | sed -ne '/inet6/{n;p}' | grep "$NEWIP" > /dev/null 2>&1 || break
453+
fi
454+
done
455+
mutex_unlock
456+
echo $NEWIP
457+
}
458+
437459
# start haveged when needed
438460
haveged_watchdog() {
439461
local show_warn=1
@@ -819,8 +841,10 @@ _cleanup() {
819841
iptables -w -D INPUT -p udp -m udp --dport 67 -j ACCEPT
820842
if [[ $IPV6 -ne 0 ]]; then
821843
ip6tables -w -D INPUT -p udp -m udp --dport 67 -j ACCEPT
822-
ip -6 route del "$INTERNET6"/"$PREFIXLEN6" dev $WIFI_IFACE
823-
ip -6 route replace "$INTERNET6"/"$PREFIXLEN6" dev $INTERNET_IFACE
844+
# Restore original subnet to internet-facing interface
845+
ip -6 addr del "$INTERNET6"/128 dev ${INTERNET_IFACE}
846+
ip -6 addr add "$INTERNET6"/"$PREFIXLEN6" dev ${INTERNET_IFACE}
847+
ip -6 route replace "$INTERNET6"/"$PREFIXLEN6" dev ${INTERNET_IFACE}
824848
fi
825849
fi
826850

@@ -1603,16 +1627,12 @@ if [[ "$SHARE_METHOD" == "bridge" ]]; then
16031627
fi
16041628
elif [[ $IPV6 -ne 0 ]]; then
16051629
echo "Looking up IPv6 address of internet interface..."
1606-
NETADDR6=$(ip -6 addr show $INTERNET_IFACE scope global | sed -e 's/ /\n/g' | sed -ne '/inet6/{n;p}')
1630+
NETADDR6=$(get_ipv6addr $INTERNET_IFACE)
16071631
if [[ -n "$NETADDR6" ]]; then
16081632
INTERNET6="${NETADDR6%/*}"
16091633
PREFIXLEN6="${NETADDR6#*/}"
1610-
# FIXME: this is a dodgy/bad way to pick an IPv6 address.
1611-
# We want a different IPv6 address for the AP (internal),
1612-
# compared to our external IPv6 address, but they need to be
1613-
# in the same /64 subnet. This is the current ugly kludge.
1614-
GATEWAY6="${INTERNET6%:*}":$(printf "%04x" "$(( 0x${INTERNET6##*:} + 1))")
1615-
echo "Got $INTERNET6/$PREFIXLEN6. Will route $GATEWAY6/$PREFIXLEN6 to clients."
1634+
GATEWAY6=$(get_new_ipv6addr $INTERNET_IFACE)
1635+
echo "Internet interface is $INTERNET6/$PREFIXLEN6. Will route $GATEWAY6/$PREFIXLEN6 to wireless clients."
16161636
else
16171637
echo "No IPv6 address found. Disabling IPv6."
16181638
IPV6=0
@@ -1834,11 +1854,14 @@ if [[ "$SHARE_METHOD" != "bridge" ]]; then
18341854
ip link set up dev ${WIFI_IFACE} || die "$VIRTDIEMSG"
18351855
ip addr add ${GATEWAY}/24 broadcast ${GATEWAY%.*}.255 dev ${WIFI_IFACE} || die "$VIRTDIEMSG"
18361856
if [[ $IPV6 -ne 0 ]]; then
1837-
# Keep only /128 for Internet-facing IPv6 address
1857+
# Normally, the Internet-facing device has been assigned a /64 subnet (saved in INTERNET6/PREFIXLEN6).
1858+
# We want to keep only /128 for the Internet-facing device, but route the rest of the subnet to
1859+
# the AP, so that it can be used by clients via DHCPv6 or SLAAC.
1860+
18381861
ip -6 addr del "$INTERNET6"/"$PREFIXLEN6" dev ${INTERNET_IFACE} || die "$VIRTDIEMSG"
18391862
ip -6 addr add "$INTERNET6"/128 dev ${INTERNET_IFACE} || die "$VIRTDIEMSG"
18401863
ip -6 route replace "$INTERNET6"/128 dev ${INTERNET_IFACE} || die "$VIRTDIEMSG"
1841-
# While routing full IPv6 subnet to clients
1864+
18421865
ip -6 addr add "$GATEWAY6"/"$PREFIXLEN6" dev ${WIFI_IFACE} || die "$VIRTDIEMSG"
18431866
ip -6 route replace "$INTERNET6"/"$PREFIXLEN6" dev ${WIFI_IFACE} || die "$VIRTDIEMSG"
18441867
fi

0 commit comments

Comments
 (0)