Discussion:
Dealing with ICMPv6 network unreachable.
(too old to reply)
Roy Marples
2015-04-02 19:58:01 UTC
Permalink
Hi List!

I'm currently holidaying in Spain, and my apartments router is giving me
no end of grief. It claims it's a IPv6 router with the address fe80::1
but with no prefix information. Interestingly enough it is serving DNS
and DHCP on v6 as well.

Anyway, the problem is that because it's added a default route, various
programs will try IPv6 first. For each address tried, the router issues
an ICMPv6 unreachable message of code 0. This is displayed with ping -v
as well, so it is hitting userland. However, applications are ignoring
it. My simple test case is wget (available in pkgsrc).

On NetBSD, using wget on a IPv6 host, such as roy.marples.name, will try
IPv6 first. It then stalls, ignoring the ICMP unreachable message.
On Linux (running in QEMU on the same NetBSD host) the same wget command
tries the IPv6 host first but reports that it's unreachable and moves
onto the IPv4 address which works fine. This is quite a fast operation.
Other applications, such as ssh and firefox also have long stalls before
falling back to IPv4 and again the fallback is quite prompt in Linux.

I've looked over the icmp and routing code but am at a total loss how or
even if this is supposed to work. Any help would be appreciated so I can
resolve this before I head home!

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2015-04-03 00:09:49 UTC
Permalink
It claims it's a IPv6 router with the address fe80::1 but with no
prefix information.
Do you mean it is sending RAs? That seems odd. I wonder if we should
be rejecting them, but we'd have to read the specs.
Interestingly enough it is serving DNS and DHCP on v6 as well.
Can you explain more precisely?
Anyway, the problem is that because it's added a default route, various
programs will try IPv6 first. For each address tried, the router issues
an ICMPv6 unreachable message of code 0. This is displayed with ping -v
as well, so it is hitting userland. However, applications are ignoring
it. My simple test case is wget (available in pkgsrc).
Three thoughts about what might be going on:

I am unclear on codes in ICMPv6; it could be that 0 is irregular and
getting filtered out by us, even though maybe it shouldn't be.

It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.

It strikes me as odd that without a public address TCP is being tried.
Does your interface have any global addresses, or just the LL one?
If the router is handing out global addresses which don't work, it's a
much harder question about doing per-protocol black-hole detection
(leading down the path to happy eyeballs).
Martin Husemann
2015-04-03 06:59:07 UTC
Permalink
Post by Roy Marples
onto the IPv4 address which works fine. This is quite a fast operation.
Other applications, such as ssh and firefox also have long stalls before
falling back to IPv4 and again the fallback is quite prompt in Linux.
Firefox usually tries both connections in parallel ("Happy Eyeballs").
You can disable this by setting network.http.fast-fallback-to-IPv4 to
false in about:config, and you can completely disable v6 by
setting network.dns.disableIPv6 to false.

However, your description does not sound like connections are the real
problem, but more your DNS setup. Did the router provide a nameserver
with IPv6 address in the DHCP option?

Martin

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Manuel Bouyer
2015-04-03 07:58:01 UTC
Permalink
Post by Greg Troxel
[...]
It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.
I fully agree. I just got my ssh connections to a linux host killed
only because I unplugged/replugged the ethernet cable of said linux box.
That's very annoying.
--
Manuel Bouyer <***@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Alan Barrett
2015-04-05 14:47:55 UTC
Permalink
Post by Roy Marples
Post by Mouse
Post by Roy Marples
There is no guarantee the same network will be plugged back
in.
True. But the time to deal with that is when you discover
another network was plugged in, not when the original network
is unplugged.
I strongly agree with Mouse. A cable being unplugged should be
treated as a temporary condition, until such time as you have
better information, such as "it's been unplugged for a long time
now", or "it's plugged in again, but looks like a different
network".
Post by Roy Marples
So lets say that we are plugged back into a new network, but it
shares the same subnet and your existing IP address conflicts
with a server on the network.
Two different networks that use the same address range? Like two
distinct instances of 192.168.1.0/24?

Yes, that can happen, but dealing with should be done in a
way that does not punish people who simply remove a cable and
re-attach it seconds later, or power cycle a switch or access
point to have it come back up a minute or two later.
Post by Roy Marples
However, I would rather be notified right away that something
was awry with the connection rather than waiting for a long
timeout on switching networks.
People who connect to multiple disjoint networks that happen to
share the same IP address range are unusual, and should have the
lowest priority in considering tradeoffs where making things work
better for one class of user causes trouble for another class of
user.

Here are a few scenarios:

1. Disconnected and re-connected to the same network after a short
delay: Don't remove addresses on disconnect, but perhaps mark
them as deprecated, or not to be used for initiating new outbound
comnnections; On re-connect, verify that we appear to be on the
same network, and mark addresses as fully usable again.

2. Disconnected and re-connected to the same network after a long
delay: Perhaps the addresses can be removed after a timeout, and
then re-connection can be handled like the very first connection
after reboot. (The timeout could be a configuration option, and
I'd suggest between 5 and 15 minutes: long enough to reboot a
router or switch, but short enough that the user is unlikely to
be able to travel to a different site and plug in to a different
network that happens to share so many qualities that dhcpcd is
unable to distinguish the two, as in case 5 below.)

3. Disconnected and re-connected to a different network after a
short delay: On re-connect, notice that the network is different,
remove the old addresses, and add new addresses.

4. Disconnected and re-connected to a different network after
a long delay: Same as case 3, or perhaps the old addresses had
already been removed as for case 2.

5. Disconnected and then re-connected to a network that is really
different, but that is somehow mis-identified as being the same:
The user loses, unless the old addresses had been removed after a
timeout as in case 2. The user can manually initiate some sort
of "repair" process, which removes old addresses and requests new
addresses.

If you can do something to make the user in case 5 happier, while
not making the user in case 1 sadder, then please do so. If you
can improve the mechanism for distinguishing between "the same"
and "different" networks, then please do so. But I think that
being nice to the user in case 1 is much more important than being
nice to the user in case 5.

--apb (Alan Barrett)

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-07 21:59:25 UTC
Permalink
Post by Alan Barrett
Post by Roy Marples
Post by Mouse
Post by Roy Marples
There is no guarantee the same network will be plugged back in.
True. But the time to deal with that is when you discover
another network was plugged in, not when the original network
is unplugged.
I strongly agree with Mouse. A cable being unplugged should be
treated as a temporary condition, until such time as you have
better information, such as "it's been unplugged for a long time
now", or "it's plugged in again, but looks like a different
network".
Post by Roy Marples
So lets say that we are plugged back into a new network, but it
shares the same subnet and your existing IP address conflicts
with a server on the network.
Two different networks that use the same address range? Like two
distinct instances of 192.168.1.0/24?
Yes, that can happen, but dealing with should be done in a
way that does not punish people who simply remove a cable and
re-attach it seconds later, or power cycle a switch or access
point to have it come back up a minute or two later.
Post by Roy Marples
However, I would rather be notified right away that something
was awry with the connection rather than waiting for a long
timeout on switching networks.
People who connect to multiple disjoint networks that happen to
share the same IP address range are unusual, and should have the
lowest priority in considering tradeoffs where making things work
better for one class of user causes trouble for another class of
user.
1. Disconnected and re-connected to the same network after a short
delay: Don't remove addresses on disconnect, but perhaps mark
them as deprecated, or not to be used for initiating new outbound
comnnections; On re-connect, verify that we appear to be on the
same network, and mark addresses as fully usable again.
IPv4 would need to grow IN_IFF_DETATCHED, IN_IFF_TENTATIVE and
IN_IFF_DUPLICATED and work in the same way as the IPv6 counterparts.
Post by Alan Barrett
2. Disconnected and re-connected to the same network after a long
delay: Perhaps the addresses can be removed after a timeout, and
then re-connection can be handled like the very first connection
after reboot. (The timeout could be a configuration option, and
I'd suggest between 5 and 15 minutes: long enough to reboot a
router or switch, but short enough that the user is unlikely to
be able to travel to a different site and plug in to a different
network that happens to share so many qualities that dhcpcd is
unable to distinguish the two, as in case 5 below.)
3. Disconnected and re-connected to a different network after a
short delay: On re-connect, notice that the network is different,
remove the old addresses, and add new addresses.
4. Disconnected and re-connected to a different network after
a long delay: Same as case 3, or perhaps the old addresses had
already been removed as for case 2.
5. Disconnected and then re-connected to a network that is really
The user loses, unless the old addresses had been removed after a
timeout as in case 2. The user can manually initiate some sort
of "repair" process, which removes old addresses and requests new
addresses.
If you can do something to make the user in case 5 happier, while
not making the user in case 1 sadder, then please do so. If you
can improve the mechanism for distinguishing between "the same"
and "different" networks, then please do so. But I think that
being nice to the user in case 1 is much more important than being
nice to the user in case 5.
No need for any of the above if the kernel can grow IPv6 like address
static semantics for IPv4. The natural DHCP/DHCPv6 process will take
care of the rest.

Please understand that dhcpcd works the way it does because no kernel
bothers to re-check existing addresses on the network on carrier up.
It has to be the kernel that does this, because dhcpcd cannot stop the
kernel from announcing "I own this address" and causing the potential
DoS I described earlier. It was only recently I patched the NetBSD
kernel to do this for IPv6, but will be quite a bigger for for IPv4.
If you're happy with the above idea then we can move forward with
changing dhcpcd to persist the address on carrier down. But this will be
for NetBSD only.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-05-02 15:25:40 UTC
Permalink
People who connect to multiple disjoint networks that happen to share
the same IP address range are unusual, and should have the lowest
priority in considering tradeoffs where making things work better for
one class of user causes trouble for another class of user.
1. Disconnected and re-connected to the same network after a short
delay: Don't remove addresses on disconnect, but perhaps mark them as
deprecated, or not to be used for initiating new outbound comnnections;
On re-connect, verify that we appear to be on the same network, and mark
addresses as fully usable again.
This has now been implemented and dhcpcd allows addresses to persist
when the link goes down.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Manuel Bouyer
2015-05-04 17:28:27 UTC
Permalink
Post by Roy Marples
People who connect to multiple disjoint networks that happen to share
the same IP address range are unusual, and should have the lowest
priority in considering tradeoffs where making things work better for
one class of user causes trouble for another class of user.
1. Disconnected and re-connected to the same network after a short
delay: Don't remove addresses on disconnect, but perhaps mark them as
deprecated, or not to be used for initiating new outbound comnnections;
On re-connect, verify that we appear to be on the same network, and mark
addresses as fully usable again.
This has now been implemented and dhcpcd allows addresses to persist
when the link goes down.
thanks !
--
Manuel Bouyer <***@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-03 08:35:35 UTC
Permalink
Post by Greg Troxel
It claims it's a IPv6 router with the address fe80::1 but with no
prefix information.
Do you mean it is sending RAs? That seems odd. I wonder if we should
be rejecting them, but we'd have to read the specs.
That was my initial thought also, but I've read the specs and can't see
anything to say they should be rejected.
There is also a few documents (NOT RFCs) on recommending using fe80::1
as the edge router because it's like easy to remember.
Post by Greg Troxel
Interestingly enough it is serving DNS and DHCP on v6 as well.
Can you explain more precisely?
It's a fully functional IPv6 router, except it's not handing out any
prefixes or addresses of any kind. The DHCPv6 is just handing out DNS
records.
Post by Greg Troxel
Anyway, the problem is that because it's added a default route, various
programs will try IPv6 first. For each address tried, the router issues
an ICMPv6 unreachable message of code 0. This is displayed with ping -v
as well, so it is hitting userland. However, applications are ignoring
it. My simple test case is wget (available in pkgsrc).
I am unclear on codes in ICMPv6; it could be that 0 is irregular and
getting filtered out by us, even though maybe it shouldn't be.
It's not irregular, it's ICMP6_DST_UNREACH_NOROUTE which is handled in
sys/netinet6/icmp6.c line 525. I have yet to explore further than this.
Post by Greg Troxel
It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.
It strikes me as odd that without a public address TCP is being tried.
Does your interface have any global addresses, or just the LL one?
If the router is handing out global addresses which don't work, it's a
much harder question about doing per-protocol black-hole detection
(leading down the path to happy eyeballs).
As I said above, no addresses are being handed out.
The local interface just have local-link addresses.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2015-04-03 14:35:36 UTC
Permalink
Post by Roy Marples
As I said above, no addresses are being handed out.
The local interface just have local-link addresses.
So the real bug on our side is arguably trying to connect to a global
address when we only have link-local addresses. I would posit (with
not much confidence) that essentially source address selection should
throw an exception rather than return a LL value, which invoked to send
to a global address. I would expect this to be covered in the specs.

