Re: force/alter ipv6 source address selection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Brian Kroth <bpkroth@xxxxxxxxx> 2010-07-02 18:46:
> I'm curious if anyone knows how to force or influence the default source
> address selection algorithm for ipv6 in linux.
> 
> For manually assigned addresses I'm aware of the trick of setting
> "preferred_lft 0" on all the other addresses so that it avoids
> deprecated addresses.
> 
> I've read a little bit about the addrlabel infrastructure but can't seem
> to get it to do what I want.  Perhaps I'm missing something there.
> 
> In brief my testing situation is this:
> - radvd sends 6to4 prefix router adverts.
> - The ipv4 address backing that is dynamic so the 6to4 prefix changes,
>   so I can't use it for static addresses, only for external connectivity
>   (ignoring dhcpv6).
> - So, I have a unique local address range (fded::/32) used for internal
>   ipv6 connectivity where I can manually assign addresses to servers.
> - I want to use that same range for dynamic clients so I leave router
>   adverts on.
> - I can't shutoff the sysctl autoconf on the interface else I'd lose the
>   global connectivity.
> - The trouble is that for routing within the local address range the
>   dynamically chosen address (eg: fded:2::5054:ff:fe10:eca8/64) is
>   chosen over the statically assigned one (fded:2::2:1/64).
> 
> This is a little convoluted I know, but more generally I'd like to know
> if/how to be able to force or at least strongly suggest a particular
> outgoing source address over another (subject to other routing rules).
> Basically I think this is given in the "implementation specific rules"
> note in rule 8 of the rfc 3484.
> 
> The current situation is problematic for programs that key some
> authentication features off of the source address (eg: cfengine).  It's
> also preferable to have a known address with PTR records for some
> connections for logging purposes and the like.  It's not always possible
> to force the application to bind to a particular address and I'd like to
> know if it's possible to do it in a system wide way.
> 
> I ran across this post [1] that claims that at least for opensolaris
> they might provide some way to prefer dhcp or manually assigned
> addresses over autoconfigured ones.
> 
> Another question that just occurred to me is: 
> can the stateless configuration algorithm be adjusted to do something
> like the following?
> - try the user's configured first choice host addr (subject to duplicate
>   address detection)
> - failback to eui64, tempaddr, or whatever else
> 
> 
> Obviously I'm still working through some of the ipv6 implementation
> details.  Let me know if you have any questions.
> 
> Thanks for your thoughts/ideas,
> Brian
> 
> [1] http://mail.opensolaris.org/pipermail/opensolaris-arc/2006-October/000728.html

A minor follow up.  I wrote a Debian style if-up.d script that should
hack in an "avoid EUI-64 addresses for some subnets" with a handful of
caveats (see the script comments).  I still feel like there should be
another method of doing this, so please let me know if you have any
thoughts, ideas, comments, questions, whatever.

Thanks,
Brian
#!/bin/bash
# avoid-eui64-addrs-subnets
# 2010-07-03
# bpkroth
#
# This script reads a space separated list of ipv6 subnets from the
# avoid-eui64-addrs-subnet option in an interfaces stanza to try to hack in an
# avoidance scheme for EUI-64 addresses on a set of subnets that may have
# manual addresses that are preferred to be used as the default source address.
#
# It's written for Debian style ifup systems and meant to be placed/symlinked
# into /etc/network/if-up.d and /etc/network/if-down.d.
#
# Note that it does nothing to choose between manual (or dhcpv6) addresses
# since one can specify "preferred_lft 0" for those addresses that should not
# be used as the default source address (see example below).
#
# Also note that it only handles the EUI-64 address for a single interface.
#
# Furthermore, it can't handle the case where the use_tempaddr sysctl is in
# use (eg: randomly rotate through addresses).
#
#
# For example:
#
# # This is the default IPv6 address.
# iface eth0 inet6 static
# 	address fded:2::2:1
#	netmask 64
#	gateway fded:2::1
#	avoid-eui64-addrs-subnets fded:2::/64
#
# # This is another service address, but is marked as deprecated so that it
# # isn't used as a default source address.  Moreover, with this method it can
# # be taken up and down individually (eg: ifdown eth0:1)
# iface eth0:1 inet6 manual
# 	up ip addr add fded:2::2:2/64 dev eth0 preferred_lft 0
#	down ip addr del fded:2::2:2/64 dev eth0
#
# See Also:
# http://marc.info/?l=linux-net&m=127811438206347&w=2

. /lib/init/vars.sh
. /lib/lsb/init-functions

# Compose some variables for ease of use later on.
myprog=`basename $0`
mydir=`basename $(dirname $0)`

if [ "$VERBOSE" == 'yes' ]; then
	myverbose=true
else
	myverbose=false
fi

# Check to see if we should actually do anything.
if [ -z "$IF_AVOID_EUI64_ADDRS_SUBNETS" ]; then
	# Option not specified, nothing to do.
	exit 0
fi

# Check for proper start/stop modes.
if [ "$MODE" != 'start' ] && [ "$MODE" != 'stop' ]; then
	log_warning_msg "$mydir/$myprog: script called from the wrong mode '$MODE'"
	exit 0
fi

# Check for some syntax.
if ! echo "$IF_AVOID_EUI64_ADDRS_SUBNETS" | egrep -qi '^(([a-f0-9]{1,4}:){1,4}:/64[ ]+)*([a-f0-9]{1,4}:){1,4}:/64[ ]*$'; then
	log_warning_msg "$mydir/$myprog: invalid avoid-eui64-addrs-subnets syntax"
	exit 0
fi

# Check for some required commands.
if ! [ -x /bin/ip ]; then
	log_warning_msg "$mydir/$myprog: missing required ip command"
	exit 0
fi
if ! [ -x /usr/bin/ipv6calc ]; then
	log_warning_msg "$mydir/$myprog:  missing required ipv6calc command"
	exit 0
fi

# This should handle logical interfaces too, though I think it would be silly
# to put them there.
mymac=`ifconfig $IFACE | awk '( $4 == "HWaddr" ) { print $5 }'`
if ! echo "$mymac" | egrep -qi '^([a-f0-9]{2}:){5}[a-f0-9]{2}$'; then
	log_warning_msg "$mydir/$myprog: couldn't retrieve MAC address for $IFACE"
	exit 0
fi

# Run through our variable arguments.
for mysubnet in $IF_AVOID_EUI64_ADDRS_SUBNETS; do
	# Credit: http://www.tunnelbroker.net/forums/index.php?topic=751.msg3714#msg3714
	myeui64=`ipv6calc --in prefix+mac --action prefixmac2ipv6 --out ipv6addr $mysubnet $mymac | sed -r -e 's|/[0-9]+$|/128|'`

	# See if that address is in the addrlabel system already.
	if ip addrlabel | egrep -qi "^prefix $myeui64 label 99[ ]*$"; then
		if [ "$MODE" == 'stop' ]; then
			$myverbose && echo "$mydir/$myprog: ip addrlabel del prefix $myeui64 label 99"
			ip addrlabel del prefix $myeui64 label 99
		elif [ "$MODE" == 'start' ]; then
			log_warning_msg "$mydir/$myprog: prefix $myeui64 is already setup with label 99, skipping"
		fi
	else
		if [ "$MODE" == 'start' ]; then
			$myverbose && echo "$mydir/$myprog: ip addrlabel add prefix $myeui64 label 99"
			ip addrlabel add prefix $myeui64 label 99
		fi
		if [ "$MODE" == 'stop' ]; then
			log_warning_msg "$mydir/$myprog: no 99 label to clean for prefix $myeui64"
		fi
	fi
done

exit 0

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux