Commit graph

1131 commits

Author SHA1 Message Date
Thomas Haller
96f1358eef core: return new route from _nm_ip_config_add_obj()
Later we will need the exact instance that we just added (or the previously
existing one, if the new route is already tracked).
2017-09-08 11:05:05 +02:00
Thomas Haller
315bd0a97d core: add nm_utils_connection_has_default_route()
Taken from "src/nm-default-route-manager.c".
2017-09-08 11:05:04 +02:00
Thomas Haller
e99a603944 device: expose nm_device_get_ip_route_metric() function
Will be used later.
2017-09-08 11:05:04 +02:00
Thomas Haller
c16e871888 core: nm_utils_ip_route_metric_normalize() util
Functions that take and addr_family argument are just nicer
to use at places where we treat IPv4 and IPv6 generically.
2017-09-08 11:05:04 +02:00
Thomas Haller
c8e6f3e5fb vpn: fix ifindex of parent IP config in apply_parent_device_config()
When creating the NMIP4Config/NMIP6Config instance, we must always use the right
ifindex. That is the ifindex, on which we want to apply the config. It also means,
that for device-based VPNs (those with priv->ip_ifindex set, like OpenVPN), the
parent's config must have the ip-ifindex of the parent device. Not of the
VPN's device.

One effect of this bug is that in add_ip4_vpn_gateway_route() we resolve
the route to the external gateway and only accept it if it's on the
parent device. But since the ifindex of the config was wrong, we would accept
route on the wrong interface.

https://bugzilla.gnome.org/show_bug.cgi?id=787370
2017-09-07 11:14:27 +02:00
Thomas Haller
5c42cdb287 all: use _nm_utils_ip4_*() utils functions 2017-09-05 18:44:04 +02:00
Thomas Haller
a17195b844 device: extend wait time for carrier after MTU change
Especially during an MTU change, the driver might need longer to
bring back carrier. In this case, extend the wait time.

https://bugzilla.redhat.com/show_bug.cgi?id=1487702
2017-09-04 21:44:10 +02:00
Beniamino Galvani
981f90e324 device: don't release external slaves on state change
If the slave is 'external' we should never touch it, in particular we
should not release the link from its master; we only have to remove it
from master's list.

https://bugzilla.redhat.com/show_bug.cgi?id=1442361
2017-09-02 10:38:28 +02:00
Beniamino Galvani
9e99590508 device: don't promote slave devices to managed
Previously, if a master device had internal state 'managed', we would
promote the slave to 'managed' as well. However,

 - if the slave is 'external', it should stay as is because we don't
   want to start managing it

 - if the slave is 'assumed', it will become managed when the
   activation succeeds, so it's not necessary to do it here

Fixes: 850c977953
2017-09-02 10:38:27 +02:00
Thomas Haller
10ac675299 platform: add support for routing tables to platform cache
The upper layers still ignore all routes outside the main table.
For now, just add support to NMPlatform.
2017-08-24 10:55:51 +02:00
Thomas Haller
b524d879f0 platform: pass string buffer to nm_platform_error_to_string() and print numeric errno
Change the output of nm_platform_error_to_string() to print the numeric value.
Also, accept a string buffer instead of using an alloca() allocated buffer.

There is still a macro to provide the previous functionality, but it
was ill-suited to call from inside a loop.
2017-08-24 10:55:45 +02:00
Thomas Haller
2f83894498 core: cleanup setting ifa_flags in ndisc_config_changed()
Some refactoring and one change:

If we don't have system-support, don't set IFA_F_MANAGETEMPADDR.
2017-08-24 10:48:03 +02:00
Thomas Haller
057b63979e core: move setting NDisc addresses/routes to NMIP6Config
Add an utility function for resetting addresses/routes of NMIP6Config
from NMNDisc data. For one, this de-duplicates code in device and
nm-iface-helper.

Also, we no longer first reset (delete) all addresses and add them anew.
Instead, we first mark all entries as dirty for deletion, merge (append)
the new entires, and delete the remaining dirty entires. This saves a
extra work, in the expected case where NMIP6Config already contains
several of the new entries.
2017-08-24 10:48:03 +02:00
Thomas Haller
f0de7d347f platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because

 - when configuring routes, multiple (managed) interfaces may get
   conflicting routes (multihoming). Only one of the routes can be actually
   configured using `ip route replace`, so we need to track routes that are
   currently shadowed.

 - when configuring routes, we might replace externally configured
   routes on unmanaged interfaces. We should not interfere with such
   routes.

That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.

Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.

It practice it is a bit more complicated because:

 - when adding an IPv4 address, kernel will automatically create a device route
   for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
   IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
   addresses yet (and we don't require such a kernel yet), we still need functionality
   similar to nm_route_manager_ip4_route_register_device_route_purge_list().
   This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().

 - trying to configure an IPv6 route with a source address will be rejected
   by kernel as long as the address is tentative (see related bug rh#1457196).
   Preferably, NMDevice would keep the list of routes which should be configured,
   while kernel would have the list of what actually is configured. There is a
   feed-back loop where both affect each other (for example, when externally deleting
   a route, NMDevice must forget about it too). Previously, NMRouteManager would have
   the task of remembering all routes which we currently want to configure, but cannot
   due to conflicting routes.
   We get rid of that, because now we configure non-exclusive routes. We however still
   will need to remember IPv6 routes with a source address, that currently cannot be
   configured yet. Hence, we will need to keep track of routes that
   currently cannot be configured, but later may be.
   That is still not done yet, as NMRouteManager didn't handle this
   correctly either.
2017-08-24 10:48:03 +02:00
Thomas Haller
990a050aff platform: cleanup and renaming of nm_platform_address_flush() function
Rename to nm_platform_ip_address_flush(), it's more consistent with naming
for other platform functions.

Also, pass an address family argument. Sometimes I feel an option makes it clearer
what the function does. Otherwise, from the name it's not clear which address
families are affected. As an API, it feels more correct to me.

We soon also get a nm_platform_ip_route_flush() function, which will
look similar.
2017-08-23 18:37:22 +02:00
Thomas Haller
94560e4ad2 platform: cleanup nmp_lookup_init_route_visible() lookup helper
nmp_lookup_init_route_visible() was originally named this way, to only return routes
that are nmp_object_is_visible(). However, all routes are visible (as long as they are
nmp_object_is_alive()). Hence, this is a historic misnomer.

Also, passing @only_default FALSE is identical to the
nmp_lookup_init_addrroute() lookup.

So, rename the function to indicate it is a lookup for default routes
only. Also, get rid of the unsupported ifindex argument for which there
is no index.
2017-08-12 16:04:28 +02:00
Beniamino Galvani
6c3195931e core: implement activation of PPP devices
Add code to NMPppDevice to activate new-style PPPoE connections. This
is a bit tricky because we can't create the link as usual in
create_and_realize(). Instead, we create a device without ifindex and
start pppd in stage2; when pppd reports a new configuration, we rename
the platform link to the correct name and set the ifindex into the
device.

This mechanism is inherently racy, but there is no way to tell pppd to
create an arbitrary interface name.
2017-08-05 08:03:16 +02:00
Beniamino Galvani
695f6ceebb device: accept NULL plink
For PPP devices we can't create a link in advance, as the link is
created by pppd when the connection is established.
2017-08-05 08:03:16 +02:00
Beniamino Galvani
df72cad107 device: add NMDevicePPP
The new device type represents a PPP interface, and will implement the
activation of new-style PPPoE connections, i.e. the ones that don't
claim the parent device.
2017-08-05 08:03:15 +02:00
Beniamino Galvani
2f4dfd0f2e device: don't set a fake permanent hardware address
Software devices don't have a permanent hardware address and thus it
doesn't make sense to enforce the 'fake' (generated) permanent one
when cloned-mac-address=permanent.  Also, setting the fake permanent
address on bond devices, prevents them from inheriting the first slave
hardware address, so let's just skip the setting of MAC when
cloned-mac-address=permanent and there is no real permanent address.

https://bugzilla.redhat.com/show_bug.cgi?id=1472965
2017-07-26 14:05:38 +02:00
Beniamino Galvani
25f2f33273 device: fix address check in start_sharing()
Fixes: 22edeb5b69
2017-07-25 14:49:50 +02:00
Thomas Haller
22edeb5b69 core: track addresses for NMIP4Config/NMIP6Config via NMDedupMultiIndex
Reasons:

 - it adds an O(1) lookup index for accessing NMIPxConfig's addresses.
   Hence, operations like merge/intersect have now runtime O(n) instead
   of O(n^2).
   Arguably, we expect low numbers of addresses in general. For low
   numbers, the O(n^2) doesn't matter and quite likely in those cases
   the previous implementation was just fine -- maybe even faster.
   But the simple case works fine either way. It's important to scale
   well in the exceptional case.
 - the tracked objects can be shared between the various NMPI4Config,
   NMIP6Config instances with NMPlatform and everybody else.
 - the NMPObject can be treated generically, meaning it enables code to
   handle both IPv4 and IPv6, or addresses and routes. See for example
   _nm_ip_config_add_obj().
 - I want core to evolve to somewhere where we don't keep copies of
   NMPlatformIP4Address, et al. instances. Instead they shall all be
   shared. I hope this will reduce memory consumption (although tracking a
   reference consumes some memory too). Also, it shortcuts nmp_object_equal()
   when comparing the same object. Calling nmp_object_equal() on the
   identical objects would be a common case after the hash function
   pre-evaluates equality.
2017-07-25 06:44:12 +02:00
Thomas Haller
beb0b9b1ad platform: reduce number of route indexes
Maintaining an index is expensive.Not so much in term of runtime, but
in term of memory.

Drop some indexes, and require the caller to use a more broad index (and
filter out unwanted elements).

Dropped:

 - can no longer lookup visible default-routes by ifindex.
   If you care about default-routes, lookup all and search for the
   desired ifindex. The overall number of default-routes is expected
   to be small.
   We drop NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_WITH_DEFAULT
   entirely.

 - no longer have a separate index for non-default routes. We
   expect that the most routes are non-default routes. So, don't
   have an index without default-routes, instead let the caller
   just lookup all routes, and reject default-routes themself.
   We keep NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_DEFAULT, but it
   now no longer tracks non-default routes.

This drops 1 out of 6 route indexes, and modifes another one, so
that we expect that there are almost no entires tracked by it.
2017-07-05 18:37:39 +02:00
Thomas Haller
667c50f5d9 core: avoid cloning platform routes but iterate the cache directly 2017-07-05 18:37:39 +02:00
Thomas Haller
89385bd968 core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.

For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.

The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-07-05 14:22:10 +02:00
Nikolay Martynov
8c91422954 device: handle carrier changes for master device differently
For master devices, instead of ignoring loss of carrier entirely,
handle it.

First of all, master devices are now by default ignore-carrier=yes.
That means, without explict user configuration in NetworkManager.conf,
the previous behavior in carrier_changed() does not change.

If the user decides to configure the master device like

    [device-with-carrier]
    match-device=type:bond,type:bridge,type:team
    ignore-carrier=no

then, master device will disconnect on carrier loss like
regular devices.

https://github.com/NetworkManager/NetworkManager/pull/18

Co-authored-by: Thomas Haller <thaller@redhat.com>
2017-06-22 13:27:01 +02:00
Thomas Haller
b0f6baad90 device: renew IP addressing on carrier change also for master devices
Commit 348452f1e0 (device: renew DHCP
lease for active "ignore-carrier" devices on carrier-on (bgo #743368))
added this behavior for non-master devices.

The same reasoning applies here too.

https://github.com/NetworkManager/NetworkManager/pull/18

Based-on-patch-by: Nikolay Martynov <mar.kolya@gmail.com>
2017-06-22 13:26:53 +02:00
Thomas Haller
e9a917d619 device: refactor how master device's set is_available()
Previously, master device types like bridge, bond, and team
would overwrite is_available() and check_connection_available()
and always return TRUE.

The device already expresses via nm_device_is_master() that it
is of a master kind. Refactor the code, so, instead of having these
device types overwrite is_available() and check_connection_available(),
let the parents implementation react on nm_device_is_master().

There is no change in behavior at all. Instead, the knowledge how to
treat a master device moves from the device implementation to the
parent class.
2017-06-22 13:26:53 +02:00
Thomas Haller
98651b90a1 device: handle default for unset ignore-carrier option depending on device
Currently, device types like Bond hack around ignore-carrier
setting, as they always want to ignore-carrier.

Prepare so that also for such master types, we rely and honor the
ignore-carrier setting better. In the next commit, bond, bridge and
team devices they will get ignore-carrier turned on by default.
2017-06-22 13:26:53 +02:00
Thomas Haller
10c0632df0 device: fix taking over device after modifying external connection
For externally managed interfaces, we create an in-memory connection
and keep the device with sys-iface-state=external.

When the user actively modifies the connection, we persist it to
storage. But we also must take over managing the device.

One problem is that nm_device_reapply() errors out if the device
is still activating. It's unclear how to reapply the connection
while the device is in the process of activation. So, if the user
modifies the created connection very quickly, reapplying the settings
will fail.

https://bugzilla.redhat.com/show_bug.cgi?id=1462223
2017-06-19 14:57:48 +02:00
Thomas Haller
4ca3002b86 device: don't set MTU of device unless explicitly configured
Since commit 2b51d3967 "device: merge branch 'th/device-mtu-bgo777251'",
we always set the MTU for certain device types during activation. Even
if the MTU is neither specified via the connection nor other means, like
DHCP.

Revert that change. On activation, if nothing explicitly configures the
MTU, leave it unchanged. This is like what we do with ethernet's
cloned-mac-address, which has a default value "preserve".
So, as last resort the default value for MTU is now 0 (don't change),
instead of depending on the device type.

Note that you also can override the default value in global
configuration via NetworkManager.conf.

This behavior makes sense, because whenever NM actively resets the MTU,
it remembers the previous value and restores it when deactivating
the connection. That wasn't implemented before 2b51d3967, and the
MTU would depend on which connection was previously active. That
is no longer an issue as the MTU gets reset when deactivating.

https://bugzilla.redhat.com/show_bug.cgi?id=1460760
2017-06-13 15:05:30 +02:00
Beniamino Galvani
aa099906f9 device: apply route metric penality only when the default route exists
It's useless (and in some cases also harmful) to commit the
configuration to update the default route metric when the device has
no default route. Also, don't commit configuration for externally
activated devices.

https://bugzilla.redhat.com/show_bug.cgi?id=1459604
2017-06-09 13:52:03 +02:00
Thomas Haller
0c26ffd638 device: suppress logging and return error reason from nm_device_generate_connection()
Don't log in a function that basically just inspects state, without
mutating it. Instead, pass the reason why a connection could not be
generated to the caller so that we have one sensible log message.
2017-06-08 21:50:23 +02:00
Thomas Haller
cc47a6a8b2 device: remove logging for emitting RECHECK_ASSUME signal
The device's RECHECK_ASSUME signal has only NMManager as subscriber
and it immediately calls recheck_assume_connection().

With the previous commit, recheck_assume_connection() always logs
a debug message, so we don't need this duplicate message anymore.
2017-06-08 21:50:23 +02:00
Thomas Haller
4b15df2656 device: expose nm_device_state_to_str() function for NMDeviceState 2017-06-08 21:50:23 +02:00
Thomas Haller
729de7d7f0 manager: fix preserving assume state during activation
Originally 850c977 "device: track system interface state in NMDevice",
intended that a connection can only be assumed initially when seeing
a device for the first time. Assuming a connection later was to be
prevented by setting device's sys-iface-state to MANAGED.

That changed too much in behavior, because we used to assume external
connections also when they are activated later on. So this was attempted
to get fixed by
  - acf1067 nm-manager: try assuming connections on managed devices
  - b6b7d90 manager: avoid generating in memory connections during startup for managed devices

It's probably just wrong to prevent assuming connections based on the
sys-iface-state. So drop the check for sys-iface-state from
recheck_assume_connection(). Now, we can assume anytime on managed,
disconnected interfaces, like previously.
Btw, note that priv->startup is totally wrong to check there, because
priv->startup has the sole purpose of tracking startup-complete property.
Startup, as far as NMManager is concerned, is platform_query_devices().

However, the problem is that we only assume connections (contrary to
doing external activation) when we have a connection-uuid from the state
file or with guess-assume during startup.

When assuming a master device, it can fail with

  (nm-bond): ignoring generated connection (IPv6LL-only and not in master-slave relationship)

thus, for internal reason the device cannot be assumed yet.

Fix that by attatching the assume-state to the device, so that on multiple
recheck_assume_connection() calls we still try to assume. Whenever we try
to assume the connection and it fails due to external reasons (like, the connection
no longer matching), we clear the assume state, so that we only try as
long as there are internal reasons why assuming fails.

https://bugzilla.redhat.com/show_bug.cgi?id=1452062
2017-06-08 21:46:34 +02:00
Thomas Haller
d83848be9d device: only set nm-owned from statefile during initial setup
The state file should only be read initially when NM starts, that is:
during NMManager's platform_query_devices().

At all later points, for example when a software device gets destroyed
and re-realized, the state file is clearly no longer relevant.

Hence, pass the set-nm-owned flag from NMManager to realize_start_setup().

This is very much the same as with the NM_UNMANAGED_FLAG_USER_EXPLICT flag,
which we also read from the state-file.
2017-06-08 21:44:22 +02:00
Beniamino Galvani
c66995ad4d device: check connectivity on the IP interface
curl must bind to the interface that has IP configuration, not the
underlying device. Without this commit, connectivity check fails on
certain connection types (PPPoE, WWAN).

Fixes: 9d43869e47
2017-06-08 11:01:05 +02:00
Beniamino Galvani
cf9ba271e6 manager: restore the previous persistent nm-owned state of devices
After a daemon restart, any software device is considered !nm-owned,
even if it was created by NM. Therefore, a device stays around even if
the connection which created it gets deactivated or deleted.

Fix this by remembering the previous nm-owned state in the device
state file.

https://bugzilla.redhat.com/show_bug.cgi?id=1376199
2017-06-07 10:27:02 +02:00
Beniamino Galvani
8cce037bf8 device: rename priv->is_nm_owned to priv->nm_owned
Only a matter of taste, but nm_device_get_is_nm_owned() sounds
strange.
2017-06-07 10:27:02 +02:00
Thomas Haller
c79a97657b device: transform NM_DEVICE_IS_MASTER gobject property to field in NMDeviceClass
We don't need this flexibility of having a full fledged GObject
property for is-master. The property value only depends on the
device's class.
2017-06-02 21:06:08 +02:00
Thomas Haller
c3aa52530c core: add nm_device_spec_match_list_full()
This gives a third return value: whether the device did not
match.
2017-06-02 21:06:08 +02:00
Thomas Haller
f2f9a635ff device: rename activate_stage5_ip4_config_commit() to activate_stage5_ip4_config_result()
We have nm_device_activate_schedule_ip4_config_result(). The name
should match.

Note, this affects logging, as we log the function name.
2017-06-02 21:06:08 +02:00
Thomas Haller
10efbc5887 device: prefix log messages related to carrier
It's easier to search in the logfile.
2017-06-02 21:06:08 +02:00
Thomas Haller
7f79b59330 device: move carrier_changed_notify() notification to nm_device_set_carrier()
Note that:

 - carrier_changed_notify() has only one implementation: NMDeviceEthernet
   to call get_link_speed() when carrier comes back.

 - currently, calling carrier_changed_notify() with carrier=FALSE
   has no effect, because NMDeviceEthernet only acts on carrier=TRUE.

  - when carrier appears, nm_device_set_carrier() will call
    carrier_changed() right away. We only call carrier_changed()
    with carrier=TRUE only at one place. The change merley moves
    carrier_changed_notify() out of the function. Apart from
    that it has no effect.

  - when carrier disappears, previoulsy we would delay action for
    4 seconds. Hence, we would delay carrier_changed_notify() as well
    -- although it has no effect.

The last point is at least ugly. Fix it by moving
carrier_changed_notify() to nm_device_set_carrier().
2017-06-02 21:06:07 +02:00
Lubomir Rintel
bf7e86128c bridge: move the Bluetooth NAP logic to bridge device
The Bluetooth NAP functionality seems only useful for the bridges. Move
it away from NMDevice.
2017-06-01 11:57:42 +02:00
Thomas Haller
b0f9571d3d libnm: add _nm_connection_get_setting_bluetooth_for_nap()
If there is value in such a helper function (there is), then
it should go alongside the other nm_connection_get_setting*()
helpers. NMDevice is already large enough.
2017-06-01 11:28:57 +02:00
Thomas Haller
1be01bd51f device: don't include header of bluetooth plugin in nm-device.h
The plugins may use stuff from core, but not the other way around.
Including "bluetooth/nm-bluez-common.h" is wrong.

The UUID argument is always "nap" in the NAP case. We don't need
the flexibility that it might be anything else. Just drop it.

As far as NMDevice is concerned, it anyway wouldn't (or shouldn't
know what the uuid is. It says register, and NMBluez5Manager should
figure out the details.
2017-06-01 11:28:57 +02:00
Lubomir Rintel
53482c38e2 device: register a bridge for Bluetooth NAP with Bluez
Bluez needs to know about then so that it can eventually enslave the BNEP links
for PANU client connections to it.
2017-05-31 20:18:24 +02:00
Lubomir Rintel
b866a12667 device: retry autoactivation upon a component addition
It might have changed circumstances that were blocking the autoactivation.
2017-05-31 20:18:12 +02:00