The other question is if the unreachable is being ignored on purpose
(because of Manuel's half of the opinion), or if it's a bug.

I can see a notion being reasonable where unreachables in SYN_SENT
cause abort, but not in established connections; that might get most of
the benefit of both cases.
Roy Marples
2015-04-03 08:38:20 UTC
Permalink
Post by Martin Husemann
Post by Roy Marples
onto the IPv4 address which works fine. This is quite a fast operation.
Other applications, such as ssh and firefox also have long stalls before
falling back to IPv4 and again the fallback is quite prompt in Linux.
Firefox usually tries both connections in parallel ("Happy Eyeballs").
You can disable this by setting network.http.fast-fallback-to-IPv4 to
false in about:config, and you can completely disable v6 by
setting network.dns.disableIPv6 to false.
Yes, firefox works reasonably well and is the exception.
Post by Martin Husemann
However, your description does not sound like connections are the real
problem, but more your DNS setup. Did the router provide a nameserver
with IPv6 address in the DHCP option?
Yes it did.
And it works fine. It gives the same responses as the IPv4 nameserver.
On both NetBSD and Linux, wget gets the IPv6 address first.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-03 08:41:51 UTC
Permalink
Post by Manuel Bouyer
Post by Greg Troxel
[...]
It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.
I fully agree. I just got my ssh connections to a linux host killed
only because I unplugged/replugged the ethernet cable of said linux box.
That's very annoying.
I would argue that's correct behaviour because the addresses will become
non functional when you take the cable out. In the IPv6 case on NetBSD
the addresses will be marked as detached and then tentative when the
cable is plugged back in. I think in the Linux case the addresses are
just removed. With dhcpcd running it will remove the addresses. There is
no guarantee the same network will be plugged back in.

If you want ssh to persist in any way or form, run tmux or screen at the
other end.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Manuel Bouyer
2015-04-03 10:32:52 UTC
Permalink
Post by Roy Marples
Post by Manuel Bouyer
Post by Greg Troxel
[...]
It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.
I fully agree. I just got my ssh connections to a linux host killed
only because I unplugged/replugged the ethernet cable of said linux box.
That's very annoying.
I would argue that's correct behaviour because the addresses will become
non functional when you take the cable out. In the IPv6 case on NetBSD
the addresses will be marked as detached and then tentative when the
cable is plugged back in. I think in the Linux case the addresses are
just removed. With dhcpcd running it will remove the addresses. There is
no guarantee the same network will be plugged back in.
But you don't know until you get another address (or the same address
back). You shouldn't loose established TCP connection when a switch is
reloaded. I really don't think that's the correct behavior.
--
Manuel Bouyer <***@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Mouse
2015-04-03 15:20:22 UTC
Permalink
Post by Roy Marples
I just got my ssh connections to a linux host killed only because I
unplugged/replugged the ethernet cable of said linux box. That's
very annoying.
I would argue that's correct behaviour because the addresses will
become non functional when you take the cable out.
Only temporarily.
Post by Roy Marples
There is no guarantee the same network will be plugged back in.
True. But the time to deal with that is when you discover another
network was plugged in, not when the original network is unplugged.
Post by Roy Marples
If you want ssh to persist in any way or form, run tmux or screen at
the other end.
I'm glad you don't control the network stack on my machines. (Nitpick:
even that doesn't actually make ssh persist. All it renders persistent
is the shell, and things run under it, on the remote machine. It also
assumes the remote machine _has_ something like tmux or screen, which
may not be the case.)

/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-03 20:36:21 UTC
Permalink
Post by Mouse
Post by Roy Marples
I just got my ssh connections to a linux host killed only because I
unplugged/replugged the ethernet cable of said linux box. That's
very annoying.
I would argue that's correct behaviour because the addresses will
become non functional when you take the cable out.
Only temporarily.
The cable has been unplugged. There is no guarantee it will be plugged
back in.
Post by Mouse
Post by Roy Marples
There is no guarantee the same network will be plugged back in.
True. But the time to deal with that is when you discover another
network was plugged in, not when the original network is unplugged.
So lets say that we are plugged back into a new network, but it shares
the same subnet and your existing IP address conflicts with a server on
the network. If a new host on the new network wants to talk to the
server and hasn't learned the LL address yet and both our host and the
server respond it's basically a coin flip which machine the new host
will actually talk to. Is this desirable behaviour? To me this is like a
mini DoS attack, although unintended.

The reverse is also true, we would need to discard our learned LL
addresses as they may be incorrect as well.

Sadly it's possible that a well configured DHCP server remains silent
when trying to renew the old lease on a different network so we could
still be using the old IP for some time - although it's possible to
configure short timeouts for this scenario.

