Instead of creating it in NMSettings, where we must use
NM_IS_DEVICE_ETHERNET() (not NM_DEVICE_TYPE_ETHERNET because various generic
devices masquerade as NM_DEVICE_TYPE_ETHERNET too), push knowledge
of which device types create default wired connections into the device
types themselves. This solves a problem with testcases where
libNetworkManager.a (which testcases link to) requires the symbol
nm_type_device_ethernet().
Instead of having basically the same code in a bunch of different
place to find helper programs, just have one place do it. Yes, this
does mean that the same sequence of paths is searched for all helpers
(so for example, dnsmasq will no longer be found first in /usr/local)
but I think consistency is the better option here.
https://bugzilla.gnome.org/show_bug.cgi?id=734131
NM keeps interfaces IFF_UP when possible to receive link layer
events like carrier changes. Unfortunately, the kernel also
uses IFF_UP as a flag to assign an IPv6LL address to the interface,
which results in IPv6 connectivity on the link even if the interface
is not supposed to be activated/connected.
NM sets disable_ipv6=1 to ensure that the kernel does not set up
IPv6LL connectivity on interfaces when they are not supposed to
be active and connected. Unfortunately, that prevents users from
manually adding IPv6 addresses to the interface, since they expect
previous kernel behavior where IPv6 is enabled whenever the
interface is IFF_UP.
Furthermore, interfaces like PPP and some WWAN devices provide
misleading information to the kernel which causes the kernel to
create the wrong IPv6LL address for the interface. The IPv6LL
address for these devices is obtained through control channels
instead (IPV6CP for PPP, proprietary protocols for WWAN devices)
and should be used instead of the kernel address. So we'd like
to suppress kernel IPv6LL address generation on these interfaces
anyway.
This patch makes use of the netlink IFLA_INET6_ADDR_GEN_MODE
attribute to take over assignment of IPv6LL addresses while
keeping the interface IFF_UP, to ensure there is only IPv6
connectivity when the user requests it.
To remain compliant with standards, if a user adds IPv6 addresses
externally, NetworkManager must also immediately add an IPv6LL
address for that interface too.
https://bugzilla.gnome.org/show_bug.cgi?id=734149
Make all mac-address properties (including NMSettingBluetooth:bdaddr,
NMSettingOlpcMesh:dhcp-anycast-addr, and NMSettingWireless:bssid) be
strings, using _nm_setting_class_transform_property() to handle
translating to/from binary form when dealing with D-Bus.
Update everything accordingly for the change, and also add a test for
transformed setting properties to test-general.
Even if we never receive an RA, if there are manually-specified or external
addresses, consider IPv6 to complete successfully. No reason to fail IPv6
if we have IP configuration already, but RA doesn't respond. If RA shows
up again, we're still listening for it and will apply the config at that
time.
Reporter left SLAAC enabled (because it's default and requires being
explicitly turned off) and added manual IPv6 address. They expected that
address to be assigned very soon after starting the connection, but it was
not assigned.
This happened because NM waits for RA before assigning any IPv6 configuration,
including the manually specified addresses. In the reporters case, there was
no IPv6 router on the network, so NM waited indefinitely for a router
advertisement and never applied any IPv6 configuration.
It seems reasonable to apply any IPv6 configuration we have available, when
we have it. We already apply RA configuration before starting DHCP, and
apply DHCP configuration if/when we get that.
The IPv4 pre-commit hook was called right before the config was
committed, while the IPv6 one was called before commit in only
one case (from nm_device_activate_ip6_config_commit). The IPv4
behavior is the intended behavior.
Note that this doesn't have any actual effect yet, since nothing
actually implements the IPv6 pre-commit hook
The fact that NMRemoteConnection has to be an NMConnection and
therefore can't be an NMObject means that it needs to reimplement bits
of NMObject functionality (and likewise NMObject needs some special
magic to deal with it). Likewise, we will need a daemon-side
equivalent of NMObject as part of the gdbus port, and we would want
NMSettingsConnection to be able to inherit from this as well.
Solve this problem by making NMConnection into an interface, and
having NMRemoteConnection and NMSettingsConnection implement it. (We
use some hacks to keep the GHashTable of NMSettings objects inside
nm-connection.c rather than having to be implemented by the
implementations.)
Since NMConnection is no longer an instantiable type, this adds
NMSimpleConnection to replace the various non-D-Bus-based uses of
NMConnection throughout the code. nm_connection_new() becomes
nm_simple_connection_new(), nm_connection_new_from_hash() becomes
nm_simple_connection_new_from_hash(), and nm_connection_duplicate()
becomes nm_simple_connection_new_clone().
For devices where we don't set the hardware address at construct time,
the first call to nm_device_update_hw_address() was hitting a
return-if-fail.
Also, when updating the hardware address, we were leaking the old
value.
Now that we have nm_utils_hwaddr_matches() for comparing addresses
(even when one is a string and the other binary), there are now places
where it's more convenient to store hardware addresses as strings
rather than binary, since we want them in string form for most
non-comparison purposes. So update for that.
In particular, this also changes nm_device_get_hw_address() to return
a string.
Also, simplify the update_permanent_hw_address() implementations by
assuming that they will only be called once. (Since they will.)
Add nm_utils_hwaddr_matches(), for comparing hardware addresses for
equality, allowing either binary or ASCII hardware addresses to be
passed, and handling the special rules for InfiniBand hardware
addresses automatically. Update code to use it.
Include <linux/if_ether.h> and <linux/if_infiniband.h> from
nm-utils.h, to get ETH_ALEN and INFINIBAND_ALEN, and remove those
includes (as well as <net/ethernet.h> and <netinet/ether.h>, and
various headers that had been included to get the ARPHRD_* constants)
from other files where they're not needed now.
Drop the arptype-based nm_utils_hwaddr funcs, and rename the
length-based ones to no longer have _len in their names. This also
switches nm_utils_hwaddr_atoba() to using a length rather than an
arptype, and adds a length argument to nm_utils_hwaddr_valid() (making
nm_utils_hwaddr_valid() now a replacement for nm_utils_hwaddr_aton()
in some places, where we were only using aton() to do validity
checking).
GLib/Gtk have mostly settled on the convention that two-letter
acronyms in type names remain all-caps (eg, "IO"), but longer acronyms
become initial-caps-only (eg, "Tcp").
NM was inconsistent, with most long acronyms using initial caps only
(Adsl, Cdma, Dcb, Gsm, Olpc, Vlan), but others using all caps (DHCP,
PPP, PPPOE, VPN). Fix libnm and src/ to use initial-caps only for all
three-or-more-letter-long acronyms (and update nmcli and nmtui for the
libnm changes).
Make use of the previously added _LOG() macros in nm-device.c.
This reduces code, but also ensures printing the same prefix for
every logline produced *for* a device instance.
Signed-off-by: Thomas Haller <thaller@redhat.com>
OtherConf implies the address has already been delivered via RA,
and possibly DNS too, meaning our IP configuration is already
good enough. If nothing on the network bothers to reply to our
DHCPv6 Information Requests, let's just run with the config
we already have instead of tearing down the whole device.
We want to set the WWAN config last, to ensure that the configuration we
use overwrites anything that pppd might have set, becuase it touches some
stuff itself. That means we have to keep the WWAN config separate, since
dev_ip4_config is used for DHCP and IPv4LL, which we always set first to
ensure they these don't overwrite external, administrator added config
(eg, priv->ext_ip4_config).
This also synchronizes the IPv4 config path with the upcoming IPv6
config path.
If the IID cannot be generated, the IPv6 address resulting from
the combination of an advertised prefix and 64-bits of zero is
both wrong and quite likely to clash with some other machine on
the network that doesn't implement IPv6 quite right either.
Require an valid interface identifier. If NetworkManager doesn't
know how to generate one, then we should fix NM to do so.
Ethernet-like interfaces aren't the only type of interfaces that can
run IPv6 but the rdisc code only returns an address if the interface's
hardware address is 6 bytes.
Interface types like PPP (rfc5072) and IPoIB (rfc4391) have their own
specifications for constructing IPv6 addresses and we should honor
those.
So instead of expecting a MAC address, let each device subclass
generate an Interface Identifier and use that for rdisc instead.
We no longer need a class method for reading the hardware address
length, for a couple reasons:
1) Using the IP interface hardware address for IP operations now makes
NMDevice's priv->hw_addr_len constant. So there's no reason to re-read
it all the time.
2) get_hw_address_length() is now only used for determining whether the
hardware address is permanent, and that only mattered for Bluetooth.
Since Bluetooth interfaces have a bogus interface name, they will never
have a valid ifindex, and thus nm_platform_link_get_address() would be
useless. So instead of using the 'permanent' stuff, just don't bother
updating the hardware address if the NMDevice's ifindex isn't valid,
and let subclasses pass the initial hardware address at device creation.
This also works correctly for NMDevice classes that previously
implemented get_hw_address_length() like ADSL and WWAN, since those
too will never have a valid ifindex or a valid hardware address.
3) Reading the device's hardware address length just ended up calling
nm_platform_link_get_address() for most devices anyway, so
nm_device_update_hw_address() would effectively read the link address
twice (once to read the length, the second time to read the actual
address). Let's just read the address once.
The IP interface may have its own hardware address (like the net
port for WWAN devices) and that's the hardware address that must be
used for DHCP and IPv6 SLAAC, not the hardware address (if any) of
the NMDevice itself.
This patch does change the NMDevice hardware address property to
always be the Device's hardware address, instead of the IP interface
hardware address. This means that ADSL and WWAN will no longer
change their hardware address to the hardware address of their
IP interface. But in all these cases, the hardware address is
non-existent (PPP) or transient and meaningless (WWAN/ADSL).
NMConfigDevice was added because in the 0.9.8 days, when each subdir
of src/ was compiled separately, it was impossible to make src/config/
depend on src/devices/ because of circular dependencies.
Since now everything gets compiled into a single libNetworkManager.la,
this is no longer a problem, and so NMConfigDevice is just an
unnecessary complication.
Clean up some of the cross-includes between headers (which made it so
that, eg, if you included NetworkManagerUtils.h in a test program, you
would need to build the test with -I$(top_srcdir)/src/platform, and if
you included nm-device.h you'd need $(POLKIT_CFLAGS)) by moving all
GObject struct definitions for src/ and src/settings/ into nm-types.h
(which already existed to solve the NMDevice/NMActRequest circular
references).
Update various .c files to explicitly include the headers they used to
get implicitly, and remove some now-unnecessary -I options from
Makefiles.
The options hash is never used except for BOUND events, so don't
bother caching it in the DHCP client object. Just pass it along
with the BOUND state change, like the IP configuration object.
DHCP failure should just clean up the client in all cases. This
also has the benefit of removing the signal handler for the DHCP
client's state-change signal before telling the client to terminate,
which will simplify some DHCP code later.
No reason to have two signals for the same thing. Previously, the
TIMEOUT signal was used for the internal overall DHCP transaction
bound, while DHCP_STATE_TIMEOUT/DHC_TIMEOUT was a signal from
the DHCP client itself that something had timed out. But in both
cases the results should be the same, so just collapse the
stand-alone TIMEOUT signal into the DHCP_STATE_TIMEOUT state.
The existing DHC_* states are pretty specific to dhclient, and aren't
useful for more generalized DHCP. NetworkManager wasn't using many
of the states anyway, and doesn't need to differentiate between
states like REBOOT/REBIND/RENEW anyway. So simplify the DHCP states
into the ones we really care about.
No need to keep references of the singleton and take an additional ref
when accessing nm_firewall_manager_get().
Especially, since the firewall manager instance was nowhere passed in from
externally, it doesn't even sense for some vague testing purporse. Not to
mention, that there are no tests that actually inject a firewall manager stub.
Signed-off-by: Thomas Haller <thaller@redhat.com>