summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouke Witteveen <j.witteveen@gmail.com>2012-05-17 11:01:10 +0200
committerJouke Witteveen <j.witteveen@gmail.com>2012-05-17 11:01:10 +0200
commit0d3e56bf3809b03e1c60a5dce0d7bb8510720369 (patch)
tree78473972a45d9bc675d3c543009c873637024d90 /src
parent91ff1c8c4ee490d113ac25fbca0f4596ca069a7d (diff)
downloadnetctl-0d3e56bf3809b03e1c60a5dce0d7bb8510720369.tar.gz
netctl-0d3e56bf3809b03e1c60a5dce0d7bb8510720369.tar.xz
Wait for DAD when using IPv6 (FS#28887)
In IPv6 you cannot bind to an address as long as it is not determined to be unique through Duplicate Address Detection. This can cause problems when routes in ROUTES6 reference a tentative source address or when something that starts after netcfg tries to. This patch does a few things: - Improve ROUTES(6) logic so that non-static connections can make use of them as intended according to the commit message of c8be1. - Make additional arguments possible for ADDR6 addresses and ROUTES6 routes, such as ADDR6=('1234:5678:9abc:def::1/64 nodad'). - Introduce a DAD_TIMEOUT variable that governs how long to wait for DAD to finish. - Move IPCFG processing to after IPv6 address set-up (it already was after IPv4 address set-up), so that custom commands can be sure to have working addresses. WARNING: This changes make it impossible to use ROUTES6 and set the address through IPCFG instead of ADDR6. This was bad, unsupported practice, but sometimes needed as ADDR6 did not allow config flags to be used. Resolving this issue should be no problem: you should be able to properly use ADDR6 now. If not, then be a real hacker and set the routes through IPCFG too. Many thanks to Steve Caligo for reporting this bug and helping out in finding a solution.
Diffstat (limited to 'src')
-rw-r--r--src/connections/ethernet58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/connections/ethernet b/src/connections/ethernet
index 41d0274..97875f8 100644
--- a/src/connections/ethernet
+++ b/src/connections/ethernet
@@ -14,6 +14,8 @@ report_iproute()
}
ethernet_up() {
+ local dad_timeout="${DAD_TIMEOUT:-3}"
+
load_profile "$1"
SYSCTL_INTERFACE="${INTERFACE/.//}"
@@ -23,7 +25,7 @@ ethernet_up() {
fi
fi
- # Disable IPv6 before the interface to prevent SLAAC
+ # Disable IPv6 before bringing the interface up to prevent SLAAC
if [[ "$IP6" == "no" ]]; then
sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.disable_ipv6=1"
fi
@@ -101,14 +103,6 @@ ethernet_up() {
report_iproute "Could not configure interface"
fi
fi
- if [[ -n "$ROUTES" ]]; then
- for route in "${ROUTES[@]}"; do
- report_debug ethernet_up ip route add $route dev "$INTERFACE"
- if ! ip route add $route dev "$INTERFACE" ; then
- report_iproute "Adding route '$route' failed"
- fi
- done
- fi
if [[ -n "$GATEWAY" ]]; then
report_debug ethernet_up ip route add default via "$GATEWAY" dev "$INTERFACE"
if ! ip route add default via "$GATEWAY" dev "$INTERFACE"; then
@@ -123,12 +117,11 @@ ethernet_up() {
;;
esac
- if [[ -n "$IPCFG" ]]; then
- for line in "${IPCFG[@]}"; do
-
- report_debug ethernet_up ip "$line"
- if ! ip $line; then
- report_iproute "Could not configure interface ($line)."
+ if [[ -n "$IP" && -n "$ROUTES" ]]; then
+ for route in "${ROUTES[@]}"; do
+ report_debug ethernet_up ip route add $route dev "$INTERFACE"
+ if ! ip route add $route dev "$INTERFACE"; then
+ report_iproute "Adding route '$route' failed"
fi
done
fi
@@ -175,9 +168,9 @@ ethernet_up() {
sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.accept_ra=0"
if [[ -n "$ADDR6" ]]; then
for addr in "${ADDR6[@]}"; do
- report_debug ethernet_up ip -6 addr add "$addr" dev "$INTERFACE"
- if ! ip -6 addr add "$addr" dev "$INTERFACE"; then
- report_iproute "Could not add address $addr to interface"
+ report_debug ethernet_up ip -6 addr add $addr dev "$INTERFACE"
+ if ! ip -6 addr add $addr dev "$INTERFACE"; then
+ report_iproute "Could not add address '$addr' to interface"
fi
done
fi
@@ -187,18 +180,38 @@ ethernet_up() {
report_iproute "Adding gateway $GATEWAY6 failed"
fi
fi
+ ;;
+ esac
+
+ if [[ -n "$IP6" ]]; then
+ # Wait for DAD to finish (FS#28887)
+ report_debug ethernet_up ip -6 addr show dev "$INTERFACE" tentative
+ while [[ -n "$(ip -6 addr show dev "$INTERFACE" tentative)" ]]; do
+ if (( dad_timeout-- <= 0 )); then
+ report_iproute "Duplicate Address Detection is taking too long"
+ fi
+ sleep 1
+ done
# Add static IPv6 routes
if [[ -n "$ROUTES6" ]]; then
for route in "${ROUTES6[@]}"; do
- report_debug ethernet_up ip -6 route add "$route" dev "$INTERFACE"
- if ! ip -6 route add "$route" dev "$INTERFACE"; then
+ report_debug ethernet_up ip -6 route add $route dev "$INTERFACE"
+ if ! ip -6 route add $route dev "$INTERFACE"; then
report_iproute "Adding route '$route' failed"
fi
done
fi
- ;;
- esac
+ fi
+
+ if [[ -n "$IPCFG" ]]; then
+ for line in "${IPCFG[@]}"; do
+ report_debug ethernet_up ip "$line"
+ if ! ip $line; then
+ report_iproute "Could not configure interface ($line)."
+ fi
+ done
+ fi
# Set hostname
if [[ -n "$HOSTNAME" ]]; then
@@ -277,4 +290,3 @@ stop_80211x() {
ethernet_$1 "$2"
exit $?
# vim: set ts=4 et sw=4:
-