If you can supply satisfactory answers to the above, then sure I'll
happily add code to dhcpcd to keep the lease on carrier down, but until
then I'd rather behave nicely on all networks.
Post by Mouse
Post by Roy Marples
If you want ssh to persist in any way or form, run tmux or screen at
the other end.
even that doesn't actually make ssh persist. All it renders persistent
is the shell, and things run under it, on the remote machine. It also
assumes the remote machine _has_ something like tmux or screen, which
may not be the case.)
True it does not make ssh persist but the shell under it and yes it
relies on something like tmux.
However, I would rather be notified right away that something was awry
with the connection rather than waiting for a long timeout on switching
networks.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Dennis Ferguson
2015-04-03 17:17:42 UTC
Permalink
Post by Greg Troxel
Post by Roy Marples
Anyway, the problem is that because it's added a default route, various
programs will try IPv6 first. For each address tried, the router issues
an ICMPv6 unreachable message of code 0. This is displayed with ping -v
as well, so it is hitting userland. However, applications are ignoring
it. My simple test case is wget (available in pkgsrc).
I am unclear on codes in ICMPv6; it could be that 0 is irregular and
getting filtered out by us, even though maybe it shouldn't be.
It seems that the proper response of TCP to net/host unreachable is
arguable. In the case you mention, it's best to abort, but a
transient unreachable situation on a TCP connection shouldn't kill the
connection.
I think it works best if errors (either unreachables or sending errors
reported by the local stack) are reported immediately when the TCP packet
that resulted in the error is a SYN packet but are ignored, falling back
to a timeout, when the connection has gotten beyond that. It is very
true that this is arguable though.
Post by Greg Troxel
It strikes me as odd that without a public address TCP is being tried.
Does your interface have any global addresses, or just the LL one?
If the router is handing out global addresses which don't work, it's a
much harder question about doing per-protocol black-hole detection
(leading down the path to happy eyeballs).
I'm not sure the first bit is right. I think TCP connections using the
LL address are okay, even when the remote address is global scope, as
long as the remote host is connected to the same wire. Since a host
can't necessarily tell whether the global addressee is on the same wire,
however, the only thing it can do is attempt to open the connection and
let the router tell it whether this is okay or not. This doesn't work
so well if the host entirely ignores the unreachables the router sends back.

I do think that if IPv6, or IPv4 for that matter, is broken for you then
a good solution is just to configure the broken protocol off, use the
one that works and just get on with it. That the IPv6 implementation
makes it hard to do this is a problem.

Dennis Ferguson

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Robert Elz
2015-04-03 20:16:03 UTC
Permalink
Date: Thu, 02 Apr 2015 20:58:01 +0100
From: Roy Marples <***@marples.name>
Message-ID: <***@uberlaptop2.marples.name>

| This is displayed with ping -v as well, so it is hitting userland.
| However, applications are ignoring it.

ICMP messages only "hit userland" for applications using raw sockets,
like ping, the vast majority of applications don't, and I think it way
to much to expect of them just on the off chance an ICMP packet appears
(which they'd have to filter out of all the random other noise that
raw sockets also let through.)

| On NetBSD, using wget on a IPv6 host, such as roy.marples.name, will try
| IPv6 first. It then stalls, ignoring the ICMP unreachable message.

That's arguably correct behaviour. ICMP used (way back in the dark ages)
to kill connections, but that was widely (and correctly) lambasted as totally
broken behaviour - it is perhaps not quite so bad for TCP SYN packets, but
even there leaves the system wide open to DoS attacks (anyone can send an
ICMP packet, they're totally unauthenticated, and unverifiable, if you abandon
the connection on receiving one, you cannot resurrect it later if an answering
SYN+ACK does appear).

It doesn't seem like it would be so bad in the case you're postulating,
where the application has another address it can try, but the kernel doesn't
know that, all it can assume is that if you asked for it to make a
connection to a particular address, that's what it should try and do.

It was (long ago) determined that apart from their use by network engineers
for diagnostics (and hence the output from ping, traceroute, etc) all that
should even be done with a received ICMP unreachable is remember it, to
allow a better error code to be returned to the application if the
connection (or connection attempt) does eventually fail.

If linux is receiving the icmp and using that to abort the connect attempt,
it is, quite simply, broken (and probably even warrants a CERT advisory).

One thing that could be done (but which would mean adapting every application
in existance) would be to invent a "connect to one of addr set" sys call,
where a bunch of addresses (not necessarily all the same AF) could be given,
allowing the kernel to know what the application knows, so it could try
more sophisticated behaviours - including good destination addr selection,
instead of relying on the DNS functions magically returning addresses to
the applications in the "right" order. That could include either multiple
SYNs (perhaps) or quick fallover in the event of an apparent error (without
actually abandoning the initial attempt).

I kind of agree with Greg Troxel, if there's any problem at all on the
NetBSD system, it would be in attempting to send to the global addr from
a LL addr - but even that isn't as clear cut as it seems, the global
addr might be on the local link, in which case the connection should succeed.

I certainly believe your holiday apartment's router is broken though,
advertising itself as a router when it has no routes at all (beyond LL)
is just perverse.

For NetBSD, aside from the unlikely possibility of a magic new connect
syscall, about all you can do when facing a broken router like this, would be
to disable IPv6 (which admittedly right now is harder than it could be.)

Certainly "fixing" it to act (in any way at all) upon the ICMP is not
the right thing to do.

