Bug 250942

Summary: IPv6 setup: fix default IPv6 address to IPV6ADDR in case of IPV6ADDR_SECONDARIES are used
Product: [Fedora] Fedora Reporter: Peter Bieringer <pb>
Component: initscriptsAssignee: Bill Nottingham <notting>
Status: CLOSED WONTFIX QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 7CC: denis, pekkas, russ+bugzilla-redhat, rvokal
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-08-06 21:48:32 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Patch to fix the address order
none
Different method, depending on used kernel version none

Description Peter Bieringer 2007-08-05 19:32:23 UTC
Cloned for F7 to bring this patch into production, because I heard nothing since
 long time that kernel would change the order.

initscripts-8.54.1-1


+++ This bug was initially created as a clone of Bug #199862 +++

Description of problem:
If an additional IPv6 address is added to an interface, this address would be
the primary address for outgoing connections (if scope is proper).

Version-Release number of selected component (if applicable):
initscripts-7.93.24.EL
kernel-2.6.9-34.0.2.EL

How reproducible:
always after reboot

Steps to Reproduce:
1. extend interface configuration for IPv6 like:

/etc/sysconfig/network-scripts/ifcfg-eth0
...

# IPv6
IPV6INIT="yes"
IPV6ADDR="2001:db8:0:1::162:1/64"
IPV6ADDR_SECONDARIES="2001:db8:0:1::188:1/64 2001:db8:0:1::189:1/64
2001:db8:0:1::190:1/64"
IPV6_DEFAULTGW="2001:db8:0:1::1"
IPV6_AUTOCONF="no"

2. initializie network
3. telnet/ssh to an IPv6 enabled destination
  
Actual results:
outgoing source address would be 2001:db8:0:1::190:1

As described, the last one added 
# ip -6 addr show dev eth0 | grep inet6 | grep global
    inet6 2001:db8:0:1::190:1/64 scope global
    inet6 2001:db8:0:1::189:1/64 scope global
    inet6 2001:db8:0:1::188:1/64 scope global
    inet6 2001:db8:0:1::162:1/64 scope global


Expected results:
Use of 2001:db8:0:1::162:1 as primary address for outgoing connections.

Additional info:

A simple patch to ifup-ipv6 solves this issue. In case of IPV6ADDR_SECONDARIES
are defined, after applying the addresses, IPV6ADDR is removed and readded to
the interface. This causes that IPV6ADDR is now the first one in the list and
therefore used as primary address for outgoing connections.

-- Additional comment from pb on 2006-07-23 08:25 EST --
Created an attachment (id=132881)
Patch which remove and readd IPV6ADDR in case of IPV6ADDR_SECONDARIES are defined


-- Additional comment from pb on 2006-07-23 15:18 EST --
Created an attachment (id=132887)
Patch which remove and readd IPV6ADDR in case of IPV6ADDR_SECONDARIES are
defined

Improved patch which checks whether IPV6ADDR is really not the first one in
list after IPV6ADDR_SECONDARIES are added. If not, remove and readd it. This
patch should be safe for the future.

-- Additional comment from notting on 2006-07-24 10:37 EST --
Can't you just set the secondary addresses with a specific scope when you add them?

-- Additional comment from pb on 2006-07-24 11:52 EST --
Specific scope doesn't help, because all addresses are global scope (they are
alias addresses for specific services to move them more or less transparent to
another host).
Flag "primary" would help, but looks like not supported in IPv6 (never seen and
"ip" doesn't support it, too). 

-- Additional comment from notting on 2006-07-24 12:08 EST --
Hm. You could also set the source address on the route itself...

-- Additional comment from pb on 2006-07-24 12:19 EST --
"ip -6 route add" accepts "src <address>" but didn't show this in routing table
and it's also not working here.

 



-- Additional comment from notting on 2006-07-24 12:47 EST --
Ugh. Add/remove just seems wrong. Is default *always* the last one added? Could
the order be reversed (add secondaries, then primary)?

-- Additional comment from pb on 2006-07-24 18:37 EST --
Current behavior (don't know the reason, perhaps Pekka or better Alexey [if
still working on the IPv6 kernel part] have more information why kernel does
this), is, that for new (at least - UDP not tested) TCP connections, the first
one shown in list is used (ping6 has a different behavior here at least on FC5,
it always using the first added one - perhaps a local issue here...).

Anyway, my 2nd patch checks, whether IPV6ADDR is *not* the first one in list, if
so, it would be removed and readded.

If we add the secondaries before the primary address in an unconditional way,
and sometimes in the future the behavior of adding addresses would change, mean
order will be kept instead of stack-behavior (last added will be first in list),
we run into a problem. Because we currently cannot expect, which kernel version
act as current or not, but assuming first address in list is the primary, my
current patch would be the fail-safest one I think.



