Submitted By: DJ Lucas (dj at linuxfromscratch dot org) Date: 2008-05-27 Initial Package Version: 3.0.2 Origin: Bruce Dubbs, Kevin Fleming, Jim Gifford, and DJ Lucas Description: Modifies client script to use only iproute2 Upstream Status: Submitted diff -Naur dhcp-4.0.0-orig/client/scripts/linux dhcp-4.0.0/client/scripts/linux --- dhcp-4.0.0-orig/client/scripts/linux 2007-06-06 17:57:32.000000000 -0500 +++ dhcp-4.0.0/client/scripts/linux 2008-05-26 23:59:24.000000000 -0500 @@ -1,26 +1,18 @@ #!/bin/bash # dhclient-script for Linux. Dan Halbert, March, 1997. # Updated for Linux 2.[12] by Brian J. Murrell, January 1999. -# No guarantees about this. I'm a novice at the details of Linux -# networking. +# iproute2 update for IPv4 addresses courtesy of +# Linux From Scratch (www.linuxfromscratch.org) May 2008. # Notes: -# 0. This script is based on the netbsd script supplied with dhcp-970306. +# This script is based on the netbsd script supplied with dhcp-970306. -# 1. ifconfig down apparently deletes all relevant routes and flushes -# the arp cache, so this doesn't need to be done explicitly. - -# 2. The alias address handling here has not been tested AT ALL. -# I'm just going by the doc of modern Linux ip aliasing, which uses -# notations like eth0:0, eth0:1, for each alias. - -# 3. I have to calculate the network address, and calculate the broadcast -# address if it is not supplied. This might be much more easily done -# by the dhclient C code, and passed on. - -# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious -# of the $1 in its args. +# Updated to use ip for IPv4 addresses. Older versions of iproute2 only +# allow CIDR notation. The cidr_convert() function and its helpers, +# dec2binary() and mask_to_binary() were added to account for this in the +# IPv4 parts. Contributions by Bruce Dubbs, Kevin Fleming, Jim Gifford, +# and DJ Lucas. # 'ip' just looks too weird. /sbin/ip looks less weird. ip=/sbin/ip @@ -57,6 +49,27 @@ fi } +dec_to_bin() { + local n=$1 + local ret="" + while [ $n != 0 ]; do + ret=$[$n%2]$ret + n=$[$n>>1] + done + echo $ret +} + +mask_to_bin() { + echo `dec_to_bin $1``dec_to_bin $2``dec_to_bin $3``dec_to_bin $4` +} + +cidr_convert() { + netmask=$1 + local mask=`mask_to_bin ${netmask//./ }` + mask=${mask%%0*} + echo ${#mask} +} + # Must be used on exit. Invokes the local dhcp client exit hooks, if any. exit_with_hooks() { exit_status=$1 @@ -78,11 +91,6 @@ fi fi -release=`uname -r` -release=`expr $release : '\(.*\)\..*'` -relminor=`echo $release |sed -e 's/[0-9]*\.\([0-9][0-9]*\)\(\..*\)*$/\1/'` -relmajor=`echo $release |sed -e 's/\([0-9][0-9]*\)\..*$/\1/'` - ### ### DHCPv4 Handlers ### @@ -94,13 +102,10 @@ old_broadcast_arg="broadcast $old_broadcast_address" fi if [ x$new_subnet_mask != x ]; then - new_subnet_arg="netmask $new_subnet_mask" + new_subnet_arg=`cidr_convert $new_subnet_mask` fi if [ x$old_subnet_mask != x ]; then - old_subnet_arg="netmask $old_subnet_mask" -fi -if [ x$alias_subnet_mask != x ]; then - alias_subnet_arg="netmask $alias_subnet_mask" + old_subnet_arg=`cidr_convert $old_subnet_mask` fi if [ x$reason = xMEDIUM ]; then @@ -111,17 +116,10 @@ if [ x$reason = xPREINIT ]; then if [ x$alias_ip_address != x ]; then # Bring down alias interface. Its routes will disappear too. - ifconfig $interface:0- inet 0 - fi - if [ $relmajor -lt 2 ] || ( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ) - then - ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \ - broadcast 255.255.255.255 up - # Add route to make broadcast work. Do not omit netmask. - route add default dev $interface netmask 0.0.0.0 - else - ifconfig $interface 0 up + ${ip} link set $interface down + ${ip} addr del $alias_ip_address dev $interface fi + ${ip} link set $interface up # We need to give the kernel some time to get the interface up. sleep 1 @@ -144,82 +142,52 @@ fi fi - if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \ - [ x$alias_ip_address != x$old_ip_address ]; then - # Possible new alias. Remove old alias. - ifconfig $interface:0- inet 0 - fi if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then - # IP address changed. Bringing down the interface will delete all routes, - # and clear the ARP cache. - ifconfig $interface inet 0 down + # IP address changed. Bring down the interface, delete all routes, and + # clear the ARP cache. + ${ip} link set $interface down + ${ip} addr flush dev $interface fi if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \ [ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then - ifconfig $interface inet $new_ip_address $new_subnet_arg \ - $new_broadcast_arg - # Add a network route to the computed network address. - if [ $relmajor -lt 2 ] || \ - ( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ); then - route add -net $new_network_number $new_subnet_arg dev $interface - fi + ${ip} link set $interface up + ${ip} addr add $new_ip_address/$new_subnet_arg $new_broadcast_arg \ + label $interface dev $interface + +# Add a network route to the computed network address. for router in $new_routers; do - route add default gw $router + ${ip} route add default via $router done fi - if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ]; - then - ifconfig $interface:0- inet 0 - ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg - route add -host $alias_ip_address $interface:0 - fi make_resolv_conf exit_with_hooks 0 fi if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ] || [ x$reason = xRELEASE ] \ || [ x$reason = xSTOP ]; then - if [ x$alias_ip_address != x ]; then - # Turn off alias interface. - ifconfig $interface:0- inet 0 - fi if [ x$old_ip_address != x ]; then - # Shut down interface, which will delete routes and clear arp cache. - ifconfig $interface inet 0 down - fi - if [ x$alias_ip_address != x ]; then - ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg - route add -host $alias_ip_address $interface:0 + # Shut down interface, delete routes, and clear arp cache. + ${ip} link set $interface down + ${ip} addr flush dev $interface fi exit_with_hooks 0 fi if [ x$reason = xTIMEOUT ]; then - if [ x$alias_ip_address != x ]; then - ifconfig $interface:0- inet 0 - fi - ifconfig $interface inet $new_ip_address $new_subnet_arg \ - $new_broadcast_arg + ${ip} link set $interface up + ${ip} addr set $new_ip_address/$new_subnet_arg $new_broadcast_arg \ + label $interface dev $interface set $new_routers - if ping -q -c 1 $1; then - if [ x$new_ip_address != x$alias_ip_address ] && \ - [ x$alias_ip_address != x ]; then - ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg - route add -host $alias_ip_address dev $interface:0 - fi - if [ $relmajor -lt 2 ] || \ - ( [ $relmajor -eq 2 ] && [ $relminor -eq 0 ] ); then - route add -net $new_network_number - fi - for router in $new_routers; do - route add default gw $router - done - make_resolv_conf - exit_with_hooks 0 - fi - ifconfig $interface inet 0 down + for router in $new_routers; do + ${ip} route add default via $router + done + + make_resolv_conf + exit_with_hooks 0 + ${ip} link set $interface down + ${ip} addr flush dev $interface exit_with_hooks 1 fi