kre


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-03 21:02:23 UTC
Permalink
Post by Robert Elz
If linux is receiving the icmp and using that to abort the connect attempt,
it is, quite simply, broken (and probably even warrants a CERT advisory).
I don't know what Linux is doing here, I just know that wget (and other
applications) are failing IPv6 early and falling back to IPv4. It could
be some other mechanism other than ICMP for all I know.
Post by Robert Elz
I kind of agree with Greg Troxel, if there's any problem at all on the
NetBSD system, it would be in attempting to send to the global addr from
a LL addr - but even that isn't as clear cut as it seems, the global
addr might be on the local link, in which case the connection should succeed.
I agree on all points.
Post by Robert Elz
I certainly believe your holiday apartment's router is broken though,
advertising itself as a router when it has no routes at all (beyond LL)
is just perverse.
My knee jerk reaction was the same.
But after contemplating the issue while soaking the sun it's not really
that broken. It's perfectly possible that the router is configured to
request a Prefix Delegation from a upstream DHCP server which has gone
silent. The normal operation of rtadvd(8) is to advertise itself as a
router and any prefixes on the advertising interface - of which there
will be none if Prefix Delegation has failed.
Post by Robert Elz
For NetBSD, aside from the unlikely possibility of a magic new connect
syscall, about all you can do when facing a broken router like this, would be
to disable IPv6 (which admittedly right now is harder than it could be.)
Certainly "fixing" it to act (in any way at all) upon the ICMP is not
the right thing to do.
Well, as discussed above, fixing it by not adding a default route if no
global addresses are available isn't a good solution either (and one I
have also considered).

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Robert Elz
2015-04-03 23:08:33 UTC
Permalink
Date: Fri, 03 Apr 2015 22:02:23 +0100
From: Roy Marples <***@marples.name>
Message-ID: <***@uberlaptop2.marples.name>

| It's perfectly possible that the router is configured to
| request a Prefix Delegation from a upstream DHCP server which has gone
| silent.

My home router does that - when it gets no IPv6 it advertises no IPv6
(ie: it only sends rtadvd when it has something to advertise). It is
a regular off the shelf commercial product (not the cheapest available
though). It works the way I think it should.

kre


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-03 23:23:44 UTC
Permalink
Post by Robert Elz
Date: Fri, 03 Apr 2015 22:02:23 +0100
| It's perfectly possible that the router is configured to
| request a Prefix Delegation from a upstream DHCP server which has gone
| silent.
My home router does that - when it gets no IPv6 it advertises no IPv6
(ie: it only sends rtadvd when it has something to advertise). It is
a regular off the shelf commercial product (not the cheapest available
though). It works the way I think it should.
I was describing the behavior of our rtadvd which could be used in a
router (like say my home brew one, but i have static prefixes to
advertise), not your router :)

Should our rtadvd be fixed not to advertise itself as a router if it's
not advertising any public prefixes?

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Robert Elz
2015-04-04 00:34:28 UTC
Permalink
Date: Sat, 04 Apr 2015 00:23:44 +0100
From: Roy Marples <***@marples.name>
Message-ID: <***@uberlaptop2.marples.name>

| Should our rtadvd be fixed not to advertise itself as a router if it's
| not advertising any public prefixes?

It isn't the prefixes it has to advertise that matters, it is whether it
has the ability to actually send packets somewhere - if it has no routes,
it can't really be a router, and should not be advertising itself as one.

kre


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2015-04-04 13:26:45 UTC
Permalink
Post by Roy Marples
Should our rtadvd be fixed not to advertise itself as a router if it's
not advertising any public prefixes?
I don't think it needs fixing, because one can configure it to do
various things, and it isn't run by default. It would only cause
trouble if someone is running a router and misconfigures things, and so
far we havn't seen that reported...

But, if you wanted to spiff it up so that when there aren't any global
prefixes, it either doesn't send RAs or doesn't advertise the default
route, with an option to make it send RAs anyway, that seems ok,
although it feels like extra code and effort to solve a non-problem.


There's a larger issue lurking, which is automatically turning off the
RA and/or ripng local default route when a tunnel is down, even if the
prefix is statically assigned. That's far more into routing daemon
implementation though.
Roy Marples
2015-04-03 23:44:40 UTC
Permalink
Post by Roy Marples
Post by Robert Elz
I kind of agree with Greg Troxel, if there's any problem at all on the
NetBSD system, it would be in attempting to send to the global addr from
a LL addr - but even that isn't as clear cut as it seems, the global
addr might be on the local link, in which case the connection should succeed.
I agree on all points.
Post by Robert Elz
I certainly believe your holiday apartment's router is broken though,
advertising itself as a router when it has no routes at all (beyond LL)
is just perverse.
My knee jerk reaction was the same.
But after contemplating the issue while soaking the sun it's not really
that broken. It's perfectly possible that the router is configured to
request a Prefix Delegation from a upstream DHCP server which has gone
silent. The normal operation of rtadvd(8) is to advertise itself as a
router and any prefixes on the advertising interface - of which there
will be none if Prefix Delegation has failed.
Post by Robert Elz
For NetBSD, aside from the unlikely possibility of a magic new connect
syscall, about all you can do when facing a broken router like this, would be
to disable IPv6 (which admittedly right now is harder than it could be.)
Certainly "fixing" it to act (in any way at all) upon the ICMP is not
the right thing to do.
Roy
Well, as discussed above, fixing it by not adding a default route if no
global addresses are available isn't a good solution either (and one I
have also considered).
I can't think of a better way of fixing it though!
And seeing as the current discussion isn't looking like any possible fix
for this is possible in NetBSD I've made dhcpcd skip adding a default
route for routers which advertise themselves as a router but without any
global prefixes. I've also added an option to turn this off and have the
original behavior.

http://roy.marples.name/projects/dhcpcd/ci/6ead1d4962b514e8?sbs=0

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2015-04-04 13:22:13 UTC
Permalink
Post by Roy Marples
Post by Roy Marples
Well, as discussed above, fixing it by not adding a default route if no
global addresses are available isn't a good solution either (and one I
have also considered).
I can't think of a better way of fixing it though!
And seeing as the current discussion isn't looking like any possible fix
for this is possible in NetBSD I've made dhcpcd skip adding a default
route for routers which advertise themselves as a router but without any
global prefixes. I've also added an option to turn this off and have the
original behavior.
http://roy.marples.name/projects/dhcpcd/ci/6ead1d4962b514e8?sbs=0
I would say though that the router offering itself as a router (and
hence capable of forwarding packets) when it isn't connected (to the
global net) is wrong. It would compete with a working router and
result in lack of delivery.

So your fix seems entirely reasonable. It basically ignores RAs (or the
router part) from routers that offer no prefixes, which is likely mostly
the same set of sitautions as routers that can't forward.
Roy Marples
2015-04-04 21:44:45 UTC
Permalink
Post by Greg Troxel
Post by Roy Marples
Post by Roy Marples
Well, as discussed above, fixing it by not adding a default route if no
global addresses are available isn't a good solution either (and one I
have also considered).
I can't think of a better way of fixing it though!
And seeing as the current discussion isn't looking like any possible fix
for this is possible in NetBSD I've made dhcpcd skip adding a default
route for routers which advertise themselves as a router but without any
global prefixes. I've also added an option to turn this off and have the
original behavior.
http://roy.marples.name/projects/dhcpcd/ci/6ead1d4962b514e8?sbs=0
I would say though that the router offering itself as a router (and
hence capable of forwarding packets) when it isn't connected (to the
global net) is wrong. It would compete with a working router and
result in lack of delivery.
So your fix seems entirely reasonable. It basically ignores RAs (or the
router part) from routers that offer no prefixes, which is likely mostly
the same set of sitautions as routers that can't forward.
Of course, the RA could contain options that add global addresses for
say DNS that won't work. As we can't second guess future options,
ignoring the RA is the only sensible approach. We also need to check the
Managed flag as we could get a global address from DHCPv6.

A more robust fix is be to only apply the RA once we add a public
address either derived from the RA or DHCPv6. I've changed dhcpcd to do
this, but need to test it more when I get back from my holidays.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2015-04-04 13:29:44 UTC
Permalink
Post by Dennis Ferguson
I'm not sure the first bit is right. I think TCP connections using the
LL address are okay, even when the remote address is global scope, as
long as the remote host is connected to the same wire. Since a host
can't necessarily tell whether the global addressee is on the same wire,
however, the only thing it can do is attempt to open the connection and
let the router tell it whether this is okay or not. This doesn't work
so well if the host entirely ignores the unreachables the router sends back.
There's some notion, on which I am fuzzy, about doing ND for prefixes
not known to be on-link. Sending a LL->global packet to a router seems
odd, because unless the global is on link, it's not going to get a
reply. And it seems bad to forward a packet with a LL source address in
general.
Post by Dennis Ferguson
I do think that if IPv6, or IPv4 for that matter, is broken for you then
a good solution is just to configure the broken protocol off, use the
one that works and just get on with it. That the IPv6 implementation
makes it hard to do this is a problem.
So we probably need two sysctls to disable v4 and v6.
Dennis Ferguson
2015-04-04 23:00:52 UTC
Permalink
Post by Greg Troxel
Post by Dennis Ferguson
I'm not sure the first bit is right. I think TCP connections using the
LL address are okay, even when the remote address is global scope, as
long as the remote host is connected to the same wire. Since a host
can't necessarily tell whether the global addressee is on the same wire,
however, the only thing it can do is attempt to open the connection and
let the router tell it whether this is okay or not. This doesn't work
so well if the host entirely ignores the unreachables the router sends back.
There's some notion, on which I am fuzzy, about doing ND for prefixes
not known to be on-link. Sending a LL->global packet to a router seems
odd, because unless the global is on link, it's not going to get a
reply. And it seems bad to forward a packet with a LL source address in
general.
IPv6 routers need to implement source address constrained forwarding
in any case, it is an unavoidable consequence of the general problem
of dealing with address scopes. If you think about what one needs to
do to border-patrol site local source addresses then the LL source address
case falls out as a simpler special case of that. A packet with a site local
source address is forwarded, but only when the outgoing interface is one
of a group (of 1 or more) attached to the same "site" as the incoming
interface; otherwise a code 2 unreachable is sent. A packet with a LL
source address is forwarded, but only when the outgoing interface is the
same as the incoming interface (a group of 1); otherwise a code 2
unreachable is sent.

It sucks to be an IPv6 router.

There are many ways that a host sending packets will end up not getting
replies to those packets, but when a host with only a LL local address
sends something through a router it will usually get a reply. Either
it will get a ND redirect pointing at the MAC address of the thing it wants
to talk to (and also packets from the thing it wants to talk to, hopefully)
or it will get an unreachable error. There's no way to predict which
it will get with certainty without actually sending something.
Post by Greg Troxel
Post by Dennis Ferguson
I do think that if IPv6, or IPv4 for that matter, is broken for you then
a good solution is just to configure the broken protocol off, use the
one that works and just get on with it. That the IPv6 implementation
makes it hard to do this is a problem.
So we probably need two sysctls to disable v4 and v6.
I actually think this is a symptom of a problem (one of several such) with
how interface configuration is represented. Protocol configuration is
per-interface configuration, so there needs to be a way to indicate which
protocols are enabled for use on each interface. BSD networking has always
tied this to address configuration; a protocol was enabled on the interface
when an address for the protocol is configured on the interface. This was
fine when life was simple, but now is full of warts in pretty much every
case that matters now:

- It doesn't work for forwarding protocols which have no per-interface
address configuration, like 802.1 bridging, so you need a special way
to configure that up not involving address configuration.

- There are cases where you would like IPv4 configured up without addresses.
You don't need IPv4 addresses configured to run IPv4 on point-to-point
links between routers, and you would like to have IPv4 configured up on
an ethernet without addresses so you could send and receive the IPv4 DHCP
packets required to determine the address to configure. Now the former
configuration can't be done while the latter needs the work around
of having dhcpcd using BPF to send and receive raw packets instead (a
sure sign your protocol stack is missing something it should have).

- IPv6 never needs to run without a protocol address since it can
(and should) conjure one up and add it itself, but since that has the
side effect of configuring itself up there now needs to be a special
case way to tell it when you don't want it to do that.

When every protocol needs to work around the configuration representation
it is pretty clear the representation itself is inadequate. Configuring
a protocol address isn't a good way to indicate that you want to enable
the protocol on the interface, that should be done separately.

I prefer dealing directly with the representation problem by splitting
interface structures (and the API those structures support) into a larger
number of components. Addresses shouldn't be added to interfaces, instead
protocol families should be added to interfaces to enable the protocol
and addresses should be added (or not) to the appropriate protocol family
on the interface. Then you would not configure IPv6 on an interface by
not configuring the IPv6 protocol family on the interface, the same way
that you avoid configuring bridging or IPv4.

Dennis Ferguson
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Roy Marples
2015-04-05 01:00:48 UTC
Permalink
Post by Dennis Ferguson
having dhcpcd using BPF to send and receive raw packets instead (a
sure sign your protocol stack is missing something it should have).
On Linux, the original dhcpcd (way before I got my mits on it) didn't
need the equivalent of BPF. It digested every packet on the interface
and was a massive CPU hog as a result.

For IPv6 we have ICMP filtering. It could be argued that adding anything
like this for IPv4 is pretty redundant because we have BPF (LPF on
Linux). The only plausible argument for it would be to standardize cross
platform ... but LPF accepts BPF filters.

TLDR; it should have had it in the first place but it didn't. Adding it
now doesn't really gain us anything.

Roy


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...