fa.openbsd.tech
[Top] [All Lists]

dhclient-scipt diff

Subject: dhclient-scipt diff
From: Vadim Zhukov <persgray@xxxxxxxxx>
Date: Thu, 31 Jul 2008 01:15:00 UTC
Newsgroups: fa.openbsd.tech

Hello all.

Since we have working multipath, I considered to update dhclient-script 
to support it. Also I made it more fail-safe - updating routes is now 
real update process, not "remove all and add all". Also a few "XXX" 
comments fixed (correctly, I hope).

I didn't get point of adding routes from bound addresses to 127.0.0.1, so 
I removed them; please correct me if it was wrong.

Runs a few days on my heavily-roaming notebook.

-- 
  Best wishes,
    Vadim Zhukov

--- dhclient-script.orig        Thu Jul 31 01:17:04 2008
+++ dhclient-script     Thu Jul 31 03:46:45 2008
@@ -22,10 +22,17 @@
 # Helper functions that implement common actions.
 #
 
+delete_route() {
+       route -q delete "$@"
+}
+
+add_route() {
+       route add -mpath -nostatic "$@"
+}
+
 delete_old_address() {
        if [ -n "$old_ip_address" ]; then
                ifconfig $interface inet $old_ip_address delete $medium
-               route delete "$old_ip_address" 127.0.0.1 >/dev/null 2>&1
        fi
 }
 
@@ -35,15 +42,11 @@
                netmask $new_subnet_mask \
                broadcast $new_broadcast_address \
                $medium
-
-       # XXX Original TIMEOUT code did not do this unless $new_routers was set?
-       route add $new_ip_address 127.0.0.1 >/dev/null 2>&1
 }
 
 delete_old_alias() {
        if [ -n "$alias_ip_address" ]; then
                ifconfig $interface inet $alias_ip_address delete > /dev/null 
2>&1
-               route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
        fi
 }
 
@@ -51,46 +54,57 @@
        if [ -n "$alias_ip_address" ]; then
                ifconfig $interface inet $alias_ip_address alias netmask \
                    $alias_subnet_mask
-               route add $alias_ip_address 127.0.0.1
        fi
 }
 
-delete_old_routes() {
-       # Delete existing default route. We only allow one, so no need to
-       # process $old_routers list.
-       route delete default >/dev/null 2>&1
+update_routes() {
+       # Do not touch same routes, just remove/add changes, using update
+       # technique if possible.
 
-       if [ -n "$old_static_routes" ]; then
-               set $old_static_routes
-               while [ $# -gt 1 ]; do
-                       route delete "$1" "$2"
-                       shift; shift
-               done
-       fi
-
-       arp -dan
-}
-
-add_new_routes() {
-       route delete default >/dev/null 2>&1
+       all_old_routes="$old_static_routes"
+       for router in $old_routers; do
+               all_old_routes="$all_old_routes default $router"
+       done
+       all_new_routes="$new_static_routes"
        for router in $new_routers; do
-               if [ "$new_ip_address" = "$router" ]; then
-                       route add default -iface $router >/dev/null 2>&1
-               else
-                       route add default $router >/dev/null 2>&1
-               fi
-               # 2nd and subsequent default routers error out, so explicitly
-               # stop processing the list after the first one.
-               break
+               all_new_routes="$all_new_routes default $router"
        done
 
-       if [ -n "$new_static_routes" ]; then
-               set $new_static_routes
-               while [ $# -gt 1 ]; do
-                       route add $1 $2
-                       shift; shift
+       # Since we use multipath and do not touch same routes, we can safely
+       # add new routes before removing old.
+       if [ -n "$all_old_routes" ]; then
+               set -A routes -- $all_new_routes
+               while [ "${#routes[@]}" -ge 2 ]; do
+                       set -- "${routes[@]}"
+                       dst="$1"; shift
+                       gtw="$2"; shift
+                       set -A routes -- "$@"
+                       set -- $all_old_routes
+                       while [ "$#" -ge 2 ]; do
+                               if [ "$gtw" = "$1" -a "$gtw" = "$2" ]; then
+                                       continue 2
+                               fi
+                       done
+                       add_route "$dst" "$gtw"
                done
+
+               set -A routes -- $all_old_routes
+               while [ "${#routes[@]}" -ge 2 ]; do
+                       set -- "${routes[@]}"
+                       dst="$1"; shift
+                       gtw="$2"; shift
+                       set -A routes -- "$@"
+                       set -- $all_new_routes
+                       while [ "$#" -ge 2 ]; do
+                               if [ "$dst" = "$1" -a "$gtw" = "$2" ]; then
+                                       continue 2
+                               fi
+                       done
+                       delete_route "$dst" "$gtw"
+               done
        fi
+
+       arp -dan
 }
 
 add_new_resolv_conf() {
@@ -162,7 +176,6 @@
                fi
                if [ "$old_ip_address" != "$new_ip_address" ]; then
                        delete_old_address
-                       delete_old_routes
                fi
        fi
        if [ "$reason" = BOUND ] ||
@@ -170,11 +183,11 @@
           [ -z "$old_ip_address" ] ||
           [ "$old_ip_address" != "$new_ip_address" ]; then
                add_new_address
-               add_new_routes
        fi
        if [ "$new_ip_address" != "$alias_ip_address" ]; then
                add_new_alias
        fi
+       update_routes
        add_new_resolv_conf
        ;;
 
@@ -182,12 +195,13 @@
        delete_old_alias
        if [ -n "$old_ip_address" ]; then
                delete_old_address
-               delete_old_routes
+               update_routes
        fi
-       # XXX Why add alias we just deleted above?
+       # Add alias we just deleted above - it's intended to be used in
+       # non-DHCP enviornments as a "safe default", see dhclient.conf(5).
        add_new_alias
        if [ -f /etc/resolv.conf.save ]; then
-               cat /etc/resolv.conf.save > /etc/resolv.conf
+               mv /etc/resolv.conf.save /etc/resolv.conf
        fi
        ;;
 
@@ -196,21 +210,36 @@
        add_new_address
        sleep 1
        if [ -n "$new_routers" ]; then
-               set "$new_routers"
-               if ping -q -c 1 -w 1 "$1"; then
-                       if [ "$new_ip_address" != "$alias_ip_address" ]; then
-                               add_new_alias
+               # Set up provided configuration if any default route specified
+               # could be reached.
+               set -- "$new_routers"
+               while [ "$#" -gt 0 ]; do
+                       if ping -q -c 1 -w 1 "$1"; then
+                               if [ "$new_ip_address" != "$alias_ip_address" ]
+                               then
+                                       add_new_alias
+                               fi
+                               update_routes
+                               if add_new_resolv_conf; then
+                                       exit 0
+                               fi
                        fi
-                       add_new_routes
-                       if add_new_resolv_conf; then
-                               exit 0
-                       fi
-               fi
+                       shift
+               done
+       else
+               # Preserve static routes, they can be used even without default
+               update_routes
+               exit 0
        fi
+
+       # Do not call delete_old_address() and remove "new" IP address instead
+       # because there may be no "old" address if we timed out from beginning.
        ifconfig $interface inet $new_ip_address delete $medium
-       # XXX Why not a delete_old_address as before all other invocations of
-       #     delete_old_routes?
-       delete_old_routes
+
+       # Force removing all "old" routes
+       new_routers=""
+       new_static_routes=""
+       update_routes
        exit 1
        ;;
 esac


<Prev in Thread] Current Thread [Next in Thread>
  • dhclient-scipt diff, Vadim Zhukov <=