Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
The gateway is a global property of the IPv4/IPv6 configuration, not
an attribute of any particular address. So represent it as such in the
API; remove the gateway from NMIPAddress, and add it to
NMSettingIPConfig.
Behind the scenes, the gateway is still serialized along with the
first address in NMSettingIPConfig:addresses, and is deserialized from
that if the settings dictionary doesn't contain a 'gateway' key.
Adjust nmcli's interactive mode to prompt for IP addresses and gateway
separately. (Patch partly from Jirka Klimeš.)
NMSettingIP[46]Config let you associate a gateway with each address,
and the writable settings backends record that information. But it
never actually gets used: NMIP4Config and NMIP6Config only ever use
the first gateway, and completely ignore any others. (And in the
common usage of the term, an interface can only have one gateway
anyway.)
So, stop pretending that multiple gateways are meaningful; don't
serialize or deserialize gateways other than the first in the
'addresses' properties, and don't read or write multiple gateway
values either.
Split a base NMSettingIPConfig class out of NMSettingIP4Config and
NMSettingIP6Config, and update things accordingly.
Further simplifications of now-redundant IPv4-vs-IPv6 code are
possible, and should happen in the future.
Add key-value attributes to NMIPAddress and NMIPRoute, and use them to
store IPv4 address labels. Demote NMSettingIP4Config:address-labels to
a D-Bus-only property, and arrange for :addresses setter to read the
labels out of that property when creating the addresses.
Merge NMIP4Address and NMIP6Address into NMIPAddress, and NMIP4Route
and NMIP6Route into NMIPRoute. The new types represent IP addresses as
strings, rather than in binary, and so are address-family agnostic.
add two functions nm_ip4_config_get_direct_route_for_host()
and nm_ip6_config_get_direct_route_for_host() to check if we have
a direct (non-gw) route to a certain host.
Signed-off-by: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=738590
Make the :addresses and :routes properties be GPtrArrays of
NMIP4Address, etc, rather than just reflecting the D-Bus data.
Make the :dns properties be arrays of strings rather than arrays of
binary IP addresses (and update the corresponding APIs as well).
Change all DBUS_TYPE_G_LIST_OF_STRING and DBUS_TYPE_G_ARRAY_OF_STRING
properties to G_TYPE_STRV, and update everything accordingly.
(This doesn't actually require using
_nm_setting_class_transform_property(); dbus-glib is happy to transform
between 'as' and G_TYPE_STRV.)
Add a header file to expose private utility functions from libnm-core
that can be used by NetworkManager (core) and libnm.so. The header
is also used to give privileged access to libnm-core. Since NM links
statically, these functions are not exported and not part of public ABI.
This also removes the NM_UTILS_PRIVATE_CALL() macro and libnm.so no
longer exports nm_utils_get_private().
Before, this functionality was partly declared in nm-utils-private.h.
This was wrong because nm-utils-private.h is for functionality
entirely private to libnm-core.
Signed-off-by: Thomas Haller <thaller@redhat.com>
In nm_ip4_config_commit() and nm_ip6_config_commit() there is no need
to copy the route. Just use the pointer returned from nm_ip4_config_get_route()/
nm_ip6_config_get_route().
Signed-off-by: Thomas Haller <thaller@redhat.com>
At some places, we considered a default route to be a route with
destination network 0.0.0.0 (::). This is wrong because a default route
is a route with plen==0.
This is for example relevant for OpenVPN which adds two routes
0.0.0.0/1 and 128.0.0.0/1 to hijack the default route. We should
not treat 0.0.0.0/1 as default route, instead NM should treat
it as any other subnet route (even if it effectively routes large
parts).
Signed-off-by: Thomas Haller <thaller@redhat.com>
Remove all remaining GParamSpec name and blurb strings (and fix
indentation while we're there), and add G_PARAM_STATIC_STRINGS to all
paramspecs that were lacking it.
When generating an NMConnection to match the current state of a
device, don't add its RA-provided and DHCP-provided routes to the
NMSettingIP4Config/NMSettingIP6Config, since those routes didn't come
from the connection profile before.
https://bugzilla.gnome.org/show_bug.cgi?id=729203
Instead of creating most routes with metric 0 and then fixing them
just before applying them, create the routes with the correct metric
in the first place (so that NMIP4Config and NMIP6Config don't have to
try to guess whether "metric 0" means "unset" or "actually metric 0").
NMIP4Config and NMIP6Config had methods to update an existing
NMSetting. However, the functions would really only work correctly if
the passed-in setting was empty.
Change them from "update_setting" to "create_setting", and have them
create the NMSetting themselves, and update NMDevice for that.
(If we need update_setting later, we can add it, after figuring out
exactly how it's actually supposed to work.)
When adding the same addresses from different sources, we want to
preserve the times with the later expiry . If the new address comes
from the kernel itself, we treat it specially and prefer the times
from other sources.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Before, when adding a gateway route to a destination within the
current subnets, it would be skipped because of the wrong assumption
that we already have a prefix route to that destination.
This assumption is wrong, because we want to reach the more specific
subnet via a gateway and not directly on the link.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Two issues:
1) routes added by external programs or by users with /sbin/ip should not
be modified, but NetworkManager was always changing those routes' metrics
to match the device priority. This caused the nm_platform_ipX_route_sync()
functions to remove the original, external route (due to mismatched metric)
and re-add the route with the NetworkManager specified metric. Fix that
by not touching routes which came from the kernel.
2) Static routes (from persistent connections) that specified a metric were
getting their metric overwritten with the NetworkManager device priority.
Stop doing that.
Since the platform no longer defaults the metric to 1024, callers of
nm_platform_ip4_route_add() (like NMPolicy's default route handling)
must do that themselves, if they desire this behavior.
Tag addresses and routes with their source. We'll use this later to do
(or not do) operations based on where the item came from.
One thing to note is that when synchronizing items with the kernel, all
items are read as source=KERNEL even when they originally came from
NetworkManager, since the kernel has no way of providing this source
information. This requires the source 'priority', which
nm_ip*_config_add_address() and nm_ip*_config_add_route() must respect
to ensure that NM-owned routes don't have their source overwritten
when merging various IP configs in ip*_config_merge_and_apply().
Also of note is that memcmp() can no longer be used to compare
addresses/routes in nm-platform.c, but this had problems before
anyway with ifindex, so that workaround from nm_platform_ip4_route_sync()
can be removed.
https://bugzilla.gnome.org/show_bug.cgi?id=722843https://bugzilla.redhat.com/show_bug.cgi?id=1005416
Now that the objects get replaced when IP configuration changes
instead of being destroyed and a new one created, they need
PropertiesChanged signals.
(noticed as a result of auditing all exported D-Bus objects)
When a gateway is not in the prefix of any of the interface's IP addresses,
NetworkManager adds a static host route to the gateway through the
interface to ensure the gateway can be reached. That route will not
be part of the persistent connection (since it was added automatically)
but would normally be picked up by connection generation. This would
cause the generated connection not to match with the persistent
connection, because the persistent connection does not have the host
route. Ignore the gateway host route when capturing the interface's
existing IP configuration.
In the migration to NMPlatform, support for ptp/peer addresses was
accidentally dropped. This broke OpenVPN configurations using 'p2p'
topology, which send a different peer address than the local address
for tunX, plus the server may also push routes that use the peer
address as the next hop. NetworkManager was unable to add these
routes, because the kernel had no idea how to talk to the peer,
because the peer's address was not assigned to any interface or
reachable over any routes.
Partly based on a patch from Dan Williams.
There can be multiple default routes for an interface with different
metrics. Grab the gateway of the default route with the lowest
metric as the overall gateway of the IP config. Otherwise the rest
could get left in the config and applied at random times.
If the interface who's IP configuration is being captured has the default
route, then read DNS servers from resolv.conf into the NMIP[4|6]Config.
This allows NetworkManager to repopulate resolv.conf if anything changes.
For example, if the system does not define a persistent hostname, then
when a device which has generated a connection activates, a hostname
lookup will be performed. The results of that lookup may change resolv.conf,
and thus NetworkManager must rewrite resolv.conf. Without capturing
DNS information at startup when generating connections, an empty
resolv.conf would be written.
Follow the IP configuration the device currently has. For IPv6, this means
not using LINK_LOCAL if the interface doesn't have a LINK_LOCAL address.
Otherwise, NM assumes too much and may begin to activate an interface that
has no IP configuration, then time out and deactivate that device.
Also improve nm_ip4_config_dump to print all properties and make
use of nm_platform_*_to_string.
Also, ensure that never_default is set to gboolean 1 or 0.
Signed-off-by: Thomas Haller <thaller@redhat.com>
When the IP[46]Config changes, a new configuration gets assembled.
Before, whenever the new configuration was different than the current
one, the IP[46]Config of the device was completely replaced. This also
meant, that the old dbus IP[46]Config object was removed and the new one
was exported.
Now instead of recreating a new configuration, it updates the existing
(already exported) configuration in-place.
Also, add new gobject properties 'gateway' and 'searches' to the config class,
they will be exported over dbus.
Also, whenever any of the exported properties changes, make sure that a
notify signal gets emitted.
https://bugzilla.gnome.org/show_bug.cgi?id=707617
Signed-off-by: Thomas Haller <thaller@redhat.com>
This new function copies the entire configuration of an existing
NMIP[46]Config object (src) and replaces the configuration in the destination
object (dst) in-place.
Signed-off-by: Thomas Haller <thaller@redhat.com>
libgsystem contains more than just the local allocation macros; in the
future we will likely want to make use of some of this such as the
structured logging support.
Before, when a route failed to be added, NM stopped adding further
routes. However, the activation still continued and the user was not
notified about the error.
Adding a route might fail for example if the gateway is not on one of
the subnets of the interface.
Now, a failure to add a route makes the activaion fail. If the
connection has autoconnect=yes, this might result in some unsuccessful
reconnection attempts.
In the future, we might want to distinguish between manually added routes
and routes from RA/DHCP. So that connecting to a wrongly configured DHCP
server still works for most parts.
https://bugzilla.redhat.com/show_bug.cgi?id=999544
Signed-off-by: Thomas Haller <thaller@redhat.com>
The fix in commit b5b43a6d65 missed the
release of the route instance (because nm_setting_ip4_config_add_route
does not take over the passed route but duplicates it).
So the orginal error was to free the route with the wrong deallocation
method gs_unref_object instead of nm_ip4_route_unref.
Signed-off-by: Thomas Haller <thaller@redhat.com>