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