-- Additional comment from notting on 2006-07-24 20:39 EST --
I don't like it; removing and readding addresses is just a bad hack. We should
find a scalable way to do this, by finding some way to set the address as primary.

I should probably try and track down a networking guru.

-- Additional comment from pb on 2006-07-25 02:08 EST --
I agree, that this is a bad hack, but at time of writing the only method I know
about.

-- Additional comment from pb on 2006-08-17 05:12 EST --
Do you get any news from the network gurus inbetween? 

-- Additional comment from notting on 2006-08-17 09:58 EST --
Not as of yet.

-- Additional comment from pb on 2006-08-22 01:49 EST --
I got response to a posting on netdev list:
http://www.mail-archive.com/netdev@vger.kernel.org/msg20021.html

It's an implementation decission and looks like this would be not changed. And
it looks like also that there is no flag to set a primary adddress.

What now? Implement my workaround in initscripts?

-- Additional comment from notting on 2006-08-22 11:37 EST --
How about the policy table suggestion?

-- Additional comment from pb on 2006-08-22 15:09 EST --
Do you know how it works? /etc/gai.conf is only working for destination
addresses as far as I understood, but we need a policy for the source address
(which can be of course from the same subnet, which makes selection sure more
difficult).

-- Additional comment from pb on 2006-08-25 08:02 EST --
I still got no information how to select src address in Linux, no response to my
posting:
http://www.linux-ipv6.org/ml/usagi-users/msg03687.html

Can it be that Linux misses support at all for this issue.

BTW: my current workaround works fine on all my systems here.

We can't change it to: "if additional addresses are defined, add them first,
afterwards the primary" because if behavior of kernel changes, we run into the
same trouble like now.

Comment 1 Peter Bieringer 2007-08-05 19:32:23 UTC
Created attachment 160718 [details]
Patch to fix the address order

Comment 2 Bill Nottingham 2007-08-06 21:48:32 UTC
This is all just horribly, horribly, wrong. Moreover, the upstream state of this
seems to be crap:

1) there's no good way to set policy in the kernel
2) the 'policy' that's there could conceivably change randomly
3) when asked, all the information I see says that they're looking on moving it
to policy based routing... with no further follow up.

Pending anything appearing as in #3, closing WONTFIX.

Comment 3 Peter Bieringer 2007-08-07 06:27:26 UTC
Bill, I can understand your position, but this won't help in current situations.

One additional question: how using policy based routing with e.g. pinning the
src address for default route to a "wished" one, when default route is
autoconfigured by receiving a router advertisement?


BTW: looks unlike to IPv4, the src can be specified, but is not supported by
kernel (at least 2.6.20-1.2952.fc6):

# ip -6 route add default via 2001:db8::1 src 2001:db8::2

# ip -6 route |grep ^default
default via 2001:db8::1 dev eth1  metric 1024  expires 21334312sec mtu 1500
advmss 1440 hoplimit 4294967295

Comment 4 Bill Nottingham 2007-08-07 14:20:50 UTC
(In reply to comment #3)
> Bill, I can understand your position, but this won't help in current situations.

I realize it's not much help, but I don't see how we can reliably code any sort
of fix when the only data we have to go on is 'the internal implementation
appears to take the last address added in kernel-X.Y.Z'; that's not a standard,
that's not something we can configure if it changes, and even the upstream IPv6
working group (AFAICT) declares the kernel behavior broken.



Comment 5 Peter Bieringer 2007-08-07 21:04:20 UTC
I can add a kernel version check before doing the hack, so it's limited to known
"buggy" version. After release of a new kernel (which happen more often in
Fedora, but never in RHEL minor releases), we can run checks and if behavior
hasn't changed, update the version in initscripts. The delay caused would be
acceptable for Fedora users imho, for RHEL users I see no problems, because the
next version to check (RHEL6) is currently still far away.

Comment 6 Bill Nottingham 2007-08-09 00:31:34 UTC
No, the point is that attempting to reorder and rejigger how interfaces are
added based on a kernel version is just ugly, even if there are version checks.
This really needs to get fixed properly in the upstream kernel.

Comment 7 Peter Bieringer 2007-08-09 05:10:04 UTC
I fully agree that this needs to be fixed in upstream kernel, but I'm unsure,
that Red Hat would backport this fix to RHEL4 (2.6.9) and RHEL5 (2.6.18). For at
least this releases, I could create a better workaround which adds IPV6ADDR as
last address and the seconaries before.

Comment 8 Peter Bieringer 2007-08-11 09:52:05 UTC
Created attachment 161112 [details]
Different method, depending on used kernel version

This patch do not remove/readd IPV6ADDR, it checks kernel version instead and
add IPV6ADDR as last one, if kernel behavior of "reverse order" is known.
Version check needs an update all the time for Fedora, but for RHEL4 it should
be well enough.