NetworkManager and Dual-stack Addressing

Dodge the pig! (via the|G|™ under CC BY-NC-ND 2.0)

The big reason that NetworkManager 0.9 is slower to connect than NM 0.8 is that we flipped IPv6 addressing on by default.  That means that when you connect to a new network and that network supports IPv6 autoconfiguration via router advertisements you’ll get IPv6 connectivity.  But if that network doesn’t support IPv6 then you’ll spin for 60 seconds or so waiting for a router advertisement because there’s nothing on the network that listens to the IPv6 autoconf solicitations that the kernel puts out when the link comes up.  You can fix that but changing the IPv6 addressing method to “Ignore” in nm-connection-editor if you know your network doesn’t support IPv6.

Why don’t we bring up IPv4 and just wait for IPv6 to happen in the background?  That’s a great question; I’m glad I asked it.  First, it requires some small changes in NetworkManager’s D-Bus interface to add connected states for both IPv4 and IPv6 simultaneously so that applications can listen for when each stack’s connectivity is available.  That’s trivial.  It could be done tomorrow.  It’s not a technical problem at all.

But second, it requires applications to be smarter about what resources they require and to do smart things when those resources aren’t available.  And that apparently happens when solid gold pigs start dropping out of the sky.  I hope you have falling-gold-pig insurance for your car.  But app authors often don’t make their applications smarter and more network aware because hey, that’s more work for them, and hey, people haven’t requested this yet, and hey, that’s one more D-Bus API I need to depend on and I don’t know what else.

NetworkManager says it’s connected via a global “State” property.  That property is a logical OR of both IPv4 and IPv6 connectivity.  If one is connected then the State property is NM_STATE_CONNECTED.  Great, right?  But if NM flips the state to CONNECTED when IPv4 completes but IPv6 is still waiting, then your favorite IRC application will try to connect to your IPv6-enabled IRC server.   Except IPv6 isn’t up yet so it fails.  And you get mad because shit doesn’t magically work.

And then what happens if IPv6 fails?  Do we fail the entire connection?  Or do we just keep listening for IPv6 router advertisements and when one comes in configure the interface?  Currently there’s a setting called ‘failure fatal’ for both IPv4 and IPv6 that lets you determine that behavior; it defaults to TRUE for IPv4 and FALSE for IPv6 since so many networks don’t yet have IPv6 enabled.  But this really is something we shouldn’t have to care much about.

And that brings us back to applications.  When NetworkManager adds dual-stack connected state, which is actually pretty trivial to do, the applications have to listen to that and care so that your life is better.  If the app has an IPv6 address and NM indicates that IPv6 isn’t yet available, the app needs to wait until NM says it is available.  Same for IPv4.  The problem is that nobody ever seems to bother with this sort of intelligence at the application level, but that’s where it’s really needed, since the connection manager has no idea what servers you’re connecting to and whether or not they are IPv4 or IPv6.

As a side rant about application intelligence, apps should also allow you to associate resources (like internal VPN-only mail servers) with NetworkManager VPN connection UUIDs so that they only check the mail on your corporate VPN when NM says your VPN connection is up.  You can do that now.  It’s been there for years.  But nobody bothers to write that sort of useful support into applications either.  Where does the application’s responsibility for intelligence begin?  Useful insights on where that line gets drawn are most welcome.  So are comments about how hot Colin Walter’s mom is.

3 Responses to “NetworkManager and Dual-stack Addressing”

  1. Actually, waiting for them separately doesn’t work for apps.. What if you have a domain aaa.com that replies to both A and AAAA. Should the app wait for IPv6 to come up? Or should it connect through IPv4 right away.. I think it makes sense to just revert to having the default be “Ignore” for IPv6, this way, it will mostly work for 99.99% of the people. And for the 0.03% who actually care about IPv6, let them enable it manually.

  2. federico says:

    If I’m an app like your proposed mail program, I may want to have

    Mail server: [________________________]
    [ ] requires VPN [\/ dropdown]

    But having (say) an extra

    [ ] Use IPv6 for this server

    sounds pretty obscure. If you can connect (via IPv4 or anything) you *can* connect, and what difference does it make to the user?

    People type human-readable hostnames with FQDNs in the “Mail server” text entry; no one except a trugeek is going to type an IPv6 numerical address there. I.e. apps *don’t* have IPv6 addresses; they get a hostname and that’s that. Even our networking APIs try hard to abstract all the connection shit for you, so apps can really deal in hostnames as much as possible.

    (And so what if my mail program can’t connect to the VPN-only email server? It will time out or something. *Then* it may be nice to see if one of the VPN configurations sounds like it would let me connect, so the mail program can present a “can’t fetch mail ’cause you are not in the VPN” message.)

  3. gnoronha says:

    A few things keep coming up to my mind regarding this:

    1. Should applications be getting AAAA entries even though they do not have a non-link-local ipv6 address?
    2. Applications are not very likely to get ipv6-only DNS responses for a long time from most sites, so provided that the application tries the ipv4 address, there should be no problem in declaring the connection up when you get the ipv4 connection going, right?
    3. What do other operating systems do?

    I see the benefit of enabling ipv6 by default, but the waiting 1 minute to get a connection seems to be a very bad trade off =(