Poll the device's IPv6 flags so we're notified when the RA has
been parsed and what the flags are. Only when that's complete
and the device's target state has been reached (or Managed mode
was indicated by the RA) should we continue with IP configuration.
Where we can do so, let's use ifindex since that's actually unique
and doesn't change when the interface name changes. We already use
ifindex in a bunch of places, and netlink *only* uses ifindex, so
this will make it easier later when we move over to ifindexes fully.
The non-blocking connection is really only good for listening for
events. It doesn't work for request/response operations (like
refilling link and address caches) because the message receive loop
in libnl will break out from the EAGAIN before it gets the response
it needs to update the cache with.
This is most evident with link cache refills when requesting the
interface index from the name, or vice-versa; the refill request
exits early with EAGAIN (due to the non-blocking nature of the
connection's socket) and the cache isn't refilled, and the index
lookup fails. We need to use blocking netlink operations in quite
a few places besides index lookups, from address/route operations
to getting the initial device carrier state.
So, split the montior's netlink connection into a non-blocking
event listener connection, and a synchronous connection which gets
used for immediate operations. This also has the effect of
validation the synchronous operations for security, which wasn't
done before in nm-netlink.c (though it wasn't really a problem).
Got the flags wrong in the previous commit; MULTI isn't about
multicast/unicast, but about multi-part packets. Instead we need
to check the netlink sockaddr structure for the group mask.
The RA flags aren't in the link flags, they are in the special
PROTINFO flags that the IPv6 stack sends. To get these, because
libnl doesn't have native support for them, we get to parse the
netlink messages directly. Furthermore, the PROTINFO message
isn't sent unless it's explicitly requested with a
RTM_GETLINK/AF_INET6 message, meaning we get to poll for it
periodically.
So switch over to the netlink monitor object (killing a lot of
duplicate code) and start requesting the PROTINFO bits from
netlink.
We need the IFLA_PROTINFO messages, and these are apparently sent
(still by the kernel) but with our own PID. So the current checks
that limit the netlink PID to zero block these messages out. Instead
(like udev) we should be checking the actual sender of the message
usign unix socket credentials.
Second, at least at this point only privileged processes can send
netlink multicast messages, so as long as the:
* the other end of the socket is UID 0 AND
* the netlink PID is 0 OR
* the message is multicast and sent to our netlink PID
the we accept the message and process it as normal. For another
example of this, see 'netlink.c' from the dhcp6s program; do a
Google search for "IFLA_PROTINFO" to find it.
Ensure it still works correctly if something tries to set the
'addresses' property using the old GType. Also make sure that
the various IP6 address comparison operations and string conversion
functions handle the gateway.
We can change the property's D-Bus signature (and thus API) here
because querying the IP6Config object's properties caused NM to
crash. Apparently we forgot to change the type of the Address
property when we C&P-ed the IP4Config into the IP6Config, and
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT is certainly the wrong type
to use since the backing object that dbus-glib would marshal
into the ARRAY_OF_ARRAY_OF_UINT wasn't that type, causing a
crash in dbus-glib when a client got the IP6Config.
Instead of not including the IP4 setting, set its method to disabled.
In reality either one is legal, but including the IP4 setting wtih
the method set to 'disabled' is more explicit.
This has been around a long time, but is very hard to trigger. It appears
to happen mostly if the supplicant segfaults on resume but has been seen
in other cases as well.
For whatever reason, the DBusGProxy's refcount reaches 0 and the proxy gets
disposed of. That in turn disposes of all the pending calls that are
in-progress on the proxy. Since we give the pending calls a closure, that
closure (nm_supplicant_info_destroy) gets called when the pending calls
are destroyed. That closure unrefs the proxy again.
Since DBusGProxy doesn't have any protection in its dispose() handler
against re-entrant disposes (which is arguably a bug of the client)
we end up infinite looping in nm_supplicant_info_destroy().
Fix that by ensuring we return early if we detect that we are already
freeing the NMSupplicantInfo object, and thus don't try to dispose
of the proxy yet again.
ifcfg-rh plugin was not able to reset MTU to "automatic" if it had been
set to a value, for wired connection. This fix removes "MTU" variable
from the ifcfg-* file when mtu is 0.
RFKILL_TYPE_WLAN is 0, and we while we had allocated the structure
for WIMAX rfkill in the manager's priv->radio_states, we hadn't
filled it in. That meant that priv->radio_states[RFKILL_TYPE_WIMAX].rtype
was 0, and thus various operations thought that wifi devices
were wimax devices, and since WiMAX rfkill is never updated because
it's not yet used, wifi would never be enabled after resume.