I have a network that advertises IPv6 addresses through IPv6 autoconfig. To allow DNS lookups and to have fancy IP addresses, we setup "static" IPv6 addresses through /etc/network/interfaces:

auto eth0
iface eth0 inet dhcp
iface eth0 inet6 static
    address a:b:c:d:e::f 
    netmask 64

Whenever we now connect through IPv6 Linux uses the IPv6 autoconfig address:


and not the static IPv6 address:


A server on the other side only sees the autoconfig address.

Is there a way to force linux (Debian/Ubuntu) to use the static address for outgoing packets? This is especially interesting for reverse DNS and firewall settings.

I don't want to disable the IPv6 autoconfig since I don't have control over the settings the router advertises.

  • I don't know what you mean by "advertise". Do you mean source IP address selection for outbound packets?
    – Celada
    Jun 19, 2012 at 17:10
  • yes, exactly. Whenever I go on a website the OS uses the autoconfig address. Both addresses are pingable though.
    – Pascal
    Jun 19, 2012 at 19:03
  • There seems to be the file /etc/gai.conf that configures the IPv6 address precedence but I don't think it's a good idea to hardcode the IPv6 address from /etc/network/interfaces in said file... (Man page: linux.die.net/man/5/gai.conf )
    – Pascal
    Jun 19, 2012 at 19:07
  • What is the point of autoconfiguring an address you aren't going to use? If you're using DNS then why not add a DNS entry for your autoconfigured IPv6 addresses? They are based on your MAC address so do not change. Really if you're trying to remember or use IPv6 addresses you're doing something wrong - they're too big. And if you're not using v6 addresses but instead using hostnames, who cares what the actual address is?
    – grifferz
    Jun 19, 2012 at 19:36
  • @grifferz IP addresses with easy-to-remember patterns in them are extremely valuable when you're deep in troubleshooting, watching packet captures and routing tables, and trying to tell one address from the other. It also comes in handy if you've got virtual IP addresses (possibly as part of a high availability cluster) specific to each service. 2001:db8::80 is obviously the web server VIP, and 2001:db8::143 is obviously the IMAP server VIP. This is as true in IPv6 as it ever was in IPv4.
    – Celada
    Jun 19, 2012 at 20:18

1 Answer 1


Of course the easiest way to prevent the autoconf addresses from getting used is to prevent the kernel from creating them by doing something like this:

echo 0 >/proc/sys/net/ipv6/conf/eth0/autoconf

Notice how this doesn't require you to reconfigure the router so that it stops emiting advertisements for the prefix.

NOTE in the comments, you talk about /etc/gai.conf, but this is not applicable. This is a configuration file of glibc, not the kernel, and it influences the destination address selection, not the source address selection.

If you still want to have the autoconf addresses present but you don't want them to get used, then read on...

For communications between hosts on the same network

I couldn't find a good way to force the address selection to prefer the static address over the autoconf one. By looking at all of the rules of RFC 3484 none of them were really helpful.

You can try to change the /64 route in your routing table for the connected subnet so that it has a "src" attribute, but it is autogenerated by the kernel when any of the addresses in the subnet are added to the interface and I was unsuccessful in editing it after the fact.

For communications with hosts on the rest of the internet

There are several ways you could influence the address selection for outbound connections. The most obvious is to use the src attribute on routes. For example:

ip route add ::/0 via <gateway> src <desired-source-IP-address>

But maybe your default route comes from a router advertisement message and is automatically inserted by the kernel. In that case it is impossible for you to give a "src" attribute for the route. So here is another method, based on configuring address labels.

By default, in Linux, the kernel's address label table looks like this:

prefix ::1/128 label 0
prefix ::/96 label 3
prefix ::ffff: label 4
prefix 2001::/32 label 6
prefix 2001:10::/28 label 7
prefix 2002::/16 label 2
prefix fc00::/7 label 5
prefix ::/0 label 1

The idea is that, when initiating a packet to a destination address with label x, the kernel prefers to use a source address with the same label x. So for example, if you send a packet to a host with a 6to4 address (that's an address in 2002::/16), the label for that is 2, and the kernel will prefer to select a 6to4 source address for the outgoing packet, if there is one available.

General IPv6 destinations get label 1 (::/0, which matches everything). Here's what you want to do:

  • Override the label assignment for the local subnet so that addresses on the local subnet get a "martian" label (a label that is not used by anything else). This rule will match the whole subnet so it will be /64.
  • Re-override the label assignment for the desired static address to set it back to 1 (that is, the same label as the rest of the Internet addresses get). This rule is going to match just the specific desired address so it will be /128.

This way, all of those autoconf addresses on the local subnet will get a martian label that won't match up with the label of anything else on the internet, so they will not be preferred, while the label for the desired source address will be 1, so it will match up with the destination address and get chosen.

If your prefix is 2001:db8::/64 and your chosen static address is 2001:db8::aaaa/128 then:

ip addrlabel add prefix 2001:db8::/64 label 99
ip addrlabel add prefix 2001:db8::aaaa/128 label 1

You could add these two commands as up commands in /etc/network/interfaces so that they get executed every time the interface comes up.

  • I will have to try setting the addresslabel prefix tomorrow. This also allows us to enforce using the global IP in the link local context.
    – Pascal
    Jun 19, 2012 at 20:44
  • I do not think that address labels allow you to enforce using the global IP in the link local context. link-local is a separate scope. See Rule #2 in RFC 3484.
    – Celada
    Jun 19, 2012 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.