[prev in list] [next in list] [prev in thread] [next in thread]
List: dhcp-client
Subject: Re: Using dhclient for IP-Aliasing
From: "Schulz, Martin" <martin.schulz () eds ! com>
Date: 2000-03-22 14:12:59
[Download RAW message or body]
*** From dhcp-client -- To unsubscribe, see the end of this message. ***
"Rasmus Ronlev" wrote:
>
> Hi,
>
> I just (today) downloaded the dhcp(d) utilities, as in the source
> distribution: dhcp-3.0b1pl13.tar.gz, and played arround with it for all
> day long (now into the night, having no life a friday night :).
>
> I think I've studied the README + man pages rather carefully, but a
> solution for my needs still seem far away. What I want to do is the
> following:
>
> - To set up a 'secondary' IP, on a mashine, that has and is supposed to
> run with a fixed IP. The secondary IP would have to be obtained using
> dhcp (dhclient), as it is not needed to be a fixed IP, and the network
> admin doesn't feel that I should tie up more than one IP from the 'fixed
> IP address pool'.
>
> The fixed IP is running without problems on the eth0 device of a Linux
> 2.2.14 kernel based system. The IP obtained through dhcp should be
> assigned to eth0:0.
> What I'm looking for here, is how to make that happen using dhclient (+
> a script, if this is nessecary - as it seems to be :).
>
> The idea solution would be to have two scripts, one to run, to optain an
> IP from the dhcp server, and another one to kill the IP and release it
> to the dhcp server, as I do not always need an alias'ed IP address on
> the mashine, just for uses sometimes (which is also why I didn't just
> get a 2nd fixed IP).
>
> When I try to run dhclient with the parameters: dhclient eth0:0 I get an
> error, that the script (that comes with the source) can not bind to the
> device, and the script just loops, if I run dhclient without any
> parameters, with the interface "eth0:0" { ... statement in the
> /etc/dhcleint.conf file. So, I'm pretty much buggered, and would
> appreciate any insight any people might have to get the outlined setup
> running.
>
> Regards,
> Rasmus Ronlev, rasmus@ronlev.com
>
>
I've had a similar experience, being flabberghasted by the absence of a
decent 'model' of the client IP management. (Is the interface to be reset?
Are aliases to be preserved? etc.). But then I haven't bothered to read the
RFC either.
The beauty is that the client logic is dealt with in dhclient-script, so you
can do there what you want.
The pity is that the linux default script is so-so.
The dhclient.conf allows you to declare an alias, which is duefully passed
on to the dhclient-script, where it gets (not so duefully) clobbered.
Here's what I did to get the dhclient-script 'respect' my alias (not a claim
to fame, but works fine for me):
# in /etc/dhclient.conf:
alias {
interface "eth0";
fixed-address 192.168.100.100;
option subnet-mask 255.255.255.0;
option domain-name "mydomain";
option broadcast-address 192.168.100.255;
}
Then use a modified dhclient-script like the attached. It's still attached,
isn't it?
Setting up multiple IP addresses under Linux 2.2 is trivial, once you use
the right tool.
(The older :0 aliasing syntax is deprecated and not necessary at all)
However, here's the double catch:
1) You need the 'ip' program (which is useful in its own right):
Download iproute2 from ftp://ftp.inr.ac.ru/ip-routing/ or simply
ftp://rpmfind.net/linux/SuSE-Linux/i386/6.3/suse/n1/iproute2.rpm
2) The ip programs expects its subnet masks as simple ints 0-32 (#of hi
bits set in mask),
and for simplicity the script expects these to be set in the
new_mask_bits and
alias_mask_bits shell/environment variables.
To get around point 2, either compute the _mask_bits from the _mask
variables or patch
the dhclient source (v. 2.0) as follows (sorry if netscape screwed up
the paste with spaces):
diff -rc dhcp-2.0/client/dhclient.c dhcp-2.0-new/client/dhclient.c
*** dhcp-2.0/client/dhclient.c Tue Jun 22 09:36:46 1999
--- dhcp-2.0-new/client/dhclient.c Sun Jan 9 23:48:21 2000
***************
*** 1936,1941 ****
--- 1936,1942 ----
struct client_lease *lease;
{
int i;
+ int mask_bits;
u_int8_t dbuf [1500];
int len;
***************
*** 1961,1970 ****
--- 1962,1977 ----
netmask.len = lease -> options [DHO_SUBNET_MASK].len;
subnet = subnet_number (lease -> address, netmask);
+ mask_bits = subnet_bits (netmask);
if (subnet.len) {
fprintf (scriptFile,
"%snetwork_number=\"%s\";\n",
prefix, piaddr (subnet));
fprintf (scriptFile, "export
%snetwork_number\n",
+ prefix);
+
+ fprintf (scriptFile, "%smask_bits=\"%d\";\n",
+ prefix, mask_bits);
+ fprintf (scriptFile, "export %smask_bits\n",
prefix);
if (!lease -> options
[DHO_BROADCAST_ADDRESS].len) {
*** dhcp-2.0/common/inet.c Sat Apr 24 12:48:10 1999
--- dhcp-2.0-new/common/inet.c Sun Jan 9 23:48:21 2000
***************
*** 68,73 ****
--- 68,90 ----
return rv;
}
+ int subnet_bits (mask)
+ struct iaddr mask;
+ {
+ int i;
+ int m;
+ int bits = 0;
+ for (i = 0; i < mask.len && (m = mask.iabuf[i]); i++) {
+
+ while ( m & 0x80 ) {
+ m &= ~0x80;
+ m <<=1;
+ bits++;
+ }
+ }
+ return bits;
+ }
+
/* Combine a network number and a integer to produce an internet
address.
This won't work for subnets with more than 32 bits of host address,
but
maybe this isn't a problem.
*/
I'm pretty sure that's just as easy to do in version 3.0.
Enjoy and let me know what you think...
Martin
-- Attached file included as plaintext by Listar --
-- File: dhclient-script
#!/bin/sh
# Invoke the local dhcp client exit hooks, if any.
function exit_with_hooks() {
exit_status=$1
if [ -x /etc/dhclient-exit-hooks ]; then
. /etc/dhclient-exit-hooks
fi
# probably should do something with exit status of the local script
exit $exit_status
}
function update_resolv_conf
{
if [ ! -z "$new_domain_name" -o ! -z "$new_domain_name_servers" ]
then
cp /etc/resolv.conf /tmp/resolv.conf.dhclient
if [ ! -z "$new_domain_name" ]
then
grep -q '^[ \t]*search[ \t][ \t]*'"$new_domain_name" /tmp/resolv.conf.dhclient || \
echo search $new_domain_name >>/tmp/resolv.conf.dhclient
fi
if [ ! -z "$new_domain_name_servers" ]
then
for nameserver in $new_domain_name_servers; do
grep -q '^[ \t]*nameserver[ \t][ \t]*'"$nameserver" /tmp/resolv.conf.dhclient || \
echo nameserver $nameserver >>/tmp/resolv.conf.dhclient
done
fi
if [ ! -f /etc/resolv.conf ] \
|| ! diff -q /etc/resolv.conf /tmp/resolv.conf.dhclient
then
if [ -f /etc/resolv.conf ]
then
ln /etc/resolv.conf /etc/resolv.conf.bak
fi
mv /tmp/resolv.conf.dhclient /etc/resolv.conf
fi
fi
}
function config_routers
{
if [ ! -z "$new_routers" ]
then
for router in $new_routers
do
route add default gw $router
done
else
status=1
fi
}
status=0
# Invoke the local dhcp client enter hooks, if they exist.
if [ -x /etc/dhclient-enter-hooks ]; then
exit_status=0
. /etc/dhclient-enter-hooks
# allow the local script to abort processing of this state
# local script must set exit_status variable to nonzero.
if [ $exit_status -ne 0 ]; then
exit $exit_status
fi
fi
if [ ! -z "$new_broadcast_address" ]
then
new_broadcast_arg="broadcast $new_broadcast_address"
fi
if [ ! -z "$old_broadcast_address" ]
then
old_broadcast_arg="broadcast $old_broadcast_address"
fi
if [ ! -z "$alias_broadcast_address" ]
then
alias_broadcast_arg="broadcast $alias_broadcast_address"
fi
if [ ! -z "$new_subnet_mask" ]
then
new_subnet_arg="netmask $new_subnet_mask"
fi
if [ ! -z "$old_subnet_mask" ]
then
old_subnet_arg="netmask $old_subnet_mask"
fi
if [ ! -z "$alias_subnet_mask" ]
then
alias_subnet_arg="netmask $alias_subnet_mask"
fi
case "$reason" in
MEDIUM)
exit_with_hooks 0
;;
PREINIT)
if [ ! -z "$alias_ip_address" ]
then
# Don't delete the alias interface! Add it!
# ip addr del $alias_ip_address dev $interface
ip addr add $alias_ip_address/$alias_mask_bits \
$alias_broadcast_arg dev $interface
fi
if [ ! -z "$old_ip_address" ]
then
ip addr del $old_ip_address dev $interface
else
ip addr del 0 dev $interface
fi
ip addr add 0/32 broadcast 255.255.255.255 dev $interface
ifconfig $interface up
# We need to give the kernel some time to get the interface up.
sleep 1
exit_with_hooks 0
;;
ARPCHECK|ARPSEND)
exit_with_hooks 0
;;
BOUND|RENEW|REBIND|REBOOT)
if [ ! -z "$old_ip_address" -a ! -z "$alias_ip_address" -a \
"$alias_ip_address" != "$old_ip_address" ]
then
# Possible new alias. Remove old alias.
ip addr del $alias_ip_address dev $interface
fi
if [ ! -z "$old_ip_address" -a "$old_ip_address" != "$new_ip_address" ]
then
# IP address changed. Bringing down the interface will delete all routes,
# and clear the ARP cache.
ifconfig $interface inet down
fi
if [ -z "$old_ip_address" -o "$reason" = "BOUND" -o "$reason" = "REBOOT" ]
then
if [ ! -z "$new_ip_address" ]
then
ip addr add $new_ip_address/$new_mask_bits \
$new_broadcast_arg dev $interface
fi
# Add a network route to the computed network address.
config_routers
fi
if [ "$new_ip_address" != "$alias_ip_address" -a ! -z "$alias_ip_address" ];
then
ip addr add $alias_ip_address/$alias_mask_bits \
$alias_broadcast_arg dev $interface
fi
update_resolv_conf
exit_with_hooks 0
;;
EXPIRE|FAIL)
if [ ! -z "$alias_ip_address" ]
then
# Turn off alias interface.
ip addr del $alias_ip_address dev $interface
fi
if [ ! -z "$old_ip_address" ]
then
# Shut down interface, which will delete routes and clear arp cache.
ifconfig $interface inet down
fi
if [ ! -z "$alias_ip_address" ]
then
ip addr add $alias_ip_address/$alias_mask_bits \
$alias_broadcast_arg dev $interface
fi
exit_with_hooks 0
;;
TIMEOUT)
if [ ! -z "$alias_ip_address" ]
then
ip addr del $alias_ip_address dev $interface
fi
ip addr add $new_ip_address/$new_mask_bits \
$new_broadcast_arg dev $interface
if [ "$new_ip_address" != "$alias_ip_address" -a ! -z "$alias_ip_address" ]
then
ip addr add $alias_ip_address/$alias_mask_bits \
$alias_broadcast_arg dev $interface
fi
if [ ! -z "$new_routers" ]
then
set $new_routers
ping -q -c 1 -i 1 $1 && config_routers
fi
update_resolv_conf
;;
esac
exit_with_hooks $status
-----------------------------------------------------------------------
To unsubscribe from this list, visit http://www.isc.org/dhcp-lists.html
or send mail to dhcp-client-request@isc.org with the subject line of
'unsubscribe'.
-----------------------------------------------------------------------
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic