DHCPv6 RFCs require the DUID to be constant over time and to
be used as a permanent identifiers of the machine. This precludes
using a network interface MAC address since the MAC address may
change, and there may be more than one network interface installed.
Storing the DUID causes problems when an OS image is cloned between
virtual or physical machines because then the saved DUID is no longer
unique.
To fix all these issues, generate the DUID from the machine's hashed
machine-id, which is already a unique identifier of the machine and
will always be present because dbus requires it, and NM requires
dbus. It is assumed administrators will change the machine-id when
cloning an OS image; thus they only have to update one file, not
two (machine-id and the stored DUID).
Administrators may still override the machine-id-derived DUID by
setting a DUID in the default dhclient config file or the
interface-specific dhclient config files.
dhclient no longer saves a generated DUID to the config files,
because the default DUID will always be regenerated from
the machine-id on startup and thus always stable.
We avoid requesting to auto-start the service when the 'MMManager' is created,
so that we can use it to follow name-owner changes (when auto-starting
requested the 'MMManager' creation may fail).
We still handle the periodic poking to the service, but instead of re-creating
the 'MMManager', we just call org.freedesktop.DBus.Peer.Ping().
Like we do when the user sets the Wireless Enabled property at
runtime, ensure the kernel's softblock state is synced with the
user's WiFi enable preference at startup. This helps compensate
for BIOSes that don't save rfkill state over reboots and ensures
consistency of between startup and runtime Wireless Enabled
property behavior.
Suggested by John G.
Some devices (namely PPPoE (pppX), ADSL (nasX, pppX), and
mobile broadband (pppX, bnepX)) create a kernel netdevice for IP
communication (called the "IP interface" in NM) as part of the
connection process and thus the IP interface lifetime does not
correspond to the NMDevice lifetime. For these devices we must
ignore removal events for the IP interface name otherwise the
NMDevice would be removed.
Caused by 8cce42f2.
For example, this bug caused the NMDeviceBt to be removed when
a PAN connection's bnepX interface went down in response to a
terminated Bluetooth connection, which of course means that
you can't restart the PAN connection as your phone is no longer
in the NM device list.
Until we handle bridges non-destructively, only manage bridges
created by NM. When quitting write out a file listing all
bridges created by NM and a timestamp, and when starting read
that file and if the timestamp is within 30 minutes, manage
any bridge that was listed in that file. This scheme, while
not foolproof (eg, if NM crashes), should ensure that NM can
recognize bridges it created if it's restarted. The file
is stored in /run or /var/run, which is cleaned each restart,
ensuring that the state does not persist across reboots.
If an automatic or user-initiated activation request for
a bridge NM does not manage is received, that request is
denied. Only if the bridge interface does not yet exist, or
was present in the managed bridges file, will an
NMDeviceBridge be created and activation be possible.
If the IP configuration requires slaves/ports, starting IP configuration
before the master device has a carrier (which means at least one slave
or port has a carrier and the device is initialized) is pointless, and
will just take longer or fail. Recent kernels have cleaned up carrier
handling on bridge/bond devices and the carrier is now a reliable
indication of whether or not the master device is ready to send/receive
traffic. Thus, if we don't have a carrier, obviously no IP configuration
that depends on connectivity is going to work.
The bridge master's carrier follows IFF_UP when no ports are added
and the ports' carrier when ports are added, so we shouldn't
depend on carrier when deciding whether to activate a bridge which
may not have any ports. Also when the
Bond master carrier state follows slave carriers, so clearly we
can't depend on carrier when deciding whether we can activate a
bond connection which doesn't yet have any slaves. Also, when
the bond's carrier goes down, we don't want to deactivate the
connection because this is normal in some failover modes and
could be the user reconfiguring slaves.
Less confusing in the logs to see the change logged before listeners
have a chance to emit other log messages that may depend on the new
carrier state.
The kernel bonding code calls "closes" (which clears IFF_UP) the slave
and restores some of its attributes (MAC address, MTU, etc), but doesn't
bring it back up. This breaks things like carrier detection, and
indeed when the device is closed, its carrier is also cleared, which
leads us to think the device is not available for activation.
To ensure that further events are noticed by the device, and that its
carrier state is accurately represented, make sure the device is still
IFF_UP after it has been released.
The hardware address of a device often changes when slaves change,
for example with bond interfaces, which take the hardware address of
their first slave. Make sure that's always up-to-date.
It's not very helpful to deactivate a slave of a bond or a bridge
port because the carrier is lost. Carrier failures are normal
operation when using various bonding failover modes. For bridge
ports, it's probably not very helpful either. Given that the
masters are all virtual interfaces and have been explicitly
configured and started by a user, the configuration should
generally be left alone unless explicitly deactivated or changed.
Two things:
1) When the slave was deactivated, nm_device_deactivate() runs before
the master gets the slave's state-changed signal, and thus priv->master
is cleared long before nm_device_notify_enslaved() is called. Which
would trigger the g_assert (priv->master).
2) If the slave is already deactivated, there's no point in re-queueing
a state change to deactivated.
So just assert that priv->master is valid if the slave is going to be
enslaved, but if the slave is being released, ignore NULL priv->master
which we don't use anyway. Also ignore redundant state changes.
The DUID is supposed to be machine-wide, so if we're writing a new
leasefile, save the default DUID to it. If we haven't saved a
persistent DUID yet, do that to.
Add infrastructure for generating DUID-LLT from a given device MAC and
passing it around to the DHCP client implementations.
Thanks to Mathieu Trudel-Lapierre for bug fixes in the
unescaping code, which were merged into this commit.
Broken by e7caad20c9.
Admittedly, GObject is opaque in this area. But here's the
equivalent concepts in C++:
*_GET_CLASS (object)->function(object):
- call youngest implementation of virtual function; checks current
object for implementation and calls it, if not overridden by the
child, walks up the inheritance chain and calls parent,
grandparent, etc. C++ equivalent is calling foo::function().
*_CLASS (object_parent_class)->function(object):
- call named parent class implementation, *not* including current
object. C++ equivalent is calling ParentClass::function().
Using _GET_CLASS()->function() inside the child implementation of
function() recursively calls the child implementation of function()
and overflows the call stack.
The code flow is actually somewhat simpler this way since the
subclasses don't have to ask NMDeviceWired for the address
every time. Plus then NMDeviceWired doesn't have to know
anything about its subclasses in the constructor.
Instead of using a mix of netlink and SIOCGIFHWADDR and doing it
in every device, create a utility function for this and have
everywhere